Klingon ship births are working.
[super-star-trek.git] / src / events.c
index 7d4392109697e2fdcf6ab88b1b1ecf3be2d601ca..7fdf27157544123fc86abd57e31ab597d2e4f206 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * 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>
 
@@ -50,12 +58,12 @@ static bool cancelrest(void)
 
 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);
@@ -84,15 +92,15 @@ void events(void)
     radio_was_broken = (game.damage[DRADIO] != 0.0);
 
     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;
@@ -133,12 +141,12 @@ void events(void)
            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;
@@ -160,7 +168,7 @@ void events(void)
            }
            else return;
        case FTBEAM: /* Tractor beam */
-           if (line==FTBEAM) {
+           if (evcode==FTBEAM) {
                if (game.state.remcom == 0) {
                    unschedule(FTBEAM);
                    break;
@@ -176,8 +184,8 @@ void events(void)
            }
            /* 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);
@@ -204,7 +212,7 @@ void events(void)
                    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];
@@ -271,8 +279,8 @@ void events(void)
            if (game.damage[DRADIO] != 0.0 && 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));
@@ -288,12 +296,11 @@ void events(void)
            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)
@@ -320,8 +327,8 @@ void events(void)
            else if (game.state.rembase != 1 &&
                     (game.damage[DRADIO] <= 0.0 || 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 "));
@@ -340,8 +347,7 @@ void events(void)
            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 {
@@ -410,7 +416,7 @@ void events(void)
            }
            break;
        case FDISTR: /* inhabited system issues distress call */
-           schedule(FDISTR, expran(0.5*game.intime));
+           unschedule(FDISTR);
            /* try a whole bunch of times to find something suitable */
            i = 100;
            do {
@@ -434,19 +440,18 @@ void events(void)
            ev = schedule(FENSLV, expran(game.intime));
            ev->quadrant = w;
            q->status = distressed;
-           if (idebug)
-               prout("=== Distress call set at %d, %d.", w.x, w.y);
 
            /* tell the captain about it if we can */
            if (game.damage[DRADIO] == 0.0 || 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];
@@ -457,17 +462,22 @@ void events(void)
            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)
            {
-               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];
@@ -475,28 +485,30 @@ void events(void)
                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++;
@@ -506,6 +518,19 @@ void events(void)
 
            /* recompute time left */
            game.state.remtime = game.state.remres/(game.state.remkl+4*game.state.remcom);
+           /* report the disaster if we can */
+           if (game.damage[DRADIO] == 0.0 || 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;
        }
     }
@@ -894,11 +919,9 @@ void snova(int insx, int insy)
        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) || game.damage[DRADIO] == 0 || 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!"));