Move a few prototypes and static'ed a few functions
[open-adventure.git] / main.c
diff --git a/main.c b/main.c
index 66c5cafa74010d1d53f6ca5441031f4705d67242..3d23c968f7b8fe531c5c7decbc9d1a1699b57284 100644 (file)
--- a/main.c
+++ b/main.c
@@ -43,20 +43,17 @@ long AMBER, AXE, BACK, BATTER, BEAR, BIRD, BLOOD,
                URN, VASE, VEND, VOLCAN, WATER;
 long WD1, WD1X, WD2, WD2X;
 
-FILE  *logfp;
+FILE  *logfp = NULL, *rfp = NULL;
 bool oldstyle = false;
 bool editline = true;
 bool prompt = true;
 
-extern void initialise();
-extern void score(long);
-extern int action(FILE *, long, long, long);
-
-void sig_handler(int signo)
+static void sig_handler(int signo)
 {
-    if (signo == SIGINT)
+    if (signo == SIGINT){
        if (logfp != NULL)
            fflush(logfp);
+       }
     exit(0);
 }
 
@@ -80,7 +77,7 @@ int main(int argc, char *argv[])
        
 /*  Options. */
 
-    while ((ch = getopt(argc, argv, "l:os")) != EOF) {
+    while ((ch = getopt(argc, argv, "l:or:s")) != EOF) {
        switch (ch) {
        case 'l':
            logfp = fopen(optarg, "w");
@@ -94,6 +91,14 @@ int main(int argc, char *argv[])
            oldstyle = true;
            editline = prompt = false;
            break;
+       case 'r':
+           rfp = fopen(optarg, "r");
+           if (rfp == NULL)
+               fprintf(stderr,
+                       "advent: can't open save file %s for read\n",
+                       optarg);
+           signal(SIGINT, sig_handler);
+           break;
        case 's':
            editline = false;
            break;
@@ -126,11 +131,15 @@ int main(int argc, char *argv[])
 
     /*  Start-up, dwarf stuff */
     game.zzword=RNDVOC(3,0);
-    game.novice=YES(stdin, WELCOME_YOU,CAVE_NEARBY,ARB_0);
     game.newloc = LOC_START;
     game.loc = LOC_START;
     game.limit=330;
-    if (game.novice)game.limit=1000;
+    if (!rfp){
+        game.novice=YES(stdin, WELCOME_YOU,CAVE_NEARBY,NO_MESSAGE);
+        if (game.novice)game.limit=1000;
+    } else {
+        restore(rfp);
+    }
 
     if (logfp)
        fprintf(logfp, "seed %ld\n", seedval);
@@ -141,7 +150,7 @@ int main(int argc, char *argv[])
            break;
     }
     /* show score and exit */
-    score(1);
+    score(quitgame);
 }
 
 static bool fallback_handler(char *buf)
@@ -244,48 +253,48 @@ static void checkhints(FILE *cmdin)
     
                /* Fall through to hint display */
                game.hintlc[hint]=0;
-               if (!YES(cmdin,HINTS[hint][3],ARB_0,OK_MAN))
+               if (!YES(cmdin,HINTS[hint][3],NO_MESSAGE,OK_MAN))
                    return;
                SETPRM(1,HINTS[hint][2],HINTS[hint][2]);
                RSPEAK(HINT_COST);
                game.hinted[hint]=YES(cmdin,WANT_HINT,HINTS[hint][4],OK_MAN);
-               if (game.hinted[hint] && game.limit > 30)
-                   game.limit=game.limit+30*HINTS[hint][2];
+               if (game.hinted[hint] && game.limit > WARNTIME)
+                   game.limit += WARNTIME*HINTS[hint][2];
            }
        }
     }
 }
 
