game.iscate=0;
game.ientesc=0;
game.isatb=0;
- game.future[FSCMOVE]=0.2777+game.state.date;
- game.future[FSCDBAS]=FOREVER;
+ schedule(FSCMOVE, 0.2777);
+ unschedule(FSCDBAS);
game.state.isx=iqx;
game.state.isy=iqy;
}
game.isatb=0;
game.ishere=0;
game.ientesc=0;
- game.future[FSCDBAS]=FOREVER;
+ unschedule(FSCDBAS);
for_local_enemies(i)
if (game.quad[game.kx[i]][game.ky[i]] == IHS) break;
game.quad[game.kx[i]][game.ky[i]] = IHDOT;
/* compute distances to starbases */
if (game.state.rembase <= 0) {
/* nothing left to do */
- game.future[FSCMOVE] = FOREVER;
+ unschedule(FSCMOVE);
return;
}
sx = game.state.isx;
}
/* check for a base */
if (game.state.rembase == 0) {
- game.future[FSCMOVE] = FOREVER;
+ unschedule(FSCMOVE);
}
else for_starbases(i) {
ibqx = game.state.baseqx[i];
if (flag) return; /* no, don't attack base! */
game.iseenit = 0;
game.isatb=1;
- game.future[FSCDBAS] = game.state.date + 1.0 +2.0*Rand();
- if (game.future[FCDBAS] < FOREVER) game.future[FSCDBAS] +=
- game.future[FCDBAS]-game.state.date;
+ schedule(FSCDBAS, 1.0 +2.0*Rand());
+ if (is_scheduled(FCDBAS))
+ postpone(FSCDBAS, scheduled(FCDBAS)-game.state.date);
if (game.damage[DRADIO] > 0 && game.condit != IHDOCKED)
return; /* no warning */
game.iseenit = 1;
skip(1);
prout(_(" reports that it is under attack from the Klingon Super-commander."));
proutn(_(" It can survive until stardate %d.\""),
- (int)game.future[FSCDBAS]);
+ (int)scheduled(FSCDBAS));
if (game.resting==0) return;
prout(_("Mr. Spock- \"Captain, shall we cancel the rest period?\""));
if (ja()==0) return;
game.state.cx[game.state.remcom] = 0;
game.state.cy[game.state.remcom] = 0;
game.state.remcom--;
- game.future[FTBEAM] = FOREVER;
+ unschedule(FTBEAM);
if (game.state.remcom != 0)
- game.future[FTBEAM] = game.state.date + expran(1.0*game.incom/game.state.remcom);
+ schedule(FTBEAM, expran(1.0*game.incom/game.state.remcom));
break;
case IHK:
game.state.remkl--;
case IHS:
game.state.nscrem--;
game.ishere = game.state.isx = game.state.isy = game.isatb = game.iscate = 0;
- game.future[FSCMOVE] = game.future[FSCDBAS] = FOREVER;
+ unschedule(FSCMOVE);
+ unschedule(FSCDBAS);
break;
}
}
game.state.remtime = game.state.remres/(game.state.remkl + 4*game.state.remcom);
/* Remove enemy ship from arrays describing local game.conditions */
- if (game.future[FCDBAS] < FOREVER && game.batx==game.quadx && game.baty==game.quady && type==IHC)
- game.future[FCDBAS] = FOREVER;
+ if (is_scheduled(FCDBAS) && game.batx==game.quadx && game.baty==game.quady && type==IHC)
+ unschedule(FCDBAS);
for_local_enemies(i)
if (game.kx[i]==ix && game.ky[i]==iy) break;
game.nenhere--;
#include "sst.h"
#include <math.h>
+void unschedule(int evtype)
+/* remove an event from the schedule */
+{
+ game.future[evtype] = FOREVER;
+}
+
+int is_scheduled(int evtype)
+/* is an event of specified type scheduled */
+{
+ return game.future[evtype] != FOREVER;
+}
+
+extern double scheduled(int evtype)
+/* when will this event happen? */
+{
+ return game.future[evtype];
+}
+
+void schedule(int evtype, double offset)
+/* schedule an event of specified type */
+{
+ game.future[evtype] = game.state.date + offset;
+}
+
+void postpone(int evtype, double offset)
+/* poistpone a scheduled event */
+{
+ game.future[evtype] += offset;
+}
+
void events(void)
{
int ictbeam=0, ipage=0, istract=0, line, i=0, j, k, l, ixhold=0, iyhold=0;
if (ipage==0) pause_game(1);
ipage=1;
snova(0,0);
- game.future[FSNOVA] = game.state.date + expran(0.5*game.intime);
+ schedule(FSNOVA, expran(0.5*game.intime));
if (game.state.galaxy[game.quadx][game.quady].supernova) return;
break;
case FSPY: /* Check with spy to see if S.C. should tractor beam */
case FTBEAM: /* Tractor beam */
if (line==FTBEAM) {
if (game.state.remcom == 0) {
- game.future[FTBEAM] = FOREVER;
+ unschedule(FTBEAM);
break;
}
i = Rand()*game.state.remcom+1.0;
yank = square(game.state.cx[i]-game.quadx) + square(game.state.cy[i]-game.quady);
if (istract || game.condit == IHDOCKED || yank == 0) {
/* Drats! Have to reschedule */
- game.future[FTBEAM] = game.state.date + game.optime +
- expran(1.5*game.intime/game.state.remcom);
+ schedule(FTBEAM,
+ game.optime + expran(1.5*game.intime/game.state.remcom));
break;
}
}
/* Adjust finish time to time of tractor beaming */
fintim = game.state.date+game.optime;
attack(0);
- if (game.state.remcom <= 0) game.future[FTBEAM] = FOREVER;
- else game.future[FTBEAM] = game.state.date+game.optime+expran(1.5*game.intime/game.state.remcom);
+ if (game.state.remcom <= 0) unschedule(FTBEAM);
+ else schedule(FTBEAM, game.optime+expran(1.5*game.intime/game.state.remcom));
break;
case FSNAP: /* Snapshot of the universe (for time warp) */
game.snapsht = game.state;
game.state.snap = 1;
- game.future[FSNAP] = game.state.date + expran(0.5 * game.intime);
+ schedule(FSNAP, expran(0.5 * game.intime));
break;
case FBATTAK: /* Commander attacks starbase */
if (game.state.remcom==0 || game.state.rembase==0) {
/* no can do */
- game.future[FBATTAK] = game.future[FCDBAS] = FOREVER;
+ unschedule(FBATTAK);
+ unschedule(FCDBAS);
break;
}
i = 0;
}
if (j>game.state.rembase) {
/* no match found -- try later */
- game.future[FBATTAK] = game.state.date + expran(0.3*game.intime);
- game.future[FCDBAS] = FOREVER;
+ schedule(FBATTAK, expran(0.3*game.intime));
+ unschedule(FCDBAS);
break;
}
/* commander + starbase combination found -- launch attack */
game.batx = game.state.baseqx[j];
game.baty = game.state.baseqy[j];
- game.future[FCDBAS] = game.state.date+1.0+3.0*Rand();
+ schedule(FCDBAS, 1.0+3.0*Rand());
if (game.isatb) /* extra time if SC already attacking */
- game.future[FCDBAS] += game.future[FSCDBAS]-game.state.date;
+ postpone(FCDBAS, scheduled(FSCDBAS)-game.state.date);
game.future[FBATTAK] = game.future[FCDBAS] +expran(0.3*game.intime);
game.iseenit = 0;
if (game.damage[DRADIO] != 0.0 &&
prout(cramlc(quadrant, game.batx, game.baty));
prout(_(" reports that it is under attack and that it can"));
proutn(_(" hold out only until stardate %d"),
- (int)game.future[FCDBAS]);
+ (int)scheduled(FCDBAS));
prout(".\"");
if (game.resting) {
skip(1);
}
break;
case FSCDBAS: /* Supercommander destroys base */
- game.future[FSCDBAS] = FOREVER;
+ unschedule(FSCDBAS);
game.isatb = 2;
if (!game.state.galaxy[game.state.isx][game.state.isy].starbase)
break; /* WAS RETURN! */
game.baty = game.state.isy;
case FCDBAS: /* Commander succeeds in destroying base */
if (line==FCDBAS) {
- game.future[FCDBAS] = FOREVER;
+ unschedule(FCDBAS);
/* find the lucky pair */
for_commanders(i)
if (game.state.cx[i]==game.batx && game.state.cy[i]==game.baty)
}
break;
case FSCMOVE: /* Supercommander moves */
- game.future[FSCMOVE] = game.state.date+0.2777;
+ schedule(FSCMOVE, 0.2777);
if (game.ientesc+istract==0 &&
game.isatb!=1 &&
(game.iscate!=1 || game.justin==1)) scom(&ipage);
break;
case FDSPROB: /* Move deep space probe */
- game.future[FDSPROB] = game.state.date + 0.01;
+ schedule(FDSPROB, 0.01);
game.probex += game.probeinx;
game.probey += game.probeiny;
i = (int)(game.probex/QUADSIZE +0.05);
proutn(_("is no longer transmitting"));
prout(".\"");
}
- game.future[FDSPROB] = FOREVER;
+ unschedule(FDSPROB);
break;
}
if (game.damage[DRADIO]==0.0 || game.condit == IHDOCKED) {
game.state.galaxy[game.probecx][game.probecy].stars) {
/* lets blow the sucker! */
snova(1,0);
- game.future[FDSPROB] = FOREVER;
+ unschedule(FDSPROB);
if (game.state.galaxy[game.quadx][game.quady].supernova)
return;
}
#ifdef EXPERIMENTAL
case FDISTR: /* inhabited system issues distress call */
/* in BSD Trek this is a straight 1 stardate ahead */
- game.future[FDISTR] = game.state.date + 1.0 + Rand();
+ schedule(FDISTR, 1.0 + Rand());
/* if we already have too many, throw this one away */
if (game.ndistr >= MAXDISTR)
break;
/* did in the Supercommander! */
game.state.nscrem = game.state.isx = game.state.isy = game.isatb = game.iscate = 0;
iscdead = 1;
- game.future[FSCMOVE] = game.future[FSCDBAS] = FOREVER;
+ unschedule(FSCMOVE);
+ unschedule(FSCDBAS);
}
if (game.state.remcom) {
int maxloop = game.state.remcom, l;
game.state.remcom--;
kldead--;
comdead++;
- if (game.state.remcom==0) game.future[FTBEAM] = FOREVER;
+ if (game.state.remcom==0) unschedule(FTBEAM);
break;
}
}
deltax /= bigger;
/* If tractor beam is to occur, don't move full distance */
- if (game.state.date+game.optime >= game.future[FTBEAM]) {
+ if (game.state.date+game.optime >= scheduled(FTBEAM)) {
trbeam = 1;
game.condit = IHRED;
- game.dist = game.dist*(game.future[FTBEAM]-game.state.date)/game.optime + 0.1;
- game.optime = game.future[FTBEAM] - game.state.date + 1e-5;
+ game.dist = game.dist*(scheduled(FTBEAM)-game.state.date)/game.optime + 0.1;
+ game.optime = scheduled(FTBEAM) - game.state.date + 1e-5;
}
/* Move within the quadrant */
game.quad[game.sectx][game.secty] = IHDOT;
game.torps = game.intorps;
game.lsupres = game.inlsr;
if (game.damage[DRADIO] == 0.0 &&
- (game.future[FCDBAS] < FOREVER || game.isatb == 1) && game.iseenit == 0) {
+ (is_scheduled(FCDBAS) || game.isatb == 1) && game.iseenit == 0) {
/* get attack report from base */
prout("Lt. Uhura- \"Captain, an important message from the starbase:\"");
attakreport(0);
game.state = game.snapsht;
game.state.snap = 0;
if (game.state.remcom) {
- game.future[FTBEAM] = game.state.date + expran(game.intime/game.state.remcom);
- game.future[FBATTAK] = game.state.date + expran(0.3*game.intime);
+ schedule(FTBEAM, expran(game.intime/game.state.remcom));
+ schedule(FBATTAK, expran(0.3*game.intime));
}
- game.future[FSNOVA] = game.state.date + expran(0.5*game.intime);
- game.future[FSNAP] = game.state.date +expran(0.25*game.state.remtime); /* next snapshot will
- be sooner */
- if (game.state.nscrem) game.future[FSCMOVE] = 0.2777;
+ schedule(FSNOVA, expran(0.5*game.intime));
+ /* next snapshot will be sooner */
+ schedule(FSNAP, expran(0.25*game.state.remtime));
+
+ if (game.state.nscrem) schedule(FSCMOVE, 0.2777);
game.isatb = 0;
- game.future[FCDBAS] = game.future[FSCDBAS] = FOREVER;
+ unschedule(FCDBAS);
+ unschedule(FSCDBAS);
game.batx = game.baty = 0;
/* Make sure Galileo is consistant -- Snapshot may have been taken
game.optime = -0.5*game.intime*log(Rand());
prout("You are traveling forward in time %d stardates.", (int)game.optime);
/* cheat to make sure no tractor beams occur during time warp */
- game.future[FTBEAM] += game.optime;
+ postpone(FTBEAM, game.optime);
game.damage[DRADIO] += game.optime;
}
newqad(0);
prout("Engineer Scott- \"The probe launcher is damaged, Sir.\"");
return;
}
- if (game.future[FDSPROB] != FOREVER) {
+ if (is_scheduled(FDSPROB)) {
chew();
skip(1);
if (game.damage[DRADIO] != 0 && game.condit != IHDOCKED) {
game.probey = game.quady*QUADSIZE + game.secty - 1;
game.probecx = game.quadx;
game.probecy = game.quady;
- game.future[FDSPROB] = game.state.date + 0.01; // Time to move one sector
+ schedule(FDSPROB, 0.01); // Time to move one sector
prout("Ensign Chekov- \"The deep space probe is launched, Captain.\"");
game.ididit = 1;
return;
game.ididit = 1;
#if 0
/* Don't worry about this */
- if (future[FTBEAM] <= game.state.date+game.optime && game.state.remcom != 0 && game.condit != IHDOCKED) {
+ if (scheduled(FTBEAM) <= game.state.date+game.optime && game.state.remcom != 0 && game.condit != IHDOCKED) {
/* We are about to be tractor beamed -- operation fails */
return 1;
}
#endif
-// asave = future[FSNOVA];
-// future[FSNOVA] = FOREVER; /* defer supernovas */
- events(); /* Used to avoid if future[FSCMOVE] within time */
-// future[FSNOVA] = asave;
+// asave = scheduled(FSNOVA);
+// unschedule(FSNOVA); /* defer supernovas */
+ events(); /* Used to avoid if FSCMOVE is scheduled within time */
+// schedule(FSNOVA, asave-game.state.time);
/*fails if game over, quadrant super-novas or we've moved to new quadrant*/
if (game.alldone || game.state.galaxy[game.quadx][game.quady].supernova || game.justin != 0) return 1;
return 0;
void attakreport(int curt)
{
if (!curt) {
- if (game.future[FCDBAS] < FOREVER) {
+ if (is_scheduled(FCDBAS)) {
prout("Starbase in %s is currently under Commander attack.",
cramlc(quadrant, game.batx, game.baty));
prout("It can hold out until Stardate %d.",
- (int)game.future[FCDBAS]);
+ (int)scheduled(FCDBAS));
}
if (game.isatb == 1) {
prout("Starbase in %s is under Super-commander attack.",
cramlc(quadrant, game.state.isx, game.state.isy));
prout("It can hold out until Stardate %d.",
- (int)game.future[FSCDBAS]);
+ (int)scheduled(FSCDBAS));
}
} else {
- if (game.future[FCDBAS] < FOREVER)
- proutn("Base in %i - %i attacked by C. Alive until %.1f", game.batx, game.baty, game.future[FCDBAS]);
+ if (is_scheduled(FCDBAS))
+ proutn("Base in %i - %i attacked by C. Alive until %.1f", game.batx, game.baty, scheduled(FCDBAS));
if (game.isatb == 1)
- proutn("Base in %i - %i attacked by S. Alive until %.1f", game.state.isx, game.state.isy, game.future[FSCDBAS]);
+ proutn("Base in %i - %i attacked by S. Alive until %.1f", game.state.isx, game.state.isy, scheduled(FSCDBAS));
}
clreol();
}
if (game.nprobes!=1) proutn("s");
prout(".");
}
- if ((game.damage[DRADIO] == 0.0 || game.condit == IHDOCKED)&&
- game.future[FDSPROB] != FOREVER) {
+ if ((game.damage[DRADIO] == 0.0 || game.condit == IHDOCKED)
+ && is_scheduled(FDSPROB)) {
if (game.isarmed)
proutn("An armed deep space probe is in");
else
if (twarp > 6.0)
prout("You'll be taking risks at that speed, Captain");
if ((game.isatb==1 && game.state.isy == iy1 && game.state.isx == ix1 &&
- game.future[FSCDBAS]< ttime+game.state.date)||
- (game.future[FCDBAS]<ttime+game.state.date && game.baty==iy1 && game.baty == iy1))
+ scheduled(FSCDBAS)< ttime+game.state.date)||
+ (scheduled(FCDBAS)<ttime+game.state.date && game.baty==iy1 && game.batx == ix1))
prout("The starbase there will be destroyed by then.");
proutn("New warp factor to try? ");
if (scan() == IHREAL) {
#endif /* EXPERIMENTAL */
}
// Initialize times for extraneous events
- game.future[FSNOVA] = game.state.date + expran(0.5 * game.intime);
- game.future[FTBEAM] = game.state.date + expran(1.5 * (game.intime / game.state.remcom));
- game.future[FSNAP] = game.state.date + 1.0 + Rand(); // Force an early snapshot
- game.future[FBATTAK] = game.state.date + expran(0.3*game.intime);
- game.future[FCDBAS] = FOREVER;
- game.future[FSCMOVE] = game.state.nscrem ? game.state.date+0.2777 : FOREVER;
- game.future[FSCDBAS] = FOREVER;
- game.future[FDSPROB] = FOREVER;
+ schedule(FSNOVA, expran(0.5 * game.intime));
+ schedule(FTBEAM, expran(1.5 * (game.intime / game.state.remcom)));
+ schedule(FSNAP, 1.0 + Rand()); // Force an early snapshot
+ schedule(FBATTAK, expran(0.3*game.intime));
+ unschedule(FCDBAS);
+ if (game.state.nscrem)
+ schedule(FSCMOVE, 0.2777);
+ else
+ unschedule(FSCMOVE);
+ unschedule(FSCDBAS);
+ unschedule(FDSPROB);
#ifdef EXPERIMENTAL
if (game.options & OPTION_WORLDS)
- /* in BSD-Trek, this is a fixed one stardate in the future */
- game.future[FDISTR] = game.state.date + 1.0 + Rand();
- game.future[FENSLV] = FOREVER;
- game.future[FREPRO] = FOREVER;
+ schedule(FDISTR, expran(1.0 + game.intime));
+ unschedule(FENSLV);
+ unschedule(FREPRO);
#endif /* EXPERIMENTAL */
// Starchart is functional but we've never seen it
game.lastchart = FOREVER;
int i;
for (i = 1; i < NEVENTS; i++) {
int key;
- if (game.future[i] == FOREVER) continue;
+ if (!is_scheduled(i)) continue;
switch (i) {
case FSNOVA: proutn("Supernova "); break;
case FTBEAM: proutn("T Beam "); break;
case FSCMOVE: proutn("SC Move "); break;
case FSCDBAS: proutn("SC Base Destroy "); break;
}
- proutn("%.2f", game.future[i]-game.state.date);
+ proutn("%.2f", scheduled(i)-game.state.date);
chew();
proutn(" ?");
key = scan();
if (key == IHREAL) {
- game.future[i] = game.state.date + aaitem;
+ schedule(i, aaitem);
}
}
chew();
#define NEVENTS (12)
#endif /* EXPERIMENTAL */
+/*
+ * abstract out the event handling -- underlying data structures will change
+ * when we implement stateful events
+ */
+extern void unschedule(int);
+extern int is_scheduled(int);
+extern void schedule(int, double);
+extern void postpone(int, double);
+extern double scheduled(int);
+
#ifdef EXPERIMENTAL
#define MAXDISTR 5 /* maximum concurrent distress calls */
#endif /* EXPERIMENTAL */