X-Git-Url: https://jxself.org/git/?p=super-star-trek.git;a=blobdiff_plain;f=src%2Fevents.c;h=7b915f22e28f45b3119f74d3c6c0013da5b74ed6;hp=dc81f56e86dfb70638c872571475c8285555d2b4;hb=188965b8e49bc7a0233258627917239b57429e77;hpb=8700dc6a521fe201815aad02cf05f7f4c297c305 diff --git a/src/events.c b/src/events.c index dc81f56..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,11 +373,127 @@ 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; } break; +#ifdef EXPERIMENTAL + case FDISTR: /* inhabited system issues distress call */ + /* in BSD Trek this is a straight 1 stardate ahead */ + schedule(FDISTR, 1.0 + Rand()); + /* if we already have too many, throw this one away */ + if (game.ndistr >= MAXDISTR) + break; + /* try a whole bunch of times to find something suitable */ + for (i = 0; i < 100; i++) { + struct quadrant *q; + iran(GALSIZE, &ix, &iy); + q = &game.state.galaxy[game.quadx][game.quady]; + /* need a quadrant which is not the current one, + which has some stars which are inhabited and + not already under attack, which is not + supernova'ed, and which has some Klingons in it */ + if (!((ix == game.quadx && iy == game.quady) || q->stars<=0 || + (q->qsystemname & Q_DISTRESSED) || + (q->qsystemname & Q_SYSTEM) == 0 || q->klings <= 0)) + break; + } + if (i >= 100) + /* can't seem to find one; ignore this call */ + break; + + /* got one!! Schedule its enslavement */ + game.ndistr++; + e = xsched(E_ENSLV, 1, ix, iy, q->qsystemname); + q->qsystemname = (e - Event) | Q_DISTRESSED; + + /* tell the captain about it if we can */ + if (game.damage[DRADIO] == 0.0) + { + printf("\nUhura: Captain, starsystem %s in quadrant %d,%d is under attack\n", + Systemname[e->systemname], ix, iy); + restcancel++; + } + else + /* if we can't tell him, make it invisible */ + e->evcode |= E_HIDDEN; + break; + case FENSLV: /* starsystem is enslaved */ + unschedule(e); + /* see if current distress call still active */ + q = &Quad[e->x][e->y]; + if (q->klings <= 0) + { + /* no Klingons, clean up */ + /* restore the system name */ + q->qsystemname = e->systemname; + break; + } + + /* play stork and schedule the first baby */ + e = schedule(E_REPRO, Param.eventdly[E_REPRO] * franf(), e->x, e->y, e->systemname); + + /* report the disaster if we can */ + if (game.damage[DRADIO] == 0.0) + { + 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 FREPRO: /* Klingon reproduces */ + /* see if distress call is still active */ + q = &Quad[e->x][e->y]; + if (q->klings <= 0) + { + unschedule(e); + q->qsystemname = e->systemname; + break; + } + xresched(e, E_REPRO, 1); + /* reproduce one Klingon */ + ix = e->x; + iy = e->y; + if (Now.klings == 127) + break; /* full right now */ + if (q->klings >= MAXKLQUAD) + { + /* this quadrant not ok, pick an adjacent one */ + for (i = ix - 1; i <= ix + 1; i++) + { + if (!VALID_QUADRANT(i)) + continue; + for (j = iy - 1; j <= iy + 1; j++) + { + if (!VALID_QUADRANT(j)) + continue; + q = &Quad[i][j]; + /* check for this quad ok (not full & no snova) */ + if (q->klings >= MAXKLQUAD || q->stars < 0) + continue; + break; + } + if (j <= iy + 1) + break; + } + if (j > iy + 1) + /* cannot create another yet */ + break; + ix = i; + iy = j; + } + /* deliver the child */ + game.remkl++; + if (ix == game.quadx && iy == game.quady) + newkling(++game.klhere, &ixhold, &iyhold); + + /* recompute time left */ + game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom); + break; +#endif /* EXPERIMENTAL */ } } } @@ -685,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; @@ -697,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; } }