Avoid a nasty bug in planet-name display, and fix another boolean.
[super-star-trek.git] / src / sst.c
index 36f444959238493d6414a44f1ab3b6c9e13671b3..95ab355dadb846d11bf906a4757b8644d28c91cd 100644 (file)
--- a/src/sst.c
+++ b/src/sst.c
@@ -162,6 +162,12 @@ for a lot of magic numbers and refactored the heck out of it.
       type is "plain" or "almy".)
 
    6. User input is now logged so we can do regression testing.
       type is "plain" or "almy".)
 
    6. User input is now logged so we can do regression testing.
+
+   7. More BSD-Trek features: You can now lose if your entire crew
+      dies in battle.  When abandoning ship in a game with inhabited
+      worlds enabled, they must have one in the quadrant to beam down
+      to; otherwise they die in space and this counts heavily against
+      your score.  Docking at a starbase replenishes your crew.
 */
 
 /* the input queue */
 */
 
 /* the input queue */
@@ -176,8 +182,7 @@ double perdate;
 char citem[10];
 int seed;              // the random-number seed
 bool idebug;           // debug mode
 char citem[10];
 int seed;              // the random-number seed
 bool idebug;           // debug mode
-bool randready;                // Has the random-number generator initialized?
-FILE *logfp;
+FILE *logfp, *replayfp;
 
 char *device[NDEVICES] = {
        "S. R. Sensors",
 
 char *device[NDEVICES] = {
        "S. R. Sensors",
@@ -595,8 +600,20 @@ int main(int argc, char **argv)
     else
        game.options |= OPTION_TTY;
 
     else
        game.options |= OPTION_TTY;
 
-    while ((option = getopt(argc, argv, "tx")) != -1) {
+    seed = (int)time(NULL);
+    while ((option = getopt(argc, argv, "r:tx")) != -1) {
        switch (option) {
        switch (option) {
+       case 'r':
+           replayfp = fopen(optarg, "r");
+           if (replayfp == NULL) {
+               fprintf(stderr, "sst: can't open replay file %s\n", optarg);
+               exit(1);        
+           }
+           if (fscanf(replayfp, "seed %d\n", &seed) != 1) {
+               fprintf(stderr, "sst: replay file %s is ill-formed\n", optarg);
+               exit(1);        
+           }
+           /* FALL THROUGH */
        case 't':
            game.options |= OPTION_TTY;
            game.options &=~ OPTION_CURSES;
        case 't':
            game.options |= OPTION_TTY;
            game.options &=~ OPTION_CURSES;
@@ -612,8 +629,10 @@ int main(int argc, char **argv)
     /* where to save the input in case of bugs */
     logfp = fopen("sst-input.log", "w");
     setlinebuf(logfp);
     /* where to save the input in case of bugs */
     logfp = fopen("sst-input.log", "w");
     setlinebuf(logfp);
+    fprintf(logfp, "seed %d\n", seed);
+    srand(seed);
 
 
-    randomize();
+    srand(seed);
     iostart();
 
     line[0] = '\0';
     iostart();
 
     line[0] = '\0';
@@ -715,14 +734,6 @@ double expran(double avrage)
 
 double Rand(void) 
 {
 
 double Rand(void) 
 {
-    if (!randready) {
-       if (seed == 0)
-           seed = (unsigned)time(NULL);
-       if (logfp)
-           fprintf(logfp, "seed %d\n", seed);
-       srand(seed);
-       randready = true;
-    }
     return rand()/(1.0 + (double)RAND_MAX);
 }
 
     return rand()/(1.0 + (double)RAND_MAX);
 }
 
@@ -871,7 +882,6 @@ void debugme(void)
        int i;
        for (i = 1; i < NEVENTS; i++) {
            int key;
        int i;
        for (i = 1; i < NEVENTS; i++) {
            int key;
-           if (!is_scheduled(i)) continue;
            switch (i) {
            case FSNOVA:  proutn("Supernova       "); break;
            case FTBEAM:  proutn("T Beam          "); break;
            switch (i) {
            case FSNOVA:  proutn("Supernova       "); break;
            case FTBEAM:  proutn("T Beam          "); break;
@@ -880,42 +890,55 @@ void debugme(void)
            case FCDBAS:  proutn("Base Destroy    "); break;
            case FSCMOVE: proutn("SC Move         "); break;
            case FSCDBAS: proutn("SC Base Destroy "); break;
            case FCDBAS:  proutn("Base Destroy    "); break;
            case FSCMOVE: proutn("SC Move         "); break;
            case FSCDBAS: proutn("SC Base Destroy "); break;
-           //case FDSPROB:proutn("Probe Move      "); break;
+           case FDSPROB: proutn("Probe Move      "); break;
            case FDISTR:  proutn("Distress Call   "); break;
            case FENSLV:  proutn("Enlavement      "); break;
            case FREPRO:  proutn("Klingon Build   "); break;
            }
            case FDISTR:  proutn("Distress Call   "); break;
            case FENSLV:  proutn("Enlavement      "); break;
            case FREPRO:  proutn("Klingon Build   "); break;
            }
-           proutn("%.2f", scheduled(i)-game.state.date);
+           if (is_scheduled(i)) {
+               proutn("%.2f", scheduled(i)-game.state.date);
+               if (i == FENSLV || i == FREPRO) {
+                   ev = findevent(i);
+                   proutn(" in %d-%d", ev->quadrant.x,ev->quadrant.y);
+               }
+           } else
+               proutn("never");
+           proutn("? ");
            chew();
            chew();
-           proutn("  ?");
            key = scan();
            key = scan();
-           if (key == IHREAL) {
+           if (key == 'n') {
+               unschedule(i);
+               chew();
+           } else if (key == IHREAL) {
                ev = schedule(i, aaitem);
                if (i == FENSLV || i == FREPRO) {
                    chew();
                    proutn("In quadrant- ");
                    key = scan();
                ev = schedule(i, aaitem);
                if (i == FENSLV || i == FREPRO) {
                    chew();
                    proutn("In quadrant- ");
                    key = scan();
-                   if (key != IHREAL) {
-                       prout("Event %d canceled, no y coordinate.", i);
-                       unschedule(i);
-                       continue;
+                   /* IHEOL says to leave coordinates as they are */
+                   if (key != IHEOL) {
+                       if (key != IHREAL) {
+                           prout("Event %d canceled, no x coordinate.", i);
+                           unschedule(i);
+                           continue;
+                       }
+                       w.x = (int)aaitem;
+                       key = scan();
+                       if (key != IHREAL) {
+                           prout("Event %d canceled, no y coordinate.", i);
+                           unschedule(i);
+                           continue;
+                       }
+                       w.y = (int)aaitem;
+                       ev->quadrant = w;
                    }
                    }
-                   w.y = (int)aaitem;
-                   key = scan();
-                   if (key != IHREAL) {
-                       prout("Event %d canceled, no x coordinate.", i);
-                       unschedule(i);
-                       continue;
-                   }
-                   w.x = (int)aaitem;
-                   ev->quadrant = w;
                }
            }
        }
        chew();
     }
     proutn("Induce supernova here? ");
                }
            }
        }
        chew();
     }
     proutn("Induce supernova here? ");
-    if (ja() != 0) {
+    if (ja()) {
        game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova = true;
        atover(1);
     }
        game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova = true;
        atover(1);
     }