Rewrite to get ride of FORTRANish galaxy and newstuff arrays. It's
authorEric S. Raymond <esr@thyrsus.com>
Mon, 7 Feb 2005 13:10:54 +0000 (13:10 +0000)
committerEric S. Raymond <esr@thyrsus.com>
Mon, 7 Feb 2005 13:10:54 +0000 (13:10 +0000)
all one C structure array now.  Also back out "Bases left" report.

12 files changed:
TODO
ai.c
battle.c
events.c
io.c
moving.c
planets.c
reports.c
setup.c
sst-doc.xml
sst.c
sst.h

diff --git a/TODO b/TODO
index dc76924bece82c8c70e73491b5f21fa870188a1b..d546f6a61439a65cb14bdff3a71416be2e00ab23 100644 (file)
--- a/TODO
+++ b/TODO
@@ -7,4 +7,6 @@
 * Code to hurl you out of quadrant if a supernova occurs as you warp in 
   seems to hang.
 
-* Regenerate Thingy at random location when unfreezing a game.
+* "Bases left" report doesn't look right in the -t version.
+
+* Orbit height is negative.
diff --git a/ai.c b/ai.c
index e766e9832d6dfaac210ff7b0fcd6acac7f93d8e3..c6a862ea25c2c4ff01ae63af5db386c21b163533 100644 (file)
--- a/ai.c
+++ b/ai.c
@@ -7,7 +7,8 @@ static int tryexit(int lookx, int looky, int ienm, int loccom, int irun)
     iqx = quadx+(lookx+(QUADSIZE-1))/QUADSIZE - 1;
     iqy = quady+(looky+(QUADSIZE-1))/QUADSIZE - 1;
     if (iqx < 1 || iqx > GALSIZE || iqy < 1 || iqy > GALSIZE ||
-       NOEXIT(game.state.galaxy[iqx][iqy]))
+       game.state.galaxy[iqx][iqy].supernova ||
+       game.state.galaxy[iqx][iqy].klingons > 8)
        return 0; /* no can do -- neg energy, supernovae, or >8 Klingons */
     if (ienm == IHR) return 0; /* Romulans cannot escape! */
     if (irun == 0) {
@@ -40,8 +41,8 @@ static int tryexit(int lookx, int looky, int ienm, int loccom, int irun)
     nenhere--;
     if (condit != IHDOCKED) newcnd();
     /* Handle global matters related to escape */
-    game.state.galaxy[quadx][quady] -= KLINGON_PLACE;
-    game.state.galaxy[iqx][iqy] += KLINGON_PLACE;
+    game.state.galaxy[quadx][quady].klingons--;
+    game.state.galaxy[iqx][iqy].klingons++;
     if (ienm==IHS) {
        ishere=0;
        iscate=0;
@@ -307,7 +308,9 @@ static int movescom(int iqx, int iqy, int flag, int *ipage)
 
     if ((iqx==quadx && iqy==quady) ||
        iqx < 1 || iqx > GALSIZE || iqy < 1 || iqy > GALSIZE ||
-       NOEXIT(game.state.galaxy[iqx][iqy])) return 1;
+       game.state.galaxy[iqx][iqy].supernova ||
+       game.state.galaxy[iqx][iqy].klingons > 8) 
+       return 1;
     if (flag) {
        /* Avoid quadrants with bases if we want to avoid Enterprise */
        for (i = 1; i <= game.state.rembase; i++)
@@ -315,10 +318,10 @@ static int movescom(int iqx, int iqy, int flag, int *ipage)
     }
     if (justin && !iscate) return 1;
     /* do the move */
-    game.state.galaxy[game.state.isx][game.state.isy] -= KLINGON_PLACE;
+    game.state.galaxy[game.state.isx][game.state.isy].klingons--;
     game.state.isx = iqx;
     game.state.isy = iqy;
-    game.state.galaxy[game.state.isx][game.state.isy] += KLINGON_PLACE;
+    game.state.galaxy[game.state.isx][game.state.isy].klingons++;
     if (ishere) {
        /* SC has scooted, Remove him from current quadrant */
        iscate=0;
@@ -345,7 +348,7 @@ static int movescom(int iqx, int iqy, int flag, int *ipage)
            game.state.plnets[i].crystals == 1) {
            /* destroy the planet */
            DESTROY(&game.state.plnets[i]);
-           game.state.newstuf[game.state.isx][game.state.isy] -= 1;
+           game.state.galaxy[game.state.isx][game.state.isy].planets -= 1;
            if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) {
                if (*ipage==0) pause_game(1);
                *ipage = 1;
@@ -428,7 +431,9 @@ void scom(int *ipage)
            ibqy = game.state.baseqy[i];
            if ((ibqx == quadx && ibqy == quady) ||
                (ibqx == batx && ibqy == baty) ||
-               NOEXIT(game.state.galaxy[ibqx][ibqy])) continue;
+               game.state.galaxy[ibqx][ibqy].supernova ||
+               game.state.galaxy[ibqx][ibqy].klingons > 8) 
+               continue;
            /* if there is a commander, an no other base is appropriate,
               we will take the one with the commander */
            for (j = 1; j <= game.state.remcom; j++) {
@@ -530,7 +535,7 @@ void scom(int *ipage)
 #endif
        (Rand() > 0.2 ||
         (game.damage[DRADIO] > 0.0 && condit != IHDOCKED) ||
-        game.starch[game.state.isx][game.state.isy] > 0))
+        !game.state.galaxy[game.state.isx][game.state.isy].charted))
        return;
     if (*ipage==0) pause_game(1);
     *ipage = 1;