-bool spotted_by_pirate(int i)
+static bool spotted_by_pirate(int i)
 {
     if (i != PIRATE) 
        return false;
 
     /*  The pirate's spotted him.  He leaves him alone once we've
      *  found chest.  K counts if a treasure is here.  If not, and
-     *  tally=1 for an unseen chest, let the pirate be spotted.
-     *  Note that game.place[CHEST]=0 might mean that he's thrown
+     *  tally=1 for an unseen chest, let the pirate be spotted.  Note
+     *  that game.place[CHEST] = NOWHERE might mean that he's thrown
      *  it to the troll, but in that case he's seen the chest
      *  (game.prop=0). */
     if (game.loc == game.chloc || game.prop[CHEST] >= 0)
        return true;
     int snarfed=0;
     bool movechest = false, robplayer = false;
-    for (int j=MINTRS; j<=MAXTRS; j++) {
+    for (int treasure=MINTRS; treasure<=MAXTRS; treasure++) {
        /*  Pirate won't take pyramid from plover room or dark
         *  room (too easy!). */
-       if (j==PYRAM && (game.loc==PLAC[PYRAM] || game.loc==PLAC[EMRALD])) {
+       if (treasure==PYRAM && (game.loc==PLAC[PYRAM] || game.loc==PLAC[EMRALD])) {
            continue;
        }
-       if (TOTING(j) || HERE(j))
+       if (TOTING(treasure) || HERE(treasure))
            ++snarfed;
-       if (TOTING(j)) {
+       if (TOTING(treasure)) {
            movechest = true;
            robplayer = true;
        }
     }
     /* Force chest placement before player finds last treasure */
-    if (game.tally == 1 && snarfed == 0 && game.place[CHEST] == 0 && HERE(LAMP) && game.prop[LAMP] == 1) {
+    if (game.tally == 1 && snarfed == 0 && game.place[CHEST] == NOWHERE && HERE(LAMP) && game.prop[LAMP] == 1) {
        RSPEAK(PIRATE_SPOTTED);
        movechest = true;
     }
@@ -305,12 +314,12 @@ bool spotted_by_pirate(int i)
     }
     if (robplayer) {
        RSPEAK(PIRATE_POUNCES);
-       for (int j=MINTRS; j<=MAXTRS; j++) {
-           if (!(j == PYRAM && (game.loc == PLAC[PYRAM] || game.loc == PLAC[EMRALD]))) {
-               if (AT(j) && game.fixed[j] == 0)
-                   CARRY(j,game.loc);
-               if (TOTING(j))
-                   DROP(j,game.chloc);
+       for (int treasure=MINTRS; treasure<=MAXTRS; treasure++) {
+           if (!(treasure == PYRAM && (game.loc == PLAC[PYRAM] || game.loc == PLAC[EMRALD]))) {
+               if (AT(treasure) && game.fixed[treasure] == 0)
+                   CARRY(treasure,game.loc);
+               if (TOTING(treasure))
+                   DROP(treasure,game.chloc);
            }
        }
     }
@@ -475,15 +484,14 @@ static void croak(FILE *cmdin)
        /*  He died during closing time.  No resurrection.  Tally up a
         *  death and exit. */
        RSPEAK(DEATH_CLOSING);
-       score(0);
-    } else {
-       /* FIXME: Arithmetic on message numbers */
-       if (!YES(cmdin,WATCH_IT+game.numdie*2,WHICH_WAY+game.numdie*2,OK_MAN))
-           score(0);
-       if (game.numdie == MAXDIE)
-           score(0);
-       game.place[WATER]=0;
-       game.place[OIL]=0;
+       score(endgame);
+
+    }
+    /* FIXME: Arithmetic on message numbers */
+    else if (game.numdie == MAXDIE || !YES(cmdin,WATCH_IT+game.numdie*2,WHICH_WAY+game.numdie*2,OK_MAN))
+           score(endgame);
+    else {
+       game.place[WATER] = game.place[OIL] = NOWHERE;
        if (TOTING(LAMP))
            game.prop[LAMP]=0;
        for (int j=1; j<=NOBJECTS; j++) {
@@ -499,7 +507,7 @@ static void croak(FILE *cmdin)
 }
 
 /*  Given the current location in "game.loc", and a motion verb number in
- *  "K", put the new location in "game.newloc".  The current loc is saved
+ *  "motion", put the new location in "game.newloc".  The current loc is saved
  *  in "game.oldloc" in case he wants to retreat.  The current
  *  game.oldloc is saved in game.oldlc2, in case he dies.  (if he
  *  does, game.newloc will be limbo, and game.oldloc will be what killed
@@ -556,7 +564,7 @@ static bool playermove(FILE *cmdin, token_t verb, int motion)
     }
     else if (motion == LOOK) {
        /*  Look.  Can't give more detail.  Pretend it wasn't dark
-        *  (though it may "now" be dark) so he won't fall into a
+        *  (though it may now be dark) so he won't fall into a
         *  pit while staring into the gloom. */
        if (game.detail < 3)
            RSPEAK(NO_MORE_DETAIL);
@@ -567,7 +575,7 @@ static bool playermove(FILE *cmdin, token_t verb, int motion)
     }
     else if (motion == CAVE) {
        /*  Cave.  Different messages depending on whether above ground. */
-       RSPEAK((OUTSID(game.loc) && game.loc != 8) ? FOLLOW_STREAM : NEED_DETAIL);
+       RSPEAK((OUTSID(game.loc) && game.loc != LOC_GRATE) ? FOLLOW_STREAM : NEED_DETAIL);
        return true;
     }
     else {
@@ -582,6 +590,7 @@ static bool playermove(FILE *cmdin, token_t verb, int motion)
        if (MOD(scratchloc,1000) == 1 || MOD(scratchloc,1000) == motion)
            break;
        if (TRAVEL[kk] < 0) {
+           /* FIXME: Magic numbers! */
            /*  Non-applicable motion.  Various messages depending on
             *  word given. */
            int spk=CANT_APPLY;
@@ -697,7 +706,8 @@ static bool playermove(FILE *cmdin, token_t verb, int motion)
            BUG(20);
        }
     } while
-           (false);
+       (false);
+    /* FIXME: Arithmetic on location number, becoming a message number */
     RSPEAK(game.newloc-500);
     game.newloc=game.loc;
     return true;
@@ -753,7 +763,7 @@ static bool closecheck(void)
        MOVE(TROLL2,PLAC[TROLL]);
        MOVE(TROLL2+NOBJECTS,FIXD[TROLL]);
        JUGGLE(CHASM);
-       if (game.prop[BEAR] != 3)DSTROY(BEAR);
+       if (game.prop[BEAR] != 3)DESTROY(BEAR);
        game.prop[CHAIN]=0;
        game.fixed[CHAIN]=0;
        game.prop[AXE]=0;
@@ -806,7 +816,7 @@ static bool closecheck(void)
 
        for (int i=1; i<=NOBJECTS; i++) {
            if (TOTING(i))
-               DSTROY(i);
+               DESTROY(i);
        }
 
        RSPEAK(CAVE_CLOSED);
@@ -830,7 +840,7 @@ static void lampcheck(void)
      *  Second is for other cases of lamp dying.  12400 is when it
      *  goes out.  Even then, he can explore outside for a while
      *  if desired. */
-    if (game.limit<=30 && HERE(BATTER) && game.prop[BATTER]==0 && HERE(LAMP))
+    if (game.limit <= WARNTIME && HERE(BATTER) && game.prop[BATTER]==0 && HERE(LAMP))
     {
        RSPEAK(REPLACE_BATTERIES);
        game.prop[BATTER]=1;
@@ -843,11 +853,11 @@ static void lampcheck(void)
        game.prop[LAMP]=0;
        if (HERE(LAMP))
            RSPEAK(LAMP_OUT);
-    } else if (game.limit <= 30) {
+    } else if (game.limit <= WARNTIME) {
        if (!game.lmwarn && HERE(LAMP)) {
            game.lmwarn=true;
            int spk=GET_BATTERIES;
-           if (game.place[BATTER] == 0)spk=LAMP_DIM;
+           if (game.place[BATTER] == NOWHERE)spk=LAMP_DIM;
            if (game.prop[BATTER] == 1)spk=MISSING_BATTERIES;
            RSPEAK(spk);
        }
@@ -903,8 +913,8 @@ static void listobjects(void)
 static bool do_command(FILE *cmdin)
 /* Get and execute a command */ 
 {
-    long KQ, verb, V1, V2;
-    long i, k, KMOD;
+    long verb, V1, V2;
+    long kmod, defn;
     static long igo = 0;
     static long obj = 0;
     enum speechpart part;
@@ -922,7 +932,7 @@ static bool do_command(FILE *cmdin)
      *  coming from place forbidden to pirate (dwarves rooted in
      *  place) let him get out (and attacked). */
     if (game.newloc != game.loc && !FORCED(game.loc) && !CNDBIT(game.loc,NOARRR)) {
-       for (i=1; i<=NDWARVES-1; i++) {
+       for (size_t i=1; i<=NDWARVES-1; i++) {
            if (game.odloc[i] == game.newloc && game.dseen[i]) {
                game.newloc=game.loc;
                RSPEAK(DWARF_BLOCK);
@@ -982,7 +992,7 @@ static bool do_command(FILE *cmdin)
        if (game.closed) {
            if (game.prop[OYSTER] < 0 && TOTING(OYSTER))
                PSPEAK(OYSTER,1);
-           for (i=1; i<=NOBJECTS; i++) {
+           for (size_t i=1; i<=NOBJECTS; i++) {
                if (TOTING(i) && game.prop[i] < 0)
                    game.prop[i] = -1-game.prop[i];
            }
@@ -1021,12 +1031,14 @@ static bool do_command(FILE *cmdin)
        } else
            lampcheck();
 
-       k=WHERE_QUERY;
-       if (LIQLOC(game.loc) == WATER)k=FEET_WET;
        V1=VOCAB(WD1,-1);
        V2=VOCAB(WD2,-1);
        if (V1 == ENTER && (V2 == STREAM || V2 == 1000+WATER)) {
-           RSPEAK(k);
+               if(LIQLOC(game.loc) == WATER){
+                       RSPEAK(FEET_WET);
+               } else {
+                       RSPEAK(WHERE_QUERY);
+               }
            goto L2012;
        }
        if (V1 == ENTER && WD2 > 0) {
@@ -1052,28 +1064,27 @@ static bool do_command(FILE *cmdin)
            if (++igo == 10)
                RSPEAK(GO_UNNEEDED);
        }
-    L2630:
-       i=VOCAB(WD1,-1);
-       if (i == -1) {
+    Lookup:
+       defn = VOCAB(WD1,-1);
+       if (defn == -1) {
            /* Gee, I don't understand. */
            if (fallback_handler(rawbuf))
-               return true;
+               continue;
            SETPRM(1,WD1,WD1X);
            RSPEAK(DONT_KNOW);
            goto L2600;
        }
-       KMOD=MOD(i,1000);
-       KQ=i/1000+1;
-       switch (KQ-1)
+       kmod=MOD(defn,1000);
+       switch (defn/1000)
        {
        case 0:
-           if (playermove(cmdin, verb, KMOD))
+           if (playermove(cmdin, verb, kmod))
                return true;
            else
                continue;       /* back to top of main interpreter loop */
-       case 1: part=unknown; obj = KMOD; break;
-       case 2: part=intransitive; verb = KMOD; break;
-       case 3: RSPEAK(KMOD); goto L2012;
+       case 1: part=unknown; obj = kmod; break;
+       case 2: part=intransitive; verb = kmod; break;
+       case 3: RSPEAK(kmod); goto L2012;
        default: BUG(22);
        }
 
@@ -1088,7 +1099,7 @@ static bool do_command(FILE *cmdin)
        case GO_CLEAROBJ: goto L2012;
        case GO_CHECKHINT: goto L2600;
        case GO_CHECKFOO: goto L2607;
-       case GO_LOOKUP: goto L2630;
+       case GO_LOOKUP: goto Lookup;
        case GO_WORD2:
            /* Get second word for analysis. */
            WD1=WD2;
@@ -1105,7 +1116,7 @@ static bool do_command(FILE *cmdin)
        case GO_DWARFWAKE:
            /*  Oh dear, he's disturbed the dwarves. */
            RSPEAK(DWARVES_AWAKEN);
-           score(0);
+           score(endgame);
            return true;
        default:
            BUG(99);