#include <math.h>
#include <stdio.h>
#include <string.h>
#include "getpar.h"
#include "trek.h"
int
events(int warp)
{
int i, j;
char *p;
struct kling *k;
double rtime;
double xdate;
double idate;
struct event *ev = NULL;
int ix, iy;
struct quad *q;
struct event *e;
int evnum;
int restcancel;
if (Move.time <= 0.0)
{
Now.time = Now.resource / Now.klings;
return (0);
}
Ship.cloakgood = 1;
idate = Now.date;
if (Move.time > 0.5 && Move.resting)
schedule(E_ATTACK, 0.5, 0, 0, 0);
while (1)
{
restcancel = 0;
evnum = -1;
xdate = idate + Move.time;
for (i = 0; i < MAXEVENTS; i++)
{
e = &Event[i];
if (e->evcode == 0 || (e->evcode & E_GHOST))
continue;
if (e->date < xdate)
{
xdate = e->date;
ev = e;
evnum = i;
}
}
e = ev;
rtime = xdate - Now.date;
Now.resource -= Now.klings * rtime;
Now.time = Now.resource / Now.klings;
Now.date = xdate;
if (Now.time <= 0.0)
lose(L_NOTIME);
# ifdef xTRACE
if (evnum >= 0 && Trace)
printf("xdate = %.2f, evcode %d params %d %d %d\n",
xdate, e->evcode, e->x, e->y, e->systemname);
# endif
if (evnum < 0)
break;
switch (e->evcode & E_EVENT)
{
case E_SNOVA:
snova(-1, 0);
xresched(e, E_SNOVA, 1);
break;
case E_LRTB:
xresched(e, E_LRTB, Now.klings);
if (Ship.cond != DOCKED)
{
i = ranf(Now.klings) + 1;
for (ix = 0; ix < NQUADS; ix++)
{
for (iy = 0; iy < NQUADS; iy++)
{
q = &Quad[ix][iy];
if (q->stars >= 0)
if ((i -= q->klings) <= 0)
break;
}
if (i <= 0)
break;
}
if (Ship.quadx == ix && Ship.quady == iy)
break;
Ship.quadx = ix;
Ship.quady = iy;
printf("\n%s caught in long range tractor beam\n", Ship.shipname);
printf("*** Pulled to quadrant %d,%d\n", Ship.quadx, Ship.quady);
Ship.sectx = ranf(NSECTS);
Ship.secty = ranf(NSECTS);
initquad(0);
Move.time = xdate - idate;
}
break;
case E_KATSB:
if (Now.bases <= 0)
{
unschedule(e);
break;
}
for (i = 0; i < Now.bases; i++)
{
ix = Now.base[i].x;
iy = Now.base[i].y;
q = &Quad[ix][iy];
if (q->klings <= 0)
continue;
for (j = 0; j < MAXEVENTS; j++)
{
e = &Event[j];
if ((e->evcode & E_EVENT) != E_KDESB)
continue;
if (e->x == ix && e->y == iy)
break;
}
if (j < MAXEVENTS)
continue;
break;
}
e = ev;
if (i >= Now.bases)
{
reschedule(e, 0.5 + 3.0 * franf());
break;
}
xresched(e, E_KATSB, 1);
e = xsched(E_KDESB, 1, ix, iy, 0);
if (!damaged(SSRADIO))
{
printf("\nUhura: Captain, we have received a distress signal\n");
printf(" from the starbase in quadrant %d,%d.\n",
ix, iy);
restcancel++;
}
else
e->evcode |= E_HIDDEN;
break;
case E_KDESB:
unschedule(e);
q = &Quad[e->x][e->y];
if (q->bases <=0 || q->klings <= 0)
break;
if (e->x == Ship.quadx && e->y == Ship.quady)
{
printf("\nSpock: ");
killb(Ship.quadx, Ship.quady);
}
else
killb(e->x, e->y);
break;
case E_ISSUE:
xresched(e, E_ISSUE, 1);
if (Ship.distressed >= MAXDISTR)
break;
for (i = 0; i < 100; i++)
{
ix = ranf(NQUADS);
iy = ranf(NQUADS);
q = &Quad[ix][iy];
if (!((ix == Ship.quadx && iy == Ship.quady) || q->stars < 0 ||
(q->qsystemname & Q_DISTRESSED) ||
(q->qsystemname & Q_SYSTEM) == 0 || q->klings <= 0))
break;
}
if (i >= 100)
break;
Ship.distressed++;
e = xsched(E_ENSLV, 1, ix, iy, q->qsystemname);
q->qsystemname = (e - Event) | Q_DISTRESSED;
if (!damaged(SSRADIO))
{
printf("\nUhura: Captain, starsystem %s in quadrant %d,%d is under attack\n",
Systemname[e->systemname], ix, iy);
restcancel++;
}
else
e->evcode |= E_HIDDEN;
break;
case E_ENSLV:
unschedule(e);
q = &Quad[e->x][e->y];
if (q->klings <= 0)
{
q->qsystemname = e->systemname;
break;
}
e = schedule(E_REPRO, Param.eventdly[E_REPRO] * franf(), e->x, e->y, e->systemname);
if (!damaged(SSRADIO))
{
printf("\nUhura: We've lost contact with starsystem %s\n",
Systemname[e->systemname]);
printf(" in quadrant %d,%d.\n",
e->x, e->y);
}
else
e->evcode |= E_HIDDEN;
break;
case E_REPRO:
q = &Quad[e->x][e->y];
if (q->klings <= 0)
{
unschedule(e);
q->qsystemname = e->systemname;
break;
}
xresched(e, E_REPRO, 1);
ix = e->x;
iy = e->y;
if (Now.klings == 127)
break;
if (q->klings >= MAXKLQUAD)
{
for (i = ix - 1; i <= ix + 1; i++)
{
if (i < 0 || i >= NQUADS)
continue;
for (j = iy - 1; j <= iy + 1; j++)
{
if (j < 0 || j >= NQUADS)
continue;
q = &Quad[i][j];
if (q->klings >= MAXKLQUAD || q->stars < 0)
continue;
break;
}
if (j <= iy + 1)
break;
}
if (j > iy + 1)
break;
ix = i;
iy = j;
}
q->klings++;
Now.klings++;
if (ix == Ship.quadx && iy == Ship.quady)
{
sector(&ix, &iy);
Sect[ix][iy] = KLINGON;
k = &Etc.klingon[Etc.nkling++];
k->x = ix;
k->y = iy;
k->power = Param.klingpwr;
k->srndreq = 0;
compkldist(Etc.klingon[0].dist == Etc.klingon[0].avgdist ? 0 : 1);
}
Now.time = Now.resource / Now.klings;
break;
case E_SNAP:
xresched(e, E_SNAP, 1);
p = (char *) Etc.snapshot;
memcpy(p, Quad, sizeof (Quad));
p += sizeof (Quad);
memcpy(p, Event, sizeof (Event));
p += sizeof (Event);
memcpy(p, &Now, sizeof (Now));
Game.snap = 1;
break;
case E_ATTACK:
if (!Move.resting)
{
unschedule(e);
break;
}
attack(1);
reschedule(e, 0.5);
break;
case E_FIXDV:
i = e->systemname;
unschedule(e);
printf("%s reports repair work on the %s finished.\n",
Device[i].person, Device[i].name);
switch (i)
{
case LIFESUP:
Ship.reserves = Param.reserves;
break;
case SINS:
if (Ship.cond == DOCKED)
break;
printf("Spock has tried to recalibrate your Space Internal Navigation System,\n");
printf(" but he has no standard base to calibrate to. Suggest you get\n");
printf(" to a starbase immediately so that you can properly recalibrate.\n");
Ship.sinsbad = 1;
break;
case SSRADIO:
restcancel = dumpssradio();
break;
}
break;
default:
break;
}
if (restcancel && Move.resting && getynpar("Spock: Shall we cancel our rest period"))
Move.time = xdate - idate;
}
if ((e = Now.eventptr[E_ATTACK]))
unschedule(e);
if (!warp)
{
if (Ship.cloaked)
Ship.energy -= Param.cloakenergy * Move.time;
rtime = 1.0 - exp(-Param.regenfac * Move.time);
Ship.shield += (Param.shield - Ship.shield) * rtime;
Ship.energy += (Param.energy - Ship.energy) * rtime;
if (damaged(LIFESUP) && Ship.cond != DOCKED)
Ship.reserves -= Move.time;
}
return (0);
}