Abolish a silly layer of macros.
[open-adventure.git] / main.c
diff --git a/main.c b/main.c
index bceb341e815fe4466d67d743f5b107e83f92cf87..335f10523307c8a869d729d89d8e93ad7ba1d634 100644 (file)
--- a/main.c
+++ b/main.c
@@ -21,14 +21,15 @@ long AMBER, AXE, BACK, BATTER, BEAR, BIRD, BLOOD,
                BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST,
                CLAM, COINS, DOOR, DPRSSN, DRAGON, DWARF, EGGS,
                EMRALD, ENTER, ENTRNC, FIND, FISSUR, FOOD,
                BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST,
                CLAM, COINS, DOOR, DPRSSN, DRAGON, DWARF, EGGS,
                EMRALD, ENTER, ENTRNC, FIND, FISSUR, FOOD,
-               GRATE, HINT, I, INVENT, J, JADE, K, KEYS,
-               KNIFE, L, LAMP, LOCK, LOOK, MAGZIN,
+               GRATE, HINT, INVENT, JADE, KEYS,
+               KNIFE, LAMP, LOCK, LOOK, MAGZIN,
                MESSAG, MIRROR, NUGGET, NUL, OGRE, OIL, OYSTER,
                PEARL, PILLOW, PLANT, PLANT2, PYRAM, RESER, ROD, ROD2,
                MESSAG, MIRROR, NUGGET, NUL, OGRE, OIL, OYSTER,
                PEARL, PILLOW, PLANT, PLANT2, PYRAM, RESER, ROD, ROD2,
-               RUBY, RUG, SAPPH, SAY, SECT, SIGN, SNAKE, SPK,
+               RUBY, RUG, SAPPH, SAY, SIGN, SNAKE,
                STEPS, STREAM, THROW, TRIDNT, TROLL, TROLL2,
                STEPS, STREAM, THROW, TRIDNT, TROLL, TROLL2,
-               URN, VASE, VEND,
-               VOLCAN, VRSION = 25, WATER, WD1, WD1X, WD2, WD2X;
+               URN, VASE, VEND, VOLCAN, WATER;
+long I, K, SPK, WD1, WD1X, WD2, WD2X;
+
 FILE  *logfp;
 bool oldstyle = false;
 lcg_state lcgstate;
 FILE  *logfp;
 bool oldstyle = false;
 lcg_state lcgstate;
@@ -151,6 +152,85 @@ static bool fallback_handler(char *buf)
     return false;
 }
 
     return false;
 }
 
