From 188965b8e49bc7a0233258627917239b57429e77 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 17 Sep 2006 23:55:46 +0000 Subject: [PATCH] Abstract all references to the future array (outside of events.c) away. This has two benefits: 1. New code is easier to read. 2. It prepares us for implementing stateful events with a different underlying data structure. We'll need this for some BSD-Trek features. --- src/ai.c | 18 ++++++------ src/battle.c | 11 ++++---- src/events.c | 76 ++++++++++++++++++++++++++++++++++++--------------- src/moving.c | 30 ++++++++++---------- src/planets.c | 10 +++---- src/reports.c | 20 +++++++------- src/setup.c | 26 ++++++++++-------- src/sst.c | 6 ++-- src/sst.h | 10 +++++++ 9 files changed, 127 insertions(+), 80 deletions(-) diff --git a/src/ai.c b/src/ai.c index 660f328..81e3205 100644 --- a/src/ai.c +++ b/src/ai.c @@ -48,8 +48,8 @@ static int tryexit(int lookx, int looky, int ienm, int loccom, int irun) 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; } @@ -331,7 +331,7 @@ static int movescom(int iqx, int iqy, int flag, int *ipage) 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; @@ -395,7 +395,7 @@ void scom(int *ipage) /* compute distances to starbases */ if (game.state.rembase <= 0) { /* nothing left to do */ - game.future[FSCMOVE] = FOREVER; + unschedule(FSCMOVE); return; } sx = game.state.isx; @@ -499,7 +499,7 @@ void scom(int *ipage) } /* check for a base */ if (game.state.rembase == 0) { - game.future[FSCMOVE] = FOREVER; + unschedule(FSCMOVE); } else for_starbases(i) { ibqx = game.state.baseqx[i]; @@ -509,9 +509,9 @@ void scom(int *ipage) 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; @@ -522,7 +522,7 @@ void scom(int *ipage) 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; diff --git a/src/battle.c b/src/battle.c index 834e106..b9b32fe 100644 --- a/src/battle.c +++ b/src/battle.c @@ -635,9 +635,9 @@ void deadkl(int ix, int iy, int type, int ixx, int iyy) 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--; @@ -645,7 +645,8 @@ void deadkl(int ix, int iy, int type, int ixx, int iyy) 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; } } @@ -658,8 +659,8 @@ void deadkl(int ix, int iy, int type, int ixx, int iyy) 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--; diff --git a/src/events.c b/src/events.c index 5b993d0..7b915f2 100644 --- a/src/events.c +++ b/src/events.c @@ -1,6 +1,36 @@ #include "sst.h" #include +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; @@ -68,7 +98,7 @@ void events(void) 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 */ @@ -90,15 +120,15 @@ void events(void) 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; } } @@ -161,18 +191,19 @@ void events(void) /* 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; @@ -188,16 +219,16 @@ void events(void) } 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 && @@ -210,7 +241,7 @@ void events(void) 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); @@ -223,7 +254,7 @@ void events(void) } 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! */ @@ -233,7 +264,7 @@ void events(void) 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) @@ -289,13 +320,13 @@ void events(void) } 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); @@ -317,7 +348,7 @@ void events(void) proutn(_("is no longer transmitting")); prout(".\""); } - game.future[FDSPROB] = FOREVER; + unschedule(FDSPROB); break; } if (game.damage[DRADIO]==0.0 || game.condit == IHDOCKED) { @@ -342,7 +373,7 @@ void events(void) 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; } @@ -350,7 +381,7 @@ void events(void) #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; @@ -801,7 +832,8 @@ void snova(int insx, int insy) /* 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; @@ -813,7 +845,7 @@ void snova(int insx, int insy) game.state.remcom--; kldead--; comdead++; - if (game.state.remcom==0) game.future[FTBEAM] = FOREVER; + if (game.state.remcom==0) unschedule(FTBEAM); break; } } diff --git a/src/moving.c b/src/moving.c index 37ccb3d..632b335 100644 --- a/src/moving.c +++ b/src/moving.c @@ -27,11 +27,11 @@ void imove(void) 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; @@ -237,7 +237,7 @@ void dock(int l) 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); @@ -778,15 +778,17 @@ void timwrp() 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 @@ -818,7 +820,7 @@ void timwrp() 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); @@ -845,7 +847,7 @@ void probe(void) 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) { @@ -892,7 +894,7 @@ void probe(void) 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; diff --git a/src/planets.c b/src/planets.c index c76dace..1ab10a1 100644 --- a/src/planets.c +++ b/src/planets.c @@ -11,15 +11,15 @@ static int consumeTime(void) 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; diff --git a/src/reports.c b/src/reports.c index 6d58c7f..a79a410 100644 --- a/src/reports.c +++ b/src/reports.c @@ -6,23 +6,23 @@ 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(); } @@ -87,8 +87,8 @@ void report(void) 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 @@ -527,8 +527,8 @@ void eta(void) 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]