Clean up nasty FORTRAN-style if statements.
[super-star-trek.git] / src / sst.c
index 850a940096efc21980d0cf5a4ba4e3e988f9543d..a0d732d31fe5674c79b6e52063016ae028822b1e 100644 (file)
--- a/src/sst.c
+++ b/src/sst.c
@@ -168,6 +168,11 @@ for a lot of magic numbers and refactored the heck out of it.
       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.
+
+   8. Still more BSD-Trek: we now have a weighted damage table.
+      Also, the nav subsystem (enabling automatic course
+      setting) can be damaged separately from the main computer (which
+      handles weapons targeting, ETA calculation, and self-destruct).
 */
 
 /* the input queue */
@@ -175,7 +180,7 @@ static char line[128], *linep = line;
 
 struct game game;
 coord thing;
-int iqhere, iqengry;
+bool iqhere, iqengry;
 int iscore, iskill;    // Common PLAQ
 double aaitem;
 double perdate;
@@ -184,22 +189,8 @@ int seed;          // the random-number seed
 bool idebug;           // debug mode
 FILE *logfp, *replayfp;
 
-char *device[NDEVICES] = {
-       "S. R. Sensors",
-       "L. R. Sensors",
-       "Phasers",
-       "Photon Tubes",
-       "Life Support",
-       "Warp Engines",
-       "Impulse Engines",
-       "Shields",
-       "Subspace Radio",
-       "Shuttle Craft",
-       "Computer",
-       "Transporter",
-       "Shield Control",
-       "Death Ray",
-       "D. S. Probe"};                                                                 
+char *systnames[NINHAB + 1];
+char *device[NDEVICES];
 
 static struct 
 {
@@ -285,14 +276,20 @@ commands[] = {
        {"HELP",        HELP,           0},
 #define SEED   37
        {"SEED",        SEED,           0},
+#if BSD_BUG_FOR_BUG
+#define VISUAL 38
+       {"VISUAL",      VISUAL,         0},
+#endif
 };
 
-#define NUMCOMMANDS    sizeof(commands)/sizeof(commands[0])
+#define NUMCOMMANDS    ARRAY_SIZE(commands)
 #define ACCEPT(i)      (!commands[i].option || (commands[i].option & game.options))
 
-static void listCommands(void) {
+static void listCommands(void) 
+/* generate a list of legal commands */
+{
     int i, k = 0;
-    proutn("LEGAL COMMANDS ARE:");
+    proutn(_("LEGAL COMMANDS ARE:"));
     for (i = 0; i < NUMCOMMANDS; i++) {
        if (!ACCEPT(i))
            continue;
@@ -304,7 +301,8 @@ static void listCommands(void) {
     skip(1);
 }
 
-static void helpme(void) 
+static void helpme(void)
+/* browse on-line help */
 {
     int i, j;
     char cmdbuf[32], *cp;
@@ -316,20 +314,21 @@ static void helpme(void)
     for(;;) {
        if (key == IHEOL) {
            setwnd(prompt_window);
-           proutn("Help on what command? ");
+           proutn(_("Help on what command? "));
            key = scan();
        }
        setwnd(message_window);
-       if (key == IHEOL) return;
+       if (key == IHEOL)
+           return;
        for (i = 0; i < NUMCOMMANDS; i++) {
            if (ACCEPT(i) && strcasecmp(commands[i].name, citem)==0) {
                i = commands[i].value;
                break;
            }
        }
-       if (i != NUMCOMMANDS) break;
+       if (i != NUMCOMMANDS)
+           break;
        skip(1);
-       prout("Valid commands:");
        listCommands();
        key = IHEOL;
        chew();
@@ -347,9 +346,13 @@ static void helpme(void)
     if (fp == NULL)
         fp = fopen(DOC_NAME, "r");
     if (fp == NULL) {
-       prout("Spock-  \"Captain, that information is missing from the");
-        prout("   computer. You need to find "DOC_NAME" and put it in the");
-        prout("   current directory or to "SSTDOC".\"");
+       prout(_("Spock-  \"Captain, that information is missing from the"));
+        proutn(_("   computer. You need to find "));
+        proutn(DOC_NAME);
+        prout(_(" and put it in the"));
+        proutn(_("   current directory or to "));
+        proutn(SSTDOC);
+        prout(".\"");
        /*
         * This used to continue: "You need to find SST.DOC and put 
         * it in the current directory."
@@ -358,7 +361,7 @@ static void helpme(void)
     }
     for (;;) {
        if (fgets(linebuf, sizeof(linebuf), fp) == NULL) {
-           prout("Spock- \"Captain, there is no information on that command.\"");
+           prout(_("Spock- \"Captain, there is no information on that command.\""));
            fclose(fp);
            return;
        }
@@ -372,23 +375,22 @@ static void helpme(void)
     }
 
     skip(1);
-    prout("Spock- \"Captain, I've found the following information:\"");
+    prout(_("Spock- \"Captain, I've found the following information:\""));
     skip(1);
 
-    while (fgets(linebuf, sizeof(linebuf),fp)) {
+    while (fgets(linebuf, sizeof(linebuf), fp)) {
+       char *eol;
        if (strstr(linebuf, "******"))
            break;
-       proutn(linebuf);
+       if ((eol = strpbrk(linebuf, "\r\n")))
+           *eol = 0;
+       prout(linebuf);
     }
     fclose(fp);
 }
 
-void enqueue(char *s) 
-{
-    strcpy(line, s);
-}
-
-static void makemoves(void) 
+static void makemoves(void)
+/* command-interpretation loop */
 {
     int key, i, v = 0;
     bool hitme;
@@ -398,7 +400,7 @@ static void makemoves(void)
        drawmaps(1);
        for(;;)  { /* get a command */
            hitme = false;
-           game.justin = 0;
+           game.justin = false;
            game.optime = 0.0;
            i = -1;
            chew();
@@ -406,10 +408,11 @@ static void makemoves(void)
            clrscr();
            proutn("COMMAND> ");
            if (scan() == IHEOL) {
-               makechart();
+               if (game.options & OPTION_CURSES)
+                   makechart();
                continue;
            }
-           game.ididit=0;
+           game.ididit = false;
            clrscr();
            setwnd(message_window);
            clrscr();
@@ -432,51 +435,55 @@ static void makemoves(void)
        commandhook(commands[i].name, true);
        switch (v) { /* command switch */
        case SRSCAN:                 // srscan
-           srscan(SCAN_FULL);
+           srscan();
            break;
        case STATUS:                 // status
-           srscan(SCAN_STATUS);
+           status(0);
            break;
        case REQUEST:                   // status request 
-           srscan(SCAN_REQUEST);
+           request();
            break;
        case LRSCAN:                    // lrscan
            lrscan();
            break;
        case PHASERS:                   // phasers
            phasers();
-           if (game.ididit) hitme = true;
+           if (game.ididit)
+               hitme = true;
            break;
        case TORPEDO:                   // photons
            photon();
-           if (game.ididit) hitme = true;
+           if (game.ididit)
+               hitme = true;
            break;
        case MOVE:                      // move
            warp(false);
            break;
        case SHIELDS:                   // shields
-           doshield(1);
+           doshield(false);
            if (game.ididit) {
-               hitme=true;
-               game.shldchg = 0;
+               hitme = true;
+               game.shldchg = false;
            }
            break;
        case DOCK:                      // dock
-           dock(1);
-           if (game.ididit) attack(0);
+           dock(true);
+           if (game.ididit)
+               attack(false);          
            break;
        case DAMAGES:                   // damages
            dreprt();
            break;
        case CHART:                     // chart
-           chart(false);
+           makechart();
            break;
        case IMPULSE:                   // impulse
            impuls();
            break;
        case REST:                      // rest
            wait();
-           if (game.ididit) hitme = true;
+           if (game.ididit)
+               hitme = true;
            break;
        case WARP:                      // warp
            setwrp();
@@ -489,22 +496,26 @@ static void makemoves(void)
            break;
        case ORBIT:                     // orbit
            orbit();
-           if (game.ididit) hitme = true;
+           if (game.ididit)
+               hitme = true;
            break;
        case TRANSPORT:                 // transport "beam"
            beam();
            break;
        case MINE:                      // mine
            mine();
-           if (game.ididit) hitme = true;
+           if (game.ididit)
+               hitme = true;
            break;
        case CRYSTALS:                  // crystals
            usecrystals();
-           if (game.ididit) hitme = true;
+           if (game.ididit)
+               hitme = true;
            break;
        case SHUTTLE:                   // shuttle
            shuttle();
-           if (game.ididit) hitme = true;
+           if (game.ididit)
+               hitme = true;
            break;
        case PLANETS:                   // Planet list
            preport();
@@ -525,7 +536,8 @@ static void makemoves(void)
            break;
        case PROBE:
            probe();                    // Launch probe
-           if (game.ididit) hitme = true;
+           if (game.ididit)
+               hitme = true;
            break;
        case ABANDON:                   // Abandon Ship
            abandn();
@@ -537,21 +549,23 @@ static void makemoves(void)
            freeze(false);
            clrscr();
            if (game.skill > SKILL_GOOD)
-               prout("WARNING--Saved games produce no plaques!");
+               prout(_("WARNING--Saved games produce no plaques!"));
            break;
        case DEATHRAY:                  // Try a desparation measure
            deathray();
-           if (game.ididit) hitme = true;
+           if (game.ididit)
+               hitme = true;
            break;
        case DEBUGCMD:                  // What do we want for debug???
            debugme();
            break;
        case MAYDAY:                    // Call for help
            mayday();
-           if (game.ididit) hitme = true;
+           if (game.ididit)
+               hitme = true;
            break;
        case QUIT:
-           game.alldone = 1;           // quit the game
+           game.alldone = true;                // quit the game
            break;
        case HELP:
            helpme();                   // get help
@@ -561,6 +575,11 @@ static void makemoves(void)
            if (key == IHREAL)
                seed = (int)aaitem;
            break;
+#if BSD_BUG_FOR_BUG
+       case VISUAL:
+           visual();                   // perform visual scan
+           break;
+#endif
        }
        commandhook(commands[i].name, false);
        for (;;) {
@@ -574,8 +593,9 @@ static void makemoves(void)
                continue;
            }
            if (hitme && !game.justin) {
-               attack(2);
-               if (game.alldone) break;
+               attack(true);
+               if (game.alldone)
+                   break;
                if (game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova) {    // went NOVA! 
                    atover(false);
                    hitme = true;
@@ -584,9 +604,11 @@ static void makemoves(void)
            }
            break;
        }
-       if (game.alldone) break;
+       if (game.alldone)
+           break;
     }
-    if (idebug) prout("=== Ending");
+    if (idebug)
+       prout("=== Ending");
 }
 
 
@@ -607,11 +629,11 @@ int main(int argc, char **argv)
            replayfp = fopen(optarg, "r");
            if (replayfp == NULL) {
                fprintf(stderr, "sst: can't open replay file %s\n", optarg);
-               exit(1);        
+               exit(1);
            }
            if (fscanf(replayfp, "seed %d\n", &seed) != 1) {
                fprintf(stderr, "sst: replay file %s is ill-formed\n", optarg);
-               exit(1);        
+               exit(1);
            }
            /* FALL THROUGH */
        case 't':
@@ -627,12 +649,13 @@ int main(int argc, char **argv)
        }
     }
     /* where to save the input in case of bugs */
-    logfp = fopen("sst-input.log", "w");
-    setlinebuf(logfp);
-    fprintf(logfp, "seed %d\n", seed);
+    logfp = fopen("/usr/tmp/sst-input.log", "w");
+    if (logfp) {
+       setlinebuf(logfp);
+       fprintf(logfp, "seed %d\n", seed);
+    }
     srand(seed);
 
-    srand(seed);
     iostart();
 
     line[0] = '\0';
@@ -647,81 +670,92 @@ int main(int argc, char **argv)
        setup(line[0] == '\0');
        if (game.alldone) {
            score();
-           game.alldone = 0;
+           game.alldone = false;
        }
-       else makemoves();
+       else
+           makemoves();
        skip(1);
        stars();
        skip(1);
 
        if (game.tourn && game.alldone) {
-           proutn("Do you want your score recorded?");
+           proutn(_("Do you want your score recorded?"));
            if (ja() == true) {
                chew2();
                freeze(false);
            }
        }
-       proutn("Do you want to play again? ");
-       if (!ja()) break;
+       proutn(_("Do you want to play again? "));
+       if (!ja())
+           break;
     }
     skip(1);
-    prout("May the Great Bird of the Galaxy roost upon your home planet.");
+    prout(_("May the Great Bird of the Galaxy roost upon your home planet."));
     return 0;
 }
 
 
-void cramen(int i) 
+void cramen(feature i) 
+/* print the name of an enemy */
 {
     /* return an enemy */
     char *s;
        
     switch (i) {
-    case IHR: s = "Romulan"; break;
-    case IHK: s = "Klingon"; break;
-    case IHC: s = "Commander"; break;
-    case IHS: s = "Super-commander"; break;
-    case IHSTAR: s = "Star"; break;
-    case IHP: s = "Planet"; break;
-    case IHB: s = "Starbase"; break;
-    case IHBLANK: s = "Black hole"; break;
-    case IHT: s = "Tholian"; break;
-    case IHWEB: s = "Tholian web"; break;
-    case IHQUEST: s = "Stranger"; break;
+    case IHR: s = _("Romulan"); break;
+    case IHK: s = _("Klingon"); break;
+    case IHC: s = _("Commander"); break;
+    case IHS: s = _("Super-commander"); break;
+    case IHSTAR: s = _("Star"); break;
+    case IHP: s = _("Planet"); break;
+    case IHB: s = _("Starbase"); break;
+    case IHBLANK: s = _("Black hole"); break;
+    case IHT: s = _("Tholian"); break;
+    case IHWEB: s = _("Tholian web"); break;
+    case IHQUEST: s = _("Stranger"); break;
+    case IHW: s = _("Inhabited World"); break;
     default: s = "Unknown??"; break;
     }
     proutn(s);
 }
 
 char *cramlc(enum loctype key, coord w)
+/* name a location */
 {
     static char buf[32];
     buf[0] = '\0';
-    if (key == quadrant) strcpy(buf, "Quadrant ");
-    else if (key == sector) strcpy(buf, "Sector ");
+    if (key == quadrant)
+       strcpy(buf, _("Quadrant "));
+    else if (key == sector)
+       strcpy(buf, _("Sector "));
     sprintf(buf+strlen(buf), "%d - %d", w.x, w.y);
     return buf;
 }
 
-void crmena(bool stars, int enemy, enum loctype key, coord w) 
+void crmena(bool stars, feature enemy, enum loctype key, coord w) 
+/* print an enemy and his location */
 {
-    if (stars) proutn("***");
+    if (stars)
+       proutn("***");
     cramen(enemy);
-    proutn(" at ");
+    proutn(_(" at "));
     proutn(cramlc(key, w));
 }
 
-void crmshp(void) 
+void crmshp(void)
+/* print our ship name */
 {
     char *s;
     switch (game.ship) {
-    case IHE: s = "Enterprise"; break;
-    case IHF: s = "Faerie Queene"; break;
+    case IHE: s = _("Enterprise"); break;
+    case IHF: s = _("Faerie Queene"); break;
     default:  s = "Ship???"; break;
     }
     proutn(s);
 }
 
-void stars(void) 
+void stars(void)
+/* print a line of stars */
 {
     prouts("******************************************************");
     skip(1);
@@ -737,10 +771,13 @@ double Rand(void)
     return rand()/(1.0 + (double)RAND_MAX);
 }
 
-void iran(int size, int *i, int *j) 
+coord randplace(int size)
+/* choose a random location */ 
 {
-    *i = Rand()*(size*1.0) + 1.0;
-    *j = Rand()*(size*1.0) + 1.0;
+    coord w;
+    w.x = Rand()*(size*1.0) + 1.0;
+    w.y = Rand()*(size*1.0) + 1.0;
+    return w;
 }
 
 void chew(void)
@@ -804,46 +841,50 @@ int scan(void)
     // Treat as alpha
     cp = citem;
     while (*linep && *linep!=' ') {
-       if ((cp - citem) < 9) *cp++ = tolower(*linep);
+       if ((cp - citem) < 9)
+           *cp++ = tolower(*linep);
        linep++;
     }
     *cp = 0;
     return IHALPHA;
 }
 
-bool ja(void) 
+bool ja(void)
+/* yes-or-no confirmation */
 {
     chew();
     for(;;) {
        scan();
        chew();
-       if (*citem == 'y') return true;
-       if (*citem == 'n') return false;
-       proutn("Please answer with \"Y\" or \"N\": ");
+       if (*citem == 'y')
+           return true;
+       if (*citem == 'n')
+           return false;
+       proutn(_("Please answer with \"y\" or \"n\": "));
     }
 }
 
-void huh(void) 
+void huh(void)
+/* complain about unparseable input */
 {
     chew();
     skip(1);
-    prout("Beg your pardon, Captain?");
+    prout(_("Beg your pardon, Captain?"));
 }
 
-int isit(char *s) 
+bool isit(char *s) 
+/* compares s to citem and returns true if it matches to the length of s */
 {
-    /* New function -- compares s to scanned citem and returns true if it
-       matches to the length of s */
-
     return strncasecmp(s, citem, max(1, strlen(citem))) == 0;
-
 }
 
-void debugme(void) 
+void debugme(void)
+/* access to the internals for debugging */
 {
     proutn("Reset levels? ");
     if (ja() == true) {
-       if (game.energy < game.inenrg) game.energy = game.inenrg;
+       if (game.energy < game.inenrg)
+           game.energy = game.inenrg;
        game.shield = game.inshld;
        game.torps = game.intorps;
        game.lsupres = game.inlsr;
@@ -858,8 +899,10 @@ void debugme(void)
     proutn("Toggle debug flag? ");
     if (ja() == true) {
        idebug = !idebug;
-       if (idebug) prout("Debug output ON");
-       else prout("Debug output OFF");
+       if (idebug)
+           prout("Debug output ON");       
+       else
+           prout("Debug output OFF");
     }
     proutn("Cause selective damage? ");
     if (ja() == true) {