+static void dohint(FILE *cmdin, int hint)
+/*  Come here if he's been long enough at required loc(s) for some
+ *  unused hint. */
+{
+    int i;
+
+    switch (hint-1)
+    {
+    case 0:
+       /* cave */
+       if(game.prop[GRATE] == 0 && !HERE(KEYS))
+           break;
+       game.hintlc[hint]=0;
+       return;
+    case 1:    /* bird */
+       if(game.place[BIRD] == game.loc && TOTING(ROD) && game.oldobj == BIRD)
+           break;
+       return;
+    case 2:    /* snake */
+       if(HERE(SNAKE) && !HERE(BIRD))
+           break;
+       game.hintlc[hint]=0;
+       return;
+    case 3:    /* maze */
+       if(game.atloc[game.loc] == 0 &&
+          game.atloc[game.oldloc] == 0 &&
+          game.atloc[game.oldlc2] == 0 &&
+          game.holdng > 1)
+           break;
+       game.hintlc[hint]=0;
+       return;
+    case 4:    /* dark */
+       if(game.prop[EMRALD] != -1 && game.prop[PYRAM] == -1)
+           break;
+       game.hintlc[hint]=0;
+       return;
+    case 5:    /* witt */
+       break;
+    case 6:    /* urn */
+       if(game.dflag == 0)
+           break;
+       game.hintlc[hint]=0;
+       return;
+    case 7:    /* woods */
+       if(game.atloc[game.loc] == 0 &&
+                  game.atloc[game.oldloc] == 0 &&
+                  game.atloc[game.oldlc2] == 0)
+               break;
+       return;
+    case 8:    /* ogre */
+       i=ATDWRF(game.loc);
+       if(i < 0) {
+           game.hintlc[hint]=0;
+           return;
+           }
+       if(HERE(OGRE) && i == 0)
+           break;
+       return;
+    case 9:    /* jade */
+       if(game.tally == 1 && game.prop[JADE] < 0)
+           break;
+       game.hintlc[hint]=0;
+       return;
+    default:
+       BUG(27);
+       break;
+    }
+    
+    /* Fall through to hint display */
+    game.hintlc[hint]=0;
+    if(!YES(cmdin,HINTS[hint][3],0,54))
+       return;
+    SETPRM(1,HINTS[hint][2],HINTS[hint][2]);
+    RSPEAK(261);
+    game.hinted[hint]=YES(cmdin,175,HINTS[hint][4],54);
+    if(game.hinted[hint] && game.limit > 30)
+       game.limit=game.limit+30*HINTS[hint][2];
+}
+
 static bool dwarfmove(void)
 /* Dwarves move.  Return true if player survives, false if he dies. */
 {
 static bool dwarfmove(void)
 /* Dwarves move.  Return true if player survives, false if he dies. */
 {
@@ -188,9 +268,9 @@ static bool dwarfmove(void)
            return true;
        game.dflag=2;
        for (I=1; I<=2; I++) {
            return true;
        game.dflag=2;
        for (I=1; I<=2; I++) {
-           J=1+randrange(NDWARVES-1);
+           int j=1+randrange(NDWARVES-1);
            if(PCT(50))
            if(PCT(50))
-               game.dloc[J]=0;
+               game.dloc[j]=0;
        }
        for (I=1; I<=NDWARVES-1; I++) {
            if(game.dloc[I] == game.loc)
        }
        for (I=1; I<=NDWARVES-1; I++) {
            if(game.dloc[I] == game.loc)
@@ -211,81 +291,99 @@ static bool dwarfmove(void)
     game.dtotal=0;
     attack=0;
     stick=0;
     game.dtotal=0;
     attack=0;
     stick=0;
-    /* 6030 */ for (I=1; I<=NDWARVES; I++) {
-       if(game.dloc[I] == 0) goto L6030;
+    for (I=1; I<=NDWARVES; I++) {
+       if(game.dloc[I] == 0)
+           continue;
        /*  Fill TK array with all the places this dwarf might go. */
        /*  Fill TK array with all the places this dwarf might go. */
-       J=1;
-       kk=game.dloc[I];
-       kk=KEY[kk];
-       if(kk == 0) goto L6016;
-    L6012:     game.newloc=MOD(labs(TRAVEL[kk])/1000,1000);
-       {long x = J-1;
-           if(game.newloc > 300 || !INDEEP(game.newloc) || game.newloc == game.odloc[I] || (J > 1 &&
-                                                                                            game.newloc == TK[x]) || J >= 20 || game.newloc == game.dloc[I] ||
-              FORCED(game.newloc) || (I == 6 && CNDBIT(game.newloc,3)) ||
-              labs(TRAVEL[kk])/1000000 == 100) goto L6014;}
-       TK[J]=game.newloc;
-       J=J+1;
-    L6014:
-       kk=kk+1;
-       if(TRAVEL[kk-1] >= 0)
-           goto L6012;
-    L6016:
-       TK[J]=game.odloc[I];
-       if(J >= 2)J=J-1;
-       J=1+randrange(J);
+       int j=1;
+       kk=KEY[game.dloc[I]];
+       if(kk != 0)
+           do {
+               game.newloc=MOD(labs(TRAVEL[kk])/1000,1000);
+               /* Have we avoided a dwarf enciounter? */
+               bool avoided = (game.newloc > 300 ||
+                               !INDEEP(game.newloc) ||
+                               game.newloc == game.odloc[I] ||
+                               (j > 1 && game.newloc == TK[j-1]) ||
+                               j >= 20 ||
+                               game.newloc == game.dloc[I] ||
+                               FORCED(game.newloc) ||
+                               (I == PIRATE && CNDBIT(game.newloc,3)) ||
+                               labs(TRAVEL[kk])/1000000 == 100);
+               if (!avoided) {
+                   TK[j++] = game.newloc;
+               }
+               ++kk;
+           } while
+               (TRAVEL[kk-1] >= 0);
+       TK[j]=game.odloc[I];
+       if(j >= 2)
+           --j;
+       j=1+randrange(j);
        game.odloc[I]=game.dloc[I];
        game.odloc[I]=game.dloc[I];
-       game.dloc[I]=TK[J];
+       game.dloc[I]=TK[j];
        game.dseen[I]=(game.dseen[I] && INDEEP(game.loc)) || (game.dloc[I] == game.loc || game.odloc[I] == game.loc);
        game.dseen[I]=(game.dseen[I] && INDEEP(game.loc)) || (game.dloc[I] == game.loc || game.odloc[I] == game.loc);
-       if(!game.dseen[I]) goto L6030;
+       if(!game.dseen[I]) continue;
        game.dloc[I]=game.loc;
        game.dloc[I]=game.loc;
-       if(I != 6) goto L6027;
-
-       /*  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
-        *  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) goto L6030;
-       K=0;
-       /* 6020 */ for (J=50; J<=MAXTRS; J++) {
-/*  Pirate won't take pyramid from plover room or dark room (too easy!). */
-           if(J == PYRAM && (game.loc == PLAC[PYRAM] || game.loc == PLAC[EMRALD])) goto L6020;
-           if(TOTING(J)) goto L6021;
-       L6020:  if(HERE(J))K=1;
-       } /* end loop */
-       if(game.tally == 1 && K == 0 && game.place[CHEST] == 0 && HERE(LAMP) && game.prop[LAMP]
-          == 1) goto L6025;
-       if(game.odloc[6] != game.dloc[6] && PCT(20))RSPEAK(127);
-       goto L6030;
-
-    L6021:     if(game.place[CHEST] != 0) goto L6022;
-    /*  Install chest only once, to insure it is the last treasure in
-     *  the list. */
-       MOVE(CHEST,game.chloc);
-       MOVE(MESSAG,game.chloc2);
-    L6022:     RSPEAK(128);
-       /* 6023 */ for (J=50; J<=MAXTRS; J++) {
-           if(J == PYRAM && (game.loc == PLAC[PYRAM] || game.loc == PLAC[EMRALD])) goto L6023;
-           if(AT(J) && game.fixed[J] == 0)CARRY(J,game.loc);
-           if(TOTING(J))DROP(J,game.chloc);
-       L6023:  /*etc*/ ;
-       } /* end loop */
-    L6024:     game.dloc[6]=game.chloc;
-       game.odloc[6]=game.chloc;
-       game.dseen[6]=false;
-       goto L6030;
-
-    L6025:
-       RSPEAK(186);
-       MOVE(CHEST,game.chloc);
-       MOVE(MESSAG,game.chloc2);
-       goto L6024;
-
-    /* This threatening little dwarf is in the room with him! */
-    L6027:
+       if(I == PIRATE) {
+           /*  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
+            *  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)
+               continue;
+           K=0;
+           for (int j=MINTRS; j<=MAXTRS; j++) {
+               /*  Pirate won't take pyramid from plover room or dark
+               *  room (too easy!). */
+               if(j == PYRAM && (game.loc == PLAC[PYRAM] || game.loc == PLAC[EMRALD]))
+                   goto L6020;
+               if(TOTING(j)) {
+                   goto L6021;
+               }
+           L6020:
+               if(HERE(j))
+                   K=1;
+           }
+           /* Force chest placement before player finds last treasure */
+           if(game.tally == 1 && K == 0 && game.place[CHEST] == 0 && HERE(LAMP) && game.prop[LAMP] == 1) {
+               RSPEAK(186);
+               MOVE(CHEST,game.chloc);
+               MOVE(MESSAG,game.chloc2);
+               game.dloc[PIRATE]=game.chloc;
+               game.odloc[PIRATE]=game.chloc;
+               game.dseen[PIRATE]=false;
+               continue;
+           }
+           if(game.odloc[PIRATE] != game.dloc[PIRATE] && PCT(20))
+               RSPEAK(127);
+           continue;
+
+       L6021:
+           if(game.place[CHEST] == 0) {
+               /*  Install chest only once, to insure it is the last treasure in
+                *  the list. */
+               MOVE(CHEST,game.chloc);
+               MOVE(MESSAG,game.chloc2);
+           }
+           RSPEAK(128);
+           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);
+               }
+           }
+           game.dloc[PIRATE]=game.chloc;
+           game.odloc[PIRATE]=game.chloc;
+           game.dseen[PIRATE]=false;
+           continue;
+       }
+
+       /* This threatening little dwarf is in the room with him! */
        ++game.dtotal;
        if(game.odloc[I] == game.dloc[I]) {
            ++attack;
        ++game.dtotal;
        if(game.odloc[I] == game.dloc[I]) {
            ++attack;
@@ -294,7 +392,6 @@ static bool dwarfmove(void)
            if(randrange(1000) < 95*(game.dflag-2))
                ++stick;
        }
            if(randrange(1000) < 95*(game.dflag-2))
                ++stick;
        }
-    L6030:;
     }
 
     /*  Now we know what's happening.  Let's tell the poor sucker about it.
     }
 
     /*  Now we know what's happening.  Let's tell the poor sucker about it.
@@ -319,6 +416,39 @@ static bool dwarfmove(void)
     return false;
 }
 
     return false;
 }
 
+static void croak(FILE *cmdin)
+/*  Okay, he's dead.  Let's get on with it. */
+{
+    if(game.closng) {
+       /*  He died during closing time.  No resurrection.  Tally up a
+        *  death and exit. */
+       RSPEAK(131);
+       ++game.numdie;
+       score(0);
+    } else {
+       ++game.numdie;
+       if(!YES(cmdin,79+game.numdie*2,80+game.numdie*2,54))
+           score(0);
+       if(game.numdie == MAXDIE)
+           score(0);
+       game.place[WATER]=0;
+       game.place[OIL]=0;
+       if(TOTING(LAMP))
+           game.prop[LAMP]=0;
+       for (int j=1; j<=NOBJECTS; j++) {
+           int i=NOBJECTS + 1 - j;
+           if(TOTING(i)) {
+               int k=game.oldlc2;
+               if(i == LAMP)
+                   k=1;
+               DROP(i,k);
+           }
+       }
+       game.loc=3;
+       game.oldloc=game.loc;
+    }
+}
+
 static bool do_command(FILE *cmdin) {
        long LL, KQ, VERB, KK, K2, V1, V2;
        long obj, i;
 static bool do_command(FILE *cmdin) {
        long LL, KQ, VERB, KK, K2, V1, V2;
        long obj, i;
@@ -348,13 +478,14 @@ static bool do_command(FILE *cmdin) {
        game.loc=game.newloc;
 
        if (!dwarfmove())
        game.loc=game.newloc;
 
        if (!dwarfmove())
-           goto L99;
+           croak(cmdin);
 
 /*  Describe the current location and (maybe) get next command. */
 
 /*  Print text for current loc. */
 
 
 /*  Describe the current location and (maybe) get next command. */
 
 /*  Print text for current loc. */
 
-L2000: if(game.loc == 0) goto L99;
+L2000: if(game.loc == 0)
+           croak(cmdin);
        KK=STEXT[game.loc];
        if(MOD(game.abbrev[game.loc],game.abbnum) == 0 || KK == 0)KK=LTEXT[game.loc];
        if(FORCED(game.loc) || !DARK(0)) goto L2001;
        KK=STEXT[game.loc];
        if(MOD(game.abbrev[game.loc],game.abbnum) == 0 || KK == 0)KK=LTEXT[game.loc];
        if(FORCED(game.loc) || !DARK(0)) goto L2001;
@@ -413,15 +544,18 @@ L2012:    VERB=0;
  *  branch to help section (on later page).  Hints all come back here eventually
  *  to finish the loop.  Ignore "HINTS" < 4 (special stuff, see database notes).
  */
  *  branch to help section (on later page).  Hints all come back here eventually
  *  to finish the loop.  Ignore "HINTS" < 4 (special stuff, see database notes).
  */
-L2600: if(COND[game.loc] < game.conds) goto L2603;
-       /* 2602 */ for (HINT=1; HINT<=HNTMAX; HINT++) {
-       if(game.hinted[HINT]) goto L2602;
-       if(!CNDBIT(game.loc,HINT+10))game.hintlc[HINT]= -1;
-       game.hintlc[HINT]=game.hintlc[HINT]+1;
-       if(game.hintlc[HINT] >= HINTS[HINT][1]) goto L40000;
-L2602: /*etc*/ ;
-       } /* end loop */
-
+L2600: if(COND[game.loc] >= game.conds) {
+           for (int hint=1; hint<=HNTMAX; hint++) {
+               if(game.hinted[hint])
+                   continue;
+               if(!CNDBIT(game.loc,hint+10))
+                   game.hintlc[hint]= -1;
+               game.hintlc[hint] = game.hintlc[hint]+1;
+               if(game.hintlc[hint] >= HINTS[hint][1]) 
+                   dohint(cmdin, hint);
+           }
+       }
+           
        /*  If closing time, check for any objects being toted with
         *  game.prop < 0 and set the prop to -1-game.prop.  This way
         *  objects won't be described until they've been picked up
        /*  If closing time, check for any objects being toted with
         *  game.prop < 0 and set the prop to -1-game.prop.  This way
         *  objects won't be described until they've been picked up
@@ -440,7 +574,7 @@ L2603:      if(game.closed) {
            game.knfloc=0;
 
        /* This is where we get a new command from the user */
            game.knfloc=0;
 
        /* This is where we get a new command from the user */
-       if (!GETIN(cmdin, WD1,WD1X,WD2,WD2X))
+       if (!GETIN(cmdin, &WD1,&WD1X,&WD2,&WD2X))
            return false;
 
        /*  Every input, check "game.foobar" flag.  If zero, nothing's
            return false;
 
        /*  Every input, check "game.foobar" flag.  If zero, nothing's
@@ -482,11 +616,14 @@ L2620:    if(WD1 == MAKEWD(23051920)) {
                game.iwest=game.iwest+1;
                if(game.iwest == 10)RSPEAK(17);
        }
                game.iwest=game.iwest+1;
                if(game.iwest == 10)RSPEAK(17);
        }
-       if(WD1 != MAKEWD( 715) || WD2 == 0) goto L2630;
-       IGO=IGO+1;
-       if(IGO == 10)RSPEAK(276);
-L2630: I=VOCAB(WD1,-1);
-       if(I == -1) goto L3000;
+       if(WD1 == MAKEWD( 715) && WD2 != 0) {
+           if(++IGO == 10)
+               RSPEAK(276);
+       }
+L2630:
+       I=VOCAB(WD1,-1);
+       if(I == -1)
+          goto L3000;
        K=MOD(I,1000);
        KQ=I/1000+1;
         switch (KQ-1) { case 0: goto L8; case 1: goto L5000; case 2: goto L4000;
        K=MOD(I,1000);
        KQ=I/1000+1;
         switch (KQ-1) { case 0: goto L8; case 1: goto L5000; case 2: goto L4000;
@@ -512,7 +649,7 @@ L3000:      SETPRM(1,WD1,WD1X);
 
 L4000: I=4000; VERB=K; goto Laction;
 L4090: I=4090; goto Laction;
 
 L4000: I=4000; VERB=K; goto Laction;
 L4090: I=4090; goto Laction;
-L5000: I=5000;
+L5000: I=5000; obj = K;
 Laction:
         switch (action(cmdin, I, VERB, obj)) {
           case 2: return true;
 Laction:
         switch (action(cmdin, I, VERB, obj)) {
           case 2: return true;
@@ -552,11 +689,40 @@ L8000:    SETPRM(1,WD1,WD1X);
 
 L8:    KK=KEY[game.loc];
        game.newloc=game.loc;
 
 L8:    KK=KEY[game.loc];
        game.newloc=game.loc;
-       if(KK == 0)BUG(26);
-       if(K == NUL) return true;
-       if(K == BACK) goto L20;
-       if(K == LOOK) goto L30;
-       if(K == CAVE) goto L40;
+       if(KK == 0)
+           BUG(26);
+       if(K == NUL)
+           return true;
+       if(K == BACK) {
+           /*  Handle "go back".  Look for verb which goes from game.loc to
+            *  game.oldloc, or to game.oldlc2 If game.oldloc has forced-motion.
+            *  K2 saves entry -> forced loc -> previous loc. */
+           K=game.oldloc;
+           if(FORCED(K))K=game.oldlc2;
+           game.oldlc2=game.oldloc;
+           game.oldloc=game.loc;
+           K2=0;
+           if(K == game.loc)K2=91;
+           if(CNDBIT(game.loc,4))K2=274;
+           if(K2 == 0) goto L21;
+           RSPEAK(K2);
+           return true;
+       }
+       if(K == 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
+            *  pit while staring into the gloom. */
+           if(game.detail < 3)RSPEAK(15);
+           game.detail=game.detail+1;
+           game.wzdark=false;
+           game.abbrev[game.loc]=0;
+           return true;
+       }
+       if(K == CAVE) {
+           /*  Cave.  Different messages depending on whether above ground. */
+           RSPEAK((OUTSID(game.loc) && game.loc != 8) ? 57 : 58);
+           return true;
+       }
        game.oldlc2=game.oldloc;
        game.oldloc=game.loc;
 
        game.oldlc2=game.oldloc;
        game.oldloc=game.loc;
 
@@ -564,7 +730,7 @@ L9: LL=labs(TRAVEL[KK]);
        if(MOD(LL,1000) == 1 || MOD(LL,1000) == K) goto L10;
        if(TRAVEL[KK] < 0) goto L50;
        KK=KK+1;
        if(MOD(LL,1000) == 1 || MOD(LL,1000) == K) goto L10;
        if(TRAVEL[KK] < 0) goto L50;
        KK=KK+1;
-        goto L9;
+       goto L9;
 
 L10:   LL=LL/1000;
 L11:   game.newloc=LL/1000;
 
 L10:   LL=LL/1000;
 L11:   game.newloc=LL/1000;
@@ -642,61 +808,33 @@ L30310: game.newloc=PLAC[TROLL]+FIXD[TROLL]-game.loc;
        game.fixed[BEAR]= -1;
        game.prop[BEAR]=3;
        game.oldlc2=game.newloc;
        game.fixed[BEAR]= -1;
        game.prop[BEAR]=3;
        game.oldlc2=game.newloc;
-        goto L99;
+       croak(cmdin);
+       goto L2000;
 
 /*  End of specials. */
 
 
 /*  End of specials. */
 
-/*  Handle "go back".  Look for verb which goes from game.loc to game.oldloc, or to game.oldlc2
- *  If game.oldloc has forced-motion.  K2 saves entry -> forced loc -> previous loc. */
-
-L20:   K=game.oldloc;
-       if(FORCED(K))K=game.oldlc2;
-       game.oldlc2=game.oldloc;
-       game.oldloc=game.loc;
-       K2=0;
-       if(K == game.loc)K2=91;
-       if(CNDBIT(game.loc,4))K2=274;
-       if(K2 == 0) goto L21;
-       RSPEAK(K2);
-       return true;
-
 L21:   LL=MOD((labs(TRAVEL[KK])/1000),1000);
        if(LL != K) {
 L21:   LL=MOD((labs(TRAVEL[KK])/1000),1000);
        if(LL != K) {
-               if(LL <= 300) {
-                       J=KEY[LL];
-                       if(FORCED(LL) && MOD((labs(TRAVEL[J])/1000),1000) == K)
-                               K2=KK;
-               }
-               if(TRAVEL[KK] < 0) goto L23;
-               KK=KK+1;
-               goto L21;
-
-L23:           KK=K2;
-               if(KK == 0) {
-                       RSPEAK(140);
-                       return true;
-               }
+           if(LL <= 300) {
+               if(FORCED(LL) && MOD((labs(TRAVEL[KEY[LL]])/1000),1000) == K)
+                   K2=KK;
+           }
+           if(TRAVEL[KK] < 0)
+               goto L23;
+           KK=KK+1;
+           goto L21;
+
+       L23:            KK=K2;
+           if(KK == 0) {
+               RSPEAK(140);
+               return true;
+           }
        }
 
        K=MOD(labs(TRAVEL[KK]),1000);
        KK=KEY[game.loc];
        }
 
        K=MOD(labs(TRAVEL[KK]),1000);
        KK=KEY[game.loc];
-        goto L9;
-
-/*  Look.  Can't give more detail.  Pretend it wasn't dark (though it may "now"
- *  be dark) so he won't fall into a pit while staring into the gloom. */
-
-L30:   if(game.detail < 3)RSPEAK(15);
-       game.detail=game.detail+1;
-       game.wzdark=false;
-       game.abbrev[game.loc]=0;
-       return true;
-
-/*  Cave.  Different messages depending on whether above ground. */
+       goto L9;
 
 
-L40:   K=58;
-       if(OUTSID(game.loc) && game.loc != 8)K=57;
-       RSPEAK(K);
-       return true;
 
 /*  Non-applicable motion.  Various messages depending on word given. */
 
 
 /*  Non-applicable motion.  Various messages depending on word given. */
 
@@ -732,102 +870,8 @@ L50:      SPK=12;
 
 L90:   RSPEAK(23);
        game.oldlc2=game.loc;
 
 L90:   RSPEAK(23);
        game.oldlc2=game.loc;
-
-/*  Okay, he's dead.  Let's get on with it. */
-
-L99:   if(game.closng) {
-       /*  He died during closing time.  No resurrection.  Tally up a
-        *  death and exit. */
-           RSPEAK(131);
-           ++game.numdie;
-           score(0);
-       } else {
-           ++game.numdie;
-           if(!YES(cmdin,79+game.numdie*2,80+game.numdie*2,54))
-               score(0);
-           if(game.numdie == MAXDIE)
-               score(0);
-           game.place[WATER]=0;
-           game.place[OIL]=0;
-           if(TOTING(LAMP))
-               game.prop[LAMP]=0;
-           for (J=1; J<=NOBJECTS; J++) {
-               I=NOBJECTS + 1 - J;
-               if(TOTING(I)) {
-                   K=game.oldlc2;
-                   if(I == LAMP)
-                       K=1;
-                   DROP(I,K);
-               }
-           }
-           game.loc=3;
-           game.oldloc=game.loc;
-           goto L2000;
-       }
-
-/*  Hints */
-
-/*  Come here if he's been long enough at required loc(s) for some unused hint.
- *  hint number is in variable "hint".  Branch to quick test for additional
- *  conditions, then come back to do neat stuff.  Goto 40010 if conditions are
- *  met and we want to offer the hint.  Goto 40020 to clear game.hintlc back to zero,
- *  40030 to take no action yet. */
-
-L40000:    switch (HINT-1) { case 0: goto L40100; case 1: goto L40200; case 2: goto
-               L40300; case 3: goto L40400; case 4: goto L40500; case 5: goto
-               L40600; case 6: goto L40700; case 7: goto L40800; case 8: goto
-               L40900; case 9: goto L41000; }
-/*             CAVE  BIRD  SNAKE MAZE  DARK  WITT  URN   WOODS OGRE
- *             JADE */
-       BUG(27);
-
-L40010: game.hintlc[HINT]=0;
-       if(!YES(cmdin,HINTS[HINT][3],0,54)) goto L2602;
-       SETPRM(1,HINTS[HINT][2],HINTS[HINT][2]);
-       RSPEAK(261);
-       game.hinted[HINT]=YES(cmdin,175,HINTS[HINT][4],54);
-       if(game.hinted[HINT] && game.limit > 30)game.limit=game.limit+30*HINTS[HINT][2];
-L40020: game.hintlc[HINT]=0;
-L40030:  goto L2602;
-
-/*  Now for the quick tests.  See database description for one-line notes. */
-
-L40100: if(game.prop[GRATE] == 0 && !HERE(KEYS)) goto L40010;
-        goto L40020;
-
-L40200: if(game.place[BIRD] == game.loc && TOTING(ROD) && game.oldobj == BIRD) goto L40010;
-        goto L40030;
-
-L40300: if(HERE(SNAKE) && !HERE(BIRD)) goto L40010;
-        goto L40020;
-
-L40400: if(game.atloc[game.loc] == 0 && game.atloc[game.oldloc] == 0 && game.atloc[game.oldlc2] == 0 && game.holdng >
-               1) goto L40010;
-        goto L40020;
-
-L40500: if(game.prop[EMRALD] != -1 && game.prop[PYRAM] == -1) goto L40010;
-        goto L40020;
-
-L40600:  goto L40010;
-
-L40700: if(game.dflag == 0) goto L40010;
-        goto L40020;
-
-L40800: if(game.atloc[game.loc] == 0 && game.atloc[game.oldloc] == 0 && game.atloc[game.oldlc2] == 0) goto
-               L40010;
-        goto L40030;
-
-L40900: I=ATDWRF(game.loc);
-       if(I < 0) goto L40020;
-       if(HERE(OGRE) && I == 0) goto L40010;
-        goto L40030;
-
-L41000: if(game.tally == 1 && game.prop[JADE] < 0) goto L40010;
-        goto L40020;
-
-
-
-
+       croak(cmdin);
+       goto L2000;
 
 /*  Cave closing and scoring */
 
 
 /*  Cave closing and scoring */