|
|
researchv10 Norman
# include "trek.h"
/**
** cause time to elapse
**/
/* snapshot for time warps */
char Snapshot[14 + sizeof Quad + sizeof Event + sizeof Base + sizeof Etc];
double randly(evname)
int evname;
{
return(Param.eventdly[evname] * franf());
}
double logdly(evname)
int evname;
{
double d;
d = Param.eventdly[evname] * Initial.time * log(franf());
if(evname==E_LRTB) d =/ Status.kling;
return(-d);
}
events()
{
register int i;
int j;
int restcancel;
KLINGONS *k;
double rtime;
double xdate;
double idate;
EVENT *ev;
int ix, iy;
register QUAD *q;
register EVENT *e;
int evnum;
if (Move.delta <= 0.0)
{
Status.time = Status.resource / Status.kling;
return;
}
idate = Status.date;
if (Move.delta > 0.5 && Move.resting)
schedule(E_ATTACK, 0.5, 0, 0, 0);
while (1)
{
restcancel = 0;
evnum = -1;
xdate = idate + Move.delta;
for (i = 0; i < MAXEVENTS; i++)
{
e = &Event[i];
if (e->evcode < 0)
continue;
if (e->date < xdate)
{
xdate = e->date;
ev = e;
evnum = i;
}
}
rtime = xdate - Status.date;
Status.resource =- Status.kling * rtime;
Status.time = Status.resource / Status.kling;
Status.date = xdate;
if (Status.time <= 0.0)
lose(L_NOTIME);
if (evnum < 0)
break;
e = ev;
switch (e->evcode)
{
case E_SNOVA: /* supernova */
snova(-1);
reschedule(e, logdly(E_SNOVA));
break;
case E_LRTB: /* long range tractor beam */
if (Status.cond != DOCKED && Nkling < 3)
{
i = ranf(Status.kling) + 1;
for (ix = 0; ix < NQUADS; ix++)
{
for (iy = 0; iy < NQUADS; iy++)
if (Quad[ix][iy].stars >= 0)
if ((i =- Quad[ix][iy].qkling) <= 0)
break;
if (i <= 0)
break;
}
Quadx = ix;
Quady = iy;
printf("%s caught in long range tractor beam", Status.shipname);
printf("; pulled to quadrant %d,%d\n", Quadx, Quady);
Sectx = ranf(NSECTS);
Secty = ranf(NSECTS);
initquad(0);
Move.delta = xdate - idate;
}
reschedule(e, logdly(E_LRTB));
break;
case E_KATSB: /* Klingon attacks starbase */
if (Status.bases <= 0)
{
unschedule(e);
break;
}
i = 1;
for (ix = 0; ix < NQUADS; ix++)
{
for (iy = 0; iy < NQUADS; iy++)
if (Quad[ix][iy].bases > 0 && Quad[ix][iy].qkling > 0)
{
i = 0;
break;
}
if (!i)
break;
}
reschedule(e, logdly(E_KATSB));
if (i) break;
e = schedule(E_KDESB, 0.5 + randly(E_KDESB), ix, iy, 0);
if (!Damage[SSRADIO])
{
printf("Uhura:\tCaptain, we have recieved a distress signal\n");
printf("\tfrom the starbase in quadrant %d,%d.\n",
ix, iy);
restcancel++;
}
else
e->evdata = E_NREPORT;
break;
case E_KDESB: /* Klingon destroys starbase */
unschedule(e);
q = &Quad[e->x][e->y];
if (q->bases <=0 || q->qkling <= 0)
break;
if (e->x == Quadx && e->y == Quady)
{
printf("\nSpock: ");
killb(Quadx, Quady);
}
else
killb(e->x, e->y);
break;
case E_ISSUE: /* issue a distress call */
reschedule(e, logdly(E_ISSUE));
if (Status.distressed >= MAXDISTR)
break;
for (i = 0; i < 100; i++)
{
ix = ranf(NQUADS);
iy = ranf(NQUADS);
q = &Quad[ix][iy];
if (!((ix == Quadx && iy == Quady) || q->stars < 0 ||
q->systemname&(Q_DISTRESS|Q_GHOST) ||
q->systemname == 0 || q->qkling <= 0))
break;
}
if (i >= 100)
break;
Status.distressed =+ 1;
e = schedule(E_ENSLV, randly(E_ENSLV), ix, iy, q->systemname);
q->systemname = (e - Event) | Q_DISTRESS;
if (!Damage[SSRADIO])
{
printf("Uhura:\tCaptain, starsystem %s in quadrant %d,%d is under attack.\n",
Systemname[e->evdata], ix, iy);
restcancel++;
}
else
e->evdata =| E_NREPORT;
break;
case E_ENSLV: /* starsystem is enslaved */
unschedule(e);
/* see if current distress call still active */
q = &Quad[e->x][e->y];
if (q->qkling <= 0)
{
e->evdata =& ~E_NREPORT;
if(q->systemname&Q_DISTRESS)
q->systemname = e->evdata;
break;
}
else
schedule(E_REPRO, randly(E_REPRO), e->x, e->y, e->evdata);
if (!Damage[SSRADIO])
{
printf("Uhura:\tWe've lost contact with starsystem %s\n",
Systemname[e->evdata]);
printf(" in quadrant %d,%d.\n",
e->x, e->y);
}
break;
case E_REPRO: /* Klingon reproduces */
/* see if distress call is still active */
q = &Quad[e->x][e->y];
if (q->qkling <= 0)
{
unschedule(e);
if (q->systemname&Q_DISTRESS)
q->systemname = e->evdata;
break;
}
reschedule(e, randly(E_REPRO));
/* reproduce one Klingon */
ix = e->x;
iy = e->y;
if (Status.kling == 127)
break; /* full right now */
if (q->qkling >= 9)
{
/* this quadrant not ok */
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->qkling >= 9 || q->stars < 0)
continue;
break;
}
if (j <= iy + 1)
break;
}
if (j > iy + 1)
/* cannot create another yet */
break;
ix = i;
iy = j;
}
q->qkling =+ 1;
Status.kling =+ 1;
if (ix == Quadx && iy == Quady)
{
/* we must position Klingon */
sector(&ix, &iy);
Sect[ix][iy] = KLINGON;
k = &Kling[Nkling++];
k->x = ix;
k->y = iy;
k->power = Param.klingpwr;
compkldist(Kling[0].dist == Kling[0].avgdist ? 0 : 1);
}
Status.time = Status.resource / Status.kling;
break;
case E_SNAP:
reschedule(e, logdly(E_SNAP));
i = &Snapshot;
i = bmove(&Status.bases, i, 2);
i = bmove(&Status.date, i, 12);
i = bmove(&Quad, i, sizeof Quad);
i = bmove(&Event, i, sizeof Event);
i = bmove(&Base, i, sizeof Base);
i = bmove(&Etc, i, sizeof Etc);
Game.snap = 1;
break;
case E_ATTACK: /* Klingons attack during rest period */
if (!Move.resting)
{
unschedule(e);
break;
}
attack(1);
reschedule(e, 0.5);
break;
case E_FIXDV:
i = e->evdata;
unschedule(e);
Damage[i] = 0;
printf("%s reports repair work on the %s finished.\n",
Device[i].person, Device[i].name);
switch (i)
{
case LIFESUP:
Status.reserves = Initial.reserves;
break;
case SINS:
if (Status.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");
Status.sinsbad = 1;
break;
case SSRADIO:
restcancel = dumpssradio();
break;
}
break;
default:
break;
}
if(Move.resting && restcancel && getynpar("Spock: Shall we cancel our rest period"))
Move.delta = xdate - idate;
}
if (e = Etc.eventptr[E_ATTACK])
unschedule(e);
if (Status.cloaked)
Status.energy =- Param.cloakenergy * Move.delta;
rtime = 1.0 - exp(-Param.regenfac * Move.delta);
Status.shield =+ (Initial.shield - Status.shield) * rtime;
Status.energy =+ (Initial.energy - Status.energy) * rtime;
if (Damage[LIFESUP] && Status.cond != DOCKED)
Status.reserves =- Move.delta;
return;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.