--- /dev/null
+# 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
--- /dev/null
+#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);
+
+}
--- /dev/null
+#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);
+}
--- /dev/null
+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
--- /dev/null
+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.)
--- /dev/null
+#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
--- /dev/null
+/* 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)
+
+
+
+
--- /dev/null
+#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");
+}
--- /dev/null
+#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);
+}
--- /dev/null
+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[];
--- /dev/null
+#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);}
--- /dev/null
+#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)
--- /dev/null
+#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);
+
+}
--- /dev/null
+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;
+