+/*
+ * events.c -- event-queue handling
+ *
+ * This isn't a real event queue a la BSD Trek yet -- you can only have one
+ * event of each type active at any given time. Mostly these means we can
+ * only have one FDISTR/FENSLV/FREPRO sequence going at any given time;
+ * BSD Trek, from which we swiped the idea, can have up to 5.
+ */
#include "sst.h"
#include <math.h>
void events(void)
{
- int ictbeam=0, ipage=0, istract=0, line, i=0, j, k, l, ixhold=0, iyhold=0;
+ int istract=0, evcode, i=0, j, k, l;
double fintim = game.state.date + game.optime, datemin, xtime, repair, yank=0;
- int radio_was_broken;
+ bool radio_was_broken, ictbeam = false, ipage = false;
struct quadrant *pdest, *q;
coord w, hold;
- event *ev;
+ event *ev, *ev2;
if (idebug) {
prout("=== EVENTS from %.2f to %.2f:", game.state.date, fintim);
}
}
- radio_was_broken = (game.damage[DRADIO] != 0.0);
+ radio_was_broken = damaged(DRADIO);
for (;;) {
- /* Select earliest extraneous event, line==0 if no events */
- line = FSPY;
+ /* Select earliest extraneous event, evcode==0 if no events */
+ evcode = FSPY;
if (game.alldone) return;
datemin = fintim;
for (l = 1; l < NEVENTS; l++)
if (game.future[l].date < datemin) {
- line = l;
+ evcode = l;
if (idebug)
- prout("== Event %d fires", line);
+ prout("== Event %d fires", evcode);
datemin = game.future[l].date;
}
xtime = datemin-game.state.date;
return;
}
/* Is life support adequate? */
- if (game.damage[DLIFSUP] && game.condit != IHDOCKED) {
+ if (damaged(DLIFSUP) && game.condit != IHDOCKED) {
if (game.lsupres < xtime && game.damage[DLIFSUP] > game.lsupres) {
finish(FLIFESUP);
return;
if (game.damage[l] > 0.0 && l != DDRAY)
game.damage[l] -= (game.damage[l]-repair > 0.0 ? repair : game.damage[l]);
/* If radio repaired, update star chart and attack reports */
- if (radio_was_broken && game.damage[DRADIO] == 0.0) {
+ if (radio_was_broken && !damaged(DRADIO)) {
prout(_("Lt. Uhura- \"Captain, the sub-space radio is working and"));
prout(_(" surveillance reports are coming in."));
skip(1);
prout(_(" The star chart is now up to date.\""));
skip(1);
}
- /* Cause extraneous event LINE to occur */
+ /* Cause extraneous event EVCODE to occur */
game.optime -= xtime;
- switch (line) {
+ switch (evcode) {
case FSNOVA: /* Supernova */
- if (ipage==0) pause_game(1);
- ipage=1;
+ if (!ipage) pause_game(1);
+ ipage=true;
snova(0,0);
schedule(FSNOVA, expran(0.5*game.intime));
if (game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova) return;
game.condit==IHDOCKED || game.isatb==1 || game.iscate==1) return;
if (game.ientesc ||
(game.energy < 2000 && game.torps < 4 && game.shield < 1250) ||
- (game.damage[DPHASER]>0 && (game.damage[DPHOTON]>0 || game.torps < 4)) ||
- (game.damage[DSHIELD] > 0 &&
- (game.energy < 2500 || game.damage[DPHASER] > 0) &&
- (game.torps < 5 || game.damage[DPHOTON] > 0))) {
+ (damaged(DPHASER) && (damaged(DPHOTON) || game.torps < 4)) ||
+ (damaged(DSHIELD) &&
+ (game.energy < 2500 || damaged(DPHASER)) &&
+ (game.torps < 5 || damaged(DPHOTON)))) {
/* Tractor-beam her! */
istract=1;
yank = square(game.state.kscmdr.x-game.quadrant.x) + square(game.state.kscmdr.y-game.quadrant.y);
}
else return;
case FTBEAM: /* Tractor beam */
- if (line==FTBEAM) {
+ if (evcode==FTBEAM) {
if (game.state.remcom == 0) {
unschedule(FTBEAM);
break;
}
/* tractor beaming cases merge here */
yank = sqrt(yank);
- if (ipage==0) pause_game(1);
- ipage=1;
+ if (!ipage) pause_game(1);
+ ipage=true;
game.optime = (10.0/(7.5*7.5))*yank; /* 7.5 is yank rate (warp 7.5) */
ictbeam = 1;
skip(1);
prout(_("Galileo, left on the planet surface, is well hidden."));
}
}
- if (line==0)
+ if (evcode==0)
game.quadrant = game.state.kscmdr;
else
game.quadrant = game.state.kcmdr[i];
game.resting = false;
}
if (!game.shldup) {
- if (game.damage[DSHIELD]==0 && game.shield > 0) {
+ if (!damaged(DSHIELD) && game.shield > 0) {
doshield(2); /* Shldsup */
game.shldchg=0;
}
postpone(FCDBAS, scheduled(FSCDBAS)-game.state.date);
game.future[FBATTAK].date = game.future[FCDBAS].date + expran(0.3*game.intime);
game.iseenit = 0;
- if (game.damage[DRADIO] != 0.0 && game.condit != IHDOCKED)
+ if (!damaged(DRADIO) && game.condit != IHDOCKED)
break; /* No warning :-( */
game.iseenit = 1;
- if (ipage==0) pause_game(1);
- ipage = 1;
+ if (!ipage) pause_game(1);
+ ipage = true;
skip(1);
proutn(_("Lt. Uhura- \"Captain, the starbase in "));
prout(cramlc(quadrant, game.battle));
game.isatb = 2;
if (!game.state.galaxy[game.state.kscmdr.x][game.state.kscmdr.y].starbase)
break; /* WAS RETURN! */
- ixhold = game.battle.x;
- iyhold = game.battle.y;
+ hold = game.battle;
game.battle = game.state.kscmdr;
/* FALL THROUGH */
case FCDBAS: /* Commander succeeds in destroying base */
- if (line==FCDBAS) {
+ if (evcode==FCDBAS) {
unschedule(FCDBAS);
/* find the lucky pair */
for_commanders(i)
prout(_("Spock- \"Captain, I believe the starbase has been destroyed.\""));
}
else if (game.state.rembase != 1 &&
- (game.damage[DRADIO] <= 0.0 || game.condit == IHDOCKED)) {
+ (!damaged(DRADIO) || game.condit == IHDOCKED)) {
/* Get word via subspace radio */
- if (ipage==0) pause_game(1);
- ipage = 1;
+ if (!ipage) pause_game(1);
+ ipage = true;
skip(1);
prout(_("Lt. Uhura- \"Captain, Starfleet Command reports that"));
proutn(_(" the starbase in "));
game.state.rembase--;
if (game.isatb == 2) {
/* reinstate a commander's base attack */
- game.battle.x = ixhold;
- game.battle.y = iyhold;
+ game.battle = hold;
game.isatb = 0;
}
else {
if (!VALID_QUADRANT(i, j) ||
game.state.galaxy[game.probec.x][game.probec.y].supernova) {
// Left galaxy or ran into supernova
- if (game.damage[DRADIO]==0.0 || game.condit == IHDOCKED) {
+ if (!damaged(DRADIO) || game.condit == IHDOCKED) {
if (ipage==0) pause_game(1);
ipage = 1;
skip(1);
unschedule(FDSPROB);
break;
}
- if (game.damage[DRADIO]==0.0 || game.condit == IHDOCKED) {
+ if (!damaged(DRADIO) || game.condit == IHDOCKED) {
if (ipage==0) pause_game(1);
ipage = 1;
skip(1);
pdest = &game.state.galaxy[game.probec.x][game.probec.y];
/* Update star chart if Radio is working or have access to
radio. */
- if (game.damage[DRADIO] == 0.0 || game.condit == IHDOCKED) {
+ if (!damaged(DRADIO) || game.condit == IHDOCKED) {
struct page *chp = &game.state.chart[game.probec.x][game.probec.y];
chp->klingons = pdest->klingons;
q->status = distressed;
/* tell the captain about it if we can */
- if (game.damage[DRADIO] == 0.0 || game.condit == IHDOCKED)
+ if (!damaged(DRADIO) || game.condit == IHDOCKED)
{
- prout("Uhura: Captain, starsystem %s in quadrant %d - %d is under attack.",
- systemname(q->planet), w.x, w.y);
+ prout("Uhura- Captain, %s in %s reports it is under attack",
+ systemname(q->planet), cramlc(quadrant, w));
+ prout("by a Klingon invasion fleet.");
if (cancelrest())
return;
}
break;
- case FENSLV: /* starsystem is enslaved */
+ case FENSLV: /* starsystem is enslaved */
ev = unschedule(FENSLV);
/* see if current distress call still active */
q = &game.state.galaxy[ev->quadrant.x][ev->quadrant.y];
q->status = enslaved;
/* play stork and schedule the first baby */
- ev = schedule(FREPRO, expran(2.0 * game.intime));
+ ev2 = schedule(FREPRO, expran(2.0 * game.intime));
+ ev2->quadrant = ev->quadrant;
/* report the disaster if we can */
- if (game.damage[DRADIO] == 0.0 || game.condit == IHDOCKED)
+ if (!damaged(DRADIO) || game.condit == IHDOCKED)
{
- prout("\nUhura: We've lost contact with starsystem %s\n",
+ prout("Uhura- We've lost contact with starsystem %s",
systemname(q->planet));
- prout(" in quadrant %d,%d.\n", ev->quadrant.x,ev->quadrant.y);
+ prout("in %s.\n", cramlc(quadrant, ev->quadrant));
}
break;
- case FREPRO: /* Klingon reproduces */
+ case FREPRO: /* Klingon reproduces */
+ /*
+ * If we ever switch to a real event queue, we'll need to
+ * explicitly retrieve and restore the x and y.
+ */
ev = schedule(FREPRO, expran(1.0 * game.intime));
/* see if current distress call still active */
q = &game.state.galaxy[ev->quadrant.x][ev->quadrant.y];
q->status = secure;
break;
}
- /* reproduce one Klingon */
- w = ev->quadrant;
if (game.state.remkl >=MAXKLGAME)
break; /* full right now */
- /* this quadrant not ok, pick an adjacent one */
- for (i = w.x - 1; i <= w.x + 1; i++)
- {
- for (j = w.y - 1; j <= w.y + 1; j++)
+ /* reproduce one Klingon */
+ w = ev->quadrant;
+ if (game.klhere >= MAXKLQUAD) {
+ /* this quadrant not ok, pick an adjacent one */
+ for (i = w.x - 1; i <= w.x + 1; i++)
{
- if (!VALID_QUADRANT(i, j))
- continue;
- q = &game.state.galaxy[w.x][w.y];
- /* check for this quad ok (not full & no snova) */
- if (q->klingons >= MAXKLQUAD || !q->supernova)
- continue;
- goto foundit;
+ for (j = w.y - 1; j <= w.y + 1; j++)
+ {
+ if (!VALID_QUADRANT(i, j))
+ continue;
+ q = &game.state.galaxy[w.x][w.y];
+ /* check for this quad ok (not full & no snova) */
+ if (q->klingons >= MAXKLQUAD || q->supernova)
+ continue;
+ goto foundit;
+ }
}
+ break; /* search for eligible quadrant failed */
+ foundit:
+ w.x = i;
+ w.y = j;
}
- break; /* search for eligible quadrant failed */
- foundit:
- w.x = i;
- w.y = j;
/* deliver the child */
game.state.remkl++;
/* recompute time left */
game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);
+ /* report the disaster if we can */
+ if (!damaged(DRADIO) || game.condit == IHDOCKED)
+ {
+ if (same(game.quadrant, w)) {
+ prout("Spock- sensors indicate the Klingons have");
+ prout("launched a warship from %s.",systemname(q->planet));
+ } else {
+ prout("Uhura- Starfleet reports increased Klingon activity");
+ if (q->planet != NOPLANET)
+ proutn("near %s", systemname(q->planet));
+ prout("in %s.\n", cramlc(quadrant, w));
+ }
+ }
break;
}
}
if (nq.x != game.quadrant.y || nq.y != game.quadrant.y || game.justin != 0) {
/* it isn't here, or we just entered (treat as inroute) */
- if (game.damage[DRADIO] == 0.0 || game.condit == IHDOCKED) {
+ if (!damaged(DRADIO) || game.condit == IHDOCKED) {
skip(1);
prout(_("Message from Starfleet Command Stardate %.2f"), game.state.date);
prout(_(" Supernova in %s; caution advised."),
game.state.nplankl += npdead;
}
/* mark supernova in galaxy and in star chart */
- if ((game.quadrant.x == nq.x && game.quadrant.y == nq.y) ||
- game.damage[DRADIO] == 0 ||
- game.condit == IHDOCKED)
+ if (same(game.quadrant, nq) || !damaged(DRADIO) || game.condit == IHDOCKED)
game.state.galaxy[nq.x][nq.y].supernova = true;
- /* If supernova destroys last klingons give special message */
+ /* If supernova destroys last Klingons give special message */
if (KLINGREM==0 && (nq.x != game.quadrant.x || nq.y != game.quadrant.y)) {
skip(2);
if (insx == 0) prout(_("Lucky you!"));