index 75ac19035437662a1a48dfdab3db81b450ded6f8..5356e3d14f9f11a1bdcb6a7ed057dc8d20274610 100644 (file)
--- a/battle.c
+++ b/battle.c
@@ -300,7 +300,6 @@ void torpedo(double course, double r, int inx, int iny, double *hit, int wait, i
        case IHB: /* Hit a base */
            skip(1);
            prout("***STARBASE DESTROYED..");
-           if (game.starch[quadx][quady] < 0) game.starch[quadx][quady] = 0;
            for (ll=1; ll<=game.state.rembase; ll++) {
                if (game.state.baseqx[ll]==quadx && game.state.baseqy[ll]==quady) {
                    game.state.baseqx[ll]=game.state.baseqx[game.state.rembase];
@@ -311,7 +310,8 @@ void torpedo(double course, double r, int inx, int iny, double *hit, int wait, i
            game.quad[ix][iy]=IHDOT;
            game.state.rembase--;
            basex=basey=0;
-           game.state.galaxy[quadx][quady] -= BASE_PLACE;
+           game.state.galaxy[quadx][quady].starbase--;
+           game.state.chart[quadx][quady].starbase--;
            game.state.basekl++;
            newcnd();
            return;
@@ -319,7 +319,7 @@ void torpedo(double course, double r, int inx, int iny, double *hit, int wait, i
            crmena(1, iquad, 2, ix, iy);
            prout(" destroyed.");
            game.state.nplankl++;
-           game.state.newstuf[quadx][quady] -= 1;
+           game.state.galaxy[quadx][quady].planets--;
            DESTROY(&game.state.plnets[iplnet]);
            iplnet = 0;
            plnetx = plnety = 0;
@@ -520,9 +520,10 @@ void attack(int torps_ok)
            r = (Rand()+Rand())*0.5 -0.5;
            r += 0.002*game.kpower[l]*r;
            torpedo(course, r, jx, jy, &hit, 0, 1, 1);
-           if (game.state.remkl==0) finish(FWON); /* Klingons did themselves in! */
-           if (game.state.galaxy[quadx][quady] == SUPERNOVA_PLACE ||
-               alldone) return; /* Supernova or finished */
+           if (game.state.remkl==0) 
+               finish(FWON); /* Klingons did themselves in! */
+           if (game.state.galaxy[quadx][quady].supernova || alldone) 
+               return; /* Supernova or finished */
            if (hit == 0) continue;
        }
        if (shldup != 0 || shldchg != 0 || condit==IHDOCKED) {
@@ -612,7 +613,7 @@ void deadkl(int ix, int iy, int type, int ixx, int iyy)
     /* Decide what kind of enemy it is and update approriately */
     if (type == IHR) {
        /* chalk up a Romulan */
-       game.state.newstuf[quadx][quady] -= ROMULAN_PLACE;
+       game.state.galaxy[quadx][quady].romulans--;
        irhere--;
        game.state.nromkl++;
        game.state.nromrem--;
@@ -627,7 +628,7 @@ void deadkl(int ix, int iy, int type, int ixx, int iyy)
     }
     else {
        /* Some type of a Klingon */
-       game.state.galaxy[quadx][quady] -= KLINGON_PLACE;
+       game.state.galaxy[quadx][quady].klingons--;
        klhere--;
        game.state.remkl--;
        switch (type) {
@@ -828,7 +829,7 @@ void photon(void)
        if (shldup || condit == IHDOCKED) 
            r *= 1.0 + 0.0001*shield;
        torpedo(course[i], r, sectx, secty, &dummy, 0, i, n);
-       if (alldone||game.state.galaxy[quadx][quady]==SUPERNOVA_PLACE)
+       if (alldone || game.state.galaxy[quadx][quady].supernova)
            return;
     }
     if (game.state.remkl==0) finish(FWON);
index 5b75fae493312b78be4cca58510d331cddf99ae1..55cc81671184eb2911c2714099a9ec80b3f7f2a7 100644 (file)
--- a/events.c
+++ b/events.c
@@ -5,19 +5,13 @@ void events(void)
 {
     int ictbeam=0, ipage=0, istract=0, line, i=0, j, k, l, ixhold=0, iyhold=0;
     double fintim = game.state.date + Time, datemin, xtime, repair, yank=0;
+    int radio_was_broken;
 
 #ifdef DEBUG
     if (idebug) prout("EVENTS");
 #endif
 
-    if (stdamtim == 1e30 && game.damage[DRADIO] != 0.0) {
-       /* chart will no longer be updated because radio is dead */
-       stdamtim = game.state.date;
-       for (i=1; i <= GALSIZE ; i++)
-           for (j=1; j <= GALSIZE; j++)
-               if (game.starch[i][j] == 1) 
-                   game.starch[i][j] = game.state.galaxy[i][j]+SUPERNOVA_PLACE;
-    }
+    radio_was_broken = (game.damage[DRADIO] != 0.0);
 
     for (;;) {
        /* Select earliest extraneous event, line==0 if no events */
@@ -55,19 +49,16 @@ void events(void)
            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 (stdamtim != 1e30 && game.damage[DRADIO] == 0.0) {
+       if (radio_was_broken && game.damage[DRADIO] == 0.0) {
            stdamtim = 1e30;
            prout("Lt. Uhura- \"Captain, the sub-space radio is working and");
            prout("   surveillance reports are coming in.");
            skip(1);
-           for (i=1; i <= GALSIZE ; i++)
-               for (j=1; j <= GALSIZE; j++)
-                   if (game.starch[i][j] >= SUPERNOVA_PLACE) game.starch[i][j] = 1;
            if (iseenit==0) {
                attakreport(0);
                iseenit = 1;
            }
-           skip(1);
+           rechart();
            prout("   The star chart is now up to date.\"");
            skip(1);
        }
@@ -79,7 +70,7 @@ void events(void)
            ipage=1;
            snova(0,0);
            game.future[FSNOVA] = game.state.date + expran(0.5*intime);
-           if (game.state.galaxy[quadx][quady] == SUPERNOVA_PLACE) return;
+           if (game.state.galaxy[quadx][quady].supernova) return;
            break;
        case FSPY: /* Check with spy to see if S.C. should tractor beam */
            if (game.state.nscrem == 0 ||
@@ -235,7 +226,7 @@ void events(void)
        case FSCDBAS: /* Supercommander destroys base */
            game.future[FSCDBAS] = 1e30;
            isatb = 2;
-           if (!BASES(game.state.galaxy[game.state.isx][game.state.isy])
+           if (!game.state.galaxy[game.state.isx][game.state.isy].starbase
                break; /* WAS RETURN! */
            ixhold = batx;
            iyhold = baty;
@@ -246,9 +237,10 @@ void events(void)
                game.future[FCDBAS] = 1e30;
                /* find the lucky pair */
                for (i = 1; i <= game.state.remcom; i++)
-                   if (game.state.cx[i]==batx && game.state.cy[i]==baty) break;
+                   if (game.state.cx[i]==batx && game.state.cy[i]==baty) 
+                       break;
                if (i > game.state.remcom || game.state.rembase == 0 ||
-                   !BASES(game.state.galaxy[batx][baty])) {
+                   !game.state.galaxy[batx][baty].starbase) {
                    /* No action to take after all */
                    batx = baty = 0;
                    break;
@@ -256,10 +248,9 @@ void events(void)
            }
            /* Code merges here for any commander destroying base */
            /* Not perfect, but will have to do */
-           if (game.starch[batx][baty] == -1) game.starch[batx][baty] = 0;
            /* Handle case where base is in same quadrant as starship */
            if (batx==quadx && baty==quady) {
-               if (game.starch[batx][baty] >= SUPERNOVA_PLACE) game.starch[batx][baty] -= BASE_PLACE;
+               game.state.chart[batx][baty].starbase = FALSE;
                game.quad[basex][basey]= IHDOT;
                basex=basey=0;
                newcnd();
@@ -278,9 +269,10 @@ void events(void)
                prout(" has been destroyed by");
                if (isatb==2) prout("the Klingon Super-Commander");
                else prout("a Klingon Commander");
+               game.state.chart[batx][baty].starbase = FALSE;
            }
            /* Remove Starbase from galaxy */
-           game.state.galaxy[batx][baty] -= BASE_PLACE;
+           game.state.galaxy[batx][baty].starbase = FALSE;
            for (i=1; i <= game.state.rembase; i++)
                if (game.state.baseqx[i]==batx && game.state.baseqy[i]==baty) {
                    game.state.baseqx[i]=game.state.baseqx[game.state.rembase];
@@ -313,7 +305,7 @@ void events(void)
                probecx = i;
                probecy = j;
                if (i < 1 || i > GALSIZE || j < 1 || j > GALSIZE ||
-                   game.state.galaxy[probecx][probecy] == SUPERNOVA_PLACE) {
+                   game.state.galaxy[probecx][probecy].supernova) {
                    // Left galaxy or ran into supernova
                    if (game.damage[DRADIO]==0.0 || condit == IHDOCKED) {
                        if (ipage==0) pause_game(1);
@@ -340,16 +332,20 @@ void events(void)
            }
            /* Update star chart if Radio is working or have access to
               radio. */
-           if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED)
-               game.starch[probecx][probecy] = game.damage[DRADIO] > 0.0 ?
-                   game.state.galaxy[probecx][probecy]+SUPERNOVA_PLACE : 1;
+           if (game.damage[DRADIO] == 0.0 || condit == IHDOCKED) {
+               game.state.chart[probecx][probecy].klingons = game.state.galaxy[probecx][probecy].klingons;
+               game.state.chart[probecx][probecy].starbase = game.state.galaxy[probecx][probecy].starbase;
+               game.state.chart[probecx][probecy].stars = game.state.galaxy[probecx][probecy].stars;
+               game.state.galaxy[probecx][probecy].charted = TRUE;
+           }
            proben--; // One less to travel
            if (proben == 0 && isarmed &&
-               STARS(game.state.galaxy[probecx][probecy])) {
+               game.state.galaxy[probecx][probecy].stars) {
                /* lets blow the sucker! */
                snova(1,0);
                game.future[FDSPROB] = 1e30;
-               if (game.state.galaxy[quadx][quady] == SUPERNOVA_PLACE) return;
+               if (game.state.galaxy[quadx][quady].supernova) 
+                   return;
            }
            break;
        }
@@ -406,7 +402,8 @@ void wait(void)
        if (origTime-delay >= 9.99 && condit == IHDOCKED)
            game.damage[DDRAY] = 0.0;
     } while 
-       (game.state.galaxy[quadx][quady] != SUPERNOVA_PLACE); // leave if quadrant supernovas
+       // leave if quadrant supernovas
+       (!game.state.galaxy[quadx][quady].supernova);
 
     resting = 0;
     Time = 0;
@@ -428,7 +425,7 @@ void nova(int ix, int iy)
     game.quad[ix][iy] = IHDOT;
     crmena(1, IHSTAR, 2, ix, iy);
     prout(" novas.");
-    game.state.galaxy[quadx][quady] -= 1;
+    game.state.galaxy[quadx][quady].stars--;
     game.state.starkl++;
        
     /* Set up stack to recursively trigger adjacent stars */
@@ -463,14 +460,14 @@ void nova(int ix, int iy)
                        top2++;
                        hits[top2][1]=ii;
                        hits[top2][2]=jj;
-                       game.state.galaxy[quadx][quady] -= 1;
+                       game.state.galaxy[quadx][quady].stars -= 1;
                        game.state.starkl++;
                        crmena(1, IHSTAR, 2, ii, jj);
                        prout(" novas.");
                        game.quad[ii][jj] = IHDOT;
                        break;
                    case IHP: /* Destroy planet */
-                       game.state.newstuf[quadx][quady] -= 1;
+                       game.state.galaxy[quadx][quady].planets -= 1;
                        game.state.nplankl++;
                        crmena(1, IHP, 2, ii, jj);
                        prout(" destroyed.");
@@ -483,9 +480,10 @@ void nova(int ix, int iy)
                        game.quad[ii][jj] = IHDOT;
                        break;
                    case IHB: /* Destroy base */
-                       game.state.galaxy[quadx][quady] -= BASE_PLACE;
+                       game.state.galaxy[quadx][quady].starbase = FALSE;
                        for (i = 1; i <= game.state.rembase; i++)
-                           if (game.state.baseqx[i]==quadx && game.state.baseqy[i]==quady) break;
+                           if (game.state.baseqx[i]==quadx && game.state.baseqy[i]==quady) 
+                               break;
                        game.state.baseqx[i] = game.state.baseqx[game.state.rembase];
                        game.state.baseqy[i] = game.state.baseqy[game.state.rembase];
                        game.state.rembase--;
@@ -594,7 +592,7 @@ void nova(int ix, int iy)
        
 void snova(int insx, int insy) 
 {
-    int comdead, nqx=0, nqy=0, nsx, nsy, num, kldead, iscdead;
+    int comdead, nqx=0, nqy=0, nsx, nsy, num=0, kldead, iscdead;
     int nrmdead, npdead;
     int incipient=0;
 
@@ -614,14 +612,14 @@ void snova(int insx, int insy)
               left of universe */
            for (nqx = 1; nqx<=GALSIZE; nqx++) {
                for (nqy = 1; nqy<=GALSIZE; nqy++) {
-                   stars += STARS(game.state.galaxy[nqx][nqy]);
+                   stars += game.state.galaxy[nqx][nqy].stars;
                }
            }
            if (stars == 0) return; /* nothing to supernova exists */
            num = Rand()*stars + 1;
            for (nqx = 1; nqx<=GALSIZE; nqx++) {
                for (nqy = 1; nqy<=GALSIZE; nqy++) {
-                   num -= STARS(game.state.galaxy[nqx][nqy]);
+                   num -= game.state.galaxy[nqx][nqy].stars;
                    if (num <= 0) break;
                }
                if (num <=0) break;
@@ -649,7 +647,7 @@ void snova(int insx, int insy)
        else {
            /* we are in the quadrant! */
            incipient = 1;
-           num = Rand()* STARS(game.state.galaxy[nqx][nqy]) + 1;
+           num = Rand()* game.state.galaxy[nqx][nqy].stars + 1;
            for (nsx=1; nsx < QUADSIZE; nsx++) {
                for (nsy=1; nsy < QUADSIZE; nsy++) {
                    if (game.quad[nsx][nsy]==IHSTAR) {
@@ -681,8 +679,8 @@ void snova(int insx, int insy)
        }
     }
     /* destroy any Klingons in supernovaed quadrant */
-    num=game.state.galaxy[nqx][nqy];
-    kldead = num/100;
+    kldead = game.state.galaxy[nqx][nqy].klingons;
+    game.state.galaxy[nqx][nqy].klingons = 0;
     comdead = iscdead = 0;
     if (nqx==game.state.isx && nqy == game.state.isy) {
        /* did in the Supercommander! */
@@ -707,9 +705,8 @@ void snova(int insx, int insy)
        }
     }
     /* destroy Romulans and planets in supernovaed quadrant */
-    num = game.state.newstuf[nqx][nqy];
-    game.state.newstuf[nqx][nqy] = 0;
-    nrmdead = num/10;
+    nrmdead = game.state.galaxy[nqx][nqy].romulans;
+    game.state.galaxy[nqx][nqy].romulans = 0;
     game.state.nromrem -= nrmdead;
     npdead = num - nrmdead*10;
     if (npdead) {
@@ -733,9 +730,8 @@ void snova(int insx, int insy)
     }
     /* If starship caused supernova, tally up destruction */
     if (insx) {
-       num = game.state.galaxy[nqx][nqy] % 100;
-       game.state.starkl += num % 10;
-       game.state.basekl += num/10;
+       game.state.starkl += game.state.galaxy[nqx][nqy].stars;
+       game.state.basekl += game.state.galaxy[nqx][nqy].starbase;
        game.state.killk += kldead;
        game.state.killc += comdead;
        game.state.nromkl += nrmdead;
@@ -746,8 +742,7 @@ void snova(int insx, int insy)
     if ((quadx == nqx && quady == nqy) ||
        game.damage[DRADIO] == 0 ||
        condit == IHDOCKED)
-       game.starch[nqx][nqy] = 1;
-    game.state.galaxy[nqx][nqy] = SUPERNOVA_PLACE;
+       game.state.galaxy[nqx][nqy].supernova = TRUE;
     /* If supernova destroys last klingons give special message */
     if (game.state.remkl==0 && (nqx != quadx || nqy != quady)) {
        skip(2);
diff --git a/io.c b/io.c
index 5de081916c4716c48a4fb5b0f74492bb3646693a..b3d2438d0b3ed289edd7a92c39790b696c5100da 100644 (file)
--- a/io.c
+++ b/io.c
@@ -408,7 +408,7 @@ void makechart(void)
 
 void setpassword(void) 
 {
-    if (!game.options & OPTION_CURSES) {
+    if (!(game.options & OPTION_CURSES)) {
        while (TRUE) {
            scan();
            strcpy(game.passwd, citem);
index f9b352bf9f0f723aaeea6c3aef121d09e41fcddb..2ba016a960af967b52f70f4f3e5d1978ddd3a66a 100644 (file)
--- a/moving.c
+++ b/moving.c
@@ -58,7 +58,7 @@ void imove(void)
                     * that attacks only happen if Klingons
                     * are present and your skill is good.
                     */
-                   if (skill > SKILL_GOOD && klhere > 0 && game.state.galaxy[quadx][quady] != SUPERNOVA_PLACE)
+                   if (skill > SKILL_GOOD && klhere > 0 && !game.state.galaxy[quadx][quady].supernova)
                        attack(0);
                    if (alldone) return;
                }
@@ -200,7 +200,7 @@ no_quad_change:
            game.kdist[l] = finald;
        }
        sortkl();
-       if (game.state.galaxy[quadx][quady] != SUPERNOVA_PLACE && iattak == 0)
+       if (!game.state.galaxy[quadx][quady].supernova && iattak == 0)
            attack(0);
        for (l = 1 ; l <= nenhere; l++) game.kavgd[l] = game.kdist[l];
     }
@@ -264,7 +264,7 @@ static void getcd(int isprobe, int akey) {
        
        if (landed == 1 && !isprobe) {
                prout("Dummy! You can't leave standard orbit until you");
-               proutn("are back abourt the ");
+               proutn("are back aboard the ");
                crmshp();
                prout(".");
                chew();
@@ -730,8 +730,8 @@ void atover(int igrab)
        crmshp();
        skip(1);
        prout("safely out of quadrant.");
-       game.starch[quadx][quady] = game.damage[DRADIO] > 0.0 ? game.state.galaxy[quadx][quady]+SUPERNOVA_PLACE:1;
-
+       if (game.damage[DRADIO] == 0.0)
+           game.state.galaxy[quadx][quady].charted = TRUE;
        /* Try to use warp engines */
        if (game.damage[DWARPEN]) {
            skip(1);
@@ -759,14 +759,16 @@ void atover(int igrab)
            finish(FSNOVAED);
            return;
        }
+    } while 
        /* Repeat if another snova */
-    } while (game.state.galaxy[quadx][quady] == SUPERNOVA_PLACE);
-    if (game.state.remkl==0) finish(FWON); /* Snova killed remaining enemy. */
+       (game.state.galaxy[quadx][quady].supernova);
+    if (game.state.remkl==0) 
+       finish(FWON); /* Snova killed remaining enemy. */
 }
 
 void timwrp() 
 {
-    int l, ll, gotit;
+    int l, gotit;
     prout("***TIME WARP ENTERED.");
     if (game.state.snap && Rand() < 0.5) {
        /* Go back in time */
@@ -804,16 +806,11 @@ void timwrp()
            prout("Checkov-  \"Security reports the Galileo has reappeared in the dock!\"");
            iscraft = 1;
        }
-
-       /* Revert star chart to earlier era, if it was known then*/
-       if (game.damage[DRADIO]==0.0 || stdamtim > game.state.date) {
-           for (l = 1; l <= GALSIZE; l++)
-               for (ll = 1; ll <= GALSIZE; ll++)
-                   if (game.starch[l][ll] > 1)
-                       game.starch[l][ll]=game.damage[DRADIO]>0.0 ? game.state.galaxy[l][ll]+SUPERNOVA_PLACE :1;
-           prout("Spock has reconstructed a correct star chart from memory");
-           if (game.damage[DRADIO] > 0.0) stdamtim = game.state.date;
-       }
+       /* 
+        * There used to be code to do the actual reconstrction here,
+        * but the starchart is now part of the snapshotted galaxy state.
+        */
+       prout("Spock has reconstructed a correct star chart from memory");
     }
     else {
        /* Go forward in time */
index 69ca3271c2e32ae9e4b35dd518384e8b5538b2b6..057fb84dbd1cd3bdd0af04efb5c707e12dda6ef4 100644 (file)
--- a/planets.c
+++ b/planets.c
@@ -23,7 +23,7 @@ static int consumeTime(void)
     events();  /* Used to avoid if future[FSCMOVE] within time */
 //     future[FSNOVA] = asave;
     /*fails if game over, quadrant super-novas or we've moved to new quadrant*/
-    if (alldone || game.state.galaxy[quadx][quady] == SUPERNOVA_PLACE || justin != 0) return 1;
+    if (alldone || game.state.galaxy[quadx][quady].supernova || justin != 0) return 1;
     return 0;
 }
 
index de2ba1b1274928937e1b150a41457535d9e7b3b9..3f654cf9a39e3f848e9e5cb78344b71eaf249526 100644 (file)
--- a/reports.c
+++ b/reports.c
@@ -135,9 +135,15 @@ void lrscan(void)
            if (x == 0 || x > GALSIZE || y == 0 || y > GALSIZE)
                proutn("  -1");
            else {
-               if (game.state.galaxy[x][y]<SUPERNOVA_PLACE) proutn(" %3d", game.state.galaxy[x][y]);
-               else proutn("***");
-               game.starch[x][y] = game.damage[DRADIO] > 0 ? game.state.galaxy[x][y]+SUPERNOVA_PLACE : 1;
+               if (!game.damage[DRADIO])
+                   game.state.galaxy[x][y].charted = TRUE;
+               game.state.chart[x][y].klingons = game.state.galaxy[x][y].klingons;
+               game.state.chart[x][y].starbase = game.state.galaxy[x][y].starbase;
+               game.state.chart[x][y].stars = game.state.galaxy[x][y].stars;
+               if (game.state.galaxy[x][y].supernova) 
+                   proutn("***");
+               else
+                   proutn(" %-3d", game.state.chart[x][y].klingons*100 + game.state.chart[x][y].starbase * 10 + game.state.chart[x][y].stars);
            }
        }
        prout(" ");
@@ -165,6 +171,20 @@ void dreprt(void)
     if (!jdam) prout("All devices functional.");
 }
 
+void rechart(void)
+/* update the chart in the Enterprise's computer from galaxy data */
+{
+    int i, j;
+    stdamtim = game.state.date;
+    for (i=1; i <= GALSIZE ; i++)
+       for (j=1; j <= GALSIZE; j++) 
+           if (game.state.galaxy[i][j].charted) {
+               game.state.chart[i][j].klingons = game.state.galaxy[i][j].klingons;
+               game.state.chart[i][j].starbase = game.state.galaxy[i][j].starbase;
+               game.state.chart[i][j].stars = game.state.galaxy[i][j].stars;
+           }
+}
+
 void chart(int nn) 
 {
     int i,j;
@@ -177,16 +197,15 @@ void chart(int nn)
     if (stdamtim != 1e30) {
        if (condit == IHDOCKED) {
            /* We are docked, so restore chart from base information */
-           stdamtim = game.state.date;
-           for (i=1; i <= GALSIZE ; i++)
-               for (j=1; j <= GALSIZE; j++)
-                   if (game.starch[i][j] == 1) game.starch[i][j] = game.state.galaxy[i][j]+SUPERNOVA_PLACE;
+           rechart();
        }
-       else {
-           proutn("(Last surveillance update %d stardates ago.",
+       else if (game.state.date-stdamtim) {
+           prout("(Last surveillance update %d stardates ago).",
                   (int)(game.state.date-stdamtim));
        }
     }
+    else if (game.damage[DRADIO] == 0.0)
+       rechart();
 
     prout("      1    2    3    4    5    6    7    8");
     for (i = 1; i <= GALSIZE; i++) {
@@ -194,14 +213,14 @@ void chart(int nn)
        for (j = 1; j <= GALSIZE; j++) {
            char buf[4];
            proutn("  ");
-           if (game.starch[i][j] == CHART_UNKNOWN)
-               strcpy(buf, ".1.");
-           else if (game.starch[i][j] == 0)
-               strcpy(buf, "...");
-           else if (game.state.galaxy[i][j]>=SUPERNOVA_PLACE)
+           if (game.state.galaxy[i][j].supernova)
                strcpy(buf, "***");
+           else if (!game.state.galaxy[i][j].charted && game.state.galaxy[i][j].starbase)
+               strcpy(buf, ".1.");
+           else if (game.state.galaxy[i][j].charted)
+               sprintf(buf, "%d%d%d", game.state.chart[i][j].klingons, game.state.chart[i][j].starbase, game.state.chart[i][j].stars);
            else
-               sprintf(buf, "%03d", game.state.galaxy[i][j]);
+               strcpy(buf, "...");
            for (cp = buf; cp < buf + sizeof(buf); cp++)
                if (*cp == '0')
                    *cp = '.';
@@ -301,23 +320,13 @@ static void status(int req)
     case 10:
        attakreport(1);
        break;
-       /*
-        * Note: attakreport() can in some cases produce two lines of
-        * output.  If that happens, and QUADSIZE is the normal 10, items
-        * 11 and up will be printed past the bottom of the quadrant display.
-        * Under the curses display logic they will get lost because they're
-        * written outside the report window.
-        */
-    case 11:   /* ESR */
-       proutn("Bases Left    %d", game.state.rembase);
-       break;
     }
 }
                
 int srscan(int l) 
 {
     static char requests[][3] =
-       {"","da","co","po","ls","wa","en","to","sh","kl","ti", "ba"};
+       {"","da","co","po","ls","wa","en","to","sh","kl","ti"};
     int leftside=TRUE, rightside=TRUE, i, j, jj, req=0, nn=FALSE;
     int goodScan=TRUE;
     switch (l) {
@@ -332,7 +341,12 @@ int srscan(int l)
                prout("  [Using Base's sensors]");
        }
        else proutn("     Short-range scan\n\r");
-       if (goodScan) game.starch[quadx][quady] = game.damage[DRADIO]>0.0 ? game.state.galaxy[quadx][quady]+SUPERNOVA_PLACE:1;
+       if (goodScan && !game.damage[DRADIO]) { 
+           game.state.chart[quadx][quady].klingons = game.state.galaxy[quadx][quady].klingons;
+           game.state.chart[quadx][quady].starbase = game.state.galaxy[quadx][quady].starbase;
+           game.state.chart[quadx][quady].stars = game.state.galaxy[quadx][quady].stars;
+           game.state.galaxy[quadx][quady].charted = TRUE;
+       }
        scan();
        if (isit("chart")) nn = TRUE;
        if (isit("no")) rightside = FALSE;
diff --git a/setup.c b/setup.c
index b9c4842578cbfc08394c258360f15b26e397a234..f4a037333a4a922334f1eeacb981cd52c7d85628 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -228,7 +228,11 @@ void setup(int needprompt)
     alive = 1;
     docfac = 0.25;
     for (i = 1; i <= GALSIZE; i++)
-       for (j = 1; j <= GALSIZE; j++) game.state.newstuf[i][j] = game.starch[i][j] = 0;
+       for (j = 1; j <= GALSIZE; j++) {
+           game.state.galaxy[i][j].charted = 0;
+           game.state.galaxy[i][j].planets = 0;
+           game.state.galaxy[i][j].romulans = 0;
+       }
     // Initialize times for extraneous events
     game.future[FSNOVA] = game.state.date + expran(0.5 * intime);
     game.future[FTBEAM] = game.state.date + expran(1.5 * (intime / game.state.remcom));
@@ -246,14 +250,14 @@ void setup(int needprompt)
        for (j=1; j<=GALSIZE; j++) {
            int k = Rand()*9.0 + 1.0;
            instar += k;
-           game.state.galaxy[i][j] = k * STAR_PLACE;
+           game.state.galaxy[i][j].stars = k;
        }
     // Locate star bases in galaxy
     for (i = 1; i <= inbase; i++) {
        int contflag;
        do {
            do iran(GALSIZE, &ix, &iy);
-           while (BASES(game.state.galaxy[ix][iy]));
+           while (game.state.galaxy[ix][iy].starbase);
            contflag = FALSE;
            for (j = i-1; j > 0; j--) {
                /* Improved placement algorithm to spread out bases */
@@ -275,8 +279,8 @@ void setup(int needprompt)
                        
        game.state.baseqx[i] = ix;
        game.state.baseqy[i] = iy;
-       game.starch[ix][iy] = CHART_UNKNOWN;
-       game.state.galaxy[ix][iy] += BASE_PLACE;
+       game.state.galaxy[ix][iy].starbase = 1;
+       game.state.chart[ix][iy].starbase = 1;
     }
     // Position ordinary Klingon Battle Cruisers
     krem = inkling - incom - game.state.nscrem;
@@ -287,10 +291,8 @@ void setup(int needprompt)
        int klump = (1.0 - r*r)*klumper;
        if (klump > krem) klump = krem;
        krem -= klump;
-       klump *= KLINGON_PLACE;
-       do iran(GALSIZE, &ix, &iy);
-       while (game.state.galaxy[ix][iy] + klump >= SUPERNOVA_PLACE);
-       game.state.galaxy[ix][iy] += klump;
+       do iran(GALSIZE,&ix,&iy); while (game.state.galaxy[ix][iy].supernova);
+       game.state.galaxy[ix][iy].klingons += klump;
     } while (krem > 0);
     // Position Klingon Commander Ships
 #ifdef DEBUG
@@ -309,21 +311,21 @@ void setup(int needprompt)
 #endif
                    iran(GALSIZE, &ix, &iy);
            }
-           while ((game.state.galaxy[ix][iy] <= KLINGON_PLACE && Rand() < 0.75)||
-                  NOEXIT(game.state.galaxy[ix][iy]));
+           while ((!game.state.galaxy[ix][iy].klingons && Rand() < 0.75)||
+                  game.state.galaxy[ix][iy].supernova||
+                  game.state.galaxy[ix][iy].klingons > 8);
            // check for duplicate
            for (j = 1; j < i; j++)
                if (game.state.cx[j]==ix && game.state.cy[j]==iy) break;
        } while (j < i);
-       game.state.galaxy[ix][iy] += KLINGON_PLACE;
+       game.state.galaxy[ix][iy].klingons++;
        game.state.cx[i] = ix;
        game.state.cy[i] = iy;
     }
     // Locate planets in galaxy
     for (i = 0; i < inplan; i++) {
-       do iran(GALSIZE, &ix, &iy);
-       while (game.state.newstuf[ix][iy] > 0);
-       game.state.newstuf[ix][iy] = 1;
+       do iran(GALSIZE, &ix, &iy); while (game.state.galaxy[ix][iy].planets);
+       game.state.galaxy[ix][iy].planets = 1;
        game.state.plnets[i].x = ix;
        game.state.plnets[i].y = iy;
        game.state.plnets[i].pclass = Rand()*3.0; // Planet class M N or O
@@ -333,15 +335,15 @@ void setup(int needprompt)
     // Locate Romulans
     for (i = 1; i <= game.state.nromrem; i++) {
        iran(GALSIZE, &ix, &iy);
-       game.state.newstuf[ix][iy] += ROMULAN_PLACE;
+       game.state.galaxy[ix][iy].romulans = 1;
     }
     // Locate the Super Commander
     if (game.state.nscrem > 0) {
        do iran(GALSIZE, &ix, &iy);
-       while (game.state.galaxy[ix][iy] >= 900);
+       while (game.state.galaxy[ix][iy].supernova || game.state.galaxy[ix][iy].klingons > 8);
        game.state.isx = ix;
        game.state.isy = iy;
-       game.state.galaxy[ix][iy] += KLINGON_PLACE;
+       game.state.galaxy[ix][iy].klingons++;
     }
     // Place thing (in tournament game, thingx == -1, don't want one!)
     if (thingx != -1) {
@@ -500,7 +502,7 @@ void newcnd(void)
 {
     condit = IHGREEN;
     if (energy < 1000.0) condit = IHYELLOW;
-    if (game.state.galaxy[quadx][quady] >= KLINGON_PLACE || game.state.newstuf[quadx][quady] >= ROMULAN_PLACE)
+    if (game.state.galaxy[quadx][quady].klingons || game.state.galaxy[quadx][quady].romulans)
        condit = IHRED;
     if (!alive) condit=IHDEAD;
 }
@@ -508,8 +510,6 @@ void newcnd(void)
 
 void newqad(int shutup) 
 {
-    int quadnum = game.state.galaxy[quadx][quady];
-    int newnum = game.state.newstuf[quadx][quady];
     int i, j, ix, iy, nplan;
 
     iattak = 1;
@@ -537,22 +537,21 @@ void newqad(int shutup)
     }
     // Clear quadrant
     for (i=1; i <= QUADSIZE; i++)
-       for (j=1; j <= QUADSIZE; j++) game.quad[i][j] = IHDOT;
+       for (j=1; j <= QUADSIZE; j++) 
+           game.quad[i][j] = IHDOT;
     // cope with supernova
-    if (quadnum >= SUPERNOVA_PLACE) {
+    if (game.state.galaxy[quadx][quady].supernova)
        return;
-    }
-    klhere = KLINGONS(quadnum);
-    irhere = ROMULANS(newnum);
-    nplan = newnum%10;
+    klhere = game.state.galaxy[quadx][quady].klingons;
+    irhere = game.state.galaxy[quadx][quady].romulans;
+    nplan  = game.state.galaxy[quadx][quady].planets;
     nenhere = klhere + irhere;
 
     // Position Starship
     game.quad[sectx][secty] = ship;
 
-    if (quadnum >= KLINGON_PLACE) {
+    if (game.state.galaxy[quadx][quady].klingons) {
        // Position ordinary Klingons
-       quadnum -= KLINGON_PLACE*klhere;
        for (i = 1; i <= klhere; i++) {
            dropin(IHK, &ix, &iy);
            game.kx[i] = ix;
@@ -587,10 +586,8 @@ void newqad(int shutup)
        game.kpower[i] = Rand()*400.0 + 450.0 + 50.0*skill;
     }
     // If quadrant needs a starbase, put it in
-    if (quadnum >= BASE_PLACE) {
-       quadnum -= BASE_PLACE;
+    if (game.state.galaxy[quadx][quady].starbase)
        dropin(IHB, &basex, &basey);
-    }
        
     if (nplan) {
        // If quadrant needs a planet, put it in
@@ -604,7 +601,8 @@ void newqad(int shutup)
     // Check for condition
     newcnd();
     // And finally the stars
-    for (i = 1; i <= quadnum; i++) dropin(IHSTAR, &ix, &iy);
+    for (i = 1; i <= game.state.galaxy[quadx][quady].stars; i++) 
+       dropin(IHSTAR, &ix, &iy);
 
     // Check for RNZ
     if (irhere > 0 && klhere == 0) {
@@ -672,7 +670,8 @@ void newqad(int shutup)
 
     // Put in a few black holes
     for (i = 1; i <= 3; i++)
-       if (Rand() > 0.5) dropin(IHBLANK, &ix, &iy);
+       if (Rand() > 0.5) 
+           dropin(IHBLANK, &ix, &iy);
 
     // Take out X's in corners if Tholian present
     if (ithere) {
index 06c38a2da1c2ce4ad1e3c5f51717beb1b663500f..3a56ba63c84bfbbada067522476d8a07ca98cd2a 100644 (file)
@@ -1771,6 +1771,9 @@ The HELP/CALL/SOS command is now MAYDAY.  SOS and CALL are still accepted.
 <listitem><para>
 Status report now indicates if dilithium crystals are on board.
 </para></listitem>
+<listitem><para>
+At Dave's prompting, restored the Space Thingy's original elusive behavior.
+</para></listitem>
 </itemizedlist>
 
 <para>Here are some good pages on the history of Star Trek games:</para>
diff --git a/sst.c b/sst.c
index 65c79ac6c35e48618e8ae03acf5af0b9779bcf58..2dca29e412550cde4c44e2c0804f12f7a0b8110d 100644 (file)
--- a/sst.c
+++ b/sst.c
@@ -114,9 +114,7 @@ Eric Raymond's changes:
 
    2. Status report now indicates when dilithium crystals are on board.
 
-   3. Can now report starbases left in scrscan.
-
-   4. Per Dave Matuszek's remarks, Thingy state is not saved across games.
+   3. Per Dave Matuszek's remarks, Thingy state is not saved across games.
    */
 
 /* the input queue */
@@ -485,14 +483,14 @@ static void makemoves(void)
                events();
                if (alldone) break;             // Events did us in
            }
-           if (game.state.galaxy[quadx][quady] == SUPERNOVA_PLACE) { // Galaxy went Nova!
+           if (game.state.galaxy[quadx][quady].supernova) { // Galaxy went Nova!
                atover(0);
                continue;
            }
            if (hitme && justin==0) {
                attack(2);
                if (alldone) break;
-               if (game.state.galaxy[quadx][quady] == SUPERNOVA_PLACE) {       // went NOVA! 
+               if (game.state.galaxy[quadx][quady].supernova) {        // went NOVA! 
                    atover(0);
                    hitme = TRUE;
                    continue;
diff --git a/sst.h b/sst.h
index 5b6fb04de36b60801697bf9a2e27031ba8d72708..9a67c1d063ac1dd44cafcb6a6d15c34ff7edc51c 100644 (file)
--- a/sst.h
+++ b/sst.h
@@ -40,11 +40,9 @@ typedef struct {
        basekl,                 // destroyed bases
        killk,                  // Klingons killed
        killc,                  // commanders killed
-       galaxy[GALSIZE+1][GALSIZE+1],   // The Galaxy (subscript 0 not used)
        cx[QUADSIZE+1],cy[QUADSIZE+1],  // Commander quadrant coordinates
        baseqx[BASEMAX],                // Base quadrant X
        baseqy[BASEMAX],                // Base quadrant Y
-       newstuf[GALSIZE+1][GALSIZE+1],  // Extended galaxy goodies
        isx, isy,               // Coordinate of Super Commander
        nscrem,                 // remaining super commanders
        nromkl,                 // Romulans killed
@@ -55,28 +53,22 @@ typedef struct {
        double date,            // stardate
            remres,             // remaining resources
            remtime;            // remaining time
+    struct {
+       int stars;
+       int planets;
+       int starbase;
+       int klingons;
+       int romulans;
+       int supernova;
+       int charted;
+    } galaxy[GALSIZE+1][GALSIZE+1];    // The Galaxy (subscript 0 not used)
+    struct {
+       int stars;
+       int starbase;
+       int klingons;
+    } chart[GALSIZE+1][GALSIZE+1];     // the starchart (subscript 0 not used)
 } snapshot;                            // Data that is snapshot
 
-/*
- * This is how the integers in the galaxy array are encoded.
- * Someday these should turn into structure fields.
- */
-#define SUPERNOVA_PLACE        1000
-#define KLINGON_PLACE  100
-#define BASE_PLACE     10
-#define STAR_PLACE     1
-#define KLINGONS(n)    ((n)/KLINGON_PLACE)
-#define BASES(n)       (((n)%KLINGON_PLACE)/BASE_PLACE)
-#define STARS(n)       ((n)%BASE_PLACE)
-#define NOEXIT(s)      ((s) > 899)     /* supernova or >8 Klingons */
-
-/* for newstuff */
-#define ROMULAN_PLACE  10
-#define ROMULANS(n)    ((n)/ROMULAN_PLACE)
-
-/* for starch */
-#define CHART_UNKNOWN  -1
-
 #define SKILL_NONE     0
 #define SKILL_NOVICE   1
 #define SKILL_FAIR     2
@@ -135,7 +127,6 @@ EXTERN struct {
     char passwd[10];           // Self Destruct password
     int kx[(QUADSIZE+1)*(QUADSIZE+1)];                 // enemy sector locations
     int ky[(QUADSIZE+1)*(QUADSIZE+1)];
-    int starch[GALSIZE+1][GALSIZE+1];          // star chart
     /* members with macro definitions start here */
     int inkling,
        inbase,
@@ -403,6 +394,7 @@ void doshield(int);
 void dock(int);
 void dreprt(void);
 void chart(int);
+void rechart(void);
 void impuls(void);
 void wait(void);
 void setwrp(void);