Don Wood's 430-point Adventure 2.5 from 1995, from rec.games.int-fiction.
authorEric S. Raymond <esr@thyrsus.com>
Thu, 16 Feb 2017 16:59:50 +0000 (11:59 -0500)
committerEric S. Raymond <esr@thyrsus.com>
Thu, 16 Feb 2017 16:59:50 +0000 (11:59 -0500)
14 files changed:
Makefile [new file with mode: 0644]
actions1.c [new file with mode: 0644]
actions2.c [new file with mode: 0644]
adventure.text [new file with mode: 0644]
copyright [new file with mode: 0644]
datime.c [new file with mode: 0644]
funcs.h [new file with mode: 0644]
init.c [new file with mode: 0644]
main.c [new file with mode: 0644]
main.h [new file with mode: 0644]
misc.c [new file with mode: 0644]
misc.h [new file with mode: 0644]
score.c [new file with mode: 0644]
share.h [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..1b88b81
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,23 @@
+# NOTE: This version of Adventure was developed by the author on private
+# equipment, and has been ported to Sun for entertainment purposes only.
+# The author (Don Woods) retains full rights to the work.
+
+OBJS=main.o init.o actions1.o actions2.o score.o misc.o datime.o
+
+.c.o:
+       gcc -O $(DBX) -c $<
+
+adventure:     $(OBJS)
+       gcc -O $(DBX) -o adventure $(OBJS)
+
+main.o:                misc.h funcs.h
+
+init.o:                misc.h main.h share.h funcs.h
+
+actions1.o:    misc.h main.h share.h funcs.h
+
+actions2.o:    misc.h main.h share.h funcs.h
+
+score.o:       misc.h main.h share.h
+
+misc.o:                misc.h main.h
diff --git a/actions1.c b/actions1.c
new file mode 100644 (file)
index 0000000..57e8cb1
--- /dev/null
@@ -0,0 +1,589 @@
+#include "misc.h"
+#include "main.h"
+#include "share.h"
+#include "funcs.h"
+
+#define TRUE  (0==0)
+#define FALSE (0!=0)
+
+extern carry(), discard(long), attack(), throw(), feed(), fill();
+
+/* This stuff was broken off as part of an effort to get the main program
+ * to compile without running out of memory.  We're called with a number
+ * that says what label the caller wanted to "goto", and we return a
+ * similar label number for the caller to "goto".
+ */
+
+/*  ANALYSE A VERB.  REMEMBER WHAT IT WAS, GO BACK FOR OBJECT IF SECOND WORD
+ *  UNLESS VERB IS "SAY", WHICH SNARFS ARBITRARY SECOND WORD. */
+
+action(STARTAT)long STARTAT; {
+       switch(STARTAT) {
+          case 4000: goto L4000;
+          case 4090: goto L4090;
+          case 5000: goto L5000;
+          }
+       BUG(99);
+
+L4000: VERB=K;
+       SPK=ACTSPK[VERB];
+       if(WD2 > 0 && VERB != SAY) return(2800);
+       if(VERB == SAY)OBJ=WD2;
+       if(OBJ > 0) goto L4090;
+
+/*  ANALYSE AN INTRANSITIVE VERB (IE, NO OBJECT GIVEN YET). */
+
+L4080: switch (VERB-1) { case 0: goto L8010; case 1: return(8000); case 2:
+               return(8000); case 3: goto L8040; case 4: return(2009); case 5: goto L8040;
+               case 6: goto L8070; case 7: goto L8080; case 8: return(8000); case
+               9: return(8000); case 10: return(2011); case 11: goto L9120; case 12:
+               goto L9130; case 13: goto L8140; case 14: goto L9150; case 15:
+               return(8000); case 16: return(8000); case 17: goto L8180; case 18:
+               return(8000); case 19: goto L8200; case 20: return(8000); case 21:
+               goto L9220; case 22: goto L9230; case 23: goto L8240; case 24:
+               goto L8250; case 25: goto L8260; case 26: goto L8270; case 27:
+               return(8000); case 28: return(8000); case 29: goto L8300; case 30:
+               goto L8310; case 31: goto L8320; case 32: goto L8330; case 33:
+               goto L8340; }
+/*          TAKE DROP  SAY OPEN NOTH LOCK   ON  OFF WAVE CALM
+ *          WALK KILL POUR  EAT DRNK  RUB TOSS QUIT FIND INVN
+ *          FEED FILL BLST SCOR  FOO  BRF READ BREK WAKE SUSP
+ *          RESU FLY  LSTN ZZZZ */
+       BUG(23);
+
+/*  ANALYSE A TRANSITIVE VERB. */
+
+L4090: switch (VERB-1) { case 0: goto L9010; case 1: goto L9020; case 2: goto
+               L9030; case 3: goto L9040; case 4: return(2009); case 5: goto L9040;
+               case 6: goto L9070; case 7: goto L9080; case 8: goto L9090; case
+               9: return(2011); case 10: return(2011); case 11: goto L9120; case 12:
+               goto L9130; case 13: goto L9140; case 14: goto L9150; case 15:
+               goto L9160; case 16: goto L9170; case 17: return(2011); case 18:
+               goto L9190; case 19: goto L9190; case 20: goto L9210; case 21:
+               goto L9220; case 22: goto L9230; case 23: return(2011); case 24:
+               return(2011); case 25: return(2011); case 26: goto L9270; case 27:
+               goto L9280; case 28: goto L9290; case 29: return(2011); case 30:
+               return(2011); case 31: goto L9320; case 32: return(2011); case 33:
+               goto L8340; }
+/*          TAKE DROP  SAY OPEN NOTH LOCK   ON  OFF WAVE CALM
+ *          WALK KILL POUR  EAT DRNK  RUB TOSS QUIT FIND INVN
+ *          FEED FILL BLST SCOR  FOO  BRF READ BREK WAKE SUSP
+ *          RESU FLY  LSTN ZZZZ */
+       BUG(24);
+
+/*  ANALYSE AN OBJECT WORD.  SEE IF THE THING IS HERE, WHETHER WE'VE GOT A VERB
+ *  YET, AND SO ON.  OBJECT MUST BE HERE UNLESS VERB IS "FIND" OR "INVENT(ORY)"
+ *  (AND NO NEW VERB YET TO BE ANALYSED).  WATER AND OIL ARE ALSO FUNNY, SINCE
+ *  THEY ARE NEVER ACTUALLY DROPPED AT ANY LOCATION, BUT MIGHT BE HERE INSIDE
+ *  THE BOTTLE OR URN OR AS A FEATURE OF THE LOCATION. */
+
+L5000: OBJ=K;
+       if(!HERE(K)) goto L5100;
+L5010: if(WD2 > 0) return(2800);
+       if(VERB != 0) goto L4090;
+       SETPRM(1,WD1,WD1X);
+       RSPEAK(255);
+        return(2600);
+
+L5100: if(K != GRATE) goto L5110;
+       if(LOC == 1 || LOC == 4 || LOC == 7)K=DPRSSN;
+       if(LOC > 9 && LOC < 15)K=ENTRNC;
+       if(K != GRATE) return(8);
+L5110: if(K == DWARF && ATDWRF(LOC) > 0) goto L5010;
+       if((LIQ(0) == K && HERE(BOTTLE)) || K == LIQLOC(LOC)) goto L5010;
+       if(OBJ != OIL || !HERE(URN) || PROP[URN] == 0) goto L5120;
+       OBJ=URN;
+        goto L5010;
+L5120: if(OBJ != PLANT || !AT(PLANT2) || PROP[PLANT2] == 0) goto L5130;
+       OBJ=PLANT2;
+        goto L5010;
+L5130: if(OBJ != KNIFE || KNFLOC != LOC) goto L5140;
+       KNFLOC= -1;
+       SPK=116;
+        return(2011);
+L5140: if(OBJ != ROD || !HERE(ROD2)) goto L5190;
+       OBJ=ROD2;
+        goto L5010;
+L5190: if((VERB == FIND || VERB == INVENT) && WD2 <= 0) goto L5010;
+       SETPRM(1,WD1,WD1X);
+       RSPEAK(256);
+        return(2012);
+
+
+
+
+/*  ROUTINES FOR PERFORMING THE VARIOUS ACTION VERBS */
+
+/*  STATEMENT NUMBERS IN THIS SECTION ARE 8000 FOR INTRANSITIVE VERBS, 9000 FOR
+ *  TRANSITIVE, PLUS TEN TIMES THE VERB NUMBER.  MANY INTRANSITIVE VERBS USE THE
+ *  TRANSITIVE CODE, AND SOME VERBS USE CODE FOR OTHER VERBS, AS NOTED BELOW. */
+
+/*  CARRY, NO OBJECT GIVEN YET.  OK IF ONLY ONE OBJECT PRESENT. */
+
+L8010: if(ATLOC[LOC] == 0 || LINK[ATLOC[LOC]] != 0 || ATDWRF(LOC) > 0) return(8000);
+       OBJ=ATLOC[LOC];
+
+/*  TRANSITIVE CARRY/DROP ARE IN SEPARATE FILE. */
+
+L9010: return(carry());
+L9020: return(discard(FALSE));
+
+/*  SAY.  ECHO WD2 (OR WD1 IF NO WD2 (SAY WHAT?, ETC.).)  MAGIC WORDS OVERRIDE. */
+
+L9030: SETPRM(1,WD2,WD2X);
+       if(WD2 <= 0)SETPRM(1,WD1,WD1X);
+       if(WD2 > 0)WD1=WD2;
+       I=VOCAB(WD1,-1);
+       if(I == 62 || I == 65 || I == 71 || I == 2025 || I == 2034) goto L9035;
+       RSPEAK(258);
+        return(2012);
+
+L9035: WD2=0;
+       OBJ=0;
+        return(2630);
+
+/*  LOCK, UNLOCK, NO OBJECT GIVEN.  ASSUME VARIOUS THINGS IF PRESENT. */
+
+L8040: SPK=28;
+       if(HERE(CLAM))OBJ=CLAM;
+       if(HERE(OYSTER))OBJ=OYSTER;
+       if(AT(DOOR))OBJ=DOOR;
+       if(AT(GRATE))OBJ=GRATE;
+       if(OBJ != 0 && HERE(CHAIN)) return(8000);
+       if(HERE(CHAIN))OBJ=CHAIN;
+       if(OBJ == 0) return(2011);
+
+/*  LOCK, UNLOCK OBJECT.  SPECIAL STUFF FOR OPENING CLAM/OYSTER AND FOR CHAIN. */
+
+L9040: if(OBJ == CLAM || OBJ == OYSTER) goto L9046;
+       if(OBJ == DOOR)SPK=111;
+       if(OBJ == DOOR && PROP[DOOR] == 1)SPK=54;
+       if(OBJ == CAGE)SPK=32;
+       if(OBJ == KEYS)SPK=55;
+       if(OBJ == GRATE || OBJ == CHAIN)SPK=31;
+       if(SPK != 31 || !HERE(KEYS)) return(2011);
+       if(OBJ == CHAIN) goto L9048;
+       if(!CLOSNG) goto L9043;
+       K=130;
+       if(!PANIC)CLOCK2=15;
+       PANIC=TRUE;
+        return(2010);
+
+L9043: K=34+PROP[GRATE];
+       PROP[GRATE]=1;
+       if(VERB == LOCK)PROP[GRATE]=0;
+       K=K+2*PROP[GRATE];
+        return(2010);
+
+/*  CLAM/OYSTER. */
+L9046: K=0;
+       if(OBJ == OYSTER)K=1;
+       SPK=124+K;
+       if(TOTING(OBJ))SPK=120+K;
+       if(!TOTING(TRIDNT))SPK=122+K;
+       if(VERB == LOCK)SPK=61;
+       if(SPK != 124) return(2011);
+       DSTROY(CLAM);
+       DROP(OYSTER,LOC);
+       DROP(PEARL,105);
+        return(2011);
+
+/*  CHAIN. */
+L9048: if(VERB == LOCK) goto L9049;
+       SPK=171;
+       if(PROP[BEAR] == 0)SPK=41;
+       if(PROP[CHAIN] == 0)SPK=37;
+       if(SPK != 171) return(2011);
+       PROP[CHAIN]=0;
+       FIXED[CHAIN]=0;
+       if(PROP[BEAR] != 3)PROP[BEAR]=2;
+       FIXED[BEAR]=2-PROP[BEAR];
+        return(2011);
+
+L9049: SPK=172;
+       if(PROP[CHAIN] != 0)SPK=34;
+       if(LOC != PLAC[CHAIN])SPK=173;
+       if(SPK != 172) return(2011);
+       PROP[CHAIN]=2;
+       if(TOTING(CHAIN))DROP(CHAIN,LOC);
+       FIXED[CHAIN]= -1;
+        return(2011);
+
+/*  LIGHT.  APPLICABLE ONLY TO LAMP AND URN. */
+
+L8070: if(HERE(LAMP) && PROP[LAMP] == 0 && LIMIT >= 0)OBJ=LAMP;
+       if(HERE(URN) && PROP[URN] == 1)OBJ=OBJ*100+URN;
+       if(OBJ == 0 || OBJ > 100) return(8000);
+
+L9070: if(OBJ == URN) goto L9073;
+       if(OBJ != LAMP) return(2011);
+       SPK=184;
+       if(LIMIT < 0) return(2011);
+       PROP[LAMP]=1;
+       RSPEAK(39);
+       if(WZDARK) return(2000);
+        return(2012);
+
+L9073: SPK=38;
+       if(PROP[URN] == 0) return(2011);
+       SPK=209;
+       PROP[URN]=2;
+        return(2011);
+
+/*  EXTINGUISH.  LAMP, URN, DRAGON/VOLCANO (NICE TRY). */
+
+L8080: if(HERE(LAMP) && PROP[LAMP] == 1)OBJ=LAMP;
+       if(HERE(URN) && PROP[URN] == 2)OBJ=OBJ*100+URN;
+       if(OBJ == 0 || OBJ > 100) return(8000);
+
+L9080: if(OBJ == URN) goto L9083;
+       if(OBJ == LAMP) goto L9086;
+       if(OBJ == DRAGON || OBJ == VOLCAN)SPK=146;
+        return(2011);
+
+L9083: PROP[URN]=PROP[URN]/2;
+       SPK=210;
+        return(2011);
+
+L9086: PROP[LAMP]=0;
+       RSPEAK(40);
+       if(DARK(0))RSPEAK(16);
+        return(2012);
+
+/*  WAVE.  NO EFFECT UNLESS WAVING ROD AT FISSURE OR AT BIRD. */
+
+L9090: if((!TOTING(OBJ)) && (OBJ != ROD || !TOTING(ROD2)))SPK=29;
+       if(OBJ != ROD || !TOTING(OBJ) || (!HERE(BIRD) && (CLOSNG || !AT(FISSUR))))
+               return(2011);
+       if(HERE(BIRD))SPK=206+MOD(PROP[BIRD],2);
+       if(SPK == 206 && LOC == PLACE[STEPS] && PROP[JADE] < 0) goto L9094;
+       if(CLOSED) return(18999);
+       if(CLOSNG || !AT(FISSUR)) return(2011);
+       if(HERE(BIRD))RSPEAK(SPK);
+       PROP[FISSUR]=1-PROP[FISSUR];
+       PSPEAK(FISSUR,2-PROP[FISSUR]);
+        return(2012);
+
+L9094: DROP(JADE,LOC);
+       PROP[JADE]=0;
+       TALLY=TALLY-1;
+       SPK=208;
+        return(2011);
+
+/*  ATTACK ALSO MOVED INTO SEPARATE MODULE. */
+
+L9120: return(attack());
+
+/*  POUR.  IF NO OBJECT, OR OBJECT IS BOTTLE, ASSUME CONTENTS OF BOTTLE.
+ *  SPECIAL TESTS FOR POURING WATER OR OIL ON PLANT OR RUSTY DOOR. */
+
+L9130: if(OBJ == BOTTLE || OBJ == 0)OBJ=LIQ(0);
+       if(OBJ == 0) return(8000);
+       if(!TOTING(OBJ)) return(2011);
+       SPK=78;
+       if(OBJ != OIL && OBJ != WATER) return(2011);
+       if(HERE(URN) && PROP[URN] == 0) goto L9134;
+       PROP[BOTTLE]=1;
+       PLACE[OBJ]=0;
+       SPK=77;
+       if(!(AT(PLANT) || AT(DOOR))) return(2011);
+
+       if(AT(DOOR)) goto L9132;
+       SPK=112;
+       if(OBJ != WATER) return(2011);
+       PSPEAK(PLANT,PROP[PLANT]+3);
+       PROP[PLANT]=MOD(PROP[PLANT]+1,3);
+       PROP[PLANT2]=PROP[PLANT];
+       K=NUL;
+        return(8);
+
+L9132: PROP[DOOR]=0;
+       if(OBJ == OIL)PROP[DOOR]=1;
+       SPK=113+PROP[DOOR];
+        return(2011);
+
+L9134: OBJ=URN;
+        goto L9220;
+
+/*  EAT.  INTRANSITIVE: ASSUME FOOD IF PRESENT, ELSE ASK WHAT.  TRANSITIVE: FOOD
+ *  OK, SOME THINGS LOSE APPETITE, REST ARE RIDICULOUS. */
+
+L8140: if(!HERE(FOOD)) return(8000);
+L8142: DSTROY(FOOD);
+       SPK=72;
+        return(2011);
+
+L9140: if(OBJ == FOOD) goto L8142;
+       if(OBJ == BIRD || OBJ == SNAKE || OBJ == CLAM || OBJ == OYSTER || OBJ ==
+               DWARF || OBJ == DRAGON || OBJ == TROLL || OBJ == BEAR || OBJ ==
+               OGRE)SPK=71;
+        return(2011);
+
+/*  DRINK.  IF NO OBJECT, ASSUME WATER AND LOOK FOR IT HERE.  IF WATER IS IN
+ *  THE BOTTLE, DRINK THAT, ELSE MUST BE AT A WATER LOC, SO DRINK STREAM. */
+
+L9150: if(OBJ == 0 && LIQLOC(LOC) != WATER && (LIQ(0) != WATER || !HERE(BOTTLE)))
+               return(8000);
+       if(OBJ == BLOOD) goto L9153;
+       if(OBJ != 0 && OBJ != WATER)SPK=110;
+       if(SPK == 110 || LIQ(0) != WATER || !HERE(BOTTLE)) return(2011);
+       PROP[BOTTLE]=1;
+       PLACE[WATER]=0;
+       SPK=74;
+        return(2011);
+
+L9153: DSTROY(BLOOD);
+       PROP[DRAGON]=2;
+       OBJSND[BIRD]=OBJSND[BIRD]+3;
+       SPK=240;
+        return(2011);
+
+/*  RUB.  YIELDS VARIOUS SNIDE REMARKS EXCEPT FOR LIT URN. */
+
+L9160: if(OBJ != LAMP)SPK=76;
+       if(OBJ != URN || PROP[URN] != 2) return(2011);
+       DSTROY(URN);
+       DROP(AMBER,LOC);
+       PROP[AMBER]=1;
+       TALLY=TALLY-1;
+       DROP(CAVITY,LOC);
+       SPK=216;
+        return(2011);
+
+/*  THROW MOVED INTO SEPARATE MODULE. */
+
+L9170: return(throw());
+
+/*  QUIT.  INTRANSITIVE ONLY.  VERIFY INTENT AND EXIT IF THAT'S WHAT HE WANTS. */
+
+L8180: if(YES(22,54,54)) score(1);
+        return(2012);
+
+/*  FIND.  MIGHT BE CARRYING IT, OR IT MIGHT BE HERE.  ELSE GIVE CAVEAT. */
+
+L9190: if(AT(OBJ) || (LIQ(0) == OBJ && AT(BOTTLE)) || K == LIQLOC(LOC) || (OBJ ==
+               DWARF && ATDWRF(LOC) > 0))SPK=94;
+       if(CLOSED)SPK=138;
+       if(TOTING(OBJ))SPK=24;
+        return(2011);
+
+/*  INVENTORY.  IF OBJECT, TREAT SAME AS FIND.  ELSE REPORT ON CURRENT BURDEN. */
+
+L8200: SPK=98;
+       /* 8201 */ for (I=1; I<=100; I++) {
+       if(I == BEAR || !TOTING(I)) goto L8201;
+       if(SPK == 98)RSPEAK(99);
+       BLKLIN=FALSE;
+       PSPEAK(I,-1);
+       BLKLIN=TRUE;
+       SPK=0;
+L8201: /*etc*/ ;
+       } /* end loop */
+       if(TOTING(BEAR))SPK=141;
+        return(2011);
+
+/* FEED/FILL ARE IN THE OTHER MODULE. */
+
+L9210: return(feed());
+L9220: return(fill());
+
+/*  BLAST.  NO EFFECT UNLESS YOU'VE GOT DYNAMITE, WHICH IS A NEAT TRICK! */
+
+L9230: if(PROP[ROD2] < 0 || !CLOSED) return(2011);
+       BONUS=133;
+       if(LOC == 115)BONUS=134;
+       if(HERE(ROD2))BONUS=135;
+       RSPEAK(BONUS);
+        score(0);
+
+/*  SCORE.  CALL SCORING ROUTINE BUT TELL IT TO RETURN. */
+
+L8240: score(-1);
+       SETPRM(1,SCORE,MXSCOR);
+       SETPRM(3,TURNS,TURNS);
+       RSPEAK(259);
+        return(2012);
+
+/*  FEE FIE FOE FOO (AND FUM).  ADVANCE TO NEXT STATE IF GIVEN IN PROPER ORDER.
+ *  LOOK UP WD1 IN SECTION 3 OF VOCAB TO DETERMINE WHICH WORD WE'VE GOT.  LAST
+ *  WORD ZIPS THE EGGS BACK TO THE GIANT ROOM (UNLESS ALREADY THERE). */
+
+L8250: K=VOCAB(WD1,3);
+       SPK=42;
+       if(FOOBAR == 1-K) goto L8252;
+       if(FOOBAR != 0)SPK=151;
+        return(2011);
+
+L8252: FOOBAR=K;
+       if(K != 4) return(2009);
+       FOOBAR=0;
+       if(PLACE[EGGS] == PLAC[EGGS] || (TOTING(EGGS) && LOC == PLAC[EGGS])) 
+               return(2011);
+/*  BRING BACK TROLL IF WE STEAL THE EGGS BACK FROM HIM BEFORE CROSSING. */
+       if(PLACE[EGGS] == 0 && PLACE[TROLL] == 0 && PROP[TROLL] ==
+               0)PROP[TROLL]=1;
+       K=2;
+       if(HERE(EGGS))K=1;
+       if(LOC == PLAC[EGGS])K=0;
+       MOVE(EGGS,PLAC[EGGS]);
+       PSPEAK(EGGS,K);
+        return(2012);
+
+/*  BRIEF.  INTRANSITIVE ONLY.  SUPPRESS LONG DESCRIPTIONS AFTER FIRST TIME. */
+
+L8260: SPK=156;
+       ABBNUM=10000;
+       DETAIL=3;
+        return(2011);
+
+/*  READ.  PRINT STUFF BASED ON OBJTXT.  OYSTER (?) IS SPECIAL CASE. */
+
+L8270: /* 8275 */ for (I=1; I<=100; I++) {
+L8275: if(HERE(I) && OBJTXT[I] != 0 && PROP[I] >= 0)OBJ=OBJ*100+I;
+       } /* end loop */
+       if(OBJ > 100 || OBJ == 0 || DARK(0)) return(8000);
+
+L9270: if(DARK(0)) goto L5190;
+       if(OBJTXT[OBJ] == 0 || PROP[OBJ] < 0) return(2011);
+       if(OBJ == OYSTER && !CLSHNT) goto L9275;
+       PSPEAK(OBJ,OBJTXT[OBJ]+PROP[OBJ]);
+        return(2012);
+
+L9275: CLSHNT=YES(192,193,54);
+        return(2012);
+
+/*  BREAK.  ONLY WORKS FOR MIRROR IN REPOSITORY AND, OF COURSE, THE VASE. */
+
+L9280: if(OBJ == MIRROR)SPK=148;
+       if(OBJ == VASE && PROP[VASE] == 0) goto L9282;
+       if(OBJ != MIRROR || !CLOSED) return(2011);
+       SPK=197;
+        return(18999);
+
+L9282: SPK=198;
+       if(TOTING(VASE))DROP(VASE,LOC);
+       PROP[VASE]=2;
+       FIXED[VASE]= -1;
+        return(2011);
+
+/*  WAKE.  ONLY USE IS TO DISTURB THE DWARVES. */
+
+L9290: if(OBJ != DWARF || !CLOSED) return(2011);
+       SPK=199;
+        return(18999);
+
+/*  SUSPEND.  OFFER TO SAVE THINGS IN A FILE, BUT CHARGING SOME POINTS (SO
+ *  CAN'T WIN BY USING SAVED GAMES TO RETRY BATTLES OR TO START OVER AFTER
+ *  LEARNING ZZWORD). */
+
+L8300: SPK=201;
+       RSPEAK(260);
+       if(!YES(200,54,54)) return(2012);
+       SAVED=SAVED+5;
+       KK= -1;
+
+/*  THIS NEXT PART IS SHARED WITH THE "RESUME" CODE.  THE TWO CASES ARE
+ *  DISTINGUISHED BY THE VALUE OF KK (-1 FOR SUSPEND, +1 FOR RESUME). */
+
+L8305: DATIME(I,K);
+       K=I+650*K;
+       SAVWRD(KK,K);
+       K=VRSION;
+       SAVWRD(0,K);
+       if(K != VRSION) goto L8312;
+/*  HEREWITH ARE ALL THE VARIABLES WHOSE VALUES CAN CHANGE DURING A GAME,
+ *  OMITTING A FEW (SUCH AS I, J, ATTACK) WHOSE VALUES BETWEEN TURNS ARE
+ *  IRRELEVANT AND SOME WHOSE VALUES WHEN A GAME IS
+ *  SUSPENDED OR RESUMED ARE GUARANTEED TO MATCH.  IF UNSURE WHETHER A VALUE
+ *  NEEDS TO BE SAVED, INCLUDE IT.  OVERKILL CAN'T HURT.  PAD THE LAST SAVWDS
+ *  WITH JUNK VARIABLES TO BRING IT UP TO 7 VALUES. */
+       SAVWDS(ABBNUM,BLKLIN,BONUS,CLOCK1,CLOCK2,CLOSED,CLOSNG);
+       SAVWDS(DETAIL,DFLAG,DKILL,DTOTAL,FOOBAR,HOLDNG,IWEST);
+       SAVWDS(KNFLOC,LIMIT,LL,LMWARN,LOC,NEWLOC,NUMDIE);
+       SAVWDS(OBJ,OLDLC2,OLDLOC,OLDOBJ,PANIC,SAVED,SETUP);
+       SAVWDS(SPK,TALLY,THRESH,TRNDEX,TRNLUZ,TURNS,OBJTXT[OYSTER]);
+       SAVWDS(VERB,WD1,WD1X,WD2,WZDARK,ZZWORD,OBJSND[BIRD]);
+       SAVWDS(OBJTXT[SIGN],CLSHNT,NOVICE,K,K,K,K);
+       SAVARR(ABB,LOCSIZ);
+       SAVARR(ATLOC,LOCSIZ);
+       SAVARR(DLOC,6);
+       SAVARR(DSEEN,6);
+       SAVARR(FIXED,100);
+       SAVARR(HINTED,HNTSIZ);
+       SAVARR(HINTLC,HNTSIZ);
+       SAVARR(LINK,200);
+       SAVARR(ODLOC,6);
+       SAVARR(PLACE,100);
+       SAVARR(PROP,100);
+       SAVWRD(KK,K);
+       if(K != 0) goto L8318;
+       K=NUL;
+       ZZWORD=RNDVOC(3,ZZWORD-MESH*2)+MESH*2;
+       if(KK > 0) return(8);
+       RSPEAK(266);
+       exit(FALSE);
+
+/*  RESUME.  READ A SUSPENDED GAME BACK FROM A FILE. */
+
+L8310: KK=1;
+       if(LOC == 1 && ABB[1] == 1) goto L8305;
+       RSPEAK(268);
+       if(!YES(200,54,54)) return(2012);
+        goto L8305;
+
+L8312: SETPRM(1,K/10,MOD(K,10));
+       SETPRM(3,VRSION/10,MOD(VRSION,10));
+       RSPEAK(269);
+        return(2000);
+
+L8318: RSPEAK(270);
+       exit(FALSE);
+
+/*  FLY.  SNIDE REMARKS UNLESS HOVERING RUG IS HERE. */
+
+L8320: if(PROP[RUG] != 2)SPK=224;
+       if(!HERE(RUG))SPK=225;
+       if(SPK/2 == 112) return(2011);
+       OBJ=RUG;
+
+L9320: if(OBJ != RUG) return(2011);
+       SPK=223;
+       if(PROP[RUG] != 2) return(2011);
+       OLDLC2=OLDLOC;
+       OLDLOC=LOC;
+       NEWLOC=PLACE[RUG]+FIXED[RUG]-LOC;
+       SPK=226;
+       if(PROP[SAPPH] >= 0)SPK=227;
+       RSPEAK(SPK);
+        return(2);
+
+/*  LISTEN.  INTRANSITIVE ONLY.  PRINT STUFF BASED ON OBJSND/LOCSND. */
+
+L8330: SPK=228;
+       K=LOCSND[LOC];
+       if(K == 0) goto L8332;
+       RSPEAK(IABS(K));
+       if(K < 0) return(2012);
+       SPK=0;
+L8332: SETPRM(1,ZZWORD-MESH*2,0);
+       /* 8335 */ for (I=1; I<=100; I++) {
+       if(!HERE(I) || OBJSND[I] == 0 || PROP[I] < 0) goto L8335;
+       PSPEAK(I,OBJSND[I]+PROP[I]);
+       SPK=0;
+       if(I == BIRD && OBJSND[I]+PROP[I] == 8)DSTROY(BIRD);
+L8335: /*etc*/ ;
+       } /* end loop */
+        return(2011);
+
+/*  Z'ZZZ (WORD GETS RECOMPUTED AT STARTUP; DIFFERENT EACH GAME). */
+
+L8340: if(!AT(RESER) && LOC != FIXED[RESER]-1) return(2011);
+       PSPEAK(RESER,PROP[RESER]+1);
+       PROP[RESER]=1-PROP[RESER];
+       if(AT(RESER)) return(2012);
+       OLDLC2=LOC;
+       NEWLOC=0;
+       RSPEAK(241);
+        return(2);
+
+}
diff --git a/actions2.c b/actions2.c
new file mode 100644 (file)
index 0000000..98be045
--- /dev/null
@@ -0,0 +1,352 @@
+#include "misc.h"
+#include "main.h"
+#include "share.h"
+#include "funcs.h"
+
+#define TRUE  (0==0)
+#define FALSE (0!=0)
+
+/*  CARRY AN OBJECT.  SPECIAL CASES FOR BIRD AND CAGE (IF BIRD IN CAGE, CAN'T
+ *  TAKE ONE WITHOUT THE OTHER).  LIQUIDS ALSO SPECIAL, SINCE THEY DEPEND ON
+ *  STATUS OF BOTTLE.  ALSO VARIOUS SIDE EFFECTS, ETC. */
+
+carry() {
+       if(TOTING(OBJ)) return(2011);
+       SPK=25;
+       if(OBJ == PLANT && PROP[PLANT] <= 0)SPK=115;
+       if(OBJ == BEAR && PROP[BEAR] == 1)SPK=169;
+       if(OBJ == CHAIN && PROP[BEAR] != 0)SPK=170;
+       if(OBJ == URN)SPK=215;
+       if(OBJ == CAVITY)SPK=217;
+       if(OBJ == BLOOD)SPK=239;
+       if(OBJ == RUG && PROP[RUG] == 2)SPK=222;
+       if(OBJ == SIGN)SPK=196;
+       if(OBJ != MESSAG) goto L9011;
+       SPK=190;
+       DSTROY(MESSAG);
+L9011: if(FIXED[OBJ] != 0) return(2011);
+       if(OBJ != WATER && OBJ != OIL) goto L9017;
+       K=OBJ;
+       OBJ=BOTTLE;
+       if(HERE(BOTTLE) && LIQ(0) == K) goto L9017;
+       if(TOTING(BOTTLE) && PROP[BOTTLE] == 1) return(fill());
+       if(PROP[BOTTLE] != 1)SPK=105;
+       if(!TOTING(BOTTLE))SPK=104;
+        return(2011);
+L9017: SPK=92;
+       if(HOLDNG >= 7) return(2011);
+       if(OBJ != BIRD || PROP[BIRD] == 1 || -1-PROP[BIRD] == 1) goto L9014;
+       if(PROP[BIRD] == 2) goto L9015;
+       if(!TOTING(CAGE))SPK=27;
+       if(TOTING(ROD))SPK=26;
+       if(SPK/2 == 13) return(2011);
+       PROP[BIRD]=1;
+L9014: if((OBJ == BIRD || OBJ == CAGE) && (PROP[BIRD] == 1 || -1-PROP[BIRD] ==
+               1))CARRY(BIRD+CAGE-OBJ,LOC);
+       CARRY(OBJ,LOC);
+       K=LIQ(0);
+       if(OBJ == BOTTLE && K != 0)PLACE[K]= -1;
+       if(!GSTONE(OBJ) || PROP[OBJ] == 0) return(2009);
+       PROP[OBJ]=0;
+       PROP[CAVITY]=1;
+        return(2009);
+
+L9015: SPK=238;
+       DSTROY(BIRD);
+        return(2011);
+}
+
+/*  DISCARD OBJECT.  "THROW" ALSO COMES HERE FOR MOST OBJECTS.  SPECIAL CASES FOR
+ *  BIRD (MIGHT ATTACK SNAKE OR DRAGON) AND CAGE (MIGHT CONTAIN BIRD) AND VASE.
+ *  DROP COINS AT VENDING MACHINE FOR EXTRA BATTERIES. */
+
+discard(just_do_it)long just_do_it; {
+       if(just_do_it) goto L9021;
+       if(TOTING(ROD2) && OBJ == ROD && !TOTING(ROD))OBJ=ROD2;
+       if(!TOTING(OBJ)) return(2011);
+       if(OBJ != BIRD || !HERE(SNAKE)) goto L9023;
+       RSPEAK(30);
+       if(CLOSED) return(19000);
+       DSTROY(SNAKE);
+/*  SET PROP FOR USE BY TRAVEL OPTIONS */
+       PROP[SNAKE]=1;
+L9021: K=LIQ(0);
+       if(K == OBJ)OBJ=BOTTLE;
+       if(OBJ == BOTTLE && K != 0)PLACE[K]=0;
+       if(OBJ == CAGE && PROP[BIRD] == 1)DROP(BIRD,LOC);
+       DROP(OBJ,LOC);
+       if(OBJ != BIRD) return(2012);
+       PROP[BIRD]=0;
+       if(FOREST(LOC))PROP[BIRD]=2;
+        return(2012);
+
+L9023: if(!(GSTONE(OBJ) && AT(CAVITY) && PROP[CAVITY] != 0)) goto L9024;
+       RSPEAK(218);
+       PROP[OBJ]=1;
+       PROP[CAVITY]=0;
+       if(!HERE(RUG) || !((OBJ == EMRALD && PROP[RUG] != 2) || (OBJ == RUBY &&
+               PROP[RUG] == 2))) goto L9021;
+       SPK=219;
+       if(TOTING(RUG))SPK=220;
+       if(OBJ == RUBY)SPK=221;
+       RSPEAK(SPK);
+       if(SPK == 220) goto L9021;
+       K=2-PROP[RUG];
+       PROP[RUG]=K;
+       if(K == 2)K=PLAC[SAPPH];
+       MOVE(RUG+100,K);
+        goto L9021;
+
+L9024: if(OBJ != COINS || !HERE(VEND)) goto L9025;
+       DSTROY(COINS);
+       DROP(BATTER,LOC);
+       PSPEAK(BATTER,0);
+        return(2012);
+
+L9025: if(OBJ != BIRD || !AT(DRAGON) || PROP[DRAGON] != 0) goto L9026;
+       RSPEAK(154);
+       DSTROY(BIRD);
+       PROP[BIRD]=0;
+        return(2012);
+
+L9026: if(OBJ != BEAR || !AT(TROLL)) goto L9027;
+       RSPEAK(163);
+       MOVE(TROLL,0);
+       MOVE(TROLL+100,0);
+       MOVE(TROLL2,PLAC[TROLL]);
+       MOVE(TROLL2+100,FIXD[TROLL]);
+       JUGGLE(CHASM);
+       PROP[TROLL]=2;
+        goto L9021;
+
+L9027: if(OBJ == VASE && LOC != PLAC[PILLOW]) goto L9028;
+       RSPEAK(54);
+        goto L9021;
+
+L9028: PROP[VASE]=2;
+       if(AT(PILLOW))PROP[VASE]=0;
+       PSPEAK(VASE,PROP[VASE]+1);
+       if(PROP[VASE] != 0)FIXED[VASE]= -1;
+        goto L9021;
+}
+
+/*  ATTACK.  ASSUME TARGET IF UNAMBIGUOUS.  "THROW" ALSO LINKS HERE.  ATTACKABLE
+ *  OBJECTS FALL INTO TWO CATEGORIES: ENEMIES (SNAKE, DWARF, ETC.)  AND OTHERS
+ *  (BIRD, CLAM, MACHINE).  AMBIGUOUS IF 2 ENEMIES, OR NO ENEMIES BUT 2 OTHERS. */
+
+attack() {
+       I=ATDWRF(LOC);
+       if(OBJ != 0) goto L9124;
+       if(I > 0)OBJ=DWARF;
+       if(HERE(SNAKE))OBJ=OBJ*100+SNAKE;
+       if(AT(DRAGON) && PROP[DRAGON] == 0)OBJ=OBJ*100+DRAGON;
+       if(AT(TROLL))OBJ=OBJ*100+TROLL;
+       if(AT(OGRE))OBJ=OBJ*100+OGRE;
+       if(HERE(BEAR) && PROP[BEAR] == 0)OBJ=OBJ*100+BEAR;
+       if(OBJ > 100) return(8000);
+       if(OBJ != 0) goto L9124;
+/*  CAN'T ATTACK BIRD OR MACHINE BY THROWING AXE. */
+       if(HERE(BIRD) && VERB != THROW)OBJ=BIRD;
+       if(HERE(VEND) && VERB != THROW)OBJ=OBJ*100+VEND;
+/*  CLAM AND OYSTER BOTH TREATED AS CLAM FOR INTRANSITIVE CASE; NO HARM DONE. */
+       if(HERE(CLAM) || HERE(OYSTER))OBJ=100*OBJ+CLAM;
+       if(OBJ > 100) return(8000);
+L9124: if(OBJ != BIRD) goto L9125;
+       SPK=137;
+       if(CLOSED) return(2011);
+       DSTROY(BIRD);
+       PROP[BIRD]=0;
+       SPK=45;
+L9125: if(OBJ != VEND) goto L9126;
+       PSPEAK(VEND,PROP[VEND]+2);
+       PROP[VEND]=3-PROP[VEND];
+        return(2012);
+
+L9126: if(OBJ == 0)SPK=44;
+       if(OBJ == CLAM || OBJ == OYSTER)SPK=150;
+       if(OBJ == SNAKE)SPK=46;
+       if(OBJ == DWARF)SPK=49;
+       if(OBJ == DWARF && CLOSED) return(19000);
+       if(OBJ == DRAGON)SPK=167;
+       if(OBJ == TROLL)SPK=157;
+       if(OBJ == OGRE)SPK=203;
+       if(OBJ == OGRE && I > 0) goto L9128;
+       if(OBJ == BEAR)SPK=165+(PROP[BEAR]+1)/2;
+       if(OBJ != DRAGON || PROP[DRAGON] != 0) return(2011);
+/*  FUN STUFF FOR DRAGON.  IF HE INSISTS ON ATTACKING IT, WIN!  SET PROP TO DEAD,
+ *  MOVE DRAGON TO CENTRAL LOC (STILL FIXED), MOVE RUG THERE (NOT FIXED), AND
+ *  MOVE HIM THERE, TOO.  THEN DO A NULL MOTION TO GET NEW DESCRIPTION. */
+       RSPEAK(49);
+       VERB=0;
+       OBJ=0;
+       GETIN(WD1,WD1X,WD2,WD2X);
+       if(WD1 != MAKEWD(25) && WD1 != MAKEWD(250519)) return(2607);
+       PSPEAK(DRAGON,3);
+       PROP[DRAGON]=1;
+       PROP[RUG]=0;
+       K=(PLAC[DRAGON]+FIXD[DRAGON])/2;
+       MOVE(DRAGON+100,-1);
+       MOVE(RUG+100,0);
+       MOVE(DRAGON,K);
+       MOVE(RUG,K);
+       DROP(BLOOD,K);
+       /* 9127 */ for (OBJ=1; OBJ<=100; OBJ++) {
+       if(PLACE[OBJ] == PLAC[DRAGON] || PLACE[OBJ] == FIXD[DRAGON])MOVE(OBJ,K);
+L9127: /*etc*/ ;
+       } /* end loop */
+       LOC=K;
+       K=NUL;
+        return(8);
+
+L9128: RSPEAK(SPK);
+       RSPEAK(6);
+       DSTROY(OGRE);
+       K=0;
+       /* 9129 */ for (I=1; I<=5; I++) {
+       if(DLOC[I] != LOC) goto L9129;
+       K=K+1;
+       DLOC[I]=61;
+       DSEEN[I]=FALSE;
+L9129: /*etc*/ ;
+       } /* end loop */
+       SPK=SPK+1+1/K;
+        return(2011);
+}
+
+/*  THROW.  SAME AS DISCARD UNLESS AXE.  THEN SAME AS ATTACK EXCEPT IGNORE BIRD,
+ *  AND IF DWARF IS PRESENT THEN ONE MIGHT BE KILLED.  (ONLY WAY TO DO SO!)
+ *  AXE ALSO SPECIAL FOR DRAGON, BEAR, AND TROLL.  TREASURES SPECIAL FOR TROLL. */
+
+throw() {
+       if(TOTING(ROD2) && OBJ == ROD && !TOTING(ROD))OBJ=ROD2;
+       if(!TOTING(OBJ)) return(2011);
+       if(OBJ >= 50 && OBJ <= MAXTRS && AT(TROLL)) goto L9178;
+       if(OBJ == FOOD && HERE(BEAR)) goto L9177;
+       if(OBJ != AXE) return(discard(FALSE));
+       I=ATDWRF(LOC);
+       if(I > 0) goto L9172;
+       SPK=152;
+       if(AT(DRAGON) && PROP[DRAGON] == 0) goto L9175;
+       SPK=158;
+       if(AT(TROLL)) goto L9175;
+       SPK=203;
+       if(AT(OGRE)) goto L9175;
+       if(HERE(BEAR) && PROP[BEAR] == 0) goto L9176;
+       OBJ=0;
+       return(attack());
+
+L9172: SPK=48;
+       if(RAN(7) < DFLAG) goto L9175;
+       DSEEN[I]=FALSE;
+       DLOC[I]=0;
+       SPK=47;
+       DKILL=DKILL+1;
+       if(DKILL == 1)SPK=149;
+L9175: RSPEAK(SPK);
+       DROP(AXE,LOC);
+       K=NUL;
+        return(8);
+
+/*  THIS'LL TEACH HIM TO THROW THE AXE AT THE BEAR! */
+L9176: SPK=164;
+       DROP(AXE,LOC);
+       FIXED[AXE]= -1;
+       PROP[AXE]=1;
+       JUGGLE(BEAR);
+        return(2011);
+
+/*  BUT THROWING FOOD IS ANOTHER STORY. */
+L9177: OBJ=BEAR;
+       return(feed());
+
+L9178: SPK=159;
+/*  SNARF A TREASURE FOR THE TROLL. */
+       DROP(OBJ,0);
+       MOVE(TROLL,0);
+       MOVE(TROLL+100,0);
+       DROP(TROLL2,PLAC[TROLL]);
+       DROP(TROLL2+100,FIXD[TROLL]);
+       JUGGLE(CHASM);
+        return(2011);
+}
+
+/*  FEED.  IF BIRD, NO SEED.  SNAKE, DRAGON, TROLL: QUIP.  IF DWARF, MAKE HIM
+ *  MAD.  BEAR, SPECIAL. */
+
+feed() {
+       if(OBJ != BIRD) goto L9212;
+       SPK=100;
+        return(2011);
+
+L9212: if(OBJ != SNAKE && OBJ != DRAGON && OBJ != TROLL) goto L9213;
+       SPK=102;
+       if(OBJ == DRAGON && PROP[DRAGON] != 0)SPK=110;
+       if(OBJ == TROLL)SPK=182;
+       if(OBJ != SNAKE || CLOSED || !HERE(BIRD)) return(2011);
+       SPK=101;
+       DSTROY(BIRD);
+       PROP[BIRD]=0;
+        return(2011);
+
+L9213: if(OBJ != DWARF) goto L9214;
+       if(!HERE(FOOD)) return(2011);
+       SPK=103;
+       DFLAG=DFLAG+2;
+        return(2011);
+
+L9214: if(OBJ != BEAR) goto L9215;
+       if(PROP[BEAR] == 0)SPK=102;
+       if(PROP[BEAR] == 3)SPK=110;
+       if(!HERE(FOOD)) return(2011);
+       DSTROY(FOOD);
+       PROP[BEAR]=1;
+       FIXED[AXE]=0;
+       PROP[AXE]=0;
+       SPK=168;
+        return(2011);
+
+L9215: if(OBJ != OGRE) goto L9216;
+       if(HERE(FOOD))SPK=202;
+        return(2011);
+
+L9216: SPK=14;
+        return(2011);
+}
+
+/*  FILL.  BOTTLE OR URN MUST BE EMPTY, AND LIQUID AVAILABLE.  (VASE IS NASTY.) */
+
+fill() {
+       if(OBJ == VASE) goto L9222;
+       if(OBJ == URN) goto L9224;
+       if(OBJ != 0 && OBJ != BOTTLE) return(2011);
+       if(OBJ == 0 && !HERE(BOTTLE)) return(8000);
+       SPK=107;
+       if(LIQLOC(LOC) == 0)SPK=106;
+       if(HERE(URN) && PROP[URN] != 0)SPK=214;
+       if(LIQ(0) != 0)SPK=105;
+       if(SPK != 107) return(2011);
+       PROP[BOTTLE]=MOD(COND[LOC],4)/2*2;
+       K=LIQ(0);
+       if(TOTING(BOTTLE))PLACE[K]= -1;
+       if(K == OIL)SPK=108;
+        return(2011);
+
+L9222: SPK=29;
+       if(LIQLOC(LOC) == 0)SPK=144;
+       if(LIQLOC(LOC) == 0 || !TOTING(VASE)) return(2011);
+       RSPEAK(145);
+       PROP[VASE]=2;
+       FIXED[VASE]= -1;
+        return(discard(TRUE));
+
+L9224: SPK=213;
+       if(PROP[URN] != 0) return(2011);
+       SPK=144;
+       K=LIQ(0);
+       if(K == 0 || !HERE(BOTTLE)) return(2011);
+       PLACE[K]=0;
+       PROP[BOTTLE]=1;
+       if(K == OIL)PROP[URN]=1;
+       SPK=211+PROP[URN];
+        return(2011);
+}
diff --git a/adventure.text b/adventure.text
new file mode 100644 (file)
index 0000000..5ec4034
--- /dev/null
@@ -0,0 +1,2295 @@
+1
+1      You are standing at the end of a road before a small brick building.
+1      Around you is a forest.  A small stream flows out of the building and
+1      down a gully.
+2      You have walked up a hill, still in the forest.  The road slopes back
+2      down the other side of the hill.  There is a building in the distance.
+3      You are inside a building, a well house for a large spring.
+4      You are in a valley in the forest beside a stream tumbling along a
+4      rocky bed.
+5      The road, which approaches from the east, ends here amid the trees.
+6      The forest thins out here to reveal a steep cliff.  There is no way
+6      down, but a small ledge can be seen to the west across the chasm.
+7      At your feet all the water of the stream splashes into a 2-inch slit
+7      in the rock.  Downstream the streambed is bare rock.
+8      You are in a 20-foot depression floored with bare dirt.  Set into the
+8      dirt is a strong steel grate mounted in concrete.  A dry streambed
+8      leads into the depression.
+9      You are in a small chamber beneath a 3x3 steel grate to the surface.
+9      A low crawl over cobbles leads inward to the west.
+10     You are crawling over cobbles in a low passage.  There is a dim light
+10     at the east end of the passage.
+11     You are in a debris room filled with stuff washed in from the surface.
+11     A low wide passage with cobbles becomes plugged with mud and debris
+11     here, but an awkward canyon leads upward and west.  In the mud someone
+11     has scrawled, "MAGIC WORD XYZZY".
+12     You are in an awkward sloping east/west canyon.
+13     You are in a splendid chamber thirty feet high.  The walls are frozen
+13     rivers of orange stone.  An awkward canyon and a good passage exit
+13     from east and west sides of the chamber.
+14     At your feet is a small pit breathing traces of white mist.  An east
+14     passage ends here except for a small crack leading on.
+15     You are at one end of a vast hall stretching forward out of sight to
+15     the west.  There are openings to either side.  Nearby, a wide stone
+15     staircase leads downward.  The hall is filled with wisps of white mist
+15     swaying to and fro almost as if alive.  A cold wind blows up the
+15     staircase.  There is a passage at the top of a dome behind you.
+16     The crack is far too small for you to follow.  At its widest it is
+16     barely wide enough to admit your foot.
+17     You are on the east bank of a fissure slicing clear across the hall.
+17     The mist is quite thick here, and the fissure is too wide to jump.
+18     This is a low room with a crude note on the wall.  The note says,
+18     "You won't get it up the steps".
+19     You are in the Hall of the Mountain King, with passages off in all
+19     directions.
+20     You are at the bottom of the pit with a broken neck.
+21     You didn't make it.
+22     The dome is unclimbable.
+23     You are at the west end of the Twopit Room.  There is a large hole in
+23     the wall above the pit at this end of the room.
+24     You are at the bottom of the eastern pit in the Twopit Room.  There is
+24     a small pool of oil in one corner of the pit.
+25     You are at the bottom of the western pit in the Twopit Room.  There is
+25     a large hole in the wall about 25 feet above you.
+26     You clamber up the plant and scurry through the hole at the top.
+27     You are on the west side of the fissure in the Hall of Mists.
+28     You are in a low n/s passage at a hole in the floor.  The hole goes
+28     down to an e/w passage.
+29     You are in the south side chamber.
+30     You are in the west side chamber of the Hall of the Mountain King.
+30     A passage continues west and up here.
+31     %!
+32     You can't get by the snake.
+33     You are in a large room, with a passage to the south, a passage to the
+33     west, and a wall of broken rock to the east.  There is a large "Y2" on
+33     a rock in the room's center.
+34     You are in a jumble of rock, with cracks everywhere.
+35     You're at a low window overlooking a huge pit, which extends up out of
+35     sight.  A floor is indistinctly visible over 50 feet below.  Traces of
+35     white mist cover the floor of the pit, becoming thicker to the right.
+35     Marks in the dust around the window would seem to indicate that
+35     someone has been here recently.  Directly across the pit from you and
+35     25 feet away there is a similar window looking into a lighted room.  A
+35     shadowy figure can be seen there peering back at you.
+36     You are in a dirty broken passage.  To the east is a crawl.  To the
+36     west is a large passage.  Above you is a hole to another passage.
+37     You are on the brink of a small clean climbable pit.  A crawl leads
+37     west.
+38     You are in the bottom of a small pit with a little stream, which
+38     enters and exits through tiny slits.
+39     You are in a large room full of dusty rocks.  There is a big hole in
+39     the floor.  There are cracks everywhere, and a passage leading east.
+40     You have crawled through a very low wide passage parallel to and north
+40     of the Hall of Mists.
+41     You are at the west end of the Hall of Mists.  A low wide crawl
+41     continues west and another goes north.  To the south is a little
+41     passage 6 feet off the floor.
+42     You are in a maze of twisty little passages, all alike.
+43     You are in a maze of twisty little passages, all alike.
+44     You are in a maze of twisty little passages, all alike.
+45     You are in a maze of twisty little passages, all alike.
+46     Dead end
+47     Dead end
+48     Dead end
+49     You are in a maze of twisty little passages, all alike.
+50     You are in a maze of twisty little passages, all alike.
+51     You are in a maze of twisty little passages, all alike.
+52     You are in a maze of twisty little passages, all alike.
+53     You are in a maze of twisty little passages, all alike.
+54     Dead end
+55     You are in a maze of twisty little passages, all alike.
+56     Dead end
+57     You are on the brink of a thirty foot pit with a massive orange column
+57     down one wall.  You could climb down here but you could not get back
+57     up.  The maze continues at this level.
+58     Dead end
+59     You have crawled through a very low wide passage parallel to and north
+59     of the Hall of Mists.
+60     You are at the east end of a very long hall apparently without side
+60     chambers.  To the east a low wide crawl slants up.  To the north a
+60     round two foot hole slants down.
+61     You are at the west end of a very long featureless hall.  The hall
+61     joins up with a narrow north/south passage.
+62     You are at a crossover of a high n/s passage and a low e/w one.
+63     Dead end
+64     You are at a complex junction.  A low hands and knees passage from the
+64     north joins a higher crawl from the east to make a walking passage
+64     going west.  There is also a large room above.  The air is damp here.
+65     You are in Bedquilt, a long east/west passage with holes everywhere.
+65     To explore at random select north, south, up, or down.
+66     You are in a room whose walls resemble swiss cheese.  Obvious passages
+66     go west, east, ne, and nw.  Part of the room is occupied by a large
+66     bedrock block.
+67     You are at the east end of the Twopit Room.  The floor here is
+67     littered with thin rock slabs, which make it easy to descend the pits.
+67     There is a path here bypassing the pits to connect passages from east
+67     and west.  There are holes all over, but the only big one is on the
+67     wall directly over the west pit where you can't get to it.
+68     You are in a large low circular chamber whose floor is an immense slab
+68     fallen from the ceiling (Slab Room).  East and west there once were
+68     large passages, but they are now filled with boulders.  Low small
+68     passages go north and south, and the south one quickly bends west
+68     around the boulders.
+69     You are in a secret n/s canyon above a large room.
+70     You are in a secret n/s canyon above a sizable passage.
+71     You are in a secret canyon at a junction of three canyons, bearing
+71     north, south, and se.  The north one is as tall as the other two
+71     combined.
+72     You are in a large low room.  Crawls lead north, se, and sw.
+73     Dead end crawl.
+74     You are in a secret canyon which here runs e/w.  It crosses over a
+74     very tight canyon 15 feet below.  If you go down you may not be able
+74     to get back up.
+75     You are at a wide place in a very tight n/s canyon.
+76     The canyon here becomes too tight to go further south.
+77     You are in a tall e/w canyon.  A low tight crawl goes 3 feet north and
+77     seems to open up.
+78     The canyon runs into a mass of boulders -- dead end.
+79     The stream flows out through a pair of 1 foot diameter sewer pipes.
+79     It would be advisable to use the exit.
+80     You are in a maze of twisty little passages, all alike.
+81     Dead end
+82     Dead end
+83     You are in a maze of twisty little passages, all alike.
+84     You are in a maze of twisty little passages, all alike.
+85     Dead end
+86     Dead end
+87     You are in a maze of twisty little passages, all alike.
+88     You are in a long, narrow corridor stretching out of sight to the
+88     west.  At the eastern end is a hole through which you can see a
+88     profusion of leaves.
+89     There is nothing here to climb.  Use "up" or "out" to leave the pit.
+90     You have climbed up the plant and out of the pit.
+91     You are at the top of a steep incline above a large room.  You could
+91     climb down here, but you would not be able to climb up.  There is a
+91     passage leading back to the north.
+92     You are in the Giant Room.  The ceiling here is too high up for your
+92     lamp to show it.  Cavernous passages lead east, north, and south.  On
+92     the west wall is scrawled the inscription, "FEE FIE FOE FOO" [sic].
+93     The passage here is blocked by a recent cave-in.
+94     You are at one end of an immense north/south passage.
+95     You are in a magnificent cavern with a rushing stream, which cascades
+95     over a sparkling waterfall into a roaring whirlpool which disappears
+95     through a hole in the floor.  Passages exit to the south and west.
+96     You are in the Soft Room.  The walls are covered with heavy curtains,
+96     the floor with a thick pile carpet.  Moss covers the ceiling.
+97     This is the Oriental Room.  Ancient oriental cave drawings cover the
+97     walls.  A gently sloping passage leads upward to the north, another
+97     passage leads se, and a hands and knees crawl leads west.
+98     You are following a wide path around the outer edge of a large cavern.
+98     Far below, through a heavy white mist, strange splashing noises can be
+98     heard.  The mist rises up through a fissure in the ceiling.  The path
+98     exits to the south and west.
+99     You are in an alcove.  A small nw path seems to widen after a short
+99     distance.  An extremely tight tunnel leads east.  It looks like a very
+99     tight squeeze.  An eerie light can be seen at the other end.
+100    You're in a small chamber lit by an eerie green light.  An extremely
+100    narrow tunnel exits to the west.  A dark corridor leads ne.
+101    You're in the dark-room.  A corridor leading south is the only exit.
+102    You are in an arched hall.  A coral passage once continued up and east
+102    from here, but is now blocked by debris.  The air smells of sea water.
+103    You're in a large room carved out of sedimentary rock.  The floor and
+103    walls are littered with bits of shells imbedded in the stone.  A
+103    shallow passage proceeds downward, and a somewhat steeper one leads
+103    up.  A low hands and knees passage enters from the south.
+104    You are in a long sloping corridor with ragged sharp walls.
+105    You are in a cul-de-sac about eight feet across.
+106    You are in an anteroom leading to a large passage to the east.  Small
+106    passages go west and up.  The remnants of recent digging are evident.
+106    A sign in midair here says "Cave under construction beyond this point.
+106    Proceed at own risk.  [Witt Construction Company]"
+107    You are in a maze of twisty little passages, all different.
+108    You are at Witt's End.  Passages lead off in *ALL* directions.
+109    You are in a north/south canyon about 25 feet across.  The floor is
+109    covered by white mist seeping in from the north.  The walls extend
+109    upward for well over 100 feet.  Suspended from some unseen point far
+109    above you, an enormous two-sided mirror is hanging parallel to and
+109    midway between the canyon walls.  (The mirror is obviously provided
+109    for the use of the dwarves who, as you know, are extremely vain.)  A
+109    small window can be seen in either wall, some fifty feet up.
+110    You're at a low window overlooking a huge pit, which extends up out of
+110    sight.  A floor is indistinctly visible over 50 feet below.  Traces of
+110    white mist cover the floor of the pit, becoming thicker to the left.
+110    Marks in the dust around the window would seem to indicate that
+110    someone has been here recently.  Directly across the pit from you and
+110    25 feet away there is a similar window looking into a lighted room.  A
+110    shadowy figure can be seen there peering back at you.
+111    A large stalactite extends from the roof and almost reaches the floor
+111    below.  You could climb down it, and jump from it to the floor, but
+111    having done so you would be unable to reach it to climb back up.
+112    You are in a little maze of twisting passages, all different.
+113    You are at the edge of a large underground reservoir.  An opaque cloud
+113    of white mist fills the room and rises rapidly upward.  The lake is
+113    fed by a stream, which tumbles out of a hole in the wall about 10 feet
+113    overhead and splashes noisily into the water somewhere within the
+113    mist.  There is a passage going back toward the south.
+114    Dead end
+115    You are at the northeast end of an immense room, even larger than the
+115    Giant Room.  It appears to be a repository for the "Adventure"
+115    program.  Massive torches far overhead bathe the room with smoky
+115    yellow light.  Scattered about you can be seen a pile of bottles (all
+115    of them empty), a nursery of young beanstalks murmuring quietly, a bed
+115    of oysters, a bundle of black rods with rusty stars on their ends, and
+115    a collection of brass lanterns.  Off to one side a great many dwarves
+115    are sleeping on the floor, snoring loudly.  A notice nearby reads: "Do
+115    not disturb the dwarves!"  An immense mirror is hanging against one
+115    wall, and stretches to the other end of the room, where various other
+115    sundry objects can be glimpsed dimly in the distance.
+116    You are at the southwest end of the repository.  To one side is a pit
+116    full of fierce green snakes.  On the other side is a row of small
+116    wicker cages, each of which contains a little sulking bird.  In one
+116    corner is a bundle of black rods with rusty marks on their ends.  A
+116    large number of velvet pillows are scattered about on the floor.  A
+116    vast mirror stretches off to the northeast.  At your feet is a large
+116    steel grate, next to which is a sign that reads, "Treasure Vault.
+116    Keys in main office."
+117    You are on one side of a large, deep chasm.  A heavy white mist rising
+117    up from below obscures all view of the far side.  A sw path leads away
+117    from the chasm into a winding corridor.
+118    You are in a long winding corridor sloping out of sight in both
+118    directions.
+119    You are in a secret canyon which exits to the north and east.
+120    You are in a secret canyon which exits to the north and east.
+121    You are in a secret canyon which exits to the north and east.
+122    You are on the far side of the chasm.  A ne path leads away from the
+122    chasm on this side.
+123    You're in a long east/west corridor.  A faint rumbling noise can be
+123    heard in the distance.
+124    The path forks here.  The left fork leads northeast.  A dull rumbling
+124    seems to get louder in that direction.  The right fork leads southeast
+124    down a gentle slope.  The main corridor enters from the west.
+125    The walls are quite warm here.  From the north can be heard a steady
+125    roar, so loud that the entire cave seems to be trembling.  Another
+125    passage leads south, and a low crawl goes east.
+126    You are on the edge of a breath-taking view.  Far below you is an
+126    active volcano, from which great gouts of molten lava come surging
+126    out, cascading back down into the depths.  The glowing rock fills the
+126    farthest reaches of the cavern with a blood-red glare, giving every-
+126    thing an eerie, macabre appearance.  The air is filled with flickering
+126    sparks of ash and a heavy smell of brimstone.  The walls are hot to
+126    the touch, and the thundering of the volcano drowns out all other
+126    sounds.  Embedded in the jagged roof far overhead are myriad twisted
+126    formations composed of pure white alabaster, which scatter the murky
+126    light into sinister apparitions upon the walls.  To one side is a deep
+126    gorge, filled with a bizarre chaos of tortured rock which seems to
+126    have been crafted by the devil himself.  An immense river of fire
+126    crashes out from the depths of the volcano, burns its way through the
+126    gorge, and plummets into a bottomless pit far off to your left.  To
+126    the right, an immense geyser of blistering steam erupts continuously
+126    from a barren island in the center of a sulfurous lake, which bubbles
+126    ominously.  The far right wall is aflame with an incandescence of its
+126    own, which lends an additional infernal splendor to the already
+126    hellish scene.  A dark, foreboding passage exits to the south.
+127    You are in a small chamber filled with large boulders.  The walls are
+127    very warm, causing the air in the room to be almost stifling from the
+127    heat.  The only exit is a crawl heading west, through which is coming
+127    a low rumbling.
+128    You are walking along a gently sloping north/south passage lined with
+128    oddly shaped limestone formations.
+129    You are standing at the entrance to a large, barren room.  A notice
+129    above the entrance reads:  "Caution!  Bear in room!"
+130    You are inside a barren room.  The center of the room is completely
+130    empty except for some dust.  Marks in the dust lead away toward the
+130    far end of the room.  The only exit is the way you came in.
+131    You are in a maze of twisting little passages, all different.
+132    You are in a little maze of twisty passages, all different.
+133    You are in a twisting maze of little passages, all different.
+134    You are in a twisting little maze of passages, all different.
+135    You are in a twisty little maze of passages, all different.
+136    You are in a twisty maze of little passages, all different.
+137    You are in a little twisty maze of passages, all different.
+138    You are in a maze of little twisting passages, all different.
+139    You are in a maze of little twisty passages, all different.
+140    Dead end
+141    You are in a long, rough-hewn, north/south corridor.
+142    There is no way to go that direction.
+143    You are in a large chamber with passages to the west and north.
+144    You are in the ogre's storeroom.  The only exit is to the south.
+145    You are wandering aimlessly through the forest.
+146    You are wandering aimlessly through the forest.
+147    You are wandering aimlessly through the forest.
+148    You are wandering aimlessly through the forest.
+149    You are wandering aimlessly through the forest.
+150    You are wandering aimlessly through the forest.
+151    You are wandering aimlessly through the forest.
+152    You are wandering aimlessly through the forest.
+153    You are wandering aimlessly through the forest.
+154    You are wandering aimlessly through the forest.
+155    You are wandering aimlessly through the forest.
+156    You are wandering aimlessly through the forest.
+157    You are wandering aimlessly through the forest.
+158    You are wandering aimlessly through the forest.
+159    You are wandering aimlessly through the forest.
+160    You are wandering aimlessly through the forest.
+161    You are wandering aimlessly through the forest.
+162    You are wandering aimlessly through the forest.
+163    You are wandering aimlessly through the forest.
+164    You are wandering aimlessly through the forest.
+165    You are wandering aimlessly through the forest.
+166    You are wandering aimlessly through the forest.
+167    You are on a small ledge on one face of a sheer cliff.  There are no
+167    paths away from the ledge.  Across the chasm is a small clearing
+167    surrounded by forest.
+168    You are walking across the bottom of the reservoir.  Walls of water
+168    rear up on either side.  The roar of the water cascading past is
+168    nearly deafening, and the mist is so thick you can barely see.
+169    You are at the northern edge of the reservoir.  A northwest passage
+169    leads sharply up from here.
+170    You are scrambling along a treacherously steep, rocky passage.
+171    You are on a very steep incline, which widens at it goes upward.
+172    You are at the base of a nearly vertical cliff.  There are some
+172    slim footholds which would enable you to climb up, but it looks
+172    extremely dangerous.  Here at the base of the cliff lie the remains
+172    of several earlier adventurers who apparently failed to make it.
+173    You are climbing along a nearly vertical cliff.
+174    Just as you reach the top, your foot slips on a loose rock and you
+174    tumble several hundred feet to join the other unlucky adventurers.
+175    Just as you reach the top, your foot slips on a loose rock and you
+175    make one last desperate grab.  Your luck holds, as does your grip.
+175    With an enormous heave, you lift yourself to the ledge above.
+176    You are on a small ledge at the top of a nearly vertical cliff.
+176    There is a low crawl leading off to the northeast.
+177    You have reached a dead end.
+178    There is now one more gruesome aspect to the spectacular vista.
+179    >>Foof!<<
+180    >>Foof!<<
+181    >>Foof!<<
+182    >>Foof!<<
+183    >>Foof!<<
+184    >>Foof!<<
+-1
+2
+1      You're in front of building.
+2      You're at hill in road.
+3      You're inside building.
+4      You're in valley.
+5      You're at end of road.
+6      You're at cliff.
+7      You're at slit in streambed.
+8      You're outside grate.
+9      You're below the grate.
+10     You're in cobble crawl.
+11     You're in debris room.
+13     You're in bird chamber.
+14     You're at top of small pit.
+15     You're in Hall of Mists.
+17     You're on east bank of fissure.
+18     You're in nugget-of-gold room.
+19     You're in Hall of Mt King.
+23     You're at west end of Twopit Room.
+24     You're in east pit.
+25     You're in west pit.
+27     You're on west bank of fissure.
+28     You're in n/s passage above e/w passage.
+30     You're in the west side chamber.
+33     You're at "Y2".
+35     You're at window on pit.
+36     You're in dirty passage.
+37     You're at brink of small pit.
+38     You're at bottom of pit with stream.
+39     You're in dusty rock room.
+41     You're at west end of Hall of Mists.
+57     You're at brink of pit.
+60     You're at east end of long hall.
+61     You're at west end of long hall.
+64     You're at complex junction.
+65     You're in Bedquilt.
+66     You're in Swiss Cheese Room.
+67     You're at east end of Twopit Room.
+68     You're in Slab Room.
+71     You're at junction of three secret canyons.
+72     You're in large low room.
+74     You're in secret e/w canyon above tight canyon.
+88     You're in narrow corridor.
+91     You're at steep incline above large room.
+92     You're in Giant Room.
+95     You're in cavern with waterfall.
+96     You're in Soft Room.
+97     You're in Oriental Room.
+98     You're in misty cavern.
+99     You're in alcove.
+100    You're in Plover Room.
+101    You're in dark-room.
+102    You're in arched hall.
+103    You're in Shell Room.
+106    You're in anteroom.
+108    You're at Witt's End.
+109    You're in Mirror Canyon.
+110    You're at window on pit.
+111    You're at top of stalactite.
+113    You're at reservoir.
+115    You're at ne end.
+116    You're at sw end.
+117    You're on sw side of chasm.
+118    You're in sloping corridor.
+122    You're on ne side of chasm.
+123    You're in corridor.
+124    You're at fork in path.
+125    You're at junction with warm walls.
+126    You're at breath-taking view.
+127    You're in Chamber of Boulders.
+128    You're in limestone passage.
+129    You're in front of Barren Room.
+130    You're in Barren Room.
+167    You're on ledge.
+168    You're at bottom of reservoir.
+169    You're north of reservoir.
+172    You're at base of cliff.
+176    You're at top of cliff.
+-1
+3
+1      2       2       44      29
+1      3       3       12      19      43
+1      4       5       13      14      46      30
+1      145     6       45
+1      8       63
+2      1       12      43
+2      5       44
+2      164     45
+2      157     46      6
+2      580     30
+3      1       11      32      44
+3      179     62
+3      181     65
+3      79      5       14
+4      1       4       12      45
+4      150     43      6
+4      156     44
+4      7       5       46      30
+4      8       63
+4      745     14
+5      2       2       43      29
+5      1       12
+5      158     46      6
+5      159     44
+5      165     45
+6      161     46      6
+6      163     43
+6      21      39
+7      1       12
+7      4       4       45
+7      150     43      6
+7      154     44
+7      8       5       16      46      63
+7      595     60      14      30      19      3
+8      151     43      6
+8      154     46
+8      153     44
+8      1       12
+8      7       4       13      45
+8      303009  3       19      30
+8      593     3
+9      303008  11      29
+9      593     11
+9      10      17      18      19      44
+9      14      31
+9      11      51
+10     9       11      20      21      43
+10     11      19      22      44      51
+10     14      31
+11     303008  63
+11     9       64
+11     10      17      18      23      24      43
+11     12      25      19      29      44
+11     180     62
+11     14      31
+12     303008  63
+12     9       64
+12     11      30      43      51
+12     13      19      29      44
+12     14      31
+13     303008  63
+13     9       64
+13     11      51
+13     12      25      43
+13     14      23      31      44
+14     303008  63
+14     9       64
+14     11      51
+14     13      23      43
+14     150020  30      31      34
+14     15      30
+14     16      33      44
+15     18      36      46
+15     17      7       38      44
+15     19      10      30      45
+15     150022  29      31      34      35      23      43
+15     14      29
+15     34      55
+16     14      1
+17     15      38      43
+17     312596  39
+17     412021  7
+17     412597  41      42      44      69
+17     27      41
+18     15      38      11      45
+19     15      10      29      43
+19     311028  45      37
+19     311029  46      36
+19     311030  44      7
+19     32      45
+19     35074   49
+19     211032  49
+19     74      66
+20     0       1
+21     0       1
+22     15      1
+23     67      43      42
+23     68      44      61
+23     25      30      31
+23     648     52
+24     67      29      11
+25     23      29      11
+25     524031  56
+25     26      56
+26     88      1
+27     312596  39
+27     412021  7
+27     412597  41      42      43      69
+27     17      41
+27     40      45
+27     41      44
+28     19      38      11      46
+28     33      45      55
+28     36      30      52
+29     19      38      11      45
+30     19      38      11      43
+30     62      44      29
+31     424089  1
+31     90      1
+32     19      1
+33     182     65
+33     28      46
+33     34      43      53      54
+33     35      44
+33     159302  71
+33     183     71
+34     33      30      55
+34     15      29
+35     33      43      55
+35     20      39
+36     37      43      17
+36     28      29      52
+36     39      44
+36     65      70
+37     36      44      17
+37     38      30      31      56
+38     37      56      29      11
+38     595     60      14      30      4       5       3       19
+39     36      43      23
+39     64      30      52      58
+39     65      70
+40     41      1
+41     42      46      29      23      56
+41     27      43
+41     59      45
+41     60      44      17
+42     41      29
+42     42      45
+42     43      43
+42     45      46
+42     80      44
+43     42      44
+43     44      46
+43     45      43
+44     43      43
+44     48      30
+44     50      46
+44     82      45
+45     42      44
+45     43      45
+45     46      43
+45     47      46
+45     87      29      30
+46     45      44      11
+47     45      43      11
+48     44      29      11
+49     50      43
+49     51      44
+50     44      43
+50     49      44
+50     51      30
+50     52      46
+51     49      44
+51     50      29
+51     52      43
+51     53      46
+52     50      44
+52     51      43
+52     52      46
+52     53      29
+52     55      45
+52     86      30
+53     51      44
+53     52      45
+53     54      46
+54     53      44      11
+55     52      44
+55     55      45
+55     56      30
+55     57      43
+56     55      29      11
+57     13      30      56
+57     55      44
+57     58      46
+57     83      45
+57     84      43
+58     57      43      11
+59     27      1
+60     41      43      29      17
+60     61      44
+60     62      45      30      52
+61     60      43
+61     62      45
+61     100107  46
+62     60      44
+62     63      45
+62     30      43
+62     61      46
+63     62      46      11
+64     39      29      56      59
+64     65      44      70
+64     103     45      74
+64     106     43
+65     64      43
+65     66      44
+65     65556   46
+65     68      61
+65     60556   29
+65     70070   29
+65     39      29
+65     50556   45
+65     75072   45
+65     71      45
+65     65556   30
+65     106     30
+66     65      47
+66     67      44
+66     80556   46
+66     77      25
+66     96      43
+66     50556   50
+66     97      72
+67     66      43
+67     23      44      42
+67     24      30      31
+68     23      46
+68     69      29      56
+68     65      45
+69     68      30      61
+69     331120  46
+69     119     46
+69     109     45
+69     113     75
+70     71      45
+70     65      30      23
+70     111     46
+71     65      48
+71     70      46
+71     110     45
+72     65      70
+72     118     49
+72     73      45
+72     97      48      72
+73     72      46      17      11
+74     19      43
+74     331120  44
+74     121     44
+74     75      30
+75     76      46
+75     77      45
+76     75      45
+77     75      43
+77     78      44
+77     66      45      17
+78     77      46
+79     3       1
+80     42      45
+80     80      44
+80     80      46
+80     81      43
+81     80      44      11
+82     44      46      11
+83     57      46
+83     84      43
+83     85      44
+84     57      45
+84     83      44
+84     114     50
+85     83      43      11
+86     52      29      11
+87     45      29      30
+88     25      30      56      43
+88     20      39
+88     92      44      27
+89     25      1
+90     23      1
+91     95      45      73      23
+91     72      30      56
+92     88      46
+92     93      43
+92     94      45
+93     92      46      27      11
+94     92      46      27      23
+94     309095  45      3       73
+94     611     45
+95     94      46      11
+95     92      27
+95     91      44
+96     66      44      11
+97     66      48
+97     72      44      17
+97     98      29      45      73
+98     97      46      72
+98     99      44
+99     98      50      73
+99     301     43      23
+99     100     43
+100    301     44      23      11
+100    99      44
+100    159302  71
+100    184     71
+100    101     47      22
+101    100     46      71      11
+102    103     30      74      11
+103    102     29      38
+103    104     30
+103    114618  46
+103    115619  46
+103    64      46
+104    103     29      74
+104    105     30
+105    104     29      11
+105    103     74
+106    64      29
+106    65      44
+106    108     43
+107    131     46
+107    132     49
+107    133     47
+107    134     48
+107    135     29
+107    136     50
+107    137     43
+107    138     44
+107    139     45
+107    61      30
+108    95556   43      45      46      47      48      49      50      29      30
+108    106     43
+108    626     44
+109    69      46
+109    113     45      75
+110    71      44
+110    20      39
+111    70      45
+111    40050   30      39      56
+111    50053   30
+111    45      30
+112    131     49
+112    132     45
+112    133     43
+112    134     50
+112    135     48
+112    136     47
+112    137     44
+112    138     30
+112    139     29
+112    140     46
+113    109     46      11
+113    445552  45      42      69
+113    168     45
+114    84      48
+115    116     49
+116    115     47
+116    593     30
+117    118     49
+117    233660  41      42      69      47
+117    332661  41
+117    303     41
+117    332021  39
+117    596     39
+118    72      30
+118    117     29
+119    69      45      11
+119    653     43      7
+120    69      45
+120    74      43
+121    74      43      11
+121    653     45      7
+122    123     47
+122    233660  41      42      69      49
+122    303     41
+122    596     39
+122    124     15
+122    126     28
+122    129     40
+123    122     44
+123    124     43      15
+123    126     28
+123    129     40
+124    123     44
+124    125     47      36
+124    128     48      37      30
+124    126     28
+124    129     40
+125    124     46      15
+125    126     45      28
+125    127     43      17
+126    125     46      23      11
+126    124     15
+126    610     30
+126    178     39
+127    125     44      11      17
+127    124     15
+127    126     28
+128    124     45      29      15
+128    129     46      30      40
+128    126     28
+129    128     44      29
+129    124     15
+129    130     43      19      40      3
+129    126     28
+130    129     44      11
+130    124     15
+130    126     28
+131    107     44
+131    132     48
+131    133     50
+131    134     49
+131    135     47
+131    136     29
+131    137     30
+131    138     45
+131    139     46
+131    112     43
+132    107     50
+132    131     29
+132    133     45
+132    134     46
+132    135     44
+132    136     49
+132    137     47
+132    138     43
+132    139     30
+132    112     48
+133    107     29
+133    131     30
+133    132     44
+133    134     47
+133    135     49
+133    136     43
+133    137     45
+133    138     50
+133    139     48
+133    112     46
+134    107     47
+134    131     45
+134    132     50
+134    133     48
+134    135     43
+134    136     30
+134    137     46
+134    138     29
+134    139     44
+134    112     49
+135    107     45
+135    131     48
+135    132     30
+135    133     46
+135    134     43
+135    136     44
+135    137     49
+135    138     47
+135    139     50
+135    112     29
+136    107     43
+136    131     44
+136    132     29
+136    133     49
+136    134     30
+136    135     46
+136    137     50
+136    138     48
+136    139     47
+136    112     45
+137    107     48
+137    131     47
+137    132     46
+137    133     30
+137    134     29
+137    135     50
+137    136     45
+137    138     49
+137    139     43
+137    112     44
+138    107     30
+138    131     43
+138    132     47
+138    133     29
+138    134     44
+138    135     45
+138    136     46
+138    137     48
+138    139     49
+138    112     50
+139    107     49
+139    131     50
+139    132     43
+139    133     44
+139    134     45
+139    135     30
+139    136     48
+139    137     29
+139    138     46
+139    112     47
+140    112     45      11
+140    338141  46
+140    142     46
+141    140     45
+141    143     46
+142    140     1
+143    141     44
+143    241560  45
+143    144     45
+144    143     46      11
+145    1       43
+145    157     44
+145    146     45
+145    147     46
+146    145     43
+146    163     44
+146    147     45
+146    162     46
+147    148     43      44
+147    146     45
+147    145     46
+148    147     43      45
+148    149     44      46
+149    148     43      45
+149    151     44
+149    150     46
+150    149     43
+150    151     44
+150    4       45
+150    7       46
+151    149     43
+151    150     44
+151    8       45
+151    152     46
+152    153     43
+152    155     44
+152    166     45
+152    151     46
+153    155     43
+153    152     44
+153    154     45
+153    8       46
+154    7       43
+154    155     44
+154    153     45
+154    8       46
+155    154     43
+155    152     44
+155    166     45
+155    153     46
+156    157     43
+156    158     44
+156    166     45
+156    4       46
+157    145     43
+157    156     44
+157    164     45
+157    2       46
+158    5       43
+158    160     44
+158    159     45
+158    156     46
+159    160     43
+159    166     44
+159    5       45
+159    158     46
+160    161     43      45
+160    158     44
+160    159     46
+161    162     43
+161    160     44      46
+161    6       45
+162    163     43
+162    161     44
+162    146     45
+162    165     46
+163    146     43
+163    162     44
+163    6       45
+163    164     46
+164    2       43
+164    165     44
+164    163     45
+164    157     46
+165    164     43
+165    5       44
+165    162     45
+165    165     46
+166    152     43
+166    155     44
+166    159     45
+166    156     46
+167    21      39
+168    169     45
+168    113     46
+169    445552  46      42      69
+169    168     46
+169    170     50      29      11
+170    171     29      50
+170    169     30      48
+171    170     30      48
+171    172     29      50
+172    171     30      48
+172    173     29      56
+173    172     30
+173    146175  29
+173    174     29
+174    0       1
+175    176     1
+176    173     56      30
+176    177     47      17
+177    176     49      11      17
+178    0       1
+179    11      1
+180    3       1
+181    33      1
+182    3       1
+183    100     1
+184    33      1
+-1
+4
+2      ROAD
+2      HILL
+3      ENTER
+4      UPSTR
+5      DOWNS
+6      FORES
+7      FORWA
+7      CONTI
+7      ONWAR
+8      BACK
+8      RETUR
+8      RETRE
+9      VALLE
+10     STAIR
+11     OUT
+11     OUTSI
+11     EXIT
+11     LEAVE
+12     BUILD
+12     HOUSE
+13     GULLY
+14     STREA
+15     FORK
+16     BED
+17     CRAWL
+18     COBBL
+19     INWAR
+19     INSID
+19     IN
+20     SURFA
+21     NULL
+21     NOWHE
+22     DARK
+23     PASSA
+23     TUNNE
+24     LOW
+25     CANYO
+26     AWKWA
+27     GIANT
+28     VIEW
+29     UPWAR
+29     UP
+29     U
+29     ABOVE
+29     ASCEN
+30     D
+30     DOWNW
+30     DOWN
+30     DESCE
+31     PIT
+32     OUTDO
+33     CRACK
+34     STEPS
+35     DOME
+36     LEFT
+37     RIGHT
+38     HALL
+39     JUMP
+40     BARRE
+41     OVER
+42     ACROS
+43     EAST
+43     E
+44     WEST
+44     W
+45     NORTH
+45     N
+46     SOUTH
+46     S
+47     NE
+48     SE
+49     SW
+50     NW
+51     DEBRI
+52     HOLE
+53     WALL
+54     BROKE
+55     Y2
+56     CLIMB
+57     LOOK
+57     EXAMI
+57     TOUCH
+57     DESCR
+58     FLOOR
+59     ROOM
+60     SLIT
+61     SLAB
+61     SLABR
+62     XYZZY
+63     DEPRE
+64     ENTRA
+65     PLUGH
+66     SECRE
+67     CAVE
+69     CROSS
+70     BEDQU
+71     PLOVE
+72     ORIEN
+73     CAVER
+74     SHELL
+75     RESER
+76     MAIN
+76     OFFIC
+1001   KEYS
+1001   KEY
+1002   LAMP
+1002   LANTE
+1003   GRATE
+1004   CAGE
+1005   ROD
+1006   ROD     (MUST BE NEXT OBJECT AFTER "REAL" ROD)
+1007   STEPS
+1008   BIRD
+1009   DOOR
+1010   PILLO
+1010   VELVE
+1011   SNAKE
+1012   FISSU
+1013   TABLE
+1014   CLAM
+1015   OYSTE
+1016   MAGAZ
+1016   ISSUE
+1016   SPELU
+1016   "SPEL
+1017   DWARF
+1017   DWARV
+1018   KNIFE
+1018   KNIVE
+1019   FOOD
+1019   RATIO
+1020   BOTTL
+1020   JAR
+1021   WATER
+1021   H2O
+1022   OIL
+1023   MIRRO
+1024   PLANT
+1024   BEANS
+1025   PLANT   (MUST BE NEXT OBJECT AFTER "REAL" PLANT)
+1026   STALA
+1027   SHADO
+1027   FIGUR
+1027   WINDO   (SAME AS FIGURE)
+1028   AXE
+1029   DRAWI
+1030   PIRAT
+1030   GENIE
+1030   DJINN
+1031   DRAGO
+1032   CHASM
+1033   TROLL
+1034   TROLL   (MUST BE NEXT OBJECT AFTER "REAL" TROLL)
+1035   BEAR
+1036   MESSA
+1037   VOLCA
+1037   GEYSE   (SAME AS VOLCANO)
+1038   MACHI
+1038   VENDI
+1039   BATTE
+1040   CARPE
+1040   MOSS
+1040   CURTA   (SAME AS CARPET)
+1041   OGRE
+1042   URN
+1043   CAVIT
+1044   BLOOD
+1045   RESER   (VERB OVERRIDES)
+1046   APPEN
+1046   LEPOR
+1047   MUD
+1048   NOTE
+1049   SIGN
+1050   GOLD
+1050   NUGGE
+1051   DIAMO
+1052   SILVE
+1052   BARS
+1053   JEWEL
+1054   COINS
+1055   CHEST
+1055   BOX
+1055   TREAS
+1056   EGGS
+1056   EGG
+1056   NEST
+1057   TRIDE
+1058   VASE
+1058   MING
+1058   SHARD
+1058   POTTE
+1059   EMERA
+1060   PLATI
+1060   PYRAM
+1061   PEARL
+1062   RUG
+1062   PERSI
+1063   SPICE
+1064   CHAIN
+1065   RUBY
+1066   JADE
+1066   NECKL
+1067   AMBER
+1067   GEMST
+1068   SAPPH
+1069   EBONY
+1069   STATU
+2001   CARRY
+2001   TAKE
+2001   KEEP
+2001   CATCH
+2001   STEAL
+2001   CAPTU
+2001   GET
+2001   TOTE
+2001   SNARF
+2002   DROP
+2002   RELEA
+2002   FREE
+2002   DISCA
+2002   DUMP
+2003   SAY
+2003   CHANT
+2003   SING
+2003   UTTER
+2003   MUMBL
+2004   UNLOC
+2004   OPEN
+2005   NOTHI
+2006   LOCK
+2006   CLOSE
+2007   LIGHT
+2007   ON
+2008   EXTIN
+2008   OFF
+2009   WAVE
+2009   SHAKE
+2009   SWING
+2010   CALM
+2010   PLACA
+2010   TAME
+2011   WALK
+2011   RUN
+2011   TRAVE
+2011   GO
+2011   PROCE
+2011   CONTI
+2011   EXPLO
+2011   FOLLO
+2011   TURN
+2012   ATTAC
+2012   KILL
+2012   FIGHT
+2012   HIT
+2012   STRIK
+2012   SLAY
+2013   POUR
+2014   EAT
+2014   DEVOU
+2015   DRINK
+2016   RUB
+2017   THROW
+2017   TOSS
+2018   QUIT
+2019   FIND
+2019   WHERE
+2020   INVEN
+2021   FEED
+2022   FILL
+2023   BLAST
+2023   DETON
+2023   IGNIT
+2023   BLOWU
+2024   SCORE
+2025   FEE
+2025   FIE
+2025   FOE
+2025   FOO
+2025   FUM
+2026   BRIEF
+2027   READ
+2027   PERUS
+2028   BREAK
+2028   SHATT
+2028   SMASH
+2029   WAKE
+2029   DISTU
+2030   SUSPE
+2030   PAUSE
+2030   SAVE
+2031   RESUM
+2031   RESTA
+2032   FLY
+2033   LISTE
+2034   Z'ZZZ   (GETS REPLACED)
+3001   FEE
+3002   FIE
+3003   FOE
+3004   FOO
+3005   FUM
+3013   THANK
+3050   SESAM
+3050   OPENS
+3050   ABRA
+3050   ABRAC
+3050   SHAZA
+3050   HOCUS
+3050   POCUS
+3051   HELP
+3051   ?
+3054   NO
+3064   TREE
+3064   TREES
+3066   DIG
+3066   EXCAV
+3068   LOST
+3069   MIST
+3079   FUCK
+3139   STOP
+3142   INFO
+3142   INFOR
+3147   SWIM
+3246   WIZAR
+3271   YES
+3275   NEWS
+-1
+5
+1      Set of keys
+000    There are some keys on the ground here.
+2      Brass lantern
+000    There is a shiny brass lamp nearby.
+100    There is a lamp shining nearby.
+3      *grate
+000    The grate is locked.
+100    The grate is open.
+4      Wicker cage
+000    There is a small wicker cage discarded nearby.
+5      Black rod
+000    A three foot black rod with a rusty star on an end lies nearby.
+6      Black rod
+000    A three foot black rod with a rusty mark on an end lies nearby.
+7      *steps
+000    Rough stone steps lead down the pit.
+100    Rough stone steps lead up the dome.
+8      Little bird in cage
+000    A cheerful little bird is sitting here singing.
+100    There is a little bird in the cage.
+200    A cheerful little bird is sitting here singing.
+300    The bird's singing is quite melodious.
+400    The bird does not seem inclined to sing while in the cage.
+500    It almost seems as though the bird is trying to tell you something.
+600    To your surprise, you can understand the bird's chirping; it is
+600    singing about the joys of its forest home.
+700    The bird does not seem inclined to sing while in the cage.
+800    The bird is singing to you in gratitude for your having returned it to
+800    its home.  In return, it informs you of a magic word which it thinks
+800    you may find useful somewhere near the Hall of Mists.  The magic word
+800    changes frequently, but for now the bird believes it is "%W".  You
+800    thank the bird for this information, and it flies off into the forest.
+9      *rusty door
+000    The way north is barred by a massive, rusty, iron door.
+100    The way north leads through a massive, rusty, iron door.
+10     Velvet pillow
+000    A small velvet pillow lies on the floor.
+11     *snake
+000    A huge green fierce snake bars the way!
+100    %!  (chased away)
+200    The snake is hissing venomously.
+12     *fissure
+000    %!
+100    A crystal bridge now spans the fissure.
+200    The crystal bridge has vanished!
+13     *stone tablet
+000    A massive stone tablet imbedded in the wall reads:
+000    "Congratulations on bringing light into the dark-room!"
+100    "Congratulations on bringing light into the dark-room!"
+14     Giant clam  >GRUNT!<
+000    There is an enormous clam here with its shell tightly closed.
+100    The clam is as tight-mouthed as a, er, clam.
+15     Giant oyster  >GROAN!<
+000    There is an enormous oyster here with its shell tightly closed.
+100    Interesting.  There seems to be something written on the underside of
+100    the oyster.
+200    Even though it's an oyster, the critter's as tight-mouthed as a clam.
+300    It says the same thing it did before.  Hm, maybe it's a pun?
+16     "Spelunker Today"
+000    There are a few recent issues of "Spelunker Today" magazine here.
+100    I'm afraid the magazine is written in dwarvish.  But pencilled on one
+100    cover you see, "Please leave the magazines at the construction site."
+19     Tasty food
+000    There is food here.
+20     Small bottle
+000    There is a bottle of water here.
+100    There is an empty bottle here.
+200    There is a bottle of oil here.
+21     Water in the bottle
+22     Oil in the bottle
+23     *mirror
+000    %!
+24     *plant
+000    There is a tiny little plant in the pit, murmuring "water, water, ..."
+100    There is a 12-foot-tall beanstalk stretching up out of the pit,
+100    bellowing "WATER!! WATER!!"
+200    There is a gigantic beanstalk stretching all the way up to the hole.
+300    The plant spurts into furious growth for a few seconds.
+400    The plant grows explosively, almost filling the bottom of the pit.
+500    You've over-watered the plant!  It's shriveling up!  And now . . .
+600    The plant continues to ask plaintively for water.
+700    The plant continues to demand water.
+800    The plant now maintains a contented silence.
+25     *phony plant (seen in Twopit Room only when tall enough)
+000    %!
+100    The top of a 12-foot-tall beanstalk is poking out of the west pit.
+200    There is a huge beanstalk growing out of the west pit up to the hole.
+26     *stalactite
+000    %!
+27     *shadowy figure and/or window
+000    The shadowy figure seems to be trying to attract your attention.
+28     Dwarf's axe
+000    There is a little axe here.
+100    There is a little axe lying beside the bear.
+29     *cave drawings
+000    %!
+30     *pirate/genie
+000    %!  (never present)
+31     *dragon
+000    A huge green fierce dragon bars the way!
+100    The blood-specked body of a huge green dead dragon lies to one side.
+200    The body of a huge green dead dragon is lying off to one side.
+300    Congratulations!  You have just vanquished a dragon with your bare
+300    hands!  (Unbelievable, isn't it?)
+400    The dragon's ominous hissing does not bode well for you.
+500    The dragon is, not surprisingly, silent.
+600    The dragon is, not surprisingly, silent.
+32     *chasm
+000    A rickety wooden bridge extends across the chasm, vanishing into the
+000    mist.  A notice posted on the bridge reads, "Stop! Pay troll!"
+100    The wreckage of a bridge (and a dead bear) can be seen at the bottom
+100    of the chasm.
+33     *troll
+000    A burly troll stands by the bridge and insists you throw him a
+000    treasure before you may cross.
+100    The troll steps out from beneath the bridge and blocks your way.
+200    %!  (chased away)
+300    The troll sounds quite adamant in his demand for a treasure.
+34     *phony troll
+000    The troll is nowhere to be seen.
+35     %!  (bear uses rtext 141)
+000    There is a ferocious cave bear eying you from the far end of the room!
+100    There is a gentle cave bear sitting placidly in one corner.
+200    There is a contented-looking bear wandering about nearby.
+300    %!  (dead)
+36     *message in second maze
+000    There is a message scrawled in the dust in a flowery script, reading:
+000    "This is not the maze where the pirate leaves his treasure chest."
+100    "This is not the maze where the pirate leaves his treasure chest."
+37     *volcano and/or geyser
+000    %!
+38     *vending machine
+000    There is a massive and somewhat battered vending machine here.  The
+000    instructions on it read: "Drop coins here to receive fresh batteries."
+100    "Drop coins here to receive fresh batteries."
+200    As you strike the vending machine, it pivots backward along with a
+200    section of wall, revealing a dark passage leading south.
+300    There is a massive vending machine here, swung back to reveal a
+300    southward passage.
+400    "Drop coins here to receive fresh batteries."
+500    The vending machine swings back to block the passage.
+39     Batteries
+000    There are fresh batteries here.
+100    Some worn-out batteries have been discarded nearby.
+40     *carpet and/or moss and/or curtains
+000    %!
+41     *ogre
+000    A formidable ogre bars the northern exit.
+100    The ogre is apparently the strong, silent type.
+42     *urn
+000    A small urn is embedded in the rock.
+100    A small urn full of oil is embedded in the rock.
+200    A small oil flame extrudes from an urn embedded in the rock.
+43     *cavity
+000    %!  (something in it)
+100    There is a small urn-shaped cavity in the rock.
+44     *blood
+000    %!  (described with dragon)
+45     *reservoir
+000    %!
+100    The waters have parted to form a narrow path across the reservoir.
+200    The waters crash together again.
+46     Leporine appendage
+000    Your keen eye spots a severed leporine appendage lying on the ground.
+47     *mud
+000    %!
+100    "MAGIC WORD XYZZY"
+48     *note
+000    %!
+100    "You won't get it up the steps"
+49     *sign
+000    %!
+100    Cave under construction beyond this point.
+100               Proceed at own risk.
+100           [Witt Construction Company]
+200    "Treasure Vault.  Keys in main office."
+50     Large gold nugget
+000    There is a large sparkling nugget of gold here!
+51     Several diamonds
+000    There are diamonds here!
+52     Bars of silver
+000    There are bars of silver here!
+53     Precious jewelry
+000    There is precious jewelry here!
+54     Rare coins
+000    There are many coins here!
+55     Treasure chest
+000    The pirate's treasure chest is here!
+56     Golden eggs
+000    There is a large nest here, full of golden eggs!
+100    The nest of golden eggs has vanished!
+200    Done!
+57     Jeweled trident
+000    There is a jewel-encrusted trident here!
+58     Ming vase
+000    There is a delicate, precious, ming vase here!
+100    The vase is now resting, delicately, on a velvet pillow.
+200    The floor is littered with worthless shards of pottery.
+300    The ming vase drops with a delicate crash.
+59     Egg-sized emerald
+000    There is an emerald here the size of a plover's egg!
+100    There is an emerald resting in a small cavity in the rock!
+60     Platinum pyramid
+000    There is a platinum pyramid here, 8 inches on a side!
+61     Glistening pearl
+000    Off to one side lies a glistening pearl!
+62     Persian rug
+000    There is a persian rug spread out on the floor!
+100    The dragon is sprawled out on a persian rug!!
+200    There is a persian rug here, hovering in mid-air!
+63     Rare spices
+000    There are rare spices here!
+64     Golden chain
+000    There is a golden chain lying in a heap on the floor!
+100    The bear is locked to the wall with a golden chain!
+200    There is a golden chain locked to the wall!
+65     Giant ruby
+000    There is an enormous ruby here!
+100    There is a ruby resting in a small cavity in the rock!
+66     Jade necklace
+000    A precious jade necklace has been dropped here!
+67     Amber gemstone
+000    There is a rare amber gemstone here!
+100    There is an amber gemstone resting in a small cavity in the rock!
+68     Star sapphire
+000    A brilliant blue star sapphire is here!
+100    There is a star sapphire resting in a small cavity in the rock!
+69     Ebony statuette
+000    There is a richly-carved ebony statuette here!
+-1
+6
+1      Somewhere nearby is Colossal Cave, where others have found fortunes in
+1      treasure and gold, though it is rumored that some who enter are never
+1      seen again.  Magic is said to work in the cave.  I will be your eyes
+1      and hands.  Direct me with commands of 1 or 2 words.  I should warn
+1      you that I look at only the first five letters of each word, so you'll
+1      have to enter "northeast" as "ne" to distinguish it from "north".
+1      You can type "help" for some general hints.  For information on how
+1      to end your adventure, scoring, etc., type "info".
+1                                    - - -
+1      This program was originally developed by Willie Crowther.  Most of the
+1      features of the current program were added by Don Woods.  Contact Don
+1      if you have any questions, comments, etc.
+2      A little dwarf with a big knife blocks your way.
+3      A little dwarf just walked around a corner, saw you, threw a little
+3      axe at you which missed, cursed, and ran away.
+4      There are %1 threatening little dwarves in the room with you.
+5      There is a threatening little dwarf in the room with you!
+6      One sharp nasty knife is thrown at you!
+7      A hollow voice says "PLUGH".
+8      It gets you!
+9      It misses!
+10     I am unsure how you are facing.  Use compass points or nearby objects.
+11     I don't know in from out here.  Use compass points or name something
+11     in the general direction you want to go.
+12     I don't know how to apply that word here.
+13     You're quite welcome.
+14     I'm game.  Would you care to explain how?
+15     Sorry, but I am not allowed to give more detail.  I will repeat the
+15     long description of your location.
+16     It is now pitch dark.  If you proceed you will likely fall into a pit.
+17     If you prefer, simply type w rather than west.
+18     Are you trying to catch the bird?
+19     Something about you seems to be frightening the bird.  Perhaps you
+19     might figure out what it is.
+20     Are you trying to somehow deal with the snake?
+21     You can't kill the snake, or drive it away, or avoid it, or anything
+21     like that.  There is a way to get by, but you don't have the necessary
+21     resources right now.
+22     Do you really want to quit now?
+23     You fell into a pit and broke every bone in your body!
+24     You are already carrying it!
+25     You can't be serious!
+26     The bird seemed unafraid at first, but as you approach it becomes
+26     disturbed and you cannot catch it.
+27     You can catch the bird, but you cannot carry it.
+28     There is nothing here with a lock!
+29     You aren't carrying it!
+30     The little bird attacks the green snake, and in an astounding flurry
+30     drives the snake away.
+31     You have no keys!
+32     It has no lock.
+33     I don't know how to lock or unlock such a thing.
+34     It was already locked.
+35     The grate is now locked.
+36     The grate is now unlocked.
+37     It was already unlocked.
+38     The urn is empty and will not light.
+39     Your lamp is now on.
+40     Your lamp is now off.
+41     There is no way to get past the bear to unlock the chain, which is
+41     probably just as well.
+42     Nothing happens.
+43     Where?
+44     There is nothing here to attack.
+45     The little bird is now dead.  Its body disappears.
+46     Attacking the snake both doesn't work and is very dangerous.
+47     You killed a little dwarf.
+48     You attack a little dwarf, but he dodges out of the way.
+49     With what?  Your bare hands?
+50     Good try, but that is an old worn-out magic word.
+51     I know of places, actions, and things.  Most of my vocabulary
+51     describes places and is used to move you there.  To move, try words
+51     like forest, building, downstream, enter, east, west, north, south,
+51     up, or down.  I know about a few special objects, like a black rod
+51     hidden in the cave.  These objects can be manipulated using some of
+51     the action words that I know.  Usually you will need to give both the
+51     object and action words (in either order), but sometimes I can infer
+51     the object from the verb alone.  Some objects also imply verbs; in
+51     particular, "inventory" implies "take inventory", which causes me to
+51     give you a list of what you're carrying.  Some objects have unexpected
+51     effects; the effects are not always desirable!  Usually people having
+51     trouble moving just need to try a few more words.  Usually people
+51     trying unsuccessfully to manipulate an object are attempting something
+51     beyond their (or my!) capabilities and should try a completely
+51     different tack.  One point often confusing to beginners is that, when
+51     there are several ways to go in a certain direction (e.g., if there
+51     are several holes in a wall), choosing that direction in effect
+51     chooses one of the ways at random; often, though, by specifying the
+51     place you want to reach you can guarantee choosing the right path.
+51     Also, to speed the game you can sometimes move long distances with a
+51     single word.  For example, "building" usually gets you to the building
+51     from anywhere above ground except when lost in the forest.  Also, note
+51     that cave passages and forest paths turn a lot, so leaving one place
+51     heading north doesn't guarantee entering the next from the south.
+51     However (another important point), except when you've used a "long
+51     distance" word such as "building", there is always a way to go back
+51     where you just came from unless I warn you to the contrary, even
+51     though the direction that takes you back might not be the reverse of
+51     what got you here.  Good luck, and have fun!
+52     There is no way to go that direction.
+53     Please stick to 1- and 2-word commands.
+54     OK
+55     You can't unlock the keys.
+56     You have crawled around in some little holes and wound up back in the
+56     main passage.
+57     I don't know where the cave is, but hereabouts no stream can run on
+57     the surface for long.  I would try the stream.
+58     I need more detailed instructions to do that.
+59     I can only tell you what you see as you move about and manipulate
+59     things.  I cannot tell you where remote things are.
+60     The ogre snarls and shoves you back.
+61     Huh?
+62     Are you trying to get into the cave?
+63     The grate is very solid and has a hardened steel lock.  You cannot
+63     enter without a key, and there are no keys nearby.  I would recommend
+63     looking elsewhere for the keys.
+64     The trees of the forest are large hardwood oak and maple, with an
+64     occasional grove of pine or spruce.  There is quite a bit of under-
+64     growth, largely birch and ash saplings plus nondescript bushes of
+64     various sorts.  This time of year visibility is quite restricted by
+64     all the leaves, but travel is quite easy if you detour around the
+64     spruce and berry bushes.
+65     Welcome to Adventure!!  Would you like instructions?
+66     Digging without a shovel is quite impractical.  Even with a shovel
+66     progress is unlikely.
+67     Blasting requires dynamite.
+68     I'm as confused as you are.
+69     Mist is a white vapor, usually water, seen from time to time in
+69     caverns.  It can be found anywhere but is frequently a sign of a deep
+69     pit leading down to water.
+70     Your feet are now wet.
+71     I think I just lost my appetite.
+72     Thank you, it was delicious!
+73     You have taken a drink from the stream.  The water tastes strongly of
+73     minerals, but is not unpleasant.  It is extremely cold.
+74     The bottle of water is now empty.
+75     Rubbing the electric lamp is not particularly rewarding.  Anyway,
+75     nothing exciting happens.
+76     Peculiar.  Nothing unexpected happens.
+77     Your bottle is empty and the ground is wet.
+78     You can't pour that.
+79     Watch it!
+80     Which way?
+81     Oh dear, you seem to have gotten yourself killed.  I might be able to
+81     help you out, but I've never really done this before.  Do you want me
+81     to try to reincarnate you?
+82     All right.  But don't blame me if something goes wr......
+82                         --- POOF!! ---
+82     You are engulfed in a cloud of orange smoke.  Coughing and gasping,
+82     you emerge from the smoke and find....
+83     You clumsy oaf, you've done it again!  I don't know how long I can
+83     keep this up.  Do you want me to try reincarnating you again?
+84     Okay, now where did I put my orange smoke?....  >POOF!<
+84     Everything disappears in a dense cloud of orange smoke.
+85     Now you've really done it!  I'm out of orange smoke!  You don't expect
+85     me to do a decent reincarnation without any orange smoke, do you?
+86     Okay, if you're so smart, do it yourself!  I'm leaving!
+90     >>> messages 81 thru 90 are reserved for "obituaries". <<<
+91     Sorry, but I no longer seem to remember how it was you got here.
+92     You can't carry anything more.  You'll have to drop something first.
+93     You can't go through a locked steel grate!
+94     I believe what you want is right here with you.
+95     You don't fit through a two-inch slit!
+96     I respectfully suggest you go across the bridge instead of jumping.
+97     There is no way across the fissure.
+98     You're not carrying anything.
+99     You are currently holding the following:
+100    It's not hungry (it's merely pinin' for the fjords).  Besides, you
+100    have no bird seed.
+101    The snake has now devoured your bird.
+102    There's nothing here it wants to eat (except perhaps you).
+103    You fool, dwarves eat only coal!  Now you've made him *REALLY* mad!!
+104    You have nothing in which to carry it.
+105    Your bottle is already full.
+106    There is nothing here with which to fill the bottle.
+107    Your bottle is now full of water.
+108    Your bottle is now full of oil.
+109    You can't fill that.
+110    Don't be ridiculous!
+111    The door is extremely rusty and refuses to open.
+112    The plant indignantly shakes the oil off its leaves and asks, "Water?"
+113    The hinges are quite thoroughly rusted now and won't budge.
+114    The oil has freed up the hinges so that the door will now move,
+114    although it requires some effort.
+115    The plant has exceptionally deep roots and cannot be pulled free.
+116    The dwarves' knives vanish as they strike the walls of the cave.
+117    Something you're carrying won't fit through the tunnel with you.
+117    You'd best take inventory and drop something.
+118    You can't fit this five-foot clam through that little passage!
+119    You can't fit this five-foot oyster through that little passage!
+120    I advise you to put down the clam before opening it.  >STRAIN!<
+121    I advise you to put down the oyster before opening it.  >WRENCH!<
+122    You don't have anything strong enough to open the clam.
+123    You don't have anything strong enough to open the oyster.
+124    A glistening pearl falls out of the clam and rolls away.  Goodness,
+124    this must really be an oyster.  (I never was very good at identifying
+124    bivalves.)  Whatever it is, it has now snapped shut again.
+125    The oyster creaks open, revealing nothing but oyster inside.  It
+125    promptly snaps shut again.
+126    You have crawled around in some little holes and found your way
+126    blocked by a recent cave-in.  You are now back in the main passage.
+127    There are faint rustling noises from the darkness behind you.
+128    Out from the shadows behind you pounces a bearded pirate!  "Har, har,"
+128    he chortles, "I'll just take all this booty and hide it away with me
+128    chest deep in the maze!"  He snatches your treasure and vanishes into
+128    the gloom.
+129    A sepulchral voice reverberating through the cave, says, "Cave closing
+129    soon.  All adventurers exit immediately through main office."
+130    A mysterious recorded voice groans into life and announces:
+130       "This exit is closed.  Please leave via main office."
+131    It looks as though you're dead.  Well, seeing as how it's so close to
+131    closing time anyway, I think we'll just call it a day.
+132    The sepulchral voice intones, "The cave is now closed."  As the echoes
+132    fade, there is a blinding flash of light (and a small puff of orange
+132    smoke). . . .    As your eyes refocus, you look around and find...
+133    There is a loud explosion, and a twenty-foot hole appears in the far
+133    wall, burying the dwarves in the rubble.  You march through the hole
+133    and find yourself in the main office, where a cheering band of
+133    friendly elves carry the conquering adventurer off into the sunset.
+134    There is a loud explosion, and a twenty-foot hole appears in the far
+134    wall, burying the snakes in the rubble.  A river of molten lava pours
+134    in through the hole, destroying everything in its path, including you!
+135    There is a loud explosion, and you are suddenly splashed across the
+135    walls of the room.
+136    The resulting ruckus has awakened the dwarves.  There are now several
+136    threatening little dwarves in the room with you!  Most of them throw
+136    knives at you!  All of them get you!
+137    Oh, leave the poor unhappy bird alone.
+138    I daresay whatever you want is around here somewhere.
+139    I don't know the word "stop".  Use "quit" if you want to give up.
+140    You can't get there from here.
+141    You are being followed by a very large, tame bear.
+142    For a summary of the most recent changes to the game, say "news".
+142    If you want to end your adventure early, say "quit".  To suspend your
+142    adventure such that you can continue later, say "suspend" (or "pause"
+142    or "save").  To see how well you're doing, say "score".  To get full
+142    credit for a treasure, you must have left it safely in the building,
+142    though you get partial credit just for locating it.  You lose points
+142    for getting killed, or for quitting, though the former costs you more.
+142    There are also points based on how much (if any) of the cave you've
+142    managed to explore; in particular, there is a large bonus just for
+142    getting in (to distinguish the beginners from the rest of the pack),
+142    and there are other ways to determine whether you've been through some
+142    of the more harrowing sections.  If you think you've found all the
+142    treasures, just keep exploring for a while.  If nothing interesting
+142    happens, you haven't found them all yet.  If something interesting
+142    *DOES* happen (incidentally, there *ARE* ways to hasten things along),
+142    it means you're getting a bonus and have an opportunity to garner many
+142    more points in the Master's section.  I may occasionally offer hints
+142    if you seem to be having trouble.  If I do, I'll warn you in advance
+142    how much it will affect your score to accept the hints.  Finally, to
+142    save time, you may specify "brief", which tells me never to repeat the
+142    full description of a place unless you explicitly ask me to.
+143    Now let's see you do it without suspending in mid-Adventure.
+144    There is nothing here with which to fill it.
+145    The sudden change in temperature has delicately shattered the vase.
+146    It is beyond your power to do that.
+147    I don't know how.
+148    It is too far up for you to reach.
+149    You killed a little dwarf.  The body vanishes in a cloud of greasy
+149    black smoke.
+150    The shell is very strong and is impervious to attack.
+151    What's the matter, can't you read?  Now you'd best start over.
+152    The axe bounces harmlessly off the dragon's thick scales.
+153    The dragon looks rather nasty.  You'd best not try to get by.
+154    The little bird attacks the green dragon, and in an astounding flurry
+154    gets burnt to a cinder.  The ashes blow away.
+155    On what?
+156    Okay, from now on I'll only describe a place in full the first time
+156    you come to it.  To get the full description, say "look".
+157    Trolls are close relatives with the rocks and have skin as tough as
+157    that of a rhinoceros.  The troll fends off your blows effortlessly.
+158    The troll deftly catches the axe, examines it carefully, and tosses it
+158    back, declaring, "Good workmanship, but it's not valuable enough."
+159    The troll catches your treasure and scurries away out of sight.
+160    The troll refuses to let you cross.
+161    There is no longer any way across the chasm.
+162    Just as you reach the other side, the bridge buckles beneath the
+162    weight of the bear, which was still following you around.  You
+162    scrabble desperately for support, but as the bridge collapses you
+162    stumble back and fall into the chasm.
+163    The bear lumbers toward the troll, who lets out a startled shriek and
+163    scurries away.  The bear soon gives up the pursuit and wanders back.
+164    The axe misses and lands near the bear where you can't get at it.
+165    With what?  Your bare hands?  Against *HIS* bear hands??
+166    The bear is confused; he only wants to be your friend.
+167    For crying out loud, the poor thing is already dead!
+168    The bear eagerly wolfs down your food, after which he seems to calm
+168    down considerably and even becomes rather friendly.
+169    The bear is still chained to the wall.
+170    The chain is still locked.
+171    The chain is now unlocked.
+172    The chain is now locked.
+173    There is nothing here to which the chain can be locked.
+174    There is nothing here to eat.
+175    Do you want the hint?
+176    Do you need help getting out of the maze?
+177    You can make the passages look less alike by dropping things.
+178    Are you trying to explore beyond the plover room?
+179    There is a way to explore that region without having to worry about
+179    falling into a pit.  None of the objects available is immediately
+179    useful in discovering the secret.
+180    Do you need help getting out of here?
+181    Don't go west.
+182    Gluttony is not one of the troll's vices.  Avarice, however, is.
+183    Your lamp is getting dim.  You'd best start wrapping this up, unless
+183    you can find some fresh batteries.  I seem to recall there's a vending
+183    machine in the maze.  Bring some coins with you.
+184    Your lamp has run out of power.
+185    Please answer the question.
+186    There are faint rustling noises from the darkness behind you.  As you
+186    turn toward them, the beam of your lamp falls across a bearded pirate.
+186    He is carrying a large chest.  "Shiver me timbers!" he cries, "I've
+186    been spotted!  I'd best hie meself off to the maze to hide me chest!"
+186    With that, he vanishes into the gloom.
+187    Your lamp is getting dim.  You'd best go back for those batteries.
+188    Your lamp is getting dim.  I'm taking the liberty of replacing the
+188    batteries.
+189    Your lamp is getting dim, and you're out of spare batteries.  You'd
+189    best start wrapping this up.
+190    You sift your fingers through the dust, but succeed only in
+190    obliterating the cryptic message.
+191    Do you need help dealing with the ogre?
+192    Hmmm, this looks like a clue, which means it'll cost you 10 points to
+192    read it.  Should I go ahead and read it anyway?
+193    It says, "There is a way out of this place.  Do you need any more
+193    information to escape?  Sorry, but this initial hint is all you get."
+194    There is nothing the presence of which will prevent you from defeating
+194    him; thus it can't hurt to fetch everything you possibly can.
+195    I'm afraid I don't understand.
+196    Your hand passes through it as though it weren't there.
+197    You strike the mirror a resounding blow, whereupon it shatters into a
+197    myriad tiny fragments.
+198    You have taken the vase and hurled it delicately to the ground.
+199    You prod the nearest dwarf, who wakes up grumpily, takes one look at
+199    you, curses, and grabs for his axe.
+200    Is this acceptable?
+201    This adventure is already over.  To start a new adventure, or to
+201    resume an earlier adventure, please run a fresh copy of the program.
+202    The ogre doesn't appear to be hungry.
+203    The ogre, who despite his bulk is quite agile, easily dodges your
+203    attack.  He seems almost amused by your puny effort.
+204    The ogre, distracted by your rush, is struck by the knife.  With a
+204    blood-curdling yell he turns and bounds after the dwarves, who flee
+204    in panic.  You are left alone in the room.
+205    The ogre, distracted by your rush, is struck by the knife.  With a
+205    blood-curdling yell he turns and bounds after the dwarf, who flees
+205    in panic.  You are left alone in the room.
+206    The bird flies about agitatedly for a moment.
+207    The bird flies agitatedly about the cage.
+208    The bird flies about agitatedly for a moment, then disappears through
+208    the crack.  It reappears shortly, carrying in its beak a jade
+208    necklace, which it drops at your feet.
+209    The urn is now lit.
+210    The urn is now dark.
+211    You empty the bottle into the urn, which promptly ejects the water
+211    with uncanny accuracy, squirting you directly between the eyes.
+212    Your bottle is now empty and the urn is full of oil.
+213    The urn is already full of oil.
+214    There's no way to get the oil out of the urn.
+215    The urn is far too firmly embedded for your puny strength to budge it.
+216    As you rub the urn, there is a flash of light and a genie appears.
+216    His aspect is stern as he advises: "One who wouldst traffic in
+216    precious stones must first learn to recognize the signals thereof."
+216    He wrests the urn from the stone, leaving a small cavity.  Turning to
+216    face you again, he fixes you with a steely eye and intones: "Caution!"
+216    Genie and urn vanish in a cloud of amber smoke.  The smoke condenses
+216    to form a rare amber gemstone, resting in the cavity in the rock.
+217    I suppose you collect doughnut holes, too?
+218    The gem fits easily into the cavity.
+219    The persian rug stiffens and rises a foot or so off the ground.
+220    The persian rug draped over your shoulder seems to wriggle for a
+220    moment, but then subsides.
+221    The persian rug settles gently to the ground.
+222    The rug hovers stubbornly where it is.
+223    The rug does not appear inclined to cooperate.
+224    If you mean to use the persian rug, it does not appear inclined to
+224    cooperate.
+225    Though you flap your arms furiously, it is to no avail.
+226    You board the persian rug, which promptly whisks you across the chasm.
+226    You have time for a fleeting glimpse of a two thousand foot drop to a
+226    mighty river; then you find yourself on the other side.
+227    The rug ferries you back across the chasm.
+228    All is silent.
+229    The stream is gurgling placidly.
+230    The wind whistles coldly past your ears.
+231    The stream splashes loudly into the pool.
+232    You are unable to make anything of the splashing noise.
+233    You can hear the murmuring of the beanstalks and the snoring of the
+233    dwarves.
+234    A loud hissing emanates from the snake pit.
+235    The air is filled with a dull rumbling sound.
+236    The roar is quite loud here.
+237    The roaring is so loud that it drowns out all other sound.
+238    The bird eyes you suspiciously and flutters away.  A moment later you
+238    feel something wet land on your head, but upon looking up you can see
+238    no sign of the culprit.
+239    There are only a few drops--not enough to carry.
+240    Your head buzzes strangely for a moment.
+241    (Uh, y'know, that wasn't very bright.)
+242    It's a pity you took so long about it.
+243    Are you wondering what to do here?
+244    This section is quite advanced.  Find the cave first.
+245    Upstream or downstream?
+246    Wizards are not to be disturbed by such as you.
+247    Would you like to be shown out of the forest?
+248    Go east ten times.  If that doesn't get you out, then go south, then
+248    west twice, then south.
+249    The waters are crashing loudly against the shore.
+250    %1 of them throw knives at you!
+251    %1 of them get you!
+252    One of them gets you!
+253    None of them hits you!
+254    Sorry, I don't know the word "%W".
+255    What do you want to do with the %L?
+256    I see no %L here.
+257    %C what?
+258    Okay, "%W".
+259    You have garnered %3 out of a possible %3 points, using %5 turn%S.
+260    I can suspend your Adventure for you so that you can resume later, but
+260    it will cost you 5 points.
+261    I am prepared to give you a hint, but it will cost you %1 point%S.
+262    You scored %3 out of a possible %3, using%5 turn%S.
+263    To achieve the next higher rating, you need %2 more point%S.
+264    To achieve the next higher rating would be a neat trick!
+264    Congratulations!!
+265    You just went off my scale!!
+266    To resume your Adventure, start a new game and then say "RESUME".
+267    Table space used:
+267    %6 of %6 words of messages   %6 of %6 travel options
+267    %6 of %6 vocabulary words    %6 of %6 locations
+267    %6 of %6 objects             %6 of %6 action verbs
+267    %6 of %6 "random" messages   %6 of %6 "class" messages
+267    %6 of %6 hints               %6 of %6 turn threshholds
+268    To resume an earlier Adventure, you must abandon the current one.
+269    I'm sorry, but that Adventure was begun using Version%2.%1 of the
+269    program, and this is Version%2.%1.  You must find the other version
+269    in order to resume that Adventure.
+270    A dark fog creeps in to surround you.  From somewhere in the fog you
+270    hear a stern voice.  "This Adventure has been tampered with!  You have
+270    been dabbling in magic, knowing not the havoc you might cause thereby.
+270    Leave at once, before you do irrevocable harm!"  The fog thickens,
+270    until at last you can see nothing at all.  Your vision then clears,
+270    and you find yourself back in The Real World.
+271    Guess again.
+272    You're missing only one other treasure.  Do you need help finding it?
+273    Once you've found all the other treasures, it is no longer possible to
+273    locate the one you're now missing.
+274    Sorry, but the path twisted and turned so much that I can't figure
+274    out which way to go to get back.
+275    Version 2.5 is essentially the same as Version II; the cave and the
+275    hazards therein are unchanged, and top score is still 430 points.
+275    There are a few more hints, especially for some of the more obscure
+275    puzzles.  There are a few minor bugfixes and cosmetic changes.  You
+275    can now save a game and resume it at once (formerly you had to wait a
+275    while first), but it now costs you a few points each time you save the
+275    game.  Saved games are now stored in much smaller files than before.
+276    You don't have to say "go" every time; just specify a direction or, if
+276    it's nearby, name the place to which you wish to move.
+-1
+7
+1      3
+2      3
+3      8       9
+4      10
+5      11
+6      0
+7      14      15
+8      13
+9      94      -1
+10     96
+11     19      -1
+12     17      27
+13     101     -1
+14     103
+15     0
+16     106
+17     0       -1
+18     0
+19     3
+20     3
+21     0
+22     0
+23     109     -1
+24     25      -1
+25     23      67
+26     111     -1
+27     35      110
+28     0
+29     97      -1
+30     0       -1
+31     119     121
+32     117     122
+33     117     122
+34     0       0
+35     130     -1
+36     0       -1
+37     126     -1
+38     140     -1
+39     0
+40     96      -1
+41     143     -1
+42     6       -1
+43     0       -1
+44     0       -1
+45     113     169
+46     166
+47     11      -1
+48     18      -1
+49     106     -1
+50     18
+51     27
+52     28
+53     29
+54     30
+55     0
+56     92
+57     95
+58     97
+59     100
+60     101
+61     0
+62     119     121
+63     127
+64     130     -1
+65     144
+66     0
+67     0
+68     167
+69     177
+-1
+8
+1      24
+2      29
+3      0
+4      33
+5      0
+6      33
+7      195
+8      195
+9      42
+10     14
+11     43
+12     110
+13     29
+14     110
+15     73
+16     75
+17     29
+18     61
+19     59
+20     59
+21     174
+22     109
+23     67
+24     61
+25     147
+26     155
+27     195
+28     146
+29     110
+30     61
+31     61
+32     14
+33     195
+34     42
+35     61
+-1
+9
+0      1       2       3       4       5       6       7       8       9       10
+0      100     115     116     126     145     146     147     148     149     150
+0      151     152     153     154     155     156     157     158     159     160
+0      161     162     163     164     165     166     167
+2      1       3       4       7       38      95      113     24      168     169
+1      24
+3      46      47      48      54      56      58      82      85      86
+3      122     123     124     125     126     127     128     129     130
+4      6       145     146     147     148     149     150     151     152
+4      153     154     155     156     157     158     159     160     161
+4      162     163     164     165     166     42      43      44      45
+4      49      50      51      52      53      55      57      80      83
+4      84      87      107     112     131     132     133     134     135
+4      136     137     138     139     108
+11     8
+12     13
+13     19
+14     42      43      44      45      46      47      48      49      50      51
+14     52      53      54      55      56      80      81      82      86      87
+15     99      100     101
+16     108
+17     6
+18     145     146     147     148     149     150     151     152     153     154
+18     155     156     157     158     159     160     161     162     163     164
+18     165     166
+19     143
+20     8       15      64      109     126
+-1
+10
+45     You are obviously a rank amateur.  Better luck next time.
+120    Your score qualifies you as a novice class adventurer.
+170    You have achieved the rating: "Experienced Adventurer".
+250    You may now consider yourself a "Seasoned Adventurer".
+320    You have reached "Junior Master" status.
+375    Your score puts you in Master Adventurer Class C.
+410    Your score puts you in Master Adventurer Class B.
+426    Your score puts you in Master Adventurer Class A.
+429    All of Adventuredom gives tribute to you, Adventurer Grandmaster!
+9999   Adventuredom stands in awe -- you have now joined the ranks of the
+9999          W O R L D   C H A M P I O N   A D V E N T U R E R S !
+9999   It may interest you to know that the Dungeon-Master himself has, to
+9999   my knowledge, never achieved this threshhold in fewer than 330 turns.
+-1
+11
+1      4       2       62      63
+2      5       2       18      19
+3      8       2       20      21
+4      75      4       176     177
+5      25      5       178     179
+6      20      3       180     181
+7      8       2       243     244
+8      25      2       247     248
+9      10      4       191     194
+10     1       4       272     273
+-1
+13
+8      3       -1
+11     2       -1
+13     -1      1
+14     1       -1
+15     2       -1
+16     -1      1
+24     6       -1
+31     4       -1
+33     3       -1
+36     -1      1
+38     -1      1
+41     1       -1
+47     -1      1
+48     -1      1
+49     -1      1
+1      229
+3      229
+4      229
+7      229
+15     230
+38     229
+64     230
+94     230
+95     231
+98     232
+109    230
+113    231
+115    233
+116    234
+123    235
+124    235
+125    236
+126    -237
+127    235
+168    -237
+169    249
+-1
+14
+200350 Tsk!  A wizard wouldn't have to take 350 turns.  This is going to cost
+200350 you a couple of points.
+300500 500 turns?  That's another few points you've lost.
+501000 Are you still at it?  Five points off for exceeding 1000 turns!
+1002500 Good grief, don't you *EVER* give up?  Do you realize you've spent
+1002500 over 2500 turns at this?  That's another ten points off, a total of
+1002500 twenty points lost for taking so long.
+-1
+0
diff --git a/copyright b/copyright
new file mode 100644 (file)
index 0000000..df9ea10
--- /dev/null
+++ b/copyright
@@ -0,0 +1,6 @@
+Don Wood's Adventure 2.5: (c) Copyright 1995 by Donald R. Woods.
+
+This software may be freely redistributed if this notice is retained.
+(The author apologises for the style of the code; it is a result of
+running the original Fortran IV source through a home-brew Fortran-to-C
+converter.)
diff --git a/datime.c b/datime.c
new file mode 100644 (file)
index 0000000..0fa30de
--- /dev/null
+++ b/datime.c
@@ -0,0 +1,50 @@
+#ifdef AMIGA
+#define _TIME_
+#include "exec/types.h"
+#include "intuition/intuition.h"
+
+#define INTUITIONREV 1
+
+struct IntuitionBase *IntuitionBase = NULL;
+
+fDATIME(X,Y)int *X, *Y; {
+static int GOTX = 0, GOTY;
+       if(GOTX == 0) {
+               IntuitionBase = (struct IntuitionBase *)
+                       OpenLibrary("intuition.library", INTUITIONREV);
+               if (IntuitionBase == NULL) {
+                       printf("Can't open library.\n");
+                       exit(FALSE);
+                       }
+               CurrentTime(&GOTX, &GOTY);
+               CloseLibrary(IntuitionBase);
+               }
+       GOTY += 654321;
+       if(GOTY >= 1000000) {GOTX += 1; GOTY -= 1000000;}
+       *X = GOTX;
+       *Y = GOTY;
+}
+#endif
+
+#ifdef __MSDOS__
+#define _TIME_
+#include "time.h"
+
+fDATIME(X,Y)long *X, *Y; {
+       time(X); time(Y);
+       *Y /= 2;
+       /* it would be even better if the two numbers were totally
+        * unrelated, like if 'time' returned 64 bits of data */
+}
+#endif
+
+#ifndef _TIME_
+#include "sys/time.h"
+
+fDATIME(X,Y)long *X, *Y; {
+       struct timeval now;
+       gettimeofday(&now, 0);
+       *X = now.tv_sec;
+       *Y = now.tv_usec;
+}
+#endif
diff --git a/funcs.h b/funcs.h
new file mode 100644 (file)
index 0000000..0daecee
--- /dev/null
+++ b/funcs.h
@@ -0,0 +1,40 @@
+/*  STATEMENT FUNCTIONS
+ *
+ *  AT(OBJ)    = TRUE IF ON EITHER SIDE OF TWO-PLACED OBJECT
+ *  CNDBIT(L,N) = TRUE IF COND(L) HAS BIT N SET (BIT 0 IS UNITS BIT)
+ *  DARK(DUMMY) = TRUE IF LOCATION "LOC" IS DARK
+ *  FORCED(LOC) = TRUE IF LOC MOVES WITHOUT ASKING FOR INPUT (COND=2)
+ *  FOREST(LOC)  = TRUE IF LOC IS PART OF THE FOREST
+ *  GSTONE(OBJ)  = TRUE IF OBJ IS A GEMSTONE
+ *  HERE(OBJ)  = TRUE IF THE OBJ IS AT "LOC" (OR IS BEING CARRIED)
+ *  LIQ(DUMMY) = OBJECT NUMBER OF LIQUID IN BOTTLE
+ *  LIQLOC(LOC) = OBJECT NUMBER OF LIQUID (IF ANY) AT LOC
+ *  PCT(N)       = TRUE N% OF THE TIME (N INTEGER FROM 0 TO 100)
+ *  TOTING(OBJ) = TRUE IF THE OBJ IS BEING CARRIED */
+
+#define TOTING(OBJ)    (PLACE[OBJ] == -1)
+#define AT(OBJ) (PLACE[OBJ] == LOC || FIXED[OBJ] == LOC)
+#define HERE(OBJ)      (AT(OBJ) || TOTING(OBJ))
+#define LIQ2(PBOTL)    ((1-(PBOTL))*WATER+((PBOTL)/2)*(WATER+OIL))
+#define LIQ(DUMMY)     (LIQ2(PROP[BOTTLE]<0 ? -1-PROP[BOTTLE] : PROP[BOTTLE]))
+#define LIQLOC(LOC)    (LIQ2((MOD(COND[LOC]/2*2,8)-5)*MOD(COND[LOC]/4,2)+1))
+#define CNDBIT(L,N)    (TSTBIT(COND[L],N))
+#define FORCED(LOC)    (COND[LOC] == 2)
+#define DARK(DUMMY)    ((!CNDBIT(LOC,0)) && (PROP[LAMP] == 0 || !HERE(LAMP)))
+#define PCT(N) (RAN(100) < (N))
+#define GSTONE(OBJ)    ((OBJ) == EMRALD || (OBJ) == RUBY || (OBJ) == AMBER || (OBJ) == SAPPH)
+#define FOREST(LOC)    ((LOC) >= 145 && (LOC) <= 166)
+#define VOCWRD(LETTRS,SECT)    (VOCAB(MAKEWD(LETTRS),SECT))
+
+/*  THE FOLLOWING TWO FUNCTIONS WERE ADDED TO FIX A BUG (CLOCK1 DECREMENTED
+ *  WHILE IN FOREST).  THEY SHOULD PROBABLY BE REPLACED BY USING ANOTHER
+ *  "COND" BIT.  FOR NOW, HOWEVER, A QUICK FIX...  OUTSID(LOC) IS TRUE IF
+ *  LOC IS OUTSIDE, INDEEP(LOC) IS TRUE IF LOC IS "DEEP" IN THE CAVE (HALL
+ *  OF MISTS OR DEEPER).  NOTE SPECIAL KLUDGES FOR "FOOF" LOCS. */
+
+#define OUTSID(LOC)    ((LOC) <= 8 || FOREST(LOC) || (LOC) == PLAC[SAPPH] || (LOC) == 180 || (LOC) == 182)
+#define INDEEP(LOC)    ((LOC) >= 15 && !OUTSID(LOC) && (LOC) != 179)
+
+
+
+
diff --git a/init.c b/init.c
new file mode 100644 (file)
index 0000000..6b2edea
--- /dev/null
+++ b/init.c
@@ -0,0 +1,708 @@
+#include "misc.h"
+#include "main.h"
+#include "share.h"
+#include "funcs.h"
+#include <stdio.h>
+
+#define TRUE  (0==0)
+#define FALSE (0!=0)
+
+/*
+ * INITIALISATION
+ */
+
+/*  CURRENT LIMITS:
+ *     12500 WORDS OF MESSAGE TEXT (LINES, LINSIZ).
+ *     885 TRAVEL OPTIONS (TRAVEL, TRVSIZ).
+ *     330 VOCABULARY WORDS (KTAB, ATAB, TABSIZ).
+ *     185 LOCATIONS (LTEXT, STEXT, KEY, COND, ABB, ATLOC, LOCSND, LOCSIZ).
+ *     100 OBJECTS (PLAC, PLACE, FIXD, FIXED, LINK (TWICE), PTEXT, PROP,
+ *                    OBJSND, OBJTXT).
+ *      35 "ACTION" VERBS (ACTSPK, VRBSIZ).
+ *     277 RANDOM MESSAGES (RTEXT, RTXSIZ).
+ *      12 DIFFERENT PLAYER CLASSIFICATIONS (CTEXT, CVAL, CLSMAX).
+ *      20 HINTS (HINTLC, HINTED, HINTS, HNTSIZ).
+ *         5 "# OF TURNS" THRESHHOLDS (TTEXT, TRNVAL, TRNSIZ).
+ *  THERE ARE ALSO LIMITS WHICH CANNOT BE EXCEEDED DUE TO THE STRUCTURE OF
+ *  THE DATABASE.  (E.G., THE VOCABULARY USES N/1000 TO DETERMINE WORD TYPE,
+ *  SO THERE CAN'T BE MORE THAN 1000 WORDS.)  THESE UPPER LIMITS ARE:
+ *     1000 NON-SYNONYMOUS VOCABULARY WORDS
+ *     300 LOCATIONS
+ *     100 OBJECTS */
+
+
+/*  DESCRIPTION OF THE DATABASE FORMAT
+ *
+ *
+ *  THE DATA FILE CONTAINS SEVERAL SECTIONS.  EACH BEGINS WITH A LINE CONTAINING
+ *  A NUMBER IDENTIFYING THE SECTION, AND ENDS WITH A LINE CONTAINING "-1".
+ *
+ *  SECTION 1: LONG FORM DESCRIPTIONS.  EACH LINE CONTAINS A LOCATION NUMBER,
+ *     A TAB, AND A LINE OF TEXT.  THE SET OF (NECESSARILY ADJACENT) LINES
+ *     WHOSE NUMBERS ARE X FORM THE LONG DESCRIPTION OF LOCATION X.
+ *  SECTION 2: SHORT FORM DESCRIPTIONS.  SAME FORMAT AS LONG FORM.  NOT ALL
+ *     PLACES HAVE SHORT DESCRIPTIONS.
+ *  SECTION 3: TRAVEL TABLE.  EACH LINE CONTAINS A LOCATION NUMBER (X), A SECOND
+ *     LOCATION NUMBER (Y), AND A LIST OF MOTION NUMBERS (SEE SECTION 4).
+ *     EACH MOTION REPRESENTS A VERB WHICH WILL GO TO Y IF CURRENTLY AT X.
+ *     Y, IN TURN, IS INTERPRETED AS FOLLOWS.  LET M=Y/1000, N=Y MOD 1000.
+ *             IF N<=300       IT IS THE LOCATION TO GO TO.
+ *             IF 300<N<=500   N-300 IS USED IN A COMPUTED GOTO TO
+ *                                     A SECTION OF SPECIAL CODE.
+ *             IF N>500        MESSAGE N-500 FROM SECTION 6 IS PRINTED,
+ *                                     AND HE STAYS WHEREVER HE IS.
+ *     MEANWHILE, M SPECIFIES THE CONDITIONS ON THE MOTION.
+ *             IF M=0          IT'S UNCONDITIONAL.
+ *             IF 0<M<100      IT IS DONE WITH M% PROBABILITY.
+ *             IF M=100        UNCONDITIONAL, BUT FORBIDDEN TO DWARVES.
+ *             IF 100<M<=200   HE MUST BE CARRYING OBJECT M-100.
+ *             IF 200<M<=300   MUST BE CARRYING OR IN SAME ROOM AS M-200.
+ *             IF 300<M<=400   PROP(M MOD 100) MUST *NOT* BE 0.
+ *             IF 400<M<=500   PROP(M MOD 100) MUST *NOT* BE 1.
+ *             IF 500<M<=600   PROP(M MOD 100) MUST *NOT* BE 2, ETC.
+ *     IF THE CONDITION (IF ANY) IS NOT MET, THEN THE NEXT *DIFFERENT*
+ *     "DESTINATION" VALUE IS USED (UNLESS IT FAILS TO MEET *ITS* CONDITIONS,
+ *     IN WHICH CASE THE NEXT IS FOUND, ETC.).  TYPICALLY, THE NEXT DEST WILL
+ *     BE FOR ONE OF THE SAME VERBS, SO THAT ITS ONLY USE IS AS THE ALTERNATE
+ *     DESTINATION FOR THOSE VERBS.  FOR INSTANCE:
+ *             15      110022  29      31      34      35      23      43
+ *             15      14      29
+ *     THIS SAYS THAT, FROM LOC 15, ANY OF THE VERBS 29, 31, ETC., WILL TAKE
+ *     HIM TO 22 IF HE'S CARRYING OBJECT 10, AND OTHERWISE WILL GO TO 14.
+ *             11      303008  49
+ *             11      9       50
+ *     THIS SAYS THAT, FROM 11, 49 TAKES HIM TO 8 UNLESS PROP(3)=0, IN WHICH
+ *     CASE HE GOES TO 9.  VERB 50 TAKES HIM TO 9 REGARDLESS OF PROP(3).
+ *  SECTION 4: VOCABULARY.  EACH LINE CONTAINS A NUMBER (N), A TAB, AND A
+ *     FIVE-LETTER WORD.  CALL M=N/1000.  IF M=0, THEN THE WORD IS A MOTION
+ *     VERB FOR USE IN TRAVELLING (SEE SECTION 3).  ELSE, IF M=1, THE WORD IS
+ *     AN OBJECT.  ELSE, IF M=2, THE WORD IS AN ACTION VERB (SUCH AS "CARRY"
+ *     OR "ATTACK").  ELSE, IF M=3, THE WORD IS A SPECIAL CASE VERB (SUCH AS
+ *     "DIG") AND N MOD 1000 IS AN INDEX INTO SECTION 6.  OBJECTS FROM 50 TO
+ *     (CURRENTLY, ANYWAY) 79 ARE CONSIDERED TREASURES (FOR PIRATE, CLOSEOUT).
+ *  SECTION 5: OBJECT DESCRIPTIONS.  EACH LINE CONTAINS A NUMBER (N), A TAB,
+ *     AND A MESSAGE.  IF N IS FROM 1 TO 100, THE MESSAGE IS THE "INVENTORY"
+ *     MESSAGE FOR OBJECT N.  OTHERWISE, N SHOULD BE 000, 100, 200, ETC., AND
+ *     THE MESSAGE SHOULD BE THE DESCRIPTION OF THE PRECEDING OBJECT WHEN ITS
+ *     PROP VALUE IS N/100.  THE N/100 IS USED ONLY TO DISTINGUISH MULTIPLE
+ *     MESSAGES FROM MULTI-LINE MESSAGES; THE PROP INFO ACTUALLY REQUIRES ALL
+ *     MESSAGES FOR AN OBJECT TO BE PRESENT AND CONSECUTIVE.  PROPERTIES WHICH
+ *     PRODUCE NO MESSAGE SHOULD BE GIVEN THE MESSAGE ">$<".
+ *  SECTION 6: ARBITRARY MESSAGES.  SAME FORMAT AS SECTIONS 1, 2, AND 5, EXCEPT
+ *     THE NUMBERS BEAR NO RELATION TO ANYTHING (EXCEPT FOR SPECIAL VERBS
+ *     IN SECTION 4).
+ *  SECTION 7: OBJECT LOCATIONS.  EACH LINE CONTAINS AN OBJECT NUMBER AND ITS
+ *     INITIAL LOCATION (ZERO (OR OMITTED) IF NONE).  IF THE OBJECT IS
+ *     IMMOVABLE, THE LOCATION IS FOLLOWED BY A "-1".  IF IT HAS TWO LOCATIONS
+ *     (E.G. THE GRATE) THE FIRST LOCATION IS FOLLOWED WITH THE SECOND, AND
+ *     THE OBJECT IS ASSUMED TO BE IMMOVABLE.
+ *  SECTION 8: ACTION DEFAULTS.  EACH LINE CONTAINS AN "ACTION-VERB" NUMBER AND
+ *     THE INDEX (IN SECTION 6) OF THE DEFAULT MESSAGE FOR THE VERB.
+ *  SECTION 9: LOCATION ATTRIBUTES.  EACH LINE CONTAINS A NUMBER (N) AND UP TO
+ *     20 LOCATION NUMBERS.  BIT N (WHERE 0 IS THE UNITS BIT) IS SET IN
+ *     COND(LOC) FOR EACH LOC GIVEN.  THE COND BITS CURRENTLY ASSIGNED ARE:
+ *             0       LIGHT
+ *             1       IF BIT 2 IS ON: ON FOR OIL, OFF FOR WATER
+ *             2       LIQUID ASSET, SEE BIT 1
+ *             3       PIRATE DOESN'T GO HERE UNLESS FOLLOWING PLAYER
+ *             4       CANNOT USE "BACK" TO MOVE AWAY
+ *     BITS PAST 10 INDICATE AREAS OF INTEREST TO "HINT" ROUTINES:
+ *             11      TRYING TO GET INTO CAVE
+ *             12      TRYING TO CATCH BIRD
+ *             13      TRYING TO DEAL WITH SNAKE
+ *             14      LOST IN MAZE
+ *             15      PONDERING DARK ROOM
+ *             16      AT WITT'S END
+ *             17      CLIFF WITH URN
+ *             18      LOST IN FOREST
+ *             19      TRYING TO DEAL WITH OGRE
+ *             20      FOUND ALL TREASURES EXCEPT JADE
+ *     COND(LOC) IS SET TO 2, OVERRIDING ALL OTHER BITS, IF LOC HAS FORCED
+ *     MOTION.
+ *  SECTION 10: CLASS MESSAGES.  EACH LINE CONTAINS A NUMBER (N), A TAB, AND A
+ *     MESSAGE DESCRIBING A CLASSIFICATION OF PLAYER.  THE SCORING SECTION
+ *     SELECTS THE APPROPRIATE MESSAGE, WHERE EACH MESSAGE IS CONSIDERED TO
+ *     APPLY TO PLAYERS WHOSE SCORES ARE HIGHER THAN THE PREVIOUS N BUT NOT
+ *     HIGHER THAN THIS N.  NOTE THAT THESE SCORES PROBABLY CHANGE WITH EVERY
+ *     MODIFICATION (AND PARTICULARLY EXPANSION) OF THE PROGRAM.
+ *  SECTION 11: HINTS.  EACH LINE CONTAINS A HINT NUMBER (ADD 10 TO GET COND
+ *     BIT; SEE SECTION 9), THE NUMBER OF TURNS HE MUST BE AT THE RIGHT LOC(S)
+ *     BEFORE TRIGGERING THE HINT, THE POINTS DEDUCTED FOR TAKING THE HINT,
+ *     THE MESSAGE NUMBER (SECTION 6) OF THE QUESTION, AND THE MESSAGE NUMBER
+ *     OF THE HINT.  THESE VALUES ARE STASHED IN THE "HINTS" ARRAY.  HNTMAX IS
+ *     SET TO THE MAX HINT NUMBER (<= HNTSIZ).
+ *  SECTION 12: UNUSED IN THIS VERSION.
+ *  SECTION 13: SOUNDS AND TEXT.  EACH LINE CONTAINS EITHER 2 OR 3 NUMBERS.  IF
+ *     2 (CALL THEM N AND S), N IS A LOCATION AND MESSAGE ABS(S) FROM SECTION
+ *     6 IS THE SOUND HEARD THERE.  IF S<0, THE SOUND THERE DROWNS OUT ALL
+ *     OTHER NOISES.  IF 3 NUMBERS (CALL THEM N, S, AND T), N IS AN OBJECT
+ *     NUMBER AND S+PROP(N) IS THE PROPERTY MESSAGE (FROM SECTION 5) IF HE
+ *     LISTENS TO THE OBJECT, AND T+PROP(N) IS THE TEXT IF HE READS IT.  IF
+ *     S OR T IS -1, THE OBJECT HAS NO SOUND OR TEXT, RESPECTIVELY.  NEITHER
+ *     S NOR T IS ALLOWED TO BE 0.
+ *  SECTION 14: TURN THRESHHOLDS.  EACH LINE CONTAINS A NUMBER (N), A TAB, AND
+ *     A MESSAGE BERATING THE PLAYER FOR TAKING SO MANY TURNS.  THE MESSAGES
+ *     MUST BE IN THE PROPER (ASCENDING) ORDER.  THE MESSAGE GETS PRINTED IF
+ *     THE PLAYER EXCEEDS N MOD 100000 TURNS, AT WHICH TIME N/100000 POINTS
+ *     GET DEDUCTED FROM HIS SCORE.
+ *  SECTION 0: END OF DATABASE. */
+
+/*  THE VARIOUS MESSAGES (SECTIONS 1, 2, 5, 6, ETC.) MAY INCLUDE CERTAIN
+ *  SPECIAL CHARACTER SEQUENCES TO DENOTE THAT THE PROGRAM MUST PROVIDE
+ *  PARAMETERS TO INSERT INTO A MESSAGE WHEN THE MESSAGE IS PRINTED.  THESE
+ *  SEQUENCES ARE:
+ *     %S = THE LETTER 'S' OR NOTHING (IF A GIVEN VALUE IS EXACTLY 1)
+ *     %W = A WORD (UP TO 10 CHARACTERS)
+ *     %L = A WORD MAPPED TO LOWER-CASE LETTERS
+ *     %U = A WORD MAPPED TO UPPER-CASE LETTERS
+ *     %C = A WORD MAPPED TO LOWER-CASE, FIRST LETTER CAPITALISED
+ *     %T = SEVERAL WORDS OF TEXT, ENDING WITH A WORD OF -1
+ *     %1 = A 1-DIGIT NUMBER
+ *     %2 = A 2-DIGIT NUMBER
+ *     ...
+ *     %9 = A 9-DIGIT NUMBER
+ *     %B = VARIABLE NUMBER OF BLANKS
+ *     %! = THE ENTIRE MESSAGE SHOULD BE SUPPRESSED */
+
+initialise() {
+       printf("Initialising...\n");
+       if(!quick_init()){raw_init(); report(); quick_save();}
+       finish_init();
+}
+
+static raw_init() {
+       printf("Couldn't find adventure.data, using adventure.text...\n");
+
+/*  CLEAR OUT THE VARIOUS TEXT-POINTER ARRAYS.  ALL TEXT IS STORED IN ARRAY
+ *  LINES; EACH LINE IS PRECEDED BY A WORD POINTING TO THE NEXT POINTER (I.E.
+ *  THE WORD FOLLOWING THE END OF THE LINE).  THE POINTER IS NEGATIVE IF THIS IS
+ *  FIRST LINE OF A MESSAGE.  THE TEXT-POINTER ARRAYS CONTAIN INDICES OF
+ *  POINTER-WORDS IN LINES.  STEXT(N) IS SHORT DESCRIPTION OF LOCATION N.
+ *  LTEXT(N) IS LONG DESCRIPTION.  PTEXT(N) POINTS TO MESSAGE FOR PROP(N)=0.
+ *  SUCCESSIVE PROP MESSAGES ARE FOUND BY CHASING POINTERS.  RTEXT CONTAINS
+ *  SECTION 6'S STUFF.  CTEXT(N) POINTS TO A PLAYER-CLASS MESSAGE.  TTEXT IS FOR
+ *  SECTION 14.  WE ALSO CLEAR COND (SEE DESCRIPTION OF SECTION 9 FOR DETAILS). */
+
+       /* 1001 */ for (I=1; I<=300; I++) {
+       if(I <= 100)PTEXT[I]=0;
+       if(I <= RTXSIZ)RTEXT[I]=0;
+       if(I <= CLSMAX)CTEXT[I]=0;
+       if(I <= 100)OBJSND[I]=0;
+       if(I <= 100)OBJTXT[I]=0;
+       if(I > LOCSIZ) goto L1001;
+       STEXT[I]=0;
+       LTEXT[I]=0;
+       COND[I]=0;
+       KEY[I]=0;
+       LOCSND[I]=0;
+L1001: /*etc*/ ;
+       } /* end loop */
+
+       LINUSE=1;
+       TRVS=1;
+       CLSSES=0;
+       TRNVLS=0;
+
+/*  START NEW DATA SECTION.  SECT IS THE SECTION NUMBER. */
+
+L1002: SECT=GETNUM(1);
+       OLDLOC= -1;
+       switch (SECT) { case 0: return(0); case 1: goto L1004; case 2: goto
+               L1004; case 3: goto L1030; case 4: goto L1040; case 5: goto L1004;
+               case 6: goto L1004; case 7: goto L1050; case 8: goto L1060; case
+               9: goto L1070; case 10: goto L1004; case 11: goto L1080; case 12:
+               break; case 13: goto L1090; case 14: goto L1004; }
+/*           (0)  (1)  (2)  (3)  (4)  (5)  (6)  (7)  (8)  (9)
+ *          (10) (11) (12) (13) (14) */
+       BUG(9);
+
+/*  SECTIONS 1, 2, 5, 6, 10, 14.  READ MESSAGES AND SET UP POINTERS. */
+
+L1004: KK=LINUSE;
+L1005: LINUSE=KK;
+       LOC=GETNUM(1);
+       if(LNLENG >= LNPOSN+70)BUG(0);
+       if(LOC == -1) goto L1002;
+       if(LNLENG < LNPOSN)BUG(1);
+L1006: KK=KK+1;
+       if(KK >= LINSIZ)BUG(2);
+       LINES[KK]=GETTXT(FALSE,FALSE,FALSE,KK);
+       if(LINES[KK] != -1) goto L1006;
+       LINES[LINUSE]=KK;
+       if(LOC == OLDLOC) goto L1005;
+       OLDLOC=LOC;
+       LINES[LINUSE]= -KK;
+       if(SECT == 14) goto L1014;
+       if(SECT == 10) goto L1012;
+       if(SECT == 6) goto L1011;
+       if(SECT == 5) goto L1010;
+       if(LOC > LOCSIZ)BUG(10);
+       if(SECT == 1) goto L1008;
+
+       STEXT[LOC]=LINUSE;
+        goto L1005;
+
+L1008: LTEXT[LOC]=LINUSE;
+        goto L1005;
+
+L1010: if(LOC > 0 && LOC <= 100)PTEXT[LOC]=LINUSE;
+        goto L1005;
+
+L1011: if(LOC > RTXSIZ)BUG(6);
+       RTEXT[LOC]=LINUSE;
+        goto L1005;
+
+L1012: CLSSES=CLSSES+1;
+       if(CLSSES > CLSMAX)BUG(11);
+       CTEXT[CLSSES]=LINUSE;
+       CVAL[CLSSES]=LOC;
+        goto L1005;
+
+L1014: TRNVLS=TRNVLS+1;
+       if(TRNVLS > TRNSIZ)BUG(11);
+       TTEXT[TRNVLS]=LINUSE;
+       TRNVAL[TRNVLS]=LOC;
+        goto L1005;
+
+/*  THE STUFF FOR SECTION 3 IS ENCODED HERE.  EACH "FROM-LOCATION" GETS A
+ *  CONTIGUOUS SECTION OF THE "TRAVEL" ARRAY.  EACH ENTRY IN TRAVEL IS
+ *  NEWLOC*1000 + KEYWORD (FROM SECTION 4, MOTION VERBS), AND IS NEGATED IF
+ *  THIS IS THE LAST ENTRY FOR THIS LOCATION.  KEY(N) IS THE INDEX IN TRAVEL
+ *  OF THE FIRST OPTION AT LOCATION N. */
+
+L1030: LOC=GETNUM(1);
+       if(LOC == -1) goto L1002;
+       NEWLOC=GETNUM(0);
+       if(KEY[LOC] != 0) goto L1033;
+       KEY[LOC]=TRVS;
+        goto L1035;
+L1033: TRVS--; TRAVEL[TRVS]= -TRAVEL[TRVS]; TRVS++;
+L1035: L=GETNUM(0);
+       if(L == 0) goto L1039;
+       TRAVEL[TRVS]=NEWLOC*1000+L;
+       TRVS=TRVS+1;
+       if(TRVS == TRVSIZ)BUG(3);
+        goto L1035;
+L1039: TRVS--; TRAVEL[TRVS]= -TRAVEL[TRVS]; TRVS++;
+        goto L1030;
+
+/*  HERE WE READ IN THE VOCABULARY.  KTAB(N) IS THE WORD NUMBER, ATAB(N) IS
+ *  THE CORRESPONDING WORD.  THE -1 AT THE END OF SECTION 4 IS LEFT IN KTAB
+ *  AS AN END-MARKER.  THE WORDS ARE GIVEN A MINIMAL HASH TO MAKE DECIPHERING
+ *  THE CORE-IMAGE HARDER.  (WE DON'T USE GETTXT'S HASH SINCE THAT WOULD FORCE
+ *  US TO HASH EACH INPUT LINE TO MAKE COMPARISONS WORK, AND THAT IN TURN
+ *  WOULD MAKE IT HARDER TO DETECT PARTICULAR INPUT WORDS.) */
+
+L1040: J=10000;
+       /* 1042 */ for (TABNDX=1; TABNDX<=TABSIZ; TABNDX++) {
+L1043: KTAB[TABNDX]=GETNUM(1);
+       if(KTAB[TABNDX] == -1) goto L1002;
+       J=J+7;
+L1042: ATAB[TABNDX]=GETTXT(TRUE,TRUE,TRUE,0)+J*J;
+       } /* end loop */
+       BUG(4);
+
+/*  READ IN THE INITIAL LOCATIONS FOR EACH OBJECT.  ALSO THE IMMOVABILITY INFO.
+ *  PLAC CONTAINS INITIAL LOCATIONS OF OBJECTS.  FIXD IS -1 FOR IMMOVABLE
+ *  OBJECTS (INCLUDING THE SNAKE), OR = SECOND LOC FOR TWO-PLACED OBJECTS. */
+
+L1050: OBJ=GETNUM(1);
+       if(OBJ == -1) goto L1002;
+       PLAC[OBJ]=GETNUM(0);
+       FIXD[OBJ]=GETNUM(0);
+        goto L1050;
+
+/*  READ DEFAULT MESSAGE NUMBERS FOR ACTION VERBS, STORE IN ACTSPK. */
+
+L1060: VERB=GETNUM(1);
+       if(VERB == -1) goto L1002;
+       ACTSPK[VERB]=GETNUM(0);
+        goto L1060;
+
+/*  READ INFO ABOUT AVAILABLE LIQUIDS AND OTHER CONDITIONS, STORE IN COND. */
+
+L1070: K=GETNUM(1);
+       if(K == -1) goto L1002;
+L1071: LOC=GETNUM(0);
+       if(LOC == 0) goto L1070;
+       if(CNDBIT(LOC,K)) BUG(8);
+       COND[LOC]=COND[LOC]+SETBIT(K);
+        goto L1071;
+
+/*  READ DATA FOR HINTS. */
+
+L1080: HNTMAX=0;
+L1081: K=GETNUM(1);
+       if(K == -1) goto L1002;
+       if(K <= 0 || K > HNTSIZ)BUG(7);
+       /* 1083 */ for (I=1; I<=4; I++) {
+L1083: HINTS[K][I] =GETNUM(0);
+       } /* end loop */
+       HNTMAX=(HNTMAX>K ? HNTMAX : K);
+        goto L1081;
+
+/*  READ THE SOUND/TEXT INFO, STORE IN OBJSND, OBJTXT, LOCSND. */
+
+L1090: K=GETNUM(1);
+       if(K == -1) goto L1002;
+       KK=GETNUM(0);
+       I=GETNUM(0);
+       if(I == 0) goto L1092;
+       OBJSND[K]=(KK>0 ? KK : 0);
+       OBJTXT[K]=(I>0 ? I : 0);
+        goto L1090;
+
+L1092: LOCSND[K]=KK;
+        goto L1090;
+}
+
+/*  FINISH CONSTRUCTING INTERNAL DATA FORMAT */
+
+/*  HAVING READ IN THE DATABASE, CERTAIN THINGS ARE NOW CONSTRUCTED.  PROPS ARE
+ *  SET TO ZERO.  WE FINISH SETTING UP COND BY CHECKING FOR FORCED-MOTION TRAVEL
+ *  ENTRIES.  THE PLAC AND FIXD ARRAYS ARE USED TO SET UP ATLOC(N) AS THE FIRST
+ *  OBJECT AT LOCATION N, AND LINK(OBJ) AS THE NEXT OBJECT AT THE SAME LOCATION
+ *  AS OBJ.  (OBJ>100 INDICATES THAT FIXED(OBJ-100)=LOC; LINK(OBJ) IS STILL THE
+ *  CORRECT LINK TO USE.)  ABB IS ZEROED; IT CONTROLS WHETHER THE ABBREVIATED
+ *  DESCRIPTION IS PRINTED.  COUNTS MOD 5 UNLESS "LOOK" IS USED. */
+
+static finish_init() {
+       /* 1101 */ for (I=1; I<=100; I++) {
+       PLACE[I]=0;
+       PROP[I]=0;
+       LINK[I]=0;
+L1101: {long x = I+100; LINK[x]=0;}
+       } /* end loop */
+
+       /* 1102 */ for (I=1; I<=LOCSIZ; I++) {
+       ABB[I]=0;
+       if(LTEXT[I] == 0 || KEY[I] == 0) goto L1102;
+       K=KEY[I];
+       if(MOD(IABS(TRAVEL[K]),1000) == 1)COND[I]=2;
+L1102: ATLOC[I]=0;
+       } /* end loop */
+
+/*  SET UP THE ATLOC AND LINK ARRAYS AS DESCRIBED ABOVE.  WE'LL USE THE DROP
+ *  SUBROUTINE, WHICH PREFACES NEW OBJECTS ON THE LISTS.  SINCE WE WANT THINGS
+ *  IN THE OTHER ORDER, WE'LL RUN THE LOOP BACKWARDS.  IF THE OBJECT IS IN TWO
+ *  LOCS, WE DROP IT TWICE.  THIS ALSO SETS UP "PLACE" AND "FIXED" AS COPIES OF
+ *  "PLAC" AND "FIXD".  ALSO, SINCE TWO-PLACED OBJECTS ARE TYPICALLY BEST
+ *  DESCRIBED LAST, WE'LL DROP THEM FIRST. */
+
+       /* 1106 */ for (I=1; I<=100; I++) {
+       K=101-I;
+       if(FIXD[K] <= 0) goto L1106;
+       DROP(K+100,FIXD[K]);
+       DROP(K,PLAC[K]);
+L1106: /*etc*/ ;
+       } /* end loop */
+
+       /* 1107 */ for (I=1; I<=100; I++) {
+       K=101-I;
+       FIXED[K]=FIXD[K];
+L1107: if(PLAC[K] != 0 && FIXD[K] <= 0)DROP(K,PLAC[K]);
+       } /* end loop */
+
+/*  TREASURES, AS NOTED EARLIER, ARE OBJECTS 50 THROUGH MAXTRS (CURRENTLY 79).
+ *  THEIR PROPS ARE INITIALLY -1, AND ARE SET TO 0 THE FIRST TIME THEY ARE
+ *  DESCRIBED.  TALLY KEEPS TRACK OF HOW MANY ARE NOT YET FOUND, SO WE KNOW
+ *  WHEN TO CLOSE THE CAVE. */
+
+       MAXTRS=79;
+       TALLY=0;
+       /* 1200 */ for (I=50; I<=MAXTRS; I++) {
+       if(PTEXT[I] != 0)PROP[I]= -1;
+L1200: TALLY=TALLY-PROP[I];
+       } /* end loop */
+
+/*  CLEAR THE HINT STUFF.  HINTLC(I) IS HOW LONG HE'S BEEN AT LOC WITH COND BIT
+ *  I.  HINTED(I) IS TRUE IFF HINT I HAS BEEN USED. */
+
+       /* 1300 */ for (I=1; I<=HNTMAX; I++) {
+       HINTED[I]=FALSE;
+L1300: HINTLC[I]=0;
+       } /* end loop */
+
+/*  DEFINE SOME HANDY MNEMONICS.  THESE CORRESPOND TO OBJECT NUMBERS. */
+
+       AXE=VOCWRD(12405,1);
+       BATTER=VOCWRD(201202005,1);
+       BEAR=VOCWRD(2050118,1);
+       BIRD=VOCWRD(2091804,1);
+       BLOOD=VOCWRD(212151504,1);
+       BOTTLE=VOCWRD(215202012,1);
+       CAGE=VOCWRD(3010705,1);
+       CAVITY=VOCWRD(301220920,1);
+       CHASM=VOCWRD(308011913,1);
+       CLAM=VOCWRD(3120113,1);
+       DOOR=VOCWRD(4151518,1);
+       DRAGON=VOCWRD(418010715,1);
+       DWARF=VOCWRD(423011806,1);
+       FISSUR=VOCWRD(609191921,1);
+       FOOD=VOCWRD(6151504,1);
+       GRATE=VOCWRD(718012005,1);
+       KEYS=VOCWRD(11052519,1);
+       KNIFE=VOCWRD(1114090605,1);
+       LAMP=VOCWRD(12011316,1);
+       MAGZIN=VOCWRD(1301070126,1);
+       MESSAG=VOCWRD(1305191901,1);
+       MIRROR=VOCWRD(1309181815,1);
+       OGRE=VOCWRD(15071805,1);
+       OIL=VOCWRD(150912,1);
+       OYSTER=VOCWRD(1525192005,1);
+       PILLOW=VOCWRD(1609121215,1);
+       PLANT=VOCWRD(1612011420,1);
+       PLANT2=PLANT+1;
+       RESER=VOCWRD(1805190518,1);
+       ROD=VOCWRD(181504,1);
+       ROD2=ROD+1;
+       SIGN=VOCWRD(19090714,1);
+       SNAKE=VOCWRD(1914011105,1);
+       STEPS=VOCWRD(1920051619,1);
+       TROLL=VOCWRD(2018151212,1);
+       TROLL2=TROLL+1;
+       URN=VOCWRD(211814,1);
+       VEND=VOCWRD(1755140409,1);
+       VOLCAN=VOCWRD(1765120301,1);
+       WATER=VOCWRD(1851200518,1);
+
+/*  OBJECTS FROM 50 THROUGH WHATEVER ARE TREASURES.  HERE ARE A FEW. */
+
+       AMBER=VOCWRD(113020518,1);
+       CHAIN=VOCWRD(308010914,1);
+       CHEST=VOCWRD(308051920,1);
+       COINS=VOCWRD(315091419,1);
+       EGGS=VOCWRD(5070719,1);
+       EMRALD=VOCWRD(513051801,1);
+       JADE=VOCWRD(10010405,1);
+       NUGGET=VOCWRD(7151204,1);
+       PEARL=VOCWRD(1605011812,1);
+       PYRAM=VOCWRD(1625180113,1);
+       RUBY=VOCWRD(18210225,1);
+       RUG=VOCWRD(182107,1);
+       SAPPH=VOCWRD(1901161608,1);
+       TRIDNT=VOCWRD(2018090405,1);
+       VASE=VOCWRD(22011905,1);
+
+/*  THESE ARE MOTION-VERB NUMBERS. */
+
+       BACK=VOCWRD(2010311,0);
+       CAVE=VOCWRD(3012205,0);
+       DPRSSN=VOCWRD(405161805,0);
+       ENTER=VOCWRD(514200518,0);
+       ENTRNC=VOCWRD(514201801,0);
+       LOOK=VOCWRD(12151511,0);
+       NUL=VOCWRD(14211212,0);
+       STREAM=VOCWRD(1920180501,0);
+
+/*  AND SOME ACTION VERBS. */
+
+       FIND=VOCWRD(6091404,2);
+       INVENT=VOCWRD(914220514,2);
+       LOCK=VOCWRD(12150311,2);
+       SAY=VOCWRD(190125,2);
+       THROW=VOCWRD(2008181523,2);
+
+/*  INITIALISE THE DWARVES.  DLOC IS LOC OF DWARVES, HARD-WIRED IN.  ODLOC IS
+ *  PRIOR LOC OF EACH DWARF, INITIALLY GARBAGE.  DALTLC IS ALTERNATE INITIAL LOC
+ *  FOR DWARF, IN CASE ONE OF THEM STARTS OUT ON TOP OF THE ADVENTURER.  (NO 2
+ *  OF THE 5 INITIAL LOCS ARE ADJACENT.)  DSEEN IS TRUE IF DWARF HAS SEEN HIM.
+ *  DFLAG CONTROLS THE LEVEL OF ACTIVATION OF ALL THIS:
+ *     0       NO DWARF STUFF YET (WAIT UNTIL REACHES HALL OF MISTS)
+ *     1       REACHED HALL OF MISTS, BUT HASN'T MET FIRST DWARF
+ *     2       MET FIRST DWARF, OTHERS START MOVING, NO KNIVES THROWN YET
+ *     3       A KNIFE HAS BEEN THROWN (FIRST SET ALWAYS MISSES)
+ *     3+      DWARVES ARE MAD (INCREASES THEIR ACCURACY)
+ *  SIXTH DWARF IS SPECIAL (THE PIRATE).  HE ALWAYS STARTS AT HIS CHEST'S
+ *  EVENTUAL LOCATION INSIDE THE MAZE.  THIS LOC IS SAVED IN CHLOC FOR REF.
+ *  THE DEAD END IN THE OTHER MAZE HAS ITS LOC STORED IN CHLOC2. */
+
+       CHLOC=114;
+       CHLOC2=140;
+       /* 1700 */ for (I=1; I<=6; I++) {
+L1700: DSEEN[I]=FALSE;
+       } /* end loop */
+       DFLAG=0;
+       DLOC[1]=19;
+       DLOC[2]=27;
+       DLOC[3]=33;
+       DLOC[4]=44;
+       DLOC[5]=64;
+       DLOC[6]=CHLOC;
+       DALTLC=18;
+
+/*  OTHER RANDOM FLAGS AND COUNTERS, AS FOLLOWS:
+ *     ABBNUM  HOW OFTEN WE SHOULD PRINT NON-ABBREVIATED DESCRIPTIONS
+ *     BONUS   USED TO DETERMINE AMOUNT OF BONUS IF HE REACHES CLOSING
+ *     CLOCK1  NUMBER OF TURNS FROM FINDING LAST TREASURE TILL CLOSING
+ *     CLOCK2  NUMBER OF TURNS FROM FIRST WARNING TILL BLINDING FLASH
+ *     CONDS   MIN VALUE FOR COND(LOC) IF LOC HAS ANY HINTS
+ *     DETAIL  HOW OFTEN WE'VE SAID "NOT ALLOWED TO GIVE MORE DETAIL"
+ *     DKILL   NUMBER OF DWARVES KILLED (UNUSED IN SCORING, NEEDED FOR MSG)
+ *     FOOBAR  CURRENT PROGRESS IN SAYING "FEE FIE FOE FOO".
+ *     HOLDNG  NUMBER OF OBJECTS BEING CARRIED
+ *     IGO     HOW MANY TIMES HE'S SAID "GO XXX" INSTEAD OF "XXX"
+ *     IWEST   HOW MANY TIMES HE'S SAID "WEST" INSTEAD OF "W"
+ *     KNFLOC  0 IF NO KNIFE HERE, LOC IF KNIFE HERE, -1 AFTER CAVEAT
+ *     LIMIT   LIFETIME OF LAMP (NOT SET HERE)
+ *     MAXDIE  NUMBER OF REINCARNATION MESSAGES AVAILABLE (UP TO 5)
+ *     NUMDIE  NUMBER OF TIMES KILLED SO FAR
+ *     THRESH  NEXT #TURNS THRESHHOLD (-1 IF NONE)
+ *     TRNDEX  INDEX IN TRNVAL OF NEXT THRESHHOLD (SECTION 14 OF DATABASE)
+ *     TRNLUZ  # POINTS LOST SO FAR DUE TO NUMBER OF TURNS USED
+ *     TURNS   TALLIES HOW MANY COMMANDS HE'S GIVEN (IGNORES YES/NO)
+ *     LOGICALS WERE EXPLAINED EARLIER */
+
+       TURNS=0;
+       TRNDEX=1;
+       THRESH= -1;
+       if(TRNVLS > 0)THRESH=MOD(TRNVAL[1],100000)+1;
+       TRNLUZ=0;
+       LMWARN=FALSE;
+       IGO=0;
+       IWEST=0;
+       KNFLOC=0;
+       DETAIL=0;
+       ABBNUM=5;
+       /* 1800 */ for (I=0; I<=4; I++) {
+L1800: {long x = 2*I+81; if(RTEXT[x] != 0)MAXDIE=I+1;}
+       } /* end loop */
+       NUMDIE=0;
+       HOLDNG=0;
+       DKILL=0;
+       FOOBAR=0;
+       BONUS=0;
+       CLOCK1=30;
+       CLOCK2=50;
+       CONDS=SETBIT(11);
+       SAVED=0;
+       CLOSNG=FALSE;
+       PANIC=FALSE;
+       CLOSED=FALSE;
+       CLSHNT=FALSE;
+       NOVICE=FALSE;
+       SETUP=1;
+
+       /* if we can ever think of how, we should save it at this point */
+
+       return(0); /* then we won't actually return from initialisation */
+}
+
+/*  REPORT ON AMOUNT OF ARRAYS ACTUALLY USED, TO PERMIT REDUCTIONS. */
+
+static report() {
+       /* 1998 */ for (K=1; K<=LOCSIZ; K++) {
+       KK=LOCSIZ+1-K;
+       if(LTEXT[KK] != 0) goto L1997;
+L1998: /*etc*/ ;
+       } /* end loop */
+
+       OBJ=0;
+L1997: /* 1996 */ for (K=1; K<=100; K++) {
+L1996: if(PTEXT[K] != 0)OBJ=OBJ+1;
+       } /* end loop */
+
+       /* 1995 */ for (K=1; K<=TABNDX; K++) {
+L1995: if(KTAB[K]/1000 == 2)VERB=KTAB[K]-2000;
+       } /* end loop */
+
+       /* 1994 */ for (K=1; K<=RTXSIZ; K++) {
+       J=RTXSIZ+1-K;
+       if(RTEXT[J] != 0) goto L1993;
+L1994: /*etc*/ ;
+       } /* end loop */
+
+L1993: SETPRM(1,LINUSE,LINSIZ);
+       SETPRM(3,TRVS,TRVSIZ);
+       SETPRM(5,TABNDX,TABSIZ);
+       SETPRM(7,KK,LOCSIZ);
+       SETPRM(9,OBJ,100);
+       SETPRM(11,VERB,VRBSIZ);
+       SETPRM(13,J,RTXSIZ);
+       SETPRM(15,CLSSES,CLSMAX);
+       SETPRM(17,HNTMAX,HNTSIZ);
+       SETPRM(19,TRNVLS,TRNSIZ);
+       RSPEAK(267);
+       TYPE0();
+}
+
+static long init_reading, init_cksum;
+static FILE *f;
+
+static void quick_item(long*);
+static void quick_array(long*, long);
+
+static quick_init() {
+#ifdef AMIGA
+       f = fopen("ram:adventure.data", READ_MODE);
+#else
+       extern char *getenv();
+       char *adv = getenv("ADVENTURE");
+       f = NULL;
+       if(adv)f = fopen(adv,READ_MODE);
+#endif
+       if(f == NULL)f = fopen("adventure.data",READ_MODE);
+       if(f == NULL)return(FALSE);
+       init_reading = TRUE;
+       init_cksum = 1;
+       quick_io();
+       if(fread(&K,4,1,f) == 1) init_cksum -= K; else init_cksum = 1;
+       fclose(f);
+       if(init_cksum != 0)printf("Checksum error!\n");
+       return(init_cksum == 0);
+}
+
+static quick_save() {
+       printf("Writing adventure.data...\n");
+       f = fopen("adventure.data",WRITE_MODE);
+       if(f == NULL){printf("Can't open file!\n"); return(0);}
+       init_reading = FALSE;
+       init_cksum = 1;
+       quick_io();
+       fwrite(&init_cksum,4,1,f);
+       fclose(f);
+       return(0);
+}
+
+static quick_io() {
+       quick_item(&LINUSE);
+       quick_item(&TRVS);
+       quick_item(&CLSSES);
+       quick_item(&TRNVLS);
+       quick_item(&TABNDX);
+       quick_item(&HNTMAX);
+       quick_array(PTEXT,100);
+       quick_array(RTEXT,RTXSIZ);
+       quick_array(CTEXT,CLSMAX);
+       quick_array(OBJSND,100);
+       quick_array(OBJTXT,100);
+       quick_array(STEXT,LOCSIZ);
+       quick_array(LTEXT,LOCSIZ);
+       quick_array(COND,LOCSIZ);
+       quick_array(KEY,LOCSIZ);
+       quick_array(LOCSND,LOCSIZ);
+       quick_array(LINES,LINSIZ);
+       quick_array(CVAL,CLSMAX);
+       quick_array(TTEXT,TRNSIZ);
+       quick_array(TRNVAL,TRNSIZ);
+       quick_array(TRAVEL,TRVSIZ);
+       quick_array(KTAB,TABSIZ);
+       quick_array(ATAB,TABSIZ);
+       quick_array(PLAC,100);
+       quick_array(FIXD,100);
+       quick_array(ACTSPK,VRBSIZ);
+       quick_array((long *)HINTS,(HNTMAX+1)*5-1);
+       return(0);
+}
+
+static void quick_item(W)long *W; {
+       if(init_reading && fread(W,4,1,f) != 1)return;
+       init_cksum = MOD(init_cksum*13+(*W),60000000);
+       if(!init_reading)fwrite(W,4,1,f);
+}
+
+static void quick_array(A,N)long *A, N; { long I;
+       if(init_reading && fread(A,4,N+1,f) != N+1)printf("Read error!\n");
+       for(I=1;I<=N;I++)init_cksum = MOD(init_cksum*13+A[I],60000000);
+       if(!init_reading && fwrite(A,4,N+1,f)!=N+1)printf("Write error!\n");
+}
diff --git a/main.c b/main.c
new file mode 100644 (file)
index 0000000..6977bc5
--- /dev/null
+++ b/main.c
@@ -0,0 +1,859 @@
+#include "misc.h"
+#ifdef __MSDOS__
+#include "alloc.h"
+#endif
+
+#define TRUE  (0==0)
+#define FALSE (0!=0)
+long ABB[186], ATAB[331], ATLOC[186], BLKLIN = TRUE, DFLAG,
+               DLOC[7], FIXED[101], HOLDNG,
+               KTAB[331], *LINES, LINK[201], LNLENG, LNPOSN,
+               PARMS[26], PLACE[101], PTEXT[101], RTEXT[278],
+               SETUP = 0, TABSIZ = 330;
+char INLINE[101], MAP1[129], MAP2[129];
+
+long ABBNUM, ACTSPK[36], AMBER, ATTACK, AXE, BACK, BATTER, BEAR, BIRD, BLOOD, BONUS,
+                BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST, CHLOC, CHLOC2,
+               CLAM, CLOCK1, CLOCK2, CLOSED, CLOSNG, CLSHNT, CLSMAX = 12, CLSSES,
+               COINS, COND[186], CONDS, CTEXT[13], CVAL[13], DALTLC, DETAIL,
+                DKILL, DOOR, DPRSSN, DRAGON, DSEEN[7], DTOTAL, DWARF, EGGS,
+               EMRALD, ENTER, ENTRNC, FIND, FISSUR, FIXD[101], FOOBAR, FOOD,
+               GRATE, HINT, HINTED[21], HINTLC[21], HINTS[21][5], HNTMAX,
+               HNTSIZ = 20, I, INVENT, IGO, IWEST, J, JADE, K, K2, KEY[186], KEYS, KK,
+               KNFLOC, KNIFE, KQ, L, LAMP, LIMIT, LINSIZ = 12500, LINUSE, LL,
+               LMWARN, LOC, LOCK, LOCSIZ = 185, LOCSND[186], LOOK, LTEXT[186],
+               MAGZIN, MAXDIE, MAXTRS, MESH = 123456789,
+               MESSAG, MIRROR, MXSCOR,
+               NEWLOC, NOVICE, NUGGET, NUL, NUMDIE, OBJ, OBJSND[101],
+               OBJTXT[101], ODLOC[7], OGRE, OIL, OLDLC2, OLDLOC, OLDOBJ, OYSTER,
+               PANIC, PEARL, PILLOW, PLAC[101], PLANT, PLANT2, PROP[101], PYRAM,
+               RESER, ROD, ROD2, RTXSIZ = 277, RUBY, RUG, SAPPH, SAVED, SAY,
+               SCORE, SECT, SIGN, SNAKE, SPK, STEPS, STEXT[186], STICK,
+               STREAM, TABNDX, TALLY, THRESH, THROW, TK[21], TRAVEL[886], TRIDNT,
+               TRNDEX, TRNLUZ, TRNSIZ = 5, TRNVAL[6], TRNVLS, TROLL, TROLL2, TRVS,
+                TRVSIZ = 885, TTEXT[6], TURNS, URN, V1, V2, VASE, VEND, VERB,
+               VOLCAN, VRBSIZ = 35, VRSION = 25, WATER, WD1, WD1X, WD2, WD2X,
+               WZDARK = FALSE, ZZWORD;
+
+extern initialise();
+extern void score(long);
+extern action(long);
+
+/*
+ * MAIN PROGRAM
+ */
+
+main() {
+
+/*  ADVENTURE (REV 2: 20 TREASURES) */
+
+/*  HISTORY: ORIGINAL IDEA & 5-TREASURE VERSION (ADVENTURES) BY WILLIE CROWTHER
+ *           15-TREASURE VERSION (ADVENTURE) BY DON WOODS, APRIL-JUNE 1977
+ *           20-TREASURE VERSION (REV 2) BY DON WOODS, AUGUST 1978
+ *             ERRATA FIXED: 78/12/25 */
+
+
+/* LOGICAL VARIABLES:
+ *
+ *  CLOSED SAYS WHETHER WE'RE ALL THE WAY CLOSED
+ *  CLOSNG SAYS WHETHER IT'S CLOSING TIME YET
+ *  CLSHNT SAYS WHETHER HE'S READ THE CLUE IN THE ENDGAME
+ *  LMWARN SAYS WHETHER HE'S BEEN WARNED ABOUT LAMP GOING DIM
+ *  NOVICE SAYS WHETHER HE ASKED FOR INSTRUCTIONS AT START-UP
+ *  PANIC SAYS WHETHER HE'S FOUND OUT HE'S TRAPPED IN THE CAVE
+ *  WZDARK SAYS WHETHER THE LOC HE'S LEAVING WAS DARK */
+
+#include "funcs.h"
+
+/*  READ THE DATABASE IF WE HAVE NOT YET DONE SO */
+
+       LINES = (long *)calloc(LINSIZ+1,sizeof(long));
+       if(!LINES){
+               printf("Not enough memory!\n");
+               exit(FALSE);
+       }
+
+       MAP2[1] = 0;
+       if(!SETUP)initialise();
+       if(SETUP > 0) goto L1;
+
+/*  UNLIKE EARLIER VERSIONS, ADVENTURE IS NO LONGER RESTARTABLE.  (THIS
+ *  LETS US GET AWAY WITH MODIFYING THINGS SUCH AS OBJSND(BIRD) WITHOUT
+ *  HAVING TO BE ABLE TO UNDO THE CHANGES LATER.)  IF A "USED" COPY IS
+ *  RERUN, WE COME HERE AND TELL THE PLAYER TO RUN A FRESH COPY. */
+
+       RSPEAK(201);
+       exit(FALSE);
+
+
+
+/*  START-UP, DWARF STUFF */
+
+L1:    SETUP= -1;
+       I=RAN(-1);
+       ZZWORD=RNDVOC(3,0)+MESH*2;
+       NOVICE=YES(65,1,0);
+       NEWLOC=1;
+       LOC=1;
+       LIMIT=330;
+       if(NOVICE)LIMIT=1000;
+
+/*  CAN'T LEAVE CAVE ONCE IT'S CLOSING (EXCEPT BY MAIN OFFICE). */
+
+L2:    if(!OUTSID(NEWLOC) || NEWLOC == 0 || !CLOSNG) goto L71;
+       RSPEAK(130);
+       NEWLOC=LOC;
+       if(!PANIC)CLOCK2=15;
+       PANIC=TRUE;
+
+/*  SEE IF A DWARF HAS SEEN HIM AND HAS COME FROM WHERE HE WANTS TO GO.  IF SO,
+ *  THE DWARF'S BLOCKING HIS WAY.  IF COMING FROM PLACE FORBIDDEN TO PIRATE
+ *  (DWARVES ROOTED IN PLACE) LET HIM GET OUT (AND ATTACKED). */
+
+L71:   if(NEWLOC == LOC || FORCED(LOC) || CNDBIT(LOC,3)) goto L74;
+       /* 73 */ for (I=1; I<=5; I++) {
+       if(ODLOC[I] != NEWLOC || !DSEEN[I]) goto L73;
+       NEWLOC=LOC;
+       RSPEAK(2);
+        goto L74;
+L73:   /*etc*/ ;
+       } /* end loop */
+L74:   LOC=NEWLOC;
+
+/*  DWARF STUFF.  SEE EARLIER COMMENTS FOR DESCRIPTION OF VARIABLES.  REMEMBER
+ *  SIXTH DWARF IS PIRATE AND IS THUS VERY DIFFERENT EXCEPT FOR MOTION RULES. */
+
+/*  FIRST OFF, DON'T LET THE DWARVES FOLLOW HIM INTO A PIT OR A WALL.  ACTIVATE
+ *  THE WHOLE MESS THE FIRST TIME HE GETS AS FAR AS THE HALL OF MISTS (LOC 15).
+ *  IF NEWLOC IS FORBIDDEN TO PIRATE (IN PARTICULAR, IF IT'S BEYOND THE TROLL
+ *  BRIDGE), BYPASS DWARF STUFF.  THAT WAY PIRATE CAN'T STEAL RETURN TOLL, AND
+ *  DWARVES CAN'T MEET THE BEAR.  ALSO MEANS DWARVES WON'T FOLLOW HIM INTO DEAD
+ *  END IN MAZE, BUT C'EST LA VIE.  THEY'LL WAIT FOR HIM OUTSIDE THE DEAD END. */
+
+       if(LOC == 0 || FORCED(LOC) || CNDBIT(NEWLOC,3)) goto L2000;
+       if(DFLAG != 0) goto L6000;
+       if(INDEEP(LOC))DFLAG=1;
+        goto L2000;
+
+/*  WHEN WE ENCOUNTER THE FIRST DWARF, WE KILL 0, 1, OR 2 OF THE 5 DWARVES.  IF
+ *  ANY OF THE SURVIVORS IS AT LOC, REPLACE HIM WITH THE ALTERNATE. */
+
+L6000: if(DFLAG != 1) goto L6010;
+       if(!INDEEP(LOC) || (PCT(95) && (!CNDBIT(LOC,4) || PCT(85)))) goto L2000;
+       DFLAG=2;
+       /* 6001 */ for (I=1; I<=2; I++) {
+       J=1+RAN(5);
+L6001: if(PCT(50))DLOC[J]=0;
+       } /* end loop */
+       /* 6002 */ for (I=1; I<=5; I++) {
+       if(DLOC[I] == LOC)DLOC[I]=DALTLC;
+L6002: ODLOC[I]=DLOC[I];
+       } /* end loop */
+       RSPEAK(3);
+       DROP(AXE,LOC);
+        goto L2000;
+
+/*  THINGS ARE IN FULL SWING.  MOVE EACH DWARF AT RANDOM, EXCEPT IF HE'S SEEN US
+ *  HE STICKS WITH US.  DWARVES STAY DEEP INSIDE.  IF WANDERING AT RANDOM,
+ *  THEY DON'T BACK UP UNLESS THERE'S NO ALTERNATIVE.  IF THEY DON'T HAVE TO
+ *  MOVE, THEY ATTACK.  AND, OF COURSE, DEAD DWARVES DON'T DO MUCH OF ANYTHING. */
+
+L6010: DTOTAL=0;
+       ATTACK=0;
+       STICK=0;
+       /* 6030 */ for (I=1; I<=6; I++) {
+       if(DLOC[I] == 0) goto L6030;
+/*  FILL TK ARRAY WITH ALL THE PLACES THIS DWARF MIGHT GO. */
+       J=1;
+       KK=DLOC[I];
+       KK=KEY[KK];
+       if(KK == 0) goto L6016;
+L6012: NEWLOC=MOD(IABS(TRAVEL[KK])/1000,1000);
+       {long x = J-1;
+       if(NEWLOC > 300 || !INDEEP(NEWLOC) || NEWLOC == ODLOC[I] || (J > 1 &&
+               NEWLOC == TK[x]) || J >= 20 || NEWLOC == DLOC[I] ||
+               FORCED(NEWLOC) || (I == 6 && CNDBIT(NEWLOC,3)) ||
+               IABS(TRAVEL[KK])/1000000 == 100) goto L6014;}
+       TK[J]=NEWLOC;
+       J=J+1;
+L6014: KK=KK+1;
+       {long x = KK-1; if(TRAVEL[x] >= 0) goto L6012;}
+L6016: TK[J]=ODLOC[I];
+       if(J >= 2)J=J-1;
+       J=1+RAN(J);
+       ODLOC[I]=DLOC[I];
+       DLOC[I]=TK[J];
+       DSEEN[I]=(DSEEN[I] && INDEEP(LOC)) || (DLOC[I] == LOC || ODLOC[I] == LOC);
+       if(!DSEEN[I]) goto L6030;
+       DLOC[I]=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 PLACE(CHEST)=0 MIGHT MEAN THAT HE'S
+ *  THROWN IT TO THE TROLL, BUT IN THAT CASE HE'S SEEN THE CHEST (PROP=0). */
+
+       if(LOC == CHLOC || 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 && (LOC == PLAC[PYRAM] || LOC == PLAC[EMRALD])) goto L6020;
+       if(TOTING(J)) goto L6021;
+L6020: if(HERE(J))K=1;
+       } /* end loop */
+       if(TALLY == 1 && K == 0 && PLACE[CHEST] == 0 && HERE(LAMP) && PROP[LAMP]
+               == 1) goto L6025;
+       if(ODLOC[6] != DLOC[6] && PCT(20))RSPEAK(127);
+        goto L6030;
+
+L6021: if(PLACE[CHEST] != 0) goto L6022;
+/*  INSTALL CHEST ONLY ONCE, TO INSURE IT IS THE LAST TREASURE IN THE LIST. */
+       MOVE(CHEST,CHLOC);
+       MOVE(MESSAG,CHLOC2);
+L6022: RSPEAK(128);
+       /* 6023 */ for (J=50; J<=MAXTRS; J++) {
+       if(J == PYRAM && (LOC == PLAC[PYRAM] || LOC == PLAC[EMRALD])) goto L6023;
+       if(AT(J) && FIXED[J] == 0)CARRY(J,LOC);
+       if(TOTING(J))DROP(J,CHLOC);
+L6023: /*etc*/ ;
+       } /* end loop */
+L6024: DLOC[6]=CHLOC;
+       ODLOC[6]=CHLOC;
+       DSEEN[6]=FALSE;
+        goto L6030;
+
+L6025: RSPEAK(186);
+       MOVE(CHEST,CHLOC);
+       MOVE(MESSAG,CHLOC2);
+        goto L6024;
+
+/*  THIS THREATENING LITTLE DWARF IS IN THE ROOM WITH HIM! */
+
+L6027: DTOTAL=DTOTAL+1;
+       if(ODLOC[I] != DLOC[I]) goto L6030;
+       ATTACK=ATTACK+1;
+       if(KNFLOC >= 0)KNFLOC=LOC;
+       if(RAN(1000) < 95*(DFLAG-2))STICK=STICK+1;
+L6030: /*etc*/ ;
+       } /* end loop */
+
+/*  NOW WE KNOW WHAT'S HAPPENING.  LET'S TELL THE POOR SUCKER ABOUT IT.
+ *  NOTE THAT VARIOUS OF THE "KNIFE" MESSAGES MUST HAVE SPECIFIC RELATIVE
+ *  POSITIONS IN THE RSPEAK DATABASE. */
+
+       if(DTOTAL == 0) goto L2000;
+       SETPRM(1,DTOTAL,0);
+       RSPEAK(4+1/DTOTAL);
+       if(ATTACK == 0) goto L2000;
+       if(DFLAG == 2)DFLAG=3;
+       SETPRM(1,ATTACK,0);
+       K=6;
+       if(ATTACK > 1)K=250;
+       RSPEAK(K);
+       SETPRM(1,STICK,0);
+       RSPEAK(K+1+2/(1+STICK));
+       if(STICK == 0) goto L2000;
+       OLDLC2=LOC;
+        goto L99;
+
+
+
+
+
+
+/*  DESCRIBE THE CURRENT LOCATION AND (MAYBE) GET NEXT COMMAND. */
+
+/*  PRINT TEXT FOR CURRENT LOC. */
+
+L2000: if(LOC == 0) goto L99;
+       KK=STEXT[LOC];
+       if(MOD(ABB[LOC],ABBNUM) == 0 || KK == 0)KK=LTEXT[LOC];
+       if(FORCED(LOC) || !DARK(0)) goto L2001;
+       if(WZDARK && PCT(35)) goto L90;
+       KK=RTEXT[16];
+L2001: if(TOTING(BEAR))RSPEAK(141);
+       SPEAK(KK);
+       K=1;
+       if(FORCED(LOC)) goto L8;
+       if(LOC == 33 && PCT(25) && !CLOSNG)RSPEAK(7);
+
+/*  PRINT OUT DESCRIPTIONS OF OBJECTS AT THIS LOCATION.  IF NOT CLOSING AND
+ *  PROPERTY VALUE IS NEGATIVE, TALLY OFF ANOTHER TREASURE.  RUG IS SPECIAL
+ *  CASE; ONCE SEEN, ITS PROP IS 1 (DRAGON ON IT) TILL DRAGON IS KILLED.
+ *  SIMILARLY FOR CHAIN; PROP IS INITIALLY 1 (LOCKED TO BEAR).  THESE HACKS
+ *  ARE BECAUSE PROP=0 IS NEEDED TO GET FULL SCORE. */
+
+       if(DARK(0)) goto L2012;
+       ABB[LOC]=ABB[LOC]+1;
+       I=ATLOC[LOC];
+L2004: if(I == 0) goto L2012;
+       OBJ=I;
+       if(OBJ > 100)OBJ=OBJ-100;
+       if(OBJ == STEPS && TOTING(NUGGET)) goto L2008;
+       if(PROP[OBJ] >= 0) goto L2006;
+       if(CLOSED) goto L2008;
+       PROP[OBJ]=0;
+       if(OBJ == RUG || OBJ == CHAIN)PROP[OBJ]=1;
+       TALLY=TALLY-1;
+/*  NOTE: THERE USED TO BE A TEST HERE TO SEE WHETHER THE PLAYER HAD BLOWN IT
+ *  SO BADLY THAT HE COULD NEVER EVER SEE THE REMAINING TREASURES, AND IF SO
+ *  THE LAMP WAS ZAPPED TO 35 TURNS.  BUT THE TESTS WERE TOO SIMPLE-MINDED;
+ *  THINGS LIKE KILLING THE BIRD BEFORE THE SNAKE WAS GONE (CAN NEVER SEE
+ *  JEWELRY), AND DOING IT "RIGHT" WAS HOPELESS.  E.G., COULD CROSS TROLL
+ *  BRIDGE SEVERAL TIMES, USING UP ALL AVAILABLE TREASURES, BREAKING VASE,
+ *  USING COINS TO BUY BATTERIES, ETC., AND EVENTUALLY NEVER BE ABLE TO GET
+ *  ACROSS AGAIN.  IF BOTTLE WERE LEFT ON FAR SIDE, COULD THEN NEVER GET EGGS
+ *  OR TRIDENT, AND THE EFFECTS PROPAGATE.  SO THE WHOLE THING WAS FLUSHED.
+ *  ANYONE WHO MAKES SUCH A GROSS BLUNDER ISN'T LIKELY TO FIND EVERYTHING
+ *  ELSE ANYWAY (SO GOES THE RATIONALISATION). */
+L2006: KK=PROP[OBJ];
+       if(OBJ == STEPS && LOC == FIXED[STEPS])KK=1;
+       PSPEAK(OBJ,KK);
+L2008: I=LINK[I];
+        goto L2004;
+
+L2009: K=54;
+L2010: SPK=K;
+L2011: RSPEAK(SPK);
+
+L2012: VERB=0;
+       OLDOBJ=OBJ;
+       OBJ=0;
+
+/*  CHECK IF THIS LOC IS ELIGIBLE FOR ANY HINTS.  IF BEEN HERE LONG ENOUGH,
+ *  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[LOC] < CONDS) goto L2603;
+       /* 2602 */ for (HINT=1; HINT<=HNTMAX; HINT++) {
+       if(HINTED[HINT]) goto L2602;
+       if(!CNDBIT(LOC,HINT+10))HINTLC[HINT]= -1;
+       HINTLC[HINT]=HINTLC[HINT]+1;
+       if(HINTLC[HINT] >= HINTS[HINT][1]) goto L40000;
+L2602: /*etc*/ ;
+       } /* end loop */
+
+/*  KICK THE RANDOM NUMBER GENERATOR JUST TO ADD VARIETY TO THE CHASE.  ALSO,
+ *  IF CLOSING TIME, CHECK FOR ANY OBJECTS BEING TOTED WITH PROP < 0 AND SET
+ *  THE PROP TO -1-PROP.  THIS WAY OBJECTS WON'T BE DESCRIBED UNTIL THEY'VE
+ *  BEEN PICKED UP AND PUT DOWN SEPARATE FROM THEIR RESPECTIVE PILES.  DON'T
+ *  TICK CLOCK1 UNLESS WELL INTO CAVE (AND NOT AT Y2). */
+
+L2603: if(!CLOSED) goto L2605;
+       if(PROP[OYSTER] < 0 && TOTING(OYSTER))PSPEAK(OYSTER,1);
+       /* 2604 */ for (I=1; I<=100; I++) {
+L2604: if(TOTING(I) && PROP[I] < 0)PROP[I]= -1-PROP[I];
+       } /* end loop */
+L2605: WZDARK=DARK(0);
+       if(KNFLOC > 0 && KNFLOC != LOC)KNFLOC=0;
+       I=RAN(1);
+       GETIN(WD1,WD1X,WD2,WD2X);
+
+/*  EVERY INPUT, CHECK "FOOBAR" FLAG.  IF ZERO, NOTHING'S GOING ON.  IF POS,
+ *  MAKE NEG.  IF NEG, HE SKIPPED A WORD, SO MAKE IT ZERO. */
+
+L2607: FOOBAR=(FOOBAR>0 ? -FOOBAR : 0);
+       TURNS=TURNS+1;
+       if(TURNS != THRESH) goto L2608;
+       SPEAK(TTEXT[TRNDEX]);
+       TRNLUZ=TRNLUZ+TRNVAL[TRNDEX]/100000;
+       TRNDEX=TRNDEX+1;
+       THRESH= -1;
+       if(TRNDEX <= TRNVLS)THRESH=MOD(TRNVAL[TRNDEX],100000)+1;
+L2608: if(VERB == SAY && WD2 > 0)VERB=0;
+       if(VERB == SAY) goto L4090;
+       if(TALLY == 0 && INDEEP(LOC) && LOC != 33)CLOCK1=CLOCK1-1;
+       if(CLOCK1 == 0) goto L10000;
+       if(CLOCK1 < 0)CLOCK2=CLOCK2-1;
+       if(CLOCK2 == 0) goto L11000;
+       if(PROP[LAMP] == 1)LIMIT=LIMIT-1;
+       if(LIMIT <= 30 && HERE(BATTER) && PROP[BATTER] == 0 && HERE(LAMP)) goto
+               L12000;
+       if(LIMIT == 0) goto L12400;
+       if(LIMIT <= 30) goto L12200;
+L19999: K=43;
+       if(LIQLOC(LOC) == WATER)K=70;
+       V1=VOCAB(WD1,-1);
+       V2=VOCAB(WD2,-1);
+       if(V1 == ENTER && (V2 == STREAM || V2 == 1000+WATER)) goto L2010;
+       if(V1 == ENTER && WD2 > 0) goto L2800;
+       if((V1 != 1000+WATER && V1 != 1000+OIL) || (V2 != 1000+PLANT && V2 !=
+               1000+DOOR)) goto L2610;
+       {long x = V2-1000; if(AT(x))WD2=MAKEWD(16152118);}
+L2610: if(V1 == 1000+CAGE && V2 == 1000+BIRD && HERE(CAGE) &&
+               HERE(BIRD))WD1=MAKEWD(301200308);
+L2620: if(WD1 != MAKEWD(23051920)) goto L2625;
+       IWEST=IWEST+1;
+       if(IWEST == 10)RSPEAK(17);
+L2625: 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;
+       K=MOD(I,1000);
+       KQ=I/1000+1;
+        switch (KQ-1) { case 0: goto L8; case 1: goto L5000; case 2: goto L4000;
+               case 3: goto L2010; }
+       BUG(22);
+
+/*  GET SECOND WORD FOR ANALYSIS. */
+
+L2800: WD1=WD2;
+       WD1X=WD2X;
+       WD2=0;
+        goto L2620;
+
+/*  GEE, I DON'T UNDERSTAND. */
+
+L3000: SETPRM(1,WD1,WD1X);
+       RSPEAK(254);
+        goto L2600;
+
+/* VERB AND OBJECT ANALYSIS MOVED TO SEPARATE MODULE. */
+
+L4000: I=4000; goto Laction;
+L4090: I=4090; goto Laction;
+L5000: I=5000;
+Laction:
+       switch (action(I)) {
+          case 2: goto L2;
+          case 8: goto L8;
+          case 2000: goto L2000;
+          case 2009: goto L2009;
+          case 2010: goto L2010;
+          case 2011: goto L2011;
+          case 2012: goto L2012;
+          case 2600: goto L2600;
+          case 2607: goto L2607;
+          case 2630: goto L2630;
+          case 2800: goto L2800;
+          case 8000: goto L8000;
+          case 18999: goto L18999;
+          case 19000: goto L19000;
+          }
+       BUG(99);
+
+/*  RANDOM INTRANSITIVE VERBS COME HERE.  CLEAR OBJ JUST IN CASE (SEE "ATTACK").
+               */
+
+L8000: SETPRM(1,WD1,WD1X);
+       RSPEAK(257);
+       OBJ=0;
+       goto L2600;
+
+/*  FIGURE OUT THE NEW LOCATION
+ *
+ *  GIVEN THE CURRENT LOCATION IN "LOC", AND A MOTION VERB NUMBER IN "K", PUT
+ *  THE NEW LOCATION IN "NEWLOC".  THE CURRENT LOC IS SAVED IN "OLDLOC" IN CASE
+ *  HE WANTS TO RETREAT.  THE CURRENT OLDLOC IS SAVED IN OLDLC2, IN CASE HE
+ *  DIES.  (IF HE DOES, NEWLOC WILL BE LIMBO, AND OLDLOC WILL BE WHAT KILLED
+ *  HIM, SO WE NEED OLDLC2, WHICH IS THE LAST PLACE HE WAS SAFE.) */
+
+L8:    KK=KEY[LOC];
+       NEWLOC=LOC;
+       if(KK == 0)BUG(26);
+       if(K == NUL) goto L2;
+       if(K == BACK) goto L20;
+       if(K == LOOK) goto L30;
+       if(K == CAVE) goto L40;
+       OLDLC2=OLDLOC;
+       OLDLOC=LOC;
+
+L9:    LL=IABS(TRAVEL[KK]);
+       if(MOD(LL,1000) == 1 || MOD(LL,1000) == K) goto L10;
+       if(TRAVEL[KK] < 0) goto L50;
+       KK=KK+1;
+        goto L9;
+
+L10:   LL=LL/1000;
+L11:   NEWLOC=LL/1000;
+       K=MOD(NEWLOC,100);
+       if(NEWLOC <= 300) goto L13;
+       if(PROP[K] != NEWLOC/100-3) goto L16;
+L12:   if(TRAVEL[KK] < 0)BUG(25);
+       KK=KK+1;
+       NEWLOC=IABS(TRAVEL[KK])/1000;
+       if(NEWLOC == LL) goto L12;
+       LL=NEWLOC;
+        goto L11;
+
+L13:   if(NEWLOC <= 100) goto L14;
+       if(TOTING(K) || (NEWLOC > 200 && AT(K))) goto L16;
+        goto L12;
+
+L14:   if(NEWLOC != 0 && !PCT(NEWLOC)) goto L12;
+L16:   NEWLOC=MOD(LL,1000);
+       if(NEWLOC <= 300) goto L2;
+       if(NEWLOC <= 500) goto L30000;
+       RSPEAK(NEWLOC-500);
+       NEWLOC=LOC;
+        goto L2;
+
+/*  SPECIAL MOTIONS COME HERE.  LABELLING CONVENTION: STATEMENT NUMBERS NNNXX
+ *  (XX=00-99) ARE USED FOR SPECIAL CASE NUMBER NNN (NNN=301-500). */
+
+L30000: NEWLOC=NEWLOC-300;
+        switch (NEWLOC) { case 1: goto L30100; case 2: goto L30200; case 3: goto
+               L30300; }
+       BUG(20);
+
+/*  TRAVEL 301.  PLOVER-ALCOVE PASSAGE.  CAN CARRY ONLY EMERALD.  NOTE: TRAVEL
+ *  TABLE MUST INCLUDE "USELESS" ENTRIES GOING THROUGH PASSAGE, WHICH CAN NEVER
+ *  BE USED FOR ACTUAL MOTION, BUT CAN BE SPOTTED BY "GO BACK". */
+
+L30100: NEWLOC=99+100-LOC;
+       if(HOLDNG == 0 || (HOLDNG == 1 && TOTING(EMRALD))) goto L2;
+       NEWLOC=LOC;
+       RSPEAK(117);
+        goto L2;
+
+/*  TRAVEL 302.  PLOVER TRANSPORT.  DROP THE EMERALD (ONLY USE SPECIAL TRAVEL IF
+ *  TOTING IT), SO HE'S FORCED TO USE THE PLOVER-PASSAGE TO GET IT OUT.  HAVING
+ *  DROPPED IT, GO BACK AND PRETEND HE WASN'T CARRYING IT AFTER ALL. */
+
+L30200: DROP(EMRALD,LOC);
+        goto L12;
+
+/*  TRAVEL 303.  TROLL BRIDGE.  MUST BE DONE ONLY AS SPECIAL MOTION SO THAT
+ *  DWARVES WON'T WANDER ACROSS AND ENCOUNTER THE BEAR.  (THEY WON'T FOLLOW THE
+ *  PLAYER THERE BECAUSE THAT REGION IS FORBIDDEN TO THE PIRATE.)  IF
+ *  PROP(TROLL)=1, HE'S CROSSED SINCE PAYING, SO STEP OUT AND BLOCK HIM.
+ *  (STANDARD TRAVEL ENTRIES CHECK FOR PROP(TROLL)=0.)  SPECIAL STUFF FOR BEAR. */
+
+L30300: if(PROP[TROLL] != 1) goto L30310;
+       PSPEAK(TROLL,1);
+       PROP[TROLL]=0;
+       MOVE(TROLL2,0);
+       MOVE(TROLL2+100,0);
+       MOVE(TROLL,PLAC[TROLL]);
+       MOVE(TROLL+100,FIXD[TROLL]);
+       JUGGLE(CHASM);
+       NEWLOC=LOC;
+        goto L2;
+
+L30310: NEWLOC=PLAC[TROLL]+FIXD[TROLL]-LOC;
+       if(PROP[TROLL] == 0)PROP[TROLL]=1;
+       if(!TOTING(BEAR)) goto L2;
+       RSPEAK(162);
+       PROP[CHASM]=1;
+       PROP[TROLL]=2;
+       DROP(BEAR,NEWLOC);
+       FIXED[BEAR]= -1;
+       PROP[BEAR]=3;
+       OLDLC2=NEWLOC;
+        goto L99;
+
+/*  END OF SPECIALS. */
+
+/*  HANDLE "GO BACK".  LOOK FOR VERB WHICH GOES FROM LOC TO OLDLOC, OR TO OLDLC2
+ *  IF OLDLOC HAS FORCED-MOTION.  K2 SAVES ENTRY -> FORCED LOC -> PREVIOUS LOC. */
+
+L20:   K=OLDLOC;
+       if(FORCED(K))K=OLDLC2;
+       OLDLC2=OLDLOC;
+       OLDLOC=LOC;
+       K2=0;
+       if(K == LOC)K2=91;
+       if(CNDBIT(LOC,4))K2=274;
+       if(K2 == 0) goto L21;
+       RSPEAK(K2);
+        goto L2;
+
+L21:   LL=MOD((IABS(TRAVEL[KK])/1000),1000);
+       if(LL == K) goto L25;
+       if(LL > 300) goto L22;
+       J=KEY[LL];
+       if(FORCED(LL) && MOD((IABS(TRAVEL[J])/1000),1000) == K)K2=KK;
+L22:   if(TRAVEL[KK] < 0) goto L23;
+       KK=KK+1;
+        goto L21;
+
+L23:   KK=K2;
+       if(KK != 0) goto L25;
+       RSPEAK(140);
+        goto L2;
+
+L25:   K=MOD(IABS(TRAVEL[KK]),1000);
+       KK=KEY[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(DETAIL < 3)RSPEAK(15);
+       DETAIL=DETAIL+1;
+       WZDARK=FALSE;
+       ABB[LOC]=0;
+        goto L2;
+
+/*  CAVE.  DIFFERENT MESSAGES DEPENDING ON WHETHER ABOVE GROUND. */
+
+L40:   K=58;
+       if(OUTSID(LOC) && LOC != 8)K=57;
+       RSPEAK(K);
+        goto L2;
+
+/*  NON-APPLICABLE MOTION.  VARIOUS MESSAGES DEPENDING ON WORD GIVEN. */
+
+L50:   SPK=12;
+       if(K >= 43 && K <= 50)SPK=52;
+       if(K == 29 || K == 30)SPK=52;
+       if(K == 7 || K == 36 || K == 37)SPK=10;
+       if(K == 11 || K == 19)SPK=11;
+       if(VERB == FIND || VERB == INVENT)SPK=59;
+       if(K == 62 || K == 65)SPK=42;
+       if(K == 17)SPK=80;
+       RSPEAK(SPK);
+        goto L2;
+
+
+
+
+
+/*  "YOU'RE DEAD, JIM."
+ *
+ *  IF THE CURRENT LOC IS ZERO, IT MEANS THE CLOWN GOT HIMSELF KILLED.  WE'LL
+ *  ALLOW THIS MAXDIE TIMES.  MAXDIE IS AUTOMATICALLY SET BASED ON THE NUMBER OF
+ *  SNIDE MESSAGES AVAILABLE.  EACH DEATH RESULTS IN A MESSAGE (81, 83, ETC.)
+ *  WHICH OFFERS REINCARNATION; IF ACCEPTED, THIS RESULTS IN MESSAGE 82, 84,
+ *  ETC.  THE LAST TIME, IF HE WANTS ANOTHER CHANCE, HE GETS A SNIDE REMARK AS
+ *  WE EXIT.  WHEN REINCARNATED, ALL OBJECTS BEING CARRIED GET DROPPED AT OLDLC2
+ *  (PRESUMABLY THE LAST PLACE PRIOR TO BEING KILLED) WITHOUT CHANGE OF PROPS.
+ *  THE LOOP RUNS BACKWARDS TO ASSURE THAT THE BIRD IS DROPPED BEFORE THE CAGE.
+ *  (THIS KLUGE COULD BE CHANGED ONCE WE'RE SURE ALL REFERENCES TO BIRD AND CAGE
+ *  ARE DONE BY KEYWORDS.)  THE LAMP IS A SPECIAL CASE (IT WOULDN'T DO TO LEAVE
+ *  IT IN THE CAVE).  IT IS TURNED OFF AND LEFT OUTSIDE THE BUILDING (ONLY IF HE
+ *  WAS CARRYING IT, OF COURSE).  HE HIMSELF IS LEFT INSIDE THE BUILDING (AND
+ *  HEAVEN HELP HIM IF HE TRIES TO XYZZY BACK INTO THE CAVE WITHOUT THE LAMP!).
+ *  OLDLOC IS ZAPPED SO HE CAN'T JUST "RETREAT". */
+
+/*  THE EASIEST WAY TO GET KILLED IS TO FALL INTO A PIT IN PITCH DARKNESS. */
+
+L90:   RSPEAK(23);
+       OLDLC2=LOC;
+
+/*  OKAY, HE'S DEAD.  LET'S GET ON WITH IT. */
+
+L99:   if(CLOSNG) goto L95;
+       NUMDIE=NUMDIE+1;
+       if(!YES(79+NUMDIE*2,80+NUMDIE*2,54)) score(0);
+       if(NUMDIE == MAXDIE) score(0);
+       PLACE[WATER]=0;
+       PLACE[OIL]=0;
+       if(TOTING(LAMP))PROP[LAMP]=0;
+       /* 98 */ for (J=1; J<=100; J++) {
+       I=101-J;
+       if(!TOTING(I)) goto L98;
+       K=OLDLC2;
+       if(I == LAMP)K=1;
+       DROP(I,K);
+L98:   /*etc*/ ;
+       } /* end loop */
+       LOC=3;
+       OLDLOC=LOC;
+        goto L2000;
+
+/*  HE DIED DURING CLOSING TIME.  NO RESURRECTION.  TALLY UP A DEATH AND EXIT. */
+
+L95:   RSPEAK(131);
+       NUMDIE=NUMDIE+1;
+        score(0);
+
+
+
+
+/*  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 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: HINTLC[HINT]=0;
+       if(!YES(HINTS[HINT][3],0,54)) goto L2602;
+       SETPRM(1,HINTS[HINT][2],HINTS[HINT][2]);
+       RSPEAK(261);
+       HINTED[HINT]=YES(175,HINTS[HINT][4],54);
+       if(HINTED[HINT] && LIMIT > 30)LIMIT=LIMIT+30*HINTS[HINT][2];
+L40020: HINTLC[HINT]=0;
+L40030:  goto L2602;
+
+/*  NOW FOR THE QUICK TESTS.  SEE DATABASE DESCRIPTION FOR ONE-LINE NOTES. */
+
+L40100: if(PROP[GRATE] == 0 && !HERE(KEYS)) goto L40010;
+        goto L40020;
+
+L40200: if(PLACE[BIRD] == LOC && TOTING(ROD) && OLDOBJ == BIRD) goto L40010;
+        goto L40030;
+
+L40300: if(HERE(SNAKE) && !HERE(BIRD)) goto L40010;
+        goto L40020;
+
+L40400: if(ATLOC[LOC] == 0 && ATLOC[OLDLOC] == 0 && ATLOC[OLDLC2] == 0 && HOLDNG >
+               1) goto L40010;
+        goto L40020;
+
+L40500: if(PROP[EMRALD] != -1 && PROP[PYRAM] == -1) goto L40010;
+        goto L40020;
+
+L40600:  goto L40010;
+
+L40700: if(DFLAG == 0) goto L40010;
+        goto L40020;
+
+L40800: if(ATLOC[LOC] == 0 && ATLOC[OLDLOC] == 0 && ATLOC[OLDLC2] == 0) goto
+               L40010;
+        goto L40030;
+
+L40900: I=ATDWRF(LOC);
+       if(I < 0) goto L40020;
+       if(HERE(OGRE) && I == 0) goto L40010;
+        goto L40030;
+
+L41000: if(TALLY == 1 && PROP[JADE] < 0) goto L40010;
+        goto L40020;
+
+
+
+
+
+/*  CAVE CLOSING AND SCORING */
+
+
+/*  THESE SECTIONS HANDLE THE CLOSING OF THE CAVE.  THE CAVE CLOSES "CLOCK1"
+ *  TURNS AFTER THE LAST TREASURE HAS BEEN LOCATED (INCLUDING THE PIRATE'S
+ *  CHEST, WHICH MAY OF COURSE NEVER SHOW UP).  NOTE THAT THE TREASURES NEED NOT
+ *  HAVE BEEN TAKEN YET, JUST LOCATED.  HENCE CLOCK1 MUST BE LARGE ENOUGH TO GET
+ *  OUT OF THE CAVE (IT ONLY TICKS WHILE INSIDE THE CAVE).  WHEN IT HITS ZERO,
+ *  WE BRANCH TO 10000 TO START CLOSING THE CAVE, AND THEN SIT BACK AND WAIT FOR
+ *  HIM TO TRY TO GET OUT.  IF HE DOESN'T WITHIN CLOCK2 TURNS, WE CLOSE THE
+ *  CAVE; IF HE DOES TRY, WE ASSUME HE PANICS, AND GIVE HIM A FEW ADDITIONAL
+ *  TURNS TO GET FRANTIC BEFORE WE CLOSE.  WHEN CLOCK2 HITS ZERO, WE BRANCH TO
+ *  11000 TO TRANSPORT HIM INTO THE FINAL PUZZLE.  NOTE THAT THE PUZZLE DEPENDS
+ *  UPON ALL SORTS OF RANDOM THINGS.  FOR INSTANCE, THERE MUST BE NO WATER OR
+ *  OIL, SINCE THERE ARE BEANSTALKS WHICH WE DON'T WANT TO BE ABLE TO WATER,
+ *  SINCE THE CODE CAN'T HANDLE IT.  ALSO, WE CAN HAVE NO KEYS, SINCE THERE IS A
+ *  GRATE (HAVING MOVED THE FIXED OBJECT!) THERE SEPARATING HIM FROM ALL THE
+ *  TREASURES.  MOST OF THESE PROBLEMS ARISE FROM THE USE OF NEGATIVE PROP
+ *  NUMBERS TO SUPPRESS THE OBJECT DESCRIPTIONS UNTIL HE'S ACTUALLY MOVED THE
+ *  OBJECTS. */
+
+/*  WHEN THE FIRST WARNING COMES, WE LOCK THE GRATE, DESTROY THE BRIDGE, KILL
+ *  ALL THE DWARVES (AND THE PIRATE), REMOVE THE TROLL AND BEAR (UNLESS DEAD),
+ *  AND SET "CLOSNG" TO TRUE.  LEAVE THE DRAGON; TOO MUCH TROUBLE TO MOVE IT.
+ *  FROM NOW UNTIL CLOCK2 RUNS OUT, HE CANNOT UNLOCK THE GRATE, MOVE TO ANY
+ *  LOCATION OUTSIDE THE CAVE, OR CREATE THE BRIDGE.  NOR CAN HE BE
+ *  RESURRECTED IF HE DIES.  NOTE THAT THE SNAKE IS ALREADY GONE, SINCE HE GOT
+ *  TO THE TREASURE ACCESSIBLE ONLY VIA THE HALL OF THE MT. KING.  ALSO, HE'S
+ *  BEEN IN GIANT ROOM (TO GET EGGS), SO WE CAN REFER TO IT.  ALSO ALSO, HE'S
+ *  GOTTEN THE PEARL, SO WE KNOW THE BIVALVE IS AN OYSTER.  *AND*, THE DWARVES
+ *  MUST HAVE BEEN ACTIVATED, SINCE WE'VE FOUND CHEST. */
+
+L10000: PROP[GRATE]=0;
+       PROP[FISSUR]=0;
+       /* 10010 */ for (I=1; I<=6; I++) {
+       DSEEN[I]=FALSE;
+L10010: DLOC[I]=0;
+       } /* end loop */
+       MOVE(TROLL,0);
+       MOVE(TROLL+100,0);
+       MOVE(TROLL2,PLAC[TROLL]);
+       MOVE(TROLL2+100,FIXD[TROLL]);
+       JUGGLE(CHASM);
+       if(PROP[BEAR] != 3)DSTROY(BEAR);
+       PROP[CHAIN]=0;
+       FIXED[CHAIN]=0;
+       PROP[AXE]=0;
+       FIXED[AXE]=0;
+       RSPEAK(129);
+       CLOCK1= -1;
+       CLOSNG=TRUE;
+        goto L19999;
+
+/*  ONCE HE'S PANICKED, AND CLOCK2 HAS RUN OUT, WE COME HERE TO SET UP THE
+ *  STORAGE ROOM.  THE ROOM HAS TWO LOCS, HARDWIRED AS 115 (NE) AND 116 (SW).
+ *  AT THE NE END, WE PLACE EMPTY BOTTLES, A NURSERY OF PLANTS, A BED OF
+ *  OYSTERS, A PILE OF LAMPS, RODS WITH STARS, SLEEPING DWARVES, AND HIM.  AT
+ *  THE SW END WE PLACE GRATE OVER TREASURES, SNAKE PIT, COVEY OF CAGED BIRDS,
+ *  MORE RODS, AND PILLOWS.  A MIRROR STRETCHES ACROSS ONE WALL.  MANY OF THE
+ *  OBJECTS COME FROM KNOWN LOCATIONS AND/OR STATES (E.G. THE SNAKE IS KNOWN TO
+ *  HAVE BEEN DESTROYED AND NEEDN'T BE CARRIED AWAY FROM ITS OLD "PLACE"),
+ *  MAKING THE VARIOUS OBJECTS BE HANDLED DIFFERENTLY.  WE ALSO DROP ALL OTHER
+ *  OBJECTS HE MIGHT BE CARRYING (LEST HE HAVE SOME WHICH COULD CAUSE TROUBLE,
+ *  SUCH AS THE KEYS).  WE DESCRIBE THE FLASH OF LIGHT AND TRUNDLE BACK. */
+
+L11000: PROP[BOTTLE]=PUT(BOTTLE,115,1);
+       PROP[PLANT]=PUT(PLANT,115,0);
+       PROP[OYSTER]=PUT(OYSTER,115,0);
+       OBJTXT[OYSTER]=3;
+       PROP[LAMP]=PUT(LAMP,115,0);
+       PROP[ROD]=PUT(ROD,115,0);
+       PROP[DWARF]=PUT(DWARF,115,0);
+       LOC=115;
+       OLDLOC=115;
+       NEWLOC=115;
+
+/*  LEAVE THE GRATE WITH NORMAL (NON-NEGATIVE) PROPERTY.  REUSE SIGN. */
+
+       I=PUT(GRATE,116,0);
+       I=PUT(SIGN,116,0);
+       OBJTXT[SIGN]=OBJTXT[SIGN]+1;
+       PROP[SNAKE]=PUT(SNAKE,116,1);
+       PROP[BIRD]=PUT(BIRD,116,1);
+       PROP[CAGE]=PUT(CAGE,116,0);
+       PROP[ROD2]=PUT(ROD2,116,0);
+       PROP[PILLOW]=PUT(PILLOW,116,0);
+
+       PROP[MIRROR]=PUT(MIRROR,115,0);
+       FIXED[MIRROR]=116;
+
+       /* 11010 */ for (I=1; I<=100; I++) {
+L11010: if(TOTING(I))DSTROY(I);
+       } /* end loop */
+
+       RSPEAK(132);
+       CLOSED=TRUE;
+        goto L2;
+
+/*  ANOTHER WAY WE CAN FORCE AN END TO THINGS IS BY HAVING THE LAMP GIVE OUT.
+ *  WHEN IT GETS CLOSE, WE COME HERE TO WARN HIM.  WE GO TO 12000 IF THE LAMP
+ *  AND FRESH BATTERIES ARE HERE, IN WHICH CASE WE REPLACE THE BATTERIES AND
+ *  CONTINUE.  12200 IS FOR OTHER CASES OF LAMP DYING.  12400 IS WHEN IT GOES
+ *  OUT.  EVEN THEN, HE CAN EXPLORE OUTSIDE FOR A WHILE IF DESIRED. */
+
+L12000: RSPEAK(188);
+       PROP[BATTER]=1;
+       if(TOTING(BATTER))DROP(BATTER,LOC);
+       LIMIT=LIMIT+2500;
+       LMWARN=FALSE;
+        goto L19999;
+
+L12200: if(LMWARN || !HERE(LAMP)) goto L19999;
+       LMWARN=TRUE;
+       SPK=187;
+       if(PLACE[BATTER] == 0)SPK=183;
+       if(PROP[BATTER] == 1)SPK=189;
+       RSPEAK(SPK);
+        goto L19999;
+
+L12400: LIMIT= -1;
+       PROP[LAMP]=0;
+       if(HERE(LAMP))RSPEAK(184);
+        goto L19999;
+
+/*  OH DEAR, HE'S DISTURBED THE DWARVES. */
+
+L18999: RSPEAK(SPK);
+L19000: RSPEAK(136);
+       score(0);
+}
diff --git a/main.h b/main.h
new file mode 100644 (file)
index 0000000..575ee97
--- /dev/null
+++ b/main.h
@@ -0,0 +1,4 @@
+extern long ABB[], ATAB[], ATLOC[], BLKLIN, DFLAG, DLOC[], FIXED[], HOLDNG,
+               KTAB[], *LINES, LINK[], LNLENG, LNPOSN,
+               PARMS[], PLACE[], PTEXT[], RTEXT[], TABSIZ;
+extern signed char INLINE[], MAP1[], MAP2[];
diff --git a/misc.c b/misc.c
new file mode 100644 (file)
index 0000000..e3e8320
--- /dev/null
+++ b/misc.c
@@ -0,0 +1,1019 @@
+#include "main.h"
+#include "misc.h"
+#include <stdio.h>
+
+#define TRUE  (0==0)
+#define FALSE (0!=0)
+
+/*  I/O ROUTINES (SPEAK, PSPEAK, RSPEAK, SETPRM, GETIN, YES) */
+
+#undef SPEAK
+void fSPEAK(N)long N; {
+long BLANK, CASE, I, K, L, NEG, NPARMS, PARM, PRMTYP, STATE;
+
+/*  PRINT THE MESSAGE WHICH STARTS AT LINES(N).  PRECEDE IT WITH A BLANK LINE
+ *  UNLESS BLKLIN IS FALSE. */
+
+
+       if(N == 0)return;
+       BLANK=BLKLIN;
+       K=N;
+       NPARMS=1;
+L10:   L=IABS(LINES[K])-1;
+       K=K+1;
+       LNLENG=0;
+       LNPOSN=1;
+       STATE=0;
+       /* 20 */ for (I=K; I<=L; I++) {
+L20:   PUTTXT(LINES[I],STATE,2,I);
+       } /* end loop */
+       LNPOSN=0;
+L30:   LNPOSN=LNPOSN+1;
+L32:   if(LNPOSN > LNLENG) goto L40;
+       if(INLINE[LNPOSN] != 63) goto L30;
+       {long x = LNPOSN+1; PRMTYP=INLINE[x];}
+/*  63 IS A "%"; THE NEXT CHARACTER DETERMINE THE TYPE OF PARAMETER:  1 (!) =
+ *  SUPPRESS MESSAGE COMPLETELY, 29 (S) = NULL IF PARM=1, ELSE 'S' (OPTIONAL
+ *  PLURAL ENDING), 33 (W) = WORD (TWO 30-BIT VALUES) WITH TRAILING SPACES
+ *  SUPPRESSED, 22 (L) OR 31 (U) = WORD BUT MAP TO LOWER/UPPER CASE, 13 (C) =
+ *  WORD IN LOWER CASE WITH FIRST LETTER CAPITALISED, 30 (T) = TEXT ENDING
+ *  WITH A WORD OF -1, 65-73 (1-9) = NUMBER USING THAT MANY CHARACTERS,
+ *  12 (B) = VARIABLE NUMBER OF BLANKS. */
+       if(PRMTYP == 1)return;
+       if(PRMTYP == 29) goto L320;
+       if(PRMTYP == 30) goto L340;
+       if(PRMTYP == 12) goto L360;
+       if(PRMTYP == 33 || PRMTYP == 22 || PRMTYP == 31 || PRMTYP == 13) goto
+               L380;
+       PRMTYP=PRMTYP-64;
+       if(PRMTYP < 1 || PRMTYP > 9) goto L30;
+       SHFTXT(LNPOSN+2,PRMTYP-2);
+       LNPOSN=LNPOSN+PRMTYP;
+       PARM=IABS(PARMS[NPARMS]);
+       NEG=0;
+       if(PARMS[NPARMS] < 0)NEG=9;
+       /* 390 */ for (I=1; I<=PRMTYP; I++) {
+       LNPOSN=LNPOSN-1;
+       INLINE[LNPOSN]=MOD(PARM,10)+64;
+       if(I == 1 || PARM != 0) goto L390;
+       INLINE[LNPOSN]=NEG;
+       NEG=0;
+L390:  PARM=PARM/10;
+       } /* end loop */
+       LNPOSN=LNPOSN+PRMTYP;
+L395:  NPARMS=NPARMS+1;
+        goto L32;
+
+L320:  SHFTXT(LNPOSN+2,-1);
+       INLINE[LNPOSN]=55;
+       if(PARMS[NPARMS] == 1)SHFTXT(LNPOSN+1,-1);
+        goto L395;
+
+L340:  SHFTXT(LNPOSN+2,-2);
+       STATE=0;
+       CASE=2;
+L345:  if(PARMS[NPARMS] < 0) goto L395;
+       {long x = NPARMS+1; if(PARMS[x] < 0)CASE=0;}
+       PUTTXT(PARMS[NPARMS],STATE,CASE,0);
+       NPARMS=NPARMS+1;
+        goto L345;
+
+L360:  PRMTYP=PARMS[NPARMS];
+       SHFTXT(LNPOSN+2,PRMTYP-2);
+       if(PRMTYP == 0) goto L395;
+       /* 365 */ for (I=1; I<=PRMTYP; I++) {
+       INLINE[LNPOSN]=0;
+L365:  LNPOSN=LNPOSN+1;
+       } /* end loop */
+        goto L395;
+
+L380:  SHFTXT(LNPOSN+2,-2);
+       STATE=0;
+       CASE= -1;
+       if(PRMTYP == 31)CASE=1;
+       if(PRMTYP == 33)CASE=0;
+       I=LNPOSN;
+       PUTTXT(PARMS[NPARMS],STATE,CASE,0);
+       {long x = NPARMS+1; PUTTXT(PARMS[x],STATE,CASE,0);}
+       if(PRMTYP == 13 && INLINE[I] >= 37 && INLINE[I] <=
+               62)INLINE[I]=INLINE[I]-26;
+       NPARMS=NPARMS+2;
+        goto L32;
+
+L40:   if(BLANK)TYPE0();
+       BLANK=FALSE;
+       TYPE();
+       K=L+1;
+       if(LINES[K] >= 0) goto L10;
+       return;
+}
+
+
+
+#define SPEAK(N) fSPEAK(N)
+#undef PSPEAK
+void fPSPEAK(MSG,SKIP)long MSG, SKIP; {
+long I, M;
+
+/*  FIND THE SKIP+1ST MESSAGE FROM MSG AND PRINT IT.  MSG SHOULD BE THE INDEX OF
+ *  THE INVENTORY MESSAGE FOR OBJECT.  (INVEN+N+1 MESSAGE IS PROP=N MESSAGE). */
+
+
+       M=PTEXT[MSG];
+       if(SKIP < 0) goto L9;
+       /* 3 */ for (I=0; I<=SKIP; I++) {
+L1:    M=IABS(LINES[M]);
+       if(LINES[M] >= 0) goto L1;
+L3:    /*etc*/ ;
+       } /* end loop */
+L9:    SPEAK(M);
+       return;
+}
+
+
+
+#define PSPEAK(MSG,SKIP) fPSPEAK(MSG,SKIP)
+#undef RSPEAK
+void fRSPEAK(I)long I; {
+;
+
+/*  PRINT THE I-TH "RANDOM" MESSAGE (SECTION 6 OF DATABASE). */
+
+
+       if(I != 0)SPEAK(RTEXT[I]);
+       return;
+}
+
+
+
+#define RSPEAK(I) fRSPEAK(I)
+#undef SETPRM
+void fSETPRM(FIRST,P1,P2)long FIRST, P1, P2; {
+;
+
+/*  STORES PARAMETERS INTO THE PRMCOM PARMS ARRAY FOR USE BY SPEAK.  P1 AND P2
+ *  ARE STORED INTO PARMS(FIRST) AND PARMS(FIRST+1). */
+
+
+       if(FIRST >= 25)BUG(29);
+       PARMS[FIRST]=P1;
+       {long x = FIRST+1; PARMS[x]=P2;}
+       return;
+}
+
+
+
+#define SETPRM(FIRST,P1,P2) fSETPRM(FIRST,P1,P2)
+#undef GETIN
+#define WORD1 (*wORD1)
+#define WORD1X (*wORD1X)
+#define WORD2 (*wORD2)
+#define WORD2X (*wORD2X)
+void fGETIN(wORD1,wORD1X,wORD2,wORD2X)long *wORD1, *wORD1X, *wORD2, *wORD2X; {
+long JUNK;
+
+/*  GET A COMMAND FROM THE ADVENTURER.  SNARF OUT THE FIRST WORD, PAD IT WITH
+ *  BLANKS, AND RETURN IT IN WORD1.  CHARS 6 THRU 10 ARE RETURNED IN WORD1X, IN
+ *  CASE WE NEED TO PRINT OUT THE WHOLE WORD IN AN ERROR MESSAGE.  ANY NUMBER OF
+ *  BLANKS MAY FOLLOW THE WORD.  IF A SECOND WORD APPEARS, IT IS RETURNED IN
+ *  WORD2 (CHARS 6 THRU 10 IN WORD2X), ELSE WORD2 IS -1. */
+
+
+L10:   if(BLKLIN)TYPE0();
+       MAPLIN(FALSE);
+       WORD1=GETTXT(TRUE,TRUE,TRUE,0);
+       if(BLKLIN && WORD1 < 0) goto L10;
+       WORD1X=GETTXT(FALSE,TRUE,TRUE,0);
+L12:   JUNK=GETTXT(FALSE,TRUE,TRUE,0);
+       if(JUNK > 0) goto L12;
+       WORD2=GETTXT(TRUE,TRUE,TRUE,0);
+       WORD2X=GETTXT(FALSE,TRUE,TRUE,0);
+L22:   JUNK=GETTXT(FALSE,TRUE,TRUE,0);
+       if(JUNK > 0) goto L22;
+       if(GETTXT(TRUE,TRUE,TRUE,0) <= 0)return;
+       RSPEAK(53);
+        goto L10;
+}
+
+
+
+#undef WORD1
+#undef WORD1X
+#undef WORD2
+#undef WORD2X
+#define GETIN(WORD1,WORD1X,WORD2,WORD2X) fGETIN(&WORD1,&WORD1X,&WORD2,&WORD2X)
+#undef YES
+long fYES(X,Y,Z)long X, Y, Z; {
+
+long YES, REPLY, JUNK1, JUNK2, JUNK3;
+
+/*  PRINT MESSAGE X, WAIT FOR YES/NO ANSWER.  IF YES, PRINT Y AND RETURN TRUE;
+ *  IF NO, PRINT Z AND RETURN FALSE. */
+
+L1:    RSPEAK(X);
+       GETIN(REPLY,JUNK1,JUNK2,JUNK3);
+       if(REPLY == MAKEWD(250519) || REPLY == MAKEWD(25)) goto L10;
+       if(REPLY == MAKEWD(1415) || REPLY == MAKEWD(14)) goto L20;
+       RSPEAK(185);
+        goto L1;
+L10:   YES=TRUE;
+       RSPEAK(Y);
+       return(YES);
+L20:   YES=FALSE;
+       RSPEAK(Z);
+       return(YES);
+}
+
+
+
+
+
+/*  LINE-PARSING ROUTINES (GETNUM, GETTXT, MAKEWD, PUTTXT, SHFTXT, TYPE0)
+               */
+
+/*  THE ROUTINES ON THIS PAGE HANDLE ALL THE STUFF THAT WOULD NORMALLY BE
+ *  TAKEN CARE OF BY FORMAT STATEMENTS.  WE DO IT THIS WAY INSTEAD SO THAT
+ *  WE CAN HANDLE TEXTUAL DATA IN A MACHINE INDEPENDENT FASHION.  ALL THE
+ *  MACHINE DEPENDENT I/O STUFF IS ON THE FOLLOWING PAGE.  SEE THAT PAGE
+ *  FOR A DESCRIPTION OF MAPCOM'S INLINE ARRAY. */
+
+#define YES(X,Y,Z) fYES(X,Y,Z)
+#undef GETNUM
+long fGETNUM(K)long K; {
+long DIGIT, GETNUM, SIGN;
+
+/*  OBTAIN THE NEXT INTEGER FROM AN INPUT LINE.  IF K>0, WE FIRST READ A
+ *  NEW INPUT LINE FROM A FILE; IF K<0, WE READ A LINE FROM THE KEYBOARD;
+ *  IF K=0 WE USE A LINE THAT HAS ALREADY BEEN READ (AND PERHAPS PARTIALLY
+ *  SCANNED).  IF WE'RE AT THE END OF THE LINE OR ENCOUNTER AN ILLEGAL
+ *  CHARACTER (NOT A DIGIT, HYPHEN, OR BLANK), WE RETURN 0. */
+
+
+       if(K != 0)MAPLIN(K > 0);
+       GETNUM=0;
+L10:   if(LNPOSN > LNLENG)return(GETNUM);
+       if(INLINE[LNPOSN] != 0) goto L20;
+       LNPOSN=LNPOSN+1;
+        goto L10;
+
+L20:   SIGN=1;
+       if(INLINE[LNPOSN] != 9) goto L32;
+       SIGN= -1;
+L30:   LNPOSN=LNPOSN+1;
+L32:   if(LNPOSN > LNLENG || INLINE[LNPOSN] == 0) goto L42;
+       DIGIT=INLINE[LNPOSN]-64;
+       if(DIGIT < 0 || DIGIT > 9) goto L40;
+       GETNUM=GETNUM*10+DIGIT;
+        goto L30;
+
+L40:   GETNUM=0;
+L42:   GETNUM=GETNUM*SIGN;
+       LNPOSN=LNPOSN+1;
+       return(GETNUM);
+}
+
+
+
+#define GETNUM(K) fGETNUM(K)
+#undef GETTXT
+long fGETTXT(SKIP,ONEWRD,UPPER,HASH)long HASH, ONEWRD, SKIP, UPPER; {
+long CHAR, GETTXT, I; static long SPLITTING = -1;
+
+/*  TAKE CHARACTERS FROM AN INPUT LINE AND PACK THEM INTO 30-BIT WORDS.
+ *  SKIP SAYS TO SKIP LEADING BLANKS.  ONEWRD SAYS STOP IF WE COME TO A
+ *  BLANK.  UPPER SAYS TO MAP ALL LETTERS TO UPPERCASE.  HASH MAY BE USED
+ *  AS A PARAMETER FOR ENCRYPTING THE TEXT IF DESIRED; HOWEVER, A HASH OF 0
+ *  SHOULD RESULT IN UNMODIFIED BYTES BEING PACKED.  IF WE REACH THE
+ *  END OF THE LINE, THE WORD IS FILLED UP WITH BLANKS (WHICH ENCODE AS 0'S).
+ *  IF WE'RE ALREADY AT END OF LINE WHEN GETTXT IS CALLED, WE RETURN -1. */
+
+       if(LNPOSN != SPLITTING)SPLITTING = -1;
+       GETTXT= -1;
+L10:   if(LNPOSN > LNLENG)return(GETTXT);
+       if((!SKIP) || INLINE[LNPOSN] != 0) goto L11;
+       LNPOSN=LNPOSN+1;
+        goto L10;
+
+L11:   GETTXT=0;
+       /* 15 */ for (I=1; I<=5; I++) {
+       GETTXT=GETTXT*64;
+       if(LNPOSN > LNLENG || (ONEWRD && INLINE[LNPOSN] == 0)) goto L15;
+       CHAR=INLINE[LNPOSN];
+       if(CHAR >= 63) goto L12;
+       SPLITTING = -1;
+       if(UPPER && CHAR >= 37)CHAR=CHAR-26;
+       GETTXT=GETTXT+CHAR;
+        goto L14;
+
+L12:   if(SPLITTING == LNPOSN) goto L13;
+       GETTXT=GETTXT+63;
+       SPLITTING = LNPOSN;
+        goto L15;
+
+L13:   GETTXT=GETTXT+CHAR-63;
+       SPLITTING = -1;
+L14:   LNPOSN=LNPOSN+1;
+L15:   /*etc*/ ;
+       } /* end loop */
+
+       if(HASH)GETTXT=GETTXT+MOD(HASH*13579L+5432L,97531L)*12345L+HASH;
+       return(GETTXT);
+}
+
+
+
+#define GETTXT(SKIP,ONEWRD,UPPER,HASH) fGETTXT(SKIP,ONEWRD,UPPER,HASH)
+#undef MAKEWD
+long fMAKEWD(LETTRS)long LETTRS; {
+long I, L, MAKEWD;
+
+/*  COMBINE FIVE UPPERCASE LETTERS (REPRESENTED BY PAIRS OF DECIMAL DIGITS
+ *  IN LETTRS) TO FORM A 30-BIT VALUE MATCHING THE ONE THAT GETTXT WOULD
+ *  RETURN GIVEN THOSE CHARACTERS PLUS TRAILING BLANKS AND HASH=0.  CAUTION:
+ *  LETTRS WILL OVERFLOW 31 BITS IF 5-LETTER WORD STARTS WITH V-Z.  AS A
+ *  KLUDGEY WORKAROUND, YOU CAN INCREMENT A LETTER BY 5 BY ADDING 50 TO
+ *  THE NEXT PAIR OF DIGITS. */
+
+
+       MAKEWD=0;
+       I=1;
+       L=LETTRS;
+L10:   MAKEWD=MAKEWD+I*(MOD(L,50)+10);
+       I=I*64;
+       if(MOD(L,100) > 50)MAKEWD=MAKEWD+I*5;
+       L=L/100;
+       if(L != 0) goto L10;
+       I=64L*64L*64L*64L*64L/I;
+       MAKEWD=MAKEWD*I;
+       return(MAKEWD);
+}
+
+
+
+#define MAKEWD(LETTRS) fMAKEWD(LETTRS)
+#undef PUTTXT
+#define STATE (*sTATE)
+void fPUTTXT(WORD,sTATE,CASE,HASH)long CASE, HASH, *sTATE, WORD; {
+long ALPH1, ALPH2, BYTE, DIV, I, W;
+
+/*  UNPACK THE 30-BIT VALUE IN WORD TO OBTAIN UP TO 5 INTEGER-ENCODED CHARS,
+ *  AND STORE THEM IN INLINE STARTING AT LNPOSN.  IF LNLENG>=LNPOSN, SHIFT
+ *  EXISTING CHARACTERS TO THE RIGHT TO MAKE ROOM.  HASH MUST BE THE SAME
+ *  AS IT WAS WHEN GETTXT CREATED THE 30-BIT WORD.  STATE WILL BE ZERO WHEN
+ *  PUTTXT IS CALLED WITH THE FIRST OF A SEQUENCE OF WORDS, BUT IS THEREAFTER
+ *  UNCHANGED BY THE CALLER, SO PUTTXT CAN USE IT TO MAINTAIN STATE ACROSS
+ *  CALLS.  LNPOSN AND LNLENG ARE INCREMENTED BY THE NUMBER OF CHARS STORED.
+ *  IF CASE=1, ALL LETTERS ARE MADE UPPERCASE; IF -1, LOWERCASE; IF 0, AS IS.
+ *  ANY OTHER VALUE FOR CASE IS THE SAME AS 0 BUT ALSO CAUSES TRAILING BLANKS
+ *  TO BE INCLUDED (IN ANTICIPATION OF SUBSEQUENT ADDITIONAL TEXT). */
+
+
+       ALPH1=13*CASE+24;
+       ALPH2=26*IABS(CASE)+ALPH1;
+       if(IABS(CASE) > 1)ALPH1=ALPH2;
+/*  ALPH1&2 DEFINE RANGE OF WRONG-CASE CHARS, 11-36 OR 37-62 OR EMPTY. */
+       DIV=64L*64L*64L*64L;
+       W=WORD;
+       if(HASH)W=W-MOD(HASH*13579L+5432L,97531L)*12345L-HASH;
+       /* 18 */ for (I=1; I<=5; I++) {
+       if(W <= 0 && STATE == 0 && IABS(CASE) <= 1)return;
+       BYTE=W/DIV;
+       if(STATE != 0 || BYTE != 63) goto L12;
+       STATE=63;
+        goto L18;
+
+L12:   SHFTXT(LNPOSN,1);
+       STATE=STATE+BYTE;
+       if(STATE < ALPH2 && STATE >= ALPH1)STATE=STATE-26*CASE;
+       INLINE[LNPOSN]=STATE;
+       LNPOSN=LNPOSN+1;
+       STATE=0;
+L18:   W=(W-BYTE*DIV)*64;
+       } /* end loop */
+       return;
+}
+
+
+
+#undef STATE
+#define PUTTXT(WORD,STATE,CASE,HASH) fPUTTXT(WORD,&STATE,CASE,HASH)
+#undef SHFTXT
+void fSHFTXT(FROM,DELTA)long DELTA, FROM; {
+long I, II, JJ;
+
+/*  MOVE INLINE(N) TO INLINE(N+DELTA) FOR N=FROM,LNLENG.  DELTA CAN BE
+ *  NEGATIVE.  LNLENG IS UPDATED; LNPOSN IS NOT CHANGED. */
+
+
+       if(LNLENG < FROM || DELTA == 0) goto L2;
+       /* 1 */ for (I=FROM; I<=LNLENG; I++) {
+       II=I;
+       if(DELTA > 0)II=FROM+LNLENG-I;
+       JJ=II+DELTA;
+L1:    INLINE[JJ]=INLINE[II];
+       } /* end loop */
+L2:    LNLENG=LNLENG+DELTA;
+       return;
+}
+
+
+
+#define SHFTXT(FROM,DELTA) fSHFTXT(FROM,DELTA)
+#undef TYPE0
+void fTYPE0() {
+long TEMP;
+
+/*  TYPE A BLANK LINE.  THIS PROCEDURE IS PROVIDED AS A CONVENIENCE FOR CALLERS
+ *  WHO OTHERWISE HAVE NO USE FOR MAPCOM. */
+
+
+       TEMP=LNLENG;
+       LNLENG=0;
+       TYPE();
+       LNLENG=TEMP;
+       return;
+}
+
+
+
+#define TYPE0() fTYPE0()
+
+
+/*  SUSPEND/RESUME I/O ROUTINES (SAVWDS, SAVARR, SAVWRD) */
+
+#undef SAVWDS
+void fSAVWDS(W1,W2,W3,W4,W5,W6,W7)long *W1, *W2, *W3, *W4, *W5, *W6, *W7; {
+;
+
+/*  WRITE OR READ 7 VARIABLES.  SEE SAVWRD. */
+
+
+       SAVWRD(0,(*W1));
+       SAVWRD(0,(*W2));
+       SAVWRD(0,(*W3));
+       SAVWRD(0,(*W4));
+       SAVWRD(0,(*W5));
+       SAVWRD(0,(*W6));
+       SAVWRD(0,(*W7));
+       return;
+}
+
+
+#define SAVWDS(W1,W2,W3,W4,W5,W6,W7) fSAVWDS(&W1,&W2,&W3,&W4,&W5,&W6,&W7)
+#undef SAVARR
+void fSAVARR(ARR,N)long ARR[], N; {
+long I;
+
+/*  WRITE OR READ AN ARRAY OF N WORDS.  SEE SAVWRD. */
+
+
+       /* 1 */ for (I=1; I<=N; I++) {
+L1:    SAVWRD(0,ARR[I]);
+       } /* end loop */
+       return;
+}
+
+
+
+#define SAVARR(ARR,N) fSAVARR(ARR,N)
+#undef SAVWRD
+#define WORD (*wORD)
+void fSAVWRD(OP,wORD)long OP, *wORD; {
+static long BUF[250], CKSUM = 0, H1, HASH = 0, N = 0, STATE = 0;
+
+/*  IF OP<0, START WRITING A FILE, USING WORD TO INITIALISE ENCRYPTION; SAVE
+ *  WORD IN THE FILE.  IF OP>0, START READING A FILE; READ THE FILE TO FIND
+ *  THE VALUE WITH WHICH TO DECRYPT THE REST.  IN EITHER CASE, IF A FILE IS
+ *  ALREADY OPEN, FINISH WRITING/READING IT AND DON'T START A NEW ONE.  IF OP=0,
+ *  READ/WRITE A SINGLE WORD.  WORDS ARE BUFFERED IN CASE THAT MAKES FOR MORE
+ *  EFFICIENT DISK USE.  WE ALSO COMPUTE A SIMPLE CHECKSUM TO CATCH ELEMENTARY
+ *  POKING WITHIN THE SAVED FILE.  WHEN WE FINISH READING/WRITING THE FILE,
+ *  WE STORE ZERO INTO WORD IF THERE'S NO CHECKSUM ERROR, ELSE NONZERO. */
+
+
+       if(OP != 0){long ifvar; ifvar=(STATE); switch (ifvar<0? -1 : ifvar>0? 1 :
+               0) { case -1: goto L30; case 0: goto L10; case 1: goto L30; }}
+       if(STATE == 0)return;
+       if(N == 250)SAVEIO(1,STATE > 0,BUF);
+       N=MOD(N,250)+1;
+       H1=MOD(HASH*1093L+221573L,1048576L);
+       HASH=MOD(H1*1093L+221573L,1048576L);
+       H1=MOD(H1,1234)*765432+MOD(HASH,123);
+       N--;
+       if(STATE > 0)WORD=BUF[N]+H1;
+       BUF[N]=WORD-H1;
+       N++;
+       CKSUM=MOD(CKSUM*13+WORD,1000000000L);
+       return;
+
+L10:   STATE=OP;
+       SAVEIO(0,STATE > 0,BUF);
+       N=1;
+       if(STATE > 0) goto L15;
+       HASH=MOD(WORD,1048576L);
+       BUF[0]=1234L*5678L-HASH;
+L13:   CKSUM=BUF[0];
+       return;
+
+L15:   SAVEIO(1,TRUE,BUF);
+       HASH=MOD(1234L*5678L-BUF[0],1048576L);
+        goto L13;
+
+L30:   if(N == 250)SAVEIO(1,STATE > 0,BUF);
+       N=MOD(N,250)+1;
+       if(STATE > 0) goto L32;
+       N--; BUF[N]=CKSUM; N++;
+       SAVEIO(1,FALSE,BUF);
+L32:   N--; WORD=BUF[N]-CKSUM; N++;
+       SAVEIO(-1,STATE > 0,BUF);
+       STATE=0;
+       return;
+}
+
+
+
+
+
+/*  DATA STRUC. ROUTINES (VOCAB, DSTROY, JUGGLE, MOVE, PUT, CARRY, DROP, ATDWRF)
+               */
+
+#undef WORD
+#define SAVWRD(OP,WORD) fSAVWRD(OP,&WORD)
+#undef VOCAB
+long fVOCAB(ID,INIT)long ID, INIT; {
+long HASH, I, VOCAB;
+
+/*  LOOK UP ID IN THE VOCABULARY (ATAB) AND RETURN ITS "DEFINITION" (KTAB), OR
+ *  -1 IF NOT FOUND.  IF INIT IS POSITIVE, THIS IS AN INITIALISATION CALL SETTING
+ *  UP A KEYWORD VARIABLE, AND NOT FINDING IT CONSTITUTES A BUG.  IT ALSO MEANS
+ *  THAT ONLY KTAB VALUES WHICH TAKEN OVER 1000 EQUAL INIT MAY BE CONSIDERED.
+ *  (THUS "STEPS", WHICH IS A MOTION VERB AS WELL AS AN OBJECT, MAY BE LOCATED
+ *  AS AN OBJECT.)  AND IT ALSO MEANS THE KTAB VALUE IS TAKEN MOD 1000. */
+
+       HASH=10000;
+       /* 1 */ for (I=1; I<=TABSIZ; I++) {
+       if(KTAB[I] == -1) goto L2;
+       HASH=HASH+7;
+       if(INIT >= 0 && KTAB[I]/1000 != INIT) goto L1;
+       if(ATAB[I] == ID+HASH*HASH) goto L3;
+L1:    /*etc*/ ;
+       } /* end loop */
+       BUG(21);
+
+L2:    VOCAB= -1;
+       if(INIT < 0)return(VOCAB);
+       BUG(5);
+
+L3:    VOCAB=KTAB[I];
+       if(INIT >= 0)VOCAB=MOD(VOCAB,1000);
+       return(VOCAB);
+}
+
+
+
+#define VOCAB(ID,INIT) fVOCAB(ID,INIT)
+#undef DSTROY
+void fDSTROY(OBJECT)long OBJECT; {
+;
+
+/*  PERMANENTLY ELIMINATE "OBJECT" BY MOVING TO A NON-EXISTENT LOCATION. */
+
+
+       MOVE(OBJECT,0);
+       return;
+}
+
+
+
+#define DSTROY(OBJECT) fDSTROY(OBJECT)
+#undef JUGGLE
+void fJUGGLE(OBJECT)long OBJECT; {
+long I, J;
+
+/*  JUGGLE AN OBJECT BY PICKING IT UP AND PUTTING IT DOWN AGAIN, THE PURPOSE
+ *  BEING TO GET THE OBJECT TO THE FRONT OF THE CHAIN OF THINGS AT ITS LOC. */
+
+
+       I=PLACE[OBJECT];
+       J=FIXED[OBJECT];
+       MOVE(OBJECT,I);
+       MOVE(OBJECT+100,J);
+       return;
+}
+
+
+
+#define JUGGLE(OBJECT) fJUGGLE(OBJECT)
+#undef MOVE
+void fMOVE(OBJECT,WHERE)long OBJECT, WHERE; {
+long FROM;
+
+/*  PLACE ANY OBJECT ANYWHERE BY PICKING IT UP AND DROPPING IT.  MAY ALREADY BE
+ *  TOTING, IN WHICH CASE THE CARRY IS A NO-OP.  MUSTN'T PICK UP OBJECTS WHICH
+ *  ARE NOT AT ANY LOC, SINCE CARRY WANTS TO REMOVE OBJECTS FROM ATLOC CHAINS. */
+
+
+       if(OBJECT > 100) goto L1;
+       FROM=PLACE[OBJECT];
+        goto L2;
+L1:    {long x = OBJECT-100; FROM=FIXED[x];}
+L2:    if(FROM > 0 && FROM <= 300)CARRY(OBJECT,FROM);
+       DROP(OBJECT,WHERE);
+       return;
+}
+
+
+
+#define MOVE(OBJECT,WHERE) fMOVE(OBJECT,WHERE)
+#undef PUT
+long fPUT(OBJECT,WHERE,PVAL)long OBJECT, PVAL, WHERE; {
+long PUT;
+
+/*  PUT IS THE SAME AS MOVE, EXCEPT IT RETURNS A VALUE USED TO SET UP THE
+ *  NEGATED PROP VALUES FOR THE REPOSITORY OBJECTS. */
+
+
+       MOVE(OBJECT,WHERE);
+       PUT=(-1)-PVAL;
+       return(PUT);
+}
+
+
+
+#define PUT(OBJECT,WHERE,PVAL) fPUT(OBJECT,WHERE,PVAL)
+#undef CARRY
+void fCARRY(OBJECT,WHERE)long OBJECT, WHERE; {
+long TEMP;
+
+/*  START TOTING AN OBJECT, REMOVING IT FROM THE LIST OF THINGS AT ITS FORMER
+ *  LOCATION.  INCR HOLDNG UNLESS IT WAS ALREADY BEING TOTED.  IF OBJECT>100
+ *  (MOVING "FIXED" SECOND LOC), DON'T CHANGE PLACE OR HOLDNG. */
+
+
+       if(OBJECT > 100) goto L5;
+       if(PLACE[OBJECT] == -1)return;
+       PLACE[OBJECT]= -1;
+       HOLDNG=HOLDNG+1;
+L5:    if(ATLOC[WHERE] != OBJECT) goto L6;
+       ATLOC[WHERE]=LINK[OBJECT];
+       return;
+L6:    TEMP=ATLOC[WHERE];
+L7:    if(LINK[TEMP] == OBJECT) goto L8;
+       TEMP=LINK[TEMP];
+        goto L7;
+L8:    LINK[TEMP]=LINK[OBJECT];
+       return;
+}
+
+
+
+#define CARRY(OBJECT,WHERE) fCARRY(OBJECT,WHERE)
+#undef DROP
+void fDROP(OBJECT,WHERE)long OBJECT, WHERE; {
+;
+
+/*  PLACE AN OBJECT AT A GIVEN LOC, PREFIXING IT ONTO THE ATLOC LIST.  DECR
+ *  HOLDNG IF THE OBJECT WAS BEING TOTED. */
+
+
+       if(OBJECT > 100) goto L1;
+       if(PLACE[OBJECT] == -1)HOLDNG=HOLDNG-1;
+       PLACE[OBJECT]=WHERE;
+        goto L2;
+L1:    {long x = OBJECT-100; FIXED[x]=WHERE;}
+L2:    if(WHERE <= 0)return;
+       LINK[OBJECT]=ATLOC[WHERE];
+       ATLOC[WHERE]=OBJECT;
+       return;
+}
+
+
+
+#define DROP(OBJECT,WHERE) fDROP(OBJECT,WHERE)
+#undef ATDWRF
+long fATDWRF(WHERE)long WHERE; {
+long ATDWRF, I;
+
+/*  RETURN THE INDEX OF FIRST DWARF AT THE GIVEN LOCATION, ZERO IF NO DWARF IS
+ *  THERE (OR IF DWARVES NOT ACTIVE YET), -1 IF ALL DWARVES ARE DEAD.  IGNORE
+ *  THE PIRATE (6TH DWARF). */
+
+
+       ATDWRF=0;
+       if(DFLAG < 2)return(ATDWRF);
+       ATDWRF= -1;
+       /* 1 */ for (I=1; I<=5; I++) {
+       if(DLOC[I] == WHERE) goto L2;
+L1:    if(DLOC[I] != 0)ATDWRF=0;
+       } /* end loop */
+       return(ATDWRF);
+
+L2:    ATDWRF=I;
+       return(ATDWRF);
+}
+
+
+
+
+#define ATDWRF(WHERE) fATDWRF(WHERE)
+
+
+
+/*  UTILITY ROUTINES (SETBIT, TSTBIT, RAN, RNDVOC, BUG) */
+
+#undef SETBIT
+long fSETBIT(BIT)long BIT; {
+long I, SETBIT;
+
+/*  RETURNS 2**BIT FOR USE IN CONSTRUCTING BIT-MASKS. */
+
+
+       SETBIT=1;
+       if(BIT <= 0)return(SETBIT);
+       /* 1 */ for (I=1; I<=BIT; I++) {
+L1:    SETBIT=SETBIT+SETBIT;
+       } /* end loop */
+       return(SETBIT);
+}
+
+
+
+#define SETBIT(BIT) fSETBIT(BIT)
+#undef TSTBIT
+long fTSTBIT(MASK,BIT)long BIT, MASK; {
+long TSTBIT;
+
+/*  RETURNS TRUE IF THE SPECIFIED BIT IS SET IN THE MASK. */
+
+
+       TSTBIT=MOD(MASK/SETBIT(BIT),2) != 0;
+       return(TSTBIT);
+}
+
+
+
+#define TSTBIT(MASK,BIT) fTSTBIT(MASK,BIT)
+#undef RAN
+long fRAN(RANGE)long RANGE; {
+static long D, R = 0, RAN, T;
+
+/*  SINCE THE RAN FUNCTION IN LIB40 SEEMS TO BE A REAL LOSE, WE'LL USE ONE OF
+ *  OUR OWN.  IT'S BEEN RUN THROUGH MANY OF THE TESTS IN KNUTH VOL. 2 AND
+ *  SEEMS TO BE QUITE RELIABLE.  RAN RETURNS A VALUE UNIFORMLY SELECTED
+ *  BETWEEN 0 AND RANGE-1. */
+
+
+       D=1;
+       if(R != 0 && RANGE >= 0) goto L1;
+       DATIME(D,T);
+       R=MOD(T+5,1048576L);
+       D=1000+MOD(D,1000);
+L1:    /* 2 */ for (T=1; T<=D; T++) {
+L2:    R=MOD(R*1093L+221587L,1048576L);
+       } /* end loop */
+       RAN=(RANGE*R)/1048576;
+       return(RAN);
+}
+
+
+
+#define RAN(RANGE) fRAN(RANGE)
+#undef RNDVOC
+long fRNDVOC(CHAR,FORCE)long CHAR, FORCE; {
+long DIV, I, J, RNDVOC;
+
+/*  SEARCHES THE VOCABULARY FOR A WORD WHOSE SECOND CHARACTER IS CHAR, AND
+ *  CHANGES THAT WORD SUCH THAT EACH OF THE OTHER FOUR CHARACTERS IS A
+ *  RANDOM LETTER.  IF FORCE IS NON-ZERO, IT IS USED AS THE NEW WORD.
+ *  RETURNS THE NEW WORD. */
+
+
+       RNDVOC=FORCE;
+       if(RNDVOC != 0) goto L3;
+       /* 1 */ for (I=1; I<=5; I++) {
+       J=11+RAN(26);
+       if(I == 2)J=CHAR;
+L1:    RNDVOC=RNDVOC*64+J;
+       } /* end loop */
+L3:    J=10000;
+       DIV=64L*64L*64L;
+       /* 5 */ for (I=1; I<=TABSIZ; I++) {
+       J=J+7;
+       if(MOD((ATAB[I]-J*J)/DIV,64L) == CHAR) goto L8;
+L5:    /*etc*/ ;
+       } /* end loop */
+       BUG(5);
+
+L8:    ATAB[I]=RNDVOC+J*J;
+       return(RNDVOC);
+}
+
+
+
+#define RNDVOC(CHAR,FORCE) fRNDVOC(CHAR,FORCE)
+#undef BUG
+void fBUG(NUM)long NUM; {
+
+/*  THE FOLLOWING CONDITIONS ARE CURRENTLY CONSIDERED FATAL BUGS.  NUMBERS < 20
+ *  ARE DETECTED WHILE READING THE DATABASE; THE OTHERS OCCUR AT "RUN TIME".
+ *     0       MESSAGE LINE > 70 CHARACTERS
+ *     1       NULL LINE IN MESSAGE
+ *     2       TOO MANY WORDS OF MESSAGES
+ *     3       TOO MANY TRAVEL OPTIONS
+ *     4       TOO MANY VOCABULARY WORDS
+ *     5       REQUIRED VOCABULARY WORD NOT FOUND
+ *     6       TOO MANY RTEXT MESSAGES
+ *     7       TOO MANY HINTS
+ *     8       LOCATION HAS COND BIT BEING SET TWICE
+ *     9       INVALID SECTION NUMBER IN DATABASE
+ *     10      TOO MANY LOCATIONS
+ *     11      TOO MANY CLASS OR TURN MESSAGES
+ *     20      SPECIAL TRAVEL (500>L>300) EXCEEDS GOTO LIST
+ *     21      RAN OFF END OF VOCABULARY TABLE
+ *     22      VOCABULARY TYPE (N/1000) NOT BETWEEN 0 AND 3
+ *     23      INTRANSITIVE ACTION VERB EXCEEDS GOTO LIST
+ *     24      TRANSITIVE ACTION VERB EXCEEDS GOTO LIST
+ *     25      CONDITIONAL TRAVEL ENTRY WITH NO ALTERNATIVE
+ *     26      LOCATION HAS NO TRAVEL ENTRIES
+ *     27      HINT NUMBER EXCEEDS GOTO LIST
+ *     28      INVALID MONTH RETURNED BY DATE FUNCTION
+ *     29      TOO MANY PARAMETERS GIVEN TO SETPRM */
+
+       printf("Fatal error %d.  See source code for interpretation.\n",
+          NUM);
+       exit(FALSE);
+}
+
+
+
+
+
+/*  MACHINE DEPENDENT ROUTINES (MAPLIN, TYPE, MPINIT, SAVEIO) */
+
+#define BUG(NUM) fBUG(NUM)
+#undef MAPLIN
+void fMAPLIN(FIL)long FIL; {
+long I, VAL; static FILE *OPENED = NULL;
+
+/*  READ A LINE OF INPUT, EITHER FROM A FILE (IF FIL=.TRUE.) OR FROM THE
+ *  KEYBOARD, TRANSLATE THE CHARS TO INTEGERS IN THE RANGE 0-126 AND STORE
+ *  THEM IN THE COMMON ARRAY "INLINE".  INTEGER VALUES ARE AS FOLLOWS:
+ *     0   = SPACE [ASCII CODE 40 OCTAL, 32 DECIMAL]
+ *    1-2  = !" [ASCII 41-42 OCTAL, 33-34 DECIMAL]
+ *    3-10 = '()*+,-. [ASCII 47-56 OCTAL, 39-46 DECIMAL]
+ *   11-36 = UPPER-CASE LETTERS
+ *   37-62 = LOWER-CASE LETTERS
+ *    63   = PERCENT (%) [ASCII 45 OCTAL, 37 DECIMAL]
+ *   64-73 = DIGITS, 0 THROUGH 9
+ *  REMAINING CHARACTERS CAN BE TRANSLATED ANY WAY THAT IS CONVENIENT;
+ *  THE "TYPE" ROUTINE BELOW IS USED TO MAP THEM BACK TO CHARACTERS WHEN
+ *  NECESSARY.  THE ABOVE MAPPINGS ARE REQUIRED SO THAT CERTAIN SPECIAL
+ *  CHARACTERS ARE KNOWN TO FIT IN 6 BITS AND/OR CAN BE EASILY SPOTTED.
+ *  ARRAY ELEMENTS BEYOND THE END OF THE LINE SHOULD BE FILLED WITH 0,
+ *  AND LNLENG SHOULD BE SET TO THE INDEX OF THE LAST CHARACTER.
+ *
+ *  IF THE DATA FILE USES A CHARACTER OTHER THAN SPACE (E.G., TAB) TO
+ *  SEPARATE NUMBERS, THAT CHARACTER SHOULD ALSO TRANSLATE TO 0.
+ *
+ *  THIS PROCEDURE MAY USE THE MAP1,MAP2 ARRAYS TO MAINTAIN STATIC DATA FOR
+ *  THE MAPPING.  MAP2(1) IS SET TO 0 WHEN THE PROGRAM STARTS
+ *  AND IS NOT CHANGED THEREAFTER UNLESS THE ROUTINES ON THIS PAGE CHOOSE
+ *  TO DO SO.
+ *
+ *  NOTE THAT MAPLIN IS EXPECTED TO OPEN THE FILE THE FIRST TIME IT IS
+ *  ASKED TO READ A LINE FROM IT.  THAT IS, THERE IS NO OTHER PLACE WHERE
+ *  THE DATA FILE IS OPENED. */
+
+
+       if(MAP2[1] == 0)MPINIT();
+
+       if(FIL) goto L15;
+       gets(INLINE+1);
+       if(feof(stdin)) score(1);
+        goto L20;
+
+L15:   if(!OPENED){
+#ifdef AMIGA
+               OPENED=fopen("ram:adventure.text","r" /* NOT binary */);
+               if(!OPENED)
+#endif
+               OPENED=fopen("adventure.text","r" /* NOT binary */);
+               if(!OPENED){printf("Can't read adventure.text!\n"); exit(FALSE);}
+               }
+       fgets(INLINE+1,100,OPENED);
+
+L20:   LNLENG=0;
+       /* 25 */ for (I=1; I<=100 && INLINE[I]!=0; I++) {
+       VAL=INLINE[I]+1;
+       INLINE[I]=MAP1[VAL];
+L25:   if(INLINE[I] != 0)LNLENG=I;
+       } /* end loop */
+       LNPOSN=1;
+       if(FIL && LNLENG == 0) goto L15;
+/*  ABOVE IS TO GET AROUND AN F40 COMPILER BUG WHEREIN IT READS A BLANK
+ *  LINE WHENEVER A CRLF IS BROKEN ACROSS A RECORD BOUNDARY. */
+       return;
+}
+
+
+
+#define MAPLIN(FIL) fMAPLIN(FIL)
+#undef TYPE
+void fTYPE() {
+long I, VAL;
+
+/*  TYPE THE FIRST "LNLENG" CHARACTERS STORED IN INLINE, MAPPING THEM
+ *  FROM INTEGERS TO TEXT PER THE RULES DESCRIBED ABOVE.  INLINE(I),
+ *  I=1,LNLENG MAY BE CHANGED BY THIS ROUTINE. */
+
+
+       if(LNLENG != 0) goto L10;
+       printf("\n");
+       return;
+
+L10:   if(MAP2[1] == 0)MPINIT();
+       /* 20 */ for (I=1; I<=LNLENG; I++) {
+       VAL=INLINE[I];
+L20:   {long x = VAL+1; INLINE[I]=MAP2[x];}
+       } /* end loop */
+       {long x = LNLENG+1; INLINE[x]=0;}
+       printf("%s\n",INLINE+1);
+       return;
+}
+
+
+
+#define TYPE() fTYPE()
+#undef MPINIT
+void fMPINIT() {
+long FIRST, I, J, LAST, VAL;
+static long RUNS[7][2] = {32,34, 39,46, 65,90, 97,122, 37,37, 48,57, 0,126};
+
+
+       /* 10 */ for (I=1; I<=128; I++) {
+L10:   MAP1[I]= -1;
+       } /* end loop */
+       VAL=0;
+       /* 20 */ for (I=0; I<7; I++) {
+       FIRST=RUNS[I][0];
+       LAST=RUNS[I][1];
+       /* 22 */ for (J=FIRST; J<=LAST; J++) {
+       J++; if(MAP1[J] >= 0) goto L22;
+       MAP1[J]=VAL;
+       VAL=VAL+1;
+L22:   J--;
+       } /* end loop */
+L20:   /*etc*/ ;
+       } /* end loop */
+       MAP1[128]=MAP1[10];
+/*  FOR THIS VERSION, TAB (9) MAPS TO SPACE (32), SO DEL (127) USES TAB'S VALUE */
+       MAP1[10]=MAP1[33];
+       MAP1[11]=MAP1[33];
+
+       /* 30 */ for (I=0; I<=126; I++) {
+       I++; VAL=MAP1[I]+1; I--;
+       MAP2[VAL]=I*('B'-'A');
+L30:   if(I >= 64)MAP2[VAL]=(I-64)*('B'-'A')+'@';
+       } /* end loop */
+
+       return;
+}
+
+
+
+#define MPINIT() fMPINIT()
+#undef SAVEIO
+void fSAVEIO(OP,IN,ARR)long ARR[], IN, OP; {
+static FILE *F; char NAME[50];
+
+/*  IF OP=0, ASK FOR A FILE NAME AND OPEN A FILE.  (IF IN=.TRUE., THE FILE IS FOR
+ *  INPUT, ELSE OUTPUT.)  IF OP>0, READ/WRITE ARR FROM/INTO THE PREVIOUSLY-OPENED
+ *  FILE.  (ARR IS A 250-INTEGER ARRAY.)  IF OP<0, FINISH READING/WRITING THE
+ *  FILE.  (FINISHING WRITING CAN BE A NO-OP IF A "STOP" STATEMENT DOES IT
+ *  AUTOMATICALLY.  FINISHING READING CAN BE A NO-OP AS LONG AS A SUBSEQUENT
+ *  SAVEIO(0,.FALSE.,X) WILL STILL WORK.)  IF YOU CAN CATCH ERRORS (E.G., NO SUCH
+ *  FILE) AND TRY AGAIN, GREAT.  DEC F40 CAN'T. */
+
+
+       {long ifvar; ifvar=(OP); switch (ifvar<0? -1 : ifvar>0? 1 : 0) { case -1:
+               goto L10; case 0: goto L20; case 1: goto L30; }}
+
+L10:   fclose(F);
+       return;
+
+L20:   printf("\nFile name: ");
+       gets(NAME);
+       F=fopen(NAME,(IN ? READ_MODE : WRITE_MODE));
+       if(F == NULL) {printf("Can't open file, try again.\n"); goto L20;}
+       return;
+
+L30:   if(IN)fread(ARR,4,250,F);
+       if(!IN)fwrite(ARR,4,250,F);
+       return;
+
+}
+
+
+
+long fIABS(N)long N; {return(N<0? -N : N);}
+long fMOD(N,M)long N, M; {return(N%M);}
diff --git a/misc.h b/misc.h
new file mode 100644 (file)
index 0000000..6654ea9
--- /dev/null
+++ b/misc.h
@@ -0,0 +1,78 @@
+#ifdef __MSDOS__       /* define fopen modes for binary files */
+#define READ_MODE "rb"
+#define WRITE_MODE "wb"
+#else
+#define READ_MODE "r"
+#define WRITE_MODE "w"
+#endif
+
+extern void fSPEAK(long);
+#define SPEAK(N) fSPEAK(N)
+extern void fPSPEAK(long,long);
+#define PSPEAK(MSG,SKIP) fPSPEAK(MSG,SKIP)
+extern void fRSPEAK(long);
+#define RSPEAK(I) fRSPEAK(I)
+extern void fSETPRM(long,long,long);
+#define SETPRM(FIRST,P1,P2) fSETPRM(FIRST,P1,P2)
+extern void fGETIN(long*,long*,long*,long*);
+#define GETIN(WORD1,WORD1X,WORD2,WORD2X) fGETIN(&WORD1,&WORD1X,&WORD2,&WORD2X)
+extern long fYES(long,long,long);
+#define YES(X,Y,Z) fYES(X,Y,Z)
+extern long fGETNUM(long);
+#define GETNUM(K) fGETNUM(K)
+extern long fGETTXT(long,long,long,long);
+#define GETTXT(SKIP,ONEWRD,UPPER,HASH) fGETTXT(SKIP,ONEWRD,UPPER,HASH)
+extern long fMAKEWD(long);
+#define MAKEWD(LETTRS) fMAKEWD(LETTRS)
+extern void fPUTTXT(long,long*,long,long);
+#define PUTTXT(WORD,STATE,CASE,HASH) fPUTTXT(WORD,&STATE,CASE,HASH)
+extern void fSHFTXT(long,long);
+#define SHFTXT(FROM,DELTA) fSHFTXT(FROM,DELTA)
+extern void fTYPE0();
+#define TYPE0() fTYPE0()
+extern void fSAVWDS(long*,long*,long*,long*,long*,long*,long*);
+#define SAVWDS(W1,W2,W3,W4,W5,W6,W7) fSAVWDS(&W1,&W2,&W3,&W4,&W5,&W6,&W7)
+extern void fSAVARR(long*,long);
+#define SAVARR(ARR,N) fSAVARR(ARR,N)
+extern void fSAVWRD(long,long*);
+#define SAVWRD(OP,WORD) fSAVWRD(OP,&WORD)
+extern long fVOCAB(long,long);
+#define VOCAB(ID,INIT) fVOCAB(ID,INIT)
+extern void fDSTROY(long);
+#define DSTROY(OBJECT) fDSTROY(OBJECT)
+extern void fJUGGLE(long);
+#define JUGGLE(OBJECT) fJUGGLE(OBJECT)
+extern void fMOVE(long,long);
+#define MOVE(OBJECT,WHERE) fMOVE(OBJECT,WHERE)
+extern long fPUT(long,long,long);
+#define PUT(OBJECT,WHERE,PVAL) fPUT(OBJECT,WHERE,PVAL)
+extern void fCARRY(long,long);
+#define CARRY(OBJECT,WHERE) fCARRY(OBJECT,WHERE)
+extern void fDROP(long,long);
+#define DROP(OBJECT,WHERE) fDROP(OBJECT,WHERE)
+extern long fATDWRF(long);
+#define ATDWRF(WHERE) fATDWRF(WHERE)
+extern long fSETBIT(long);
+#define SETBIT(BIT) fSETBIT(BIT)
+extern long fTSTBIT(long,long);
+#define TSTBIT(MASK,BIT) fTSTBIT(MASK,BIT)
+extern long fRAN(long);
+#define RAN(RANGE) fRAN(RANGE)
+extern long fRNDVOC(long,long);
+#define RNDVOC(CHAR,FORCE) fRNDVOC(CHAR,FORCE)
+extern void fBUG(long);
+#define BUG(NUM) fBUG(NUM)
+extern void fMAPLIN(long);
+#define MAPLIN(FIL) fMAPLIN(FIL)
+extern void fTYPE();
+#define TYPE() fTYPE()
+extern void fMPINIT();
+#define MPINIT() fMPINIT()
+extern void fSAVEIO(long,long,long*);
+#define SAVEIO(OP,IN,ARR) fSAVEIO(OP,IN,ARR)
+extern void fDATIME(long*,long*);
+#define DATIME(D,T) fDATIME(&D,&T)
+extern long fIABS(long);
+#define IABS(N) fIABS(N)
+extern long fMOD(long,long);
+#define MOD(N,M) fMOD(N,M)
diff --git a/score.c b/score.c
new file mode 100644 (file)
index 0000000..acda23f
--- /dev/null
+++ b/score.c
@@ -0,0 +1,119 @@
+#include "misc.h"
+#include "main.h"
+#include "share.h"
+
+#define TRUE  (0==0)
+#define FALSE (0!=0)
+
+/*
+ * SCORING AND WRAP-UP
+ */
+
+void score(MODE)long MODE; {
+       /* <0 if scoring, >0 if quitting, =0 if died or won */
+
+/*  THE PRESENT SCORING ALGORITHM IS AS FOLLOWS:
+ *     OBJECTIVE:          POINTS:        PRESENT TOTAL POSSIBLE:
+ *  GETTING WELL INTO CAVE   25                    25
+ *  EACH TREASURE < CHEST    12                    60
+ *  TREASURE CHEST ITSELF    14                    14
+ *  EACH TREASURE > CHEST    16                   224
+ *  SURVIVING             (MAX-NUM)*10             30
+ *  NOT QUITTING              4                     4
+ *  REACHING "CLOSNG"        25                    25
+ *  "CLOSED": QUIT/KILLED    10
+ *            KLUTZED        25
+ *            WRONG WAY      30
+ *            SUCCESS        45                    45
+ *  CAME TO WITT'S END        1                     1
+ *  ROUND OUT THE TOTAL       2                     2
+ *                                       TOTAL:   430
+ *  POINTS CAN ALSO BE DEDUCTED FOR USING HINTS OR TOO MANY TURNS, OR FOR
+ *  SAVING INTERMEDIATE POSITIONS. */
+
+L20000: SCORE=0;
+       MXSCOR=0;
+
+/*  FIRST TALLY UP THE TREASURES.  MUST BE IN BUILDING AND NOT BROKEN.
+ *  GIVE THE POOR GUY 2 POINTS JUST FOR FINDING EACH TREASURE. */
+
+       /* 20010 */ for (I=50; I<=MAXTRS; I++) {
+       if(PTEXT[I] == 0) goto L20010;
+       K=12;
+       if(I == CHEST)K=14;
+       if(I > CHEST)K=16;
+       if(PROP[I] >= 0)SCORE=SCORE+2;
+       if(PLACE[I] == 3 && PROP[I] == 0)SCORE=SCORE+K-2;
+       MXSCOR=MXSCOR+K;
+L20010: /*etc*/ ;
+       } /* end loop */
+
+/*  NOW LOOK AT HOW HE FINISHED AND HOW FAR HE GOT.  MAXDIE AND NUMDIE TELL US
+ *  HOW WELL HE SURVIVED.  DFLAG WILL
+ *  TELL US IF HE EVER GOT SUITABLY DEEP INTO THE CAVE.  CLOSNG STILL INDICATES
+ *  WHETHER HE REACHED THE ENDGAME.  AND IF HE GOT AS FAR AS "CAVE CLOSED"
+ *  (INDICATED BY "CLOSED"), THEN BONUS IS ZERO FOR MUNDANE EXITS OR 133, 134,
+ *  135 IF HE BLEW IT (SO TO SPEAK). */
+
+       SCORE=SCORE+(MAXDIE-NUMDIE)*10;
+       MXSCOR=MXSCOR+MAXDIE*10;
+       if(MODE == 0)SCORE=SCORE+4;
+       MXSCOR=MXSCOR+4;
+       if(DFLAG != 0)SCORE=SCORE+25;
+       MXSCOR=MXSCOR+25;
+       if(CLOSNG)SCORE=SCORE+25;
+       MXSCOR=MXSCOR+25;
+       if(!CLOSED) goto L20020;
+       if(BONUS == 0)SCORE=SCORE+10;
+       if(BONUS == 135)SCORE=SCORE+25;
+       if(BONUS == 134)SCORE=SCORE+30;
+       if(BONUS == 133)SCORE=SCORE+45;
+L20020: MXSCOR=MXSCOR+45;
+
+/*  DID HE COME TO WITT'S END AS HE SHOULD? */
+
+       if(PLACE[MAGZIN] == 108)SCORE=SCORE+1;
+       MXSCOR=MXSCOR+1;
+
+/*  ROUND IT OFF. */
+
+       SCORE=SCORE+2;
+       MXSCOR=MXSCOR+2;
+
+/*  DEDUCT FOR HINTS/TURNS/SAVES.  HINTS < 4 ARE SPECIAL; SEE DATABASE DESC. */
+
+       /* 20030 */ for (I=1; I<=HNTMAX; I++) {
+L20030: if(HINTED[I])SCORE=SCORE-HINTS[I][2];
+       } /* end loop */
+       if(NOVICE)SCORE=SCORE-5;
+       if(CLSHNT)SCORE=SCORE-10;
+       SCORE=SCORE-TRNLUZ-SAVED;
+
+/*  RETURN TO SCORE COMMAND IF THAT'S WHERE WE CAME FROM. */
+
+       if(MODE < 0) return;
+
+/*  THAT SHOULD BE GOOD ENOUGH.  LET'S TELL HIM ALL ABOUT IT. */
+
+       if(SCORE+TRNLUZ+1 >= MXSCOR && TRNLUZ != 0)RSPEAK(242);
+       if(SCORE+SAVED+1 >= MXSCOR && SAVED != 0)RSPEAK(143);
+       SETPRM(1,SCORE,MXSCOR);
+       SETPRM(3,TURNS,TURNS);
+       RSPEAK(262);
+       /* 20200 */ for (I=1; I<=CLSSES; I++) {
+       if(CVAL[I] >= SCORE) goto L20210;
+L20200: /*etc*/ ;
+       } /* end loop */
+       SPK=265;
+        goto L25000;
+
+L20210: SPEAK(CTEXT[I]);
+       SPK=264;
+       if(I >= CLSSES) goto L25000;
+       I=CVAL[I]+1-SCORE;
+       SETPRM(1,I,I);
+       SPK=263;
+L25000: RSPEAK(SPK);
+       exit(FALSE);
+
+}
diff --git a/share.h b/share.h
new file mode 100644 (file)
index 0000000..ff4252b
--- /dev/null
+++ b/share.h
@@ -0,0 +1,24 @@
+extern void score(long);
+extern long ABBNUM, ACTSPK[], AMBER, ATTACK, AXE, BACK, BATTER, BEAR,
+   BIRD, BLOOD, BONUS,
+   BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST, CHLOC, CHLOC2,
+   CLAM, CLOCK1, CLOCK2, CLOSED, CLOSNG, CLSHNT, CLSMAX, CLSSES,
+   COINS, COND[], CONDS, CTEXT[], CVAL[], DALTLC, DETAIL,
+   DKILL, DOOR, DPRSSN, DRAGON, DSEEN[], DTOTAL, DWARF, EGGS,
+   EMRALD, ENTER, ENTRNC, FIND, FISSUR, FIXD[], FOOBAR, FOOD,
+   GRATE, HINT, HINTED[], HINTLC[], HINTS[][5], HNTMAX,
+   HNTSIZ, I, INVENT, IGO, IWEST, J, JADE, K, K2, KEY[], KEYS, KK,
+   KNFLOC, KNIFE, KQ, L, LAMP, LIMIT, LINSIZ, LINUSE, LL,
+   LMWARN, LOC, LOCK, LOCSIZ, LOCSND[], LOOK, LTEXT[],
+   MAGZIN, MAXDIE, MAXTRS, MESH, MESSAG, MIRROR, MXSCOR,
+   NEWLOC, NOVICE, NUGGET, NUL, NUMDIE, OBJ, OBJSND[],
+   OBJTXT[], ODLOC[], OGRE, OIL, OLDLC2, OLDLOC, OLDOBJ, OYSTER,
+   PANIC, PEARL, PILLOW, PLAC[], PLANT, PLANT2, PROP[], PYRAM,
+   RESER, ROD, ROD2, RTXSIZ, RUBY, RUG, SAPPH, SAVED, SAY,
+   SCORE, SECT, SETUP, SIGN, SNAKE, SPK, STEPS, STEXT[], STICK,
+   STREAM, TABNDX, TALLY, THRESH, THROW, TK[], TRAVEL[], TRIDNT,
+   TRNDEX, TRNLUZ, TRNSIZ, TRNVAL[], TRNVLS, TROLL, TROLL2, TRVS,
+   TRVSIZ, TTEXT[], TURNS, URN, V1, V2, VASE, VEND, VERB,
+   VOLCAN, VRBSIZ, VRSION, WATER, WD1, WD1X, WD2, WD2X,
+   WZDARK, ZZWORD;
+