Fix up case on all comments to make them more readable. No code changes.
The all-capsing was a FORTRAN remnant.Also, we change a few FORTRANisms so they are less confusing in this C context; ".TRUE." and ".FALSE." become "true" and "false", "MOD" is mapped to % in places tha t are like C expressions and (usually) "modulo" in places that aren't.
This commit is contained in:
parent
809f53d099
commit
18767d52dd
7 changed files with 690 additions and 690 deletions
116
actions1.c
116
actions1.c
|
@ -11,8 +11,8 @@
|
|||
* 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. */
|
||||
/* Analyse a verb. remember what it was, go back for object if second word
|
||||
* unless verb is "say", which snarfs arbitrary second word. */
|
||||
|
||||
int action(long STARTAT) {
|
||||
switch(STARTAT) {
|
||||
|
@ -28,7 +28,7 @@ L4000: VERB=K;
|
|||
if(VERB == SAY)OBJ=WD2;
|
||||
if(OBJ > 0) goto L4090;
|
||||
|
||||
/* ANALYSE AN INTRANSITIVE VERB (IE, NO OBJECT GIVEN YET). */
|
||||
/* 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;
|
||||
|
@ -48,7 +48,7 @@ L4080: switch (VERB-1) { case 0: goto L8010; case 1: return(8000); case 2:
|
|||
* RESU FLY LSTN ZZZZ */
|
||||
BUG(23);
|
||||
|
||||
/* ANALYSE A TRANSITIVE VERB. */
|
||||
/* 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;
|
||||
|
@ -68,11 +68,11 @@ L4090: switch (VERB-1) { case 0: goto L9010; case 1: goto L9020; case 2: goto
|
|||
* 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. */
|
||||
/* 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;
|
||||
|
@ -109,23 +109,23 @@ L5190: if((VERB == FIND || VERB == INVENT) && WD2 <= 0) goto L5010;
|
|||
|
||||
|
||||
|
||||
/* ROUTINES FOR PERFORMING THE VARIOUS ACTION VERBS */
|
||||
/* 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. */
|
||||
/* 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. */
|
||||
/* 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. */
|
||||
/* 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. */
|
||||
/* 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);
|
||||
|
@ -139,7 +139,7 @@ L9035: WD2=0;
|
|||
OBJ=0;
|
||||
return(2630);
|
||||
|
||||
/* LOCK, UNLOCK, NO OBJECT GIVEN. ASSUME VARIOUS THINGS IF PRESENT. */
|
||||
/* Lock, unlock, no object given. Assume various things if present. */
|
||||
|
||||
L8040: SPK=28;
|
||||
if(HERE(CLAM))OBJ=CLAM;
|
||||
|
@ -150,7 +150,7 @@ L8040: SPK=28;
|
|||
if(HERE(CHAIN))OBJ=CHAIN;
|
||||
if(OBJ == 0) return(2011);
|
||||
|
||||
/* LOCK, UNLOCK OBJECT. SPECIAL STUFF FOR OPENING CLAM/OYSTER AND FOR CHAIN. */
|
||||
/* 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;
|
||||
|
@ -172,7 +172,7 @@ L9043: K=34+PROP[GRATE];
|
|||
K=K+2*PROP[GRATE];
|
||||
return(2010);
|
||||
|
||||
/* CLAM/OYSTER. */
|
||||
/* Clam/Oyster. */
|
||||
L9046: K=0;
|
||||
if(OBJ == OYSTER)K=1;
|
||||
SPK=124+K;
|
||||
|
@ -185,7 +185,7 @@ L9046: K=0;
|
|||
DROP(PEARL,105);
|
||||
return(2011);
|
||||
|
||||
/* CHAIN. */
|
||||
/* Chain. */
|
||||
L9048: if(VERB == LOCK) goto L9049;
|
||||
SPK=171;
|
||||
if(PROP[BEAR] == 0)SPK=41;
|
||||
|
@ -206,7 +206,7 @@ L9049: SPK=172;
|
|||
FIXED[CHAIN]= -1;
|
||||
return(2011);
|
||||
|
||||
/* LIGHT. APPLICABLE ONLY TO LAMP AND URN. */
|
||||
/* 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;
|
||||
|
@ -227,7 +227,7 @@ L9073: SPK=38;
|
|||
PROP[URN]=2;
|
||||
return(2011);
|
||||
|
||||
/* EXTINGUISH. LAMP, URN, DRAGON/VOLCANO (NICE TRY). */
|
||||
/* 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;
|
||||
|
@ -247,7 +247,7 @@ L9086: PROP[LAMP]=0;
|
|||
if(DARK(0))RSPEAK(16);
|
||||
return(2012);
|
||||
|
||||
/* WAVE. NO EFFECT UNLESS WAVING ROD AT FISSURE OR AT BIRD. */
|
||||
/* 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))))
|
||||
|
@ -267,12 +267,12 @@ L9094: DROP(JADE,LOC);
|
|||
SPK=208;
|
||||
return(2011);
|
||||
|
||||
/* ATTACK ALSO MOVED INTO SEPARATE MODULE. */
|
||||
/* 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. */
|
||||
/* 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);
|
||||
|
@ -302,8 +302,8 @@ L9132: PROP[DOOR]=0;
|
|||
L9134: OBJ=URN;
|
||||
goto L9220;
|
||||
|
||||
/* EAT. INTRANSITIVE: ASSUME FOOD IF PRESENT, ELSE ASK WHAT. TRANSITIVE: FOOD
|
||||
* OK, SOME THINGS LOSE APPETITE, REST ARE RIDICULOUS. */
|
||||
/* 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);
|
||||
|
@ -316,8 +316,8 @@ L9140: if(OBJ == FOOD) goto L8142;
|
|||
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. */
|
||||
/* 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);
|
||||
|
@ -335,7 +335,7 @@ L9153: DSTROY(BLOOD);
|
|||
SPK=240;
|
||||
return(2011);
|
||||
|
||||
/* RUB. YIELDS VARIOUS SNIDE REMARKS EXCEPT FOR LIT URN. */
|
||||
/* Rub. Yields various snide remarks except for lit urn. */
|
||||
|
||||
L9160: if(OBJ != LAMP)SPK=76;
|
||||
if(OBJ != URN || PROP[URN] != 2) return(2011);
|
||||
|
@ -347,16 +347,16 @@ L9160: if(OBJ != LAMP)SPK=76;
|
|||
SPK=216;
|
||||
return(2011);
|
||||
|
||||
/* THROW MOVED INTO SEPARATE MODULE. */
|
||||
/* Throw moved into separate module. */
|
||||
|
||||
L9170: return(throw());
|
||||
|
||||
/* QUIT. INTRANSITIVE ONLY. VERIFY INTENT AND EXIT IF THAT'S WHAT HE WANTS. */
|
||||
/* 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. */
|
||||
/* 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;
|
||||
|
@ -364,7 +364,7 @@ L9190: if(AT(OBJ) || (LIQ(0) == OBJ && AT(BOTTLE)) || K == LIQLOC(LOC) || (OBJ =
|
|||
if(TOTING(OBJ))SPK=24;
|
||||
return(2011);
|
||||
|
||||
/* INVENTORY. IF OBJECT, TREAT SAME AS FIND. ELSE REPORT ON CURRENT BURDEN. */
|
||||
/* Inventory. If object, treat same as find. Else report on current burden. */
|
||||
|
||||
L8200: SPK=98;
|
||||
/* 8201 */ for (I=1; I<=100; I++) {
|
||||
|
@ -379,12 +379,12 @@ L8201: /*etc*/ ;
|
|||
if(TOTING(BEAR))SPK=141;
|
||||
return(2011);
|
||||
|
||||
/* FEED/FILL ARE IN THE OTHER MODULE. */
|
||||
/* 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! */
|
||||
/* Blast. No effect unless you've got dynamite, which is a neat trick! */
|
||||
|
||||
L9230: if(PROP[ROD2] < 0 || !CLOSED) return(2011);
|
||||
BONUS=133;
|
||||
|
@ -393,7 +393,7 @@ L9230: if(PROP[ROD2] < 0 || !CLOSED) return(2011);
|
|||
RSPEAK(BONUS);
|
||||
score(0);
|
||||
|
||||
/* SCORE. CALL SCORING ROUTINE BUT TELL IT TO RETURN. */
|
||||
/* Score. Call scoring routine but tell it to return. */
|
||||
|
||||
L8240: score(-1);
|
||||
SETPRM(1,SCORE,MXSCOR);
|
||||
|
@ -416,7 +416,7 @@ L8252: FOOBAR=K;
|
|||
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. */
|
||||
/* 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;
|
||||
|
@ -426,14 +426,14 @@ L8252: FOOBAR=K;
|
|||
PSPEAK(EGGS,K);
|
||||
return(2012);
|
||||
|
||||
/* BRIEF. INTRANSITIVE ONLY. SUPPRESS LONG DESCRIPTIONS AFTER FIRST TIME. */
|
||||
/* 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. */
|
||||
/* 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;
|
||||
|
@ -449,7 +449,7 @@ L9270: if(DARK(0)) goto L5190;
|
|||
L9275: CLSHNT=YES(192,193,54);
|
||||
return(2012);
|
||||
|
||||
/* BREAK. ONLY WORKS FOR MIRROR IN REPOSITORY AND, OF COURSE, THE VASE. */
|
||||
/* 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;
|
||||
|
@ -463,15 +463,15 @@ L9282: SPK=198;
|
|||
FIXED[VASE]= -1;
|
||||
return(2011);
|
||||
|
||||
/* WAKE. ONLY USE IS TO DISTURB THE DWARVES. */
|
||||
/* 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). */
|
||||
/* 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);
|
||||
|
@ -479,8 +479,8 @@ L8300: SPK=201;
|
|||
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). */
|
||||
/* 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;
|
||||
|
@ -488,12 +488,12 @@ L8305: DATIME(I,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. */
|
||||
/* 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);
|
||||
|
@ -520,7 +520,7 @@ L8305: DATIME(I,K);
|
|||
RSPEAK(266);
|
||||
exit(0);
|
||||
|
||||
/* RESUME. READ A SUSPENDED GAME BACK FROM A FILE. */
|
||||
/* Resume. Read a suspended game back from a file. */
|
||||
|
||||
L8310: KK=1;
|
||||
if(LOC == 1 && ABB[1] == 1) goto L8305;
|
||||
|
@ -536,7 +536,7 @@ L8312: SETPRM(1,K/10,MOD(K,10));
|
|||
L8318: RSPEAK(270);
|
||||
exit(0);
|
||||
|
||||
/* FLY. SNIDE REMARKS UNLESS HOVERING RUG IS HERE. */
|
||||
/* Fly. Snide remarks unless hovering rug is here. */
|
||||
|
||||
L8320: if(PROP[RUG] != 2)SPK=224;
|
||||
if(!HERE(RUG))SPK=225;
|
||||
|
@ -554,7 +554,7 @@ L9320: if(OBJ != RUG) return(2011);
|
|||
RSPEAK(SPK);
|
||||
return(2);
|
||||
|
||||
/* LISTEN. INTRANSITIVE ONLY. PRINT STUFF BASED ON OBJSND/LOCSND. */
|
||||
/* Listen. Intransitive only. Print stuff based on objsnd/locsnd. */
|
||||
|
||||
L8330: SPK=228;
|
||||
K=LOCSND[LOC];
|
||||
|
@ -572,7 +572,7 @@ L8335: /*etc*/ ;
|
|||
} /* end loop */
|
||||
return(2011);
|
||||
|
||||
/* Z'ZZZ (WORD GETS RECOMPUTED AT STARTUP; DIFFERENT EACH GAME). */
|
||||
/* 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);
|
||||
|
|
42
actions2.c
42
actions2.c
|
@ -3,9 +3,9 @@
|
|||
#include "share.h"
|
||||
#include "funcs.h"
|
||||
|
||||
/* 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 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. */
|
||||
|
||||
int carry(void) {
|
||||
if(TOTING(OBJ)) return(2011);
|
||||
|
@ -53,9 +53,9 @@ L9015: SPK=238;
|
|||
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 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. */
|
||||
|
||||
int discard(bool just_do_it) {
|
||||
if(just_do_it) goto L9021;
|
||||
|
@ -127,9 +127,9 @@ L9028: PROP[VASE]=2;
|
|||
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. 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. */
|
||||
|
||||
int attack() {
|
||||
I=ATDWRF(LOC);
|
||||
|
@ -170,9 +170,9 @@ L9126: if(OBJ == 0)SPK=44;
|
|||
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. */
|
||||
/* 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;
|
||||
|
@ -210,9 +210,9 @@ L9129: /*etc*/ ;
|
|||
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. 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. */
|
||||
|
||||
int throw() {
|
||||
if(TOTING(ROD2) && OBJ == ROD && !TOTING(ROD))OBJ=ROD2;
|
||||
|
@ -244,7 +244,7 @@ L9175: RSPEAK(SPK);
|
|||
K=NUL;
|
||||
return(8);
|
||||
|
||||
/* THIS'LL TEACH HIM TO THROW THE AXE AT THE BEAR! */
|
||||
/* This'll teach him to throw the axe at the bear! */
|
||||
L9176: SPK=164;
|
||||
DROP(AXE,LOC);
|
||||
FIXED[AXE]= -1;
|
||||
|
@ -252,12 +252,12 @@ L9176: SPK=164;
|
|||
JUGGLE(BEAR);
|
||||
return(2011);
|
||||
|
||||
/* BUT THROWING FOOD IS ANOTHER STORY. */
|
||||
/* But throwing food is another story. */
|
||||
L9177: OBJ=BEAR;
|
||||
return(feed());
|
||||
|
||||
L9178: SPK=159;
|
||||
/* SNARF A TREASURE FOR THE TROLL. */
|
||||
/* Snarf a treasure for the troll. */
|
||||
DROP(OBJ,0);
|
||||
MOVE(TROLL,0);
|
||||
MOVE(TROLL+100,0);
|
||||
|
@ -267,8 +267,8 @@ L9178: SPK=159;
|
|||
return(2011);
|
||||
}
|
||||
|
||||
/* FEED. IF BIRD, NO SEED. SNAKE, DRAGON, TROLL: QUIP. IF DWARF, MAKE HIM
|
||||
* MAD. BEAR, SPECIAL. */
|
||||
/* Feed. If bird, no seed. snake, dragon, troll: quip. If dwarf, make him
|
||||
* mad. Bear, special. */
|
||||
|
||||
int feed() {
|
||||
if(OBJ != BIRD) goto L9212;
|
||||
|
@ -310,7 +310,7 @@ L9216: SPK=14;
|
|||
return(2011);
|
||||
}
|
||||
|
||||
/* FILL. BOTTLE OR URN MUST BE EMPTY, AND LIQUID AVAILABLE. (VASE IS NASTY.) */
|
||||
/* Fill. Bottle or urn must be empty, and liquid available. (Vase is nasty.) */
|
||||
|
||||
int fill() {
|
||||
if(OBJ == VASE) goto L9222;
|
||||
|
|
34
funcs.h
34
funcs.h
|
@ -1,18 +1,18 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
/* STATEMENT FUNCTIONS
|
||||
/* 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 */
|
||||
* 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)
|
||||
|
@ -28,11 +28,11 @@
|
|||
#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. */
|
||||
/* 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)
|
||||
|
|
458
init.c
458
init.c
|
@ -6,161 +6,161 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
/*
|
||||
* INITIALISATION
|
||||
* 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,
|
||||
/* 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 */
|
||||
* 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
|
||||
/* 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".
|
||||
* 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:
|
||||
* 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 % 100) must *not* be 0.
|
||||
* If 400<M<=500 PROP(M % 100) must *not* be 1.
|
||||
* If 500<M<=600 PROP(M % 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.
|
||||
* 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. */
|
||||
* 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 % 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 % 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
|
||||
/* 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 */
|
||||
* %9 = A 9-digit number
|
||||
* %B = Variable number of blanks
|
||||
* %! = The entire message should be suppressed */
|
||||
|
||||
static bool quick_init(void);
|
||||
static int raw_init(void);
|
||||
|
@ -178,15 +178,15 @@ void initialise(void) {
|
|||
static int raw_init(void) {
|
||||
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). */
|
||||
/* 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;
|
||||
|
@ -208,7 +208,7 @@ L1001: /*etc*/ ;
|
|||
CLSSES=0;
|
||||
TRNVLS=0;
|
||||
|
||||
/* START NEW DATA SECTION. SECT IS THE SECTION NUMBER. */
|
||||
/* Start new data section. sect is the section number. */
|
||||
|
||||
L1002: SECT=GETNUM(1);
|
||||
OLDLOC= -1;
|
||||
|
@ -221,7 +221,7 @@ L1002: SECT=GETNUM(1);
|
|||
* (10) (11) (12) (13) (14) */
|
||||
BUG(9);
|
||||
|
||||
/* SECTIONS 1, 2, 5, 6, 10, 14. READ MESSAGES AND SET UP POINTERS. */
|
||||
/* Sections 1, 2, 5, 6, 10, 14. Read messages and set up pointers. */
|
||||
|
||||
L1004: KK=LINUSE;
|
||||
L1005: LINUSE=KK;
|
||||
|
@ -269,11 +269,11 @@ L1014: TRNVLS=TRNVLS+1;
|
|||
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. */
|
||||
/* 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;
|
||||
|
@ -291,12 +291,12 @@ L1035: L=GETNUM(0);
|
|||
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.) */
|
||||
/* 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++) {
|
||||
|
@ -307,9 +307,9 @@ 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. */
|
||||
/* 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;
|
||||
|
@ -317,14 +317,14 @@ L1050: OBJ=GETNUM(1);
|
|||
FIXD[OBJ]=GETNUM(0);
|
||||
goto L1050;
|
||||
|
||||
/* READ DEFAULT MESSAGE NUMBERS FOR ACTION VERBS, STORE IN ACTSPK. */
|
||||
/* 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. */
|
||||
/* Read info about available liquids and other conditions, store in COND. */
|
||||
|
||||
L1070: K=GETNUM(1);
|
||||
if(K == -1) goto L1002;
|
||||
|
@ -334,7 +334,7 @@ L1071: LOC=GETNUM(0);
|
|||
COND[LOC]=COND[LOC]+SETBIT(K);
|
||||
goto L1071;
|
||||
|
||||
/* READ DATA FOR HINTS. */
|
||||
/* Read data for hints. */
|
||||
|
||||
L1080: HNTMAX=0;
|
||||
L1081: K=GETNUM(1);
|
||||
|
@ -346,7 +346,7 @@ L1083: HINTS[K][I] =GETNUM(0);
|
|||
HNTMAX=(HNTMAX>K ? HNTMAX : K);
|
||||
goto L1081;
|
||||
|
||||
/* READ THE SOUND/TEXT INFO, STORE IN OBJSND, OBJTXT, LOCSND. */
|
||||
/* Read the sound/text info, store in OBJSND, OBJTXT, LOCSND. */
|
||||
|
||||
L1090: K=GETNUM(1);
|
||||
if(K == -1) goto L1002;
|
||||
|
@ -361,15 +361,15 @@ L1092: LOCSND[K]=KK;
|
|||
goto L1090;
|
||||
}
|
||||
|
||||
/* FINISH CONSTRUCTING INTERNAL DATA FORMAT */
|
||||
/* 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. */
|
||||
/* 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 modulo 5 unless "LOOK" is used. */
|
||||
|
||||
static int finish_init(void) {
|
||||
/* 1101 */ for (I=1; I<=100; I++) {
|
||||
|
@ -387,12 +387,12 @@ L1101: {long x = I+100; LINK[x]=0;}
|
|||
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. */
|
||||
/* 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;
|
||||
|
@ -408,10 +408,10 @@ L1106: /*etc*/ ;
|
|||
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. */
|
||||
/* 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;
|
||||
|
@ -420,15 +420,15 @@ L1107: if(PLAC[K] != 0 && FIXD[K] <= 0)DROP(K,PLAC[K]);
|
|||
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. */
|
||||
/* 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. */
|
||||
/* Define some handy mnemonics. these correspond to object numbers. */
|
||||
|
||||
AXE=VOCWRD(12405,1);
|
||||
BATTER=VOCWRD(201202005,1);
|
||||
|
@ -471,7 +471,7 @@ L1300: HINTLC[I]=0;
|
|||
VOLCAN=VOCWRD(1765120301,1);
|
||||
WATER=VOCWRD(1851200518,1);
|
||||
|
||||
/* OBJECTS FROM 50 THROUGH WHATEVER ARE TREASURES. HERE ARE A FEW. */
|
||||
/* Objects from 50 through whatever are treasures. Here are a few. */
|
||||
|
||||
AMBER=VOCWRD(113020518,1);
|
||||
CHAIN=VOCWRD(308010914,1);
|
||||
|
@ -489,7 +489,7 @@ L1300: HINTLC[I]=0;
|
|||
TRIDNT=VOCWRD(2018090405,1);
|
||||
VASE=VOCWRD(22011905,1);
|
||||
|
||||
/* THESE ARE MOTION-VERB NUMBERS. */
|
||||
/* These are motion-verb numbers. */
|
||||
|
||||
BACK=VOCWRD(2010311,0);
|
||||
CAVE=VOCWRD(3012205,0);
|
||||
|
@ -500,7 +500,7 @@ L1300: HINTLC[I]=0;
|
|||
NUL=VOCWRD(14211212,0);
|
||||
STREAM=VOCWRD(1920180501,0);
|
||||
|
||||
/* AND SOME ACTION VERBS. */
|
||||
/* And some action verbs. */
|
||||
|
||||
FIND=VOCWRD(6091404,2);
|
||||
INVENT=VOCWRD(914220514,2);
|
||||
|
@ -508,19 +508,19 @@ L1300: HINTLC[I]=0;
|
|||
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. */
|
||||
/* 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;
|
||||
|
@ -536,27 +536,27 @@ L1700: DSEEN[I]=false;
|
|||
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 */
|
||||
/* 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;
|
||||
|
@ -593,7 +593,7 @@ L1800: {long x = 2*I+81; if(RTEXT[x] != 0)MAXDIE=I+1;}
|
|||
return(0); /* then we won't actually return from initialisation */
|
||||
}
|
||||
|
||||
/* REPORT ON AMOUNT OF ARRAYS ACTUALLY USED, TO PERMIT REDUCTIONS. */
|
||||
/* Report on amount of arrays actually used, to permit reductions. */
|
||||
|
||||
static void report(void) {
|
||||
/* 1998 */ for (K=1; K<=LOCSIZ; K++) {
|
||||
|
|
332
main.c
332
main.c
|
@ -50,27 +50,27 @@ extern int action(long);
|
|||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
/* ADVENTURE (REV 2: 20 TREASURES) */
|
||||
/* 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 */
|
||||
/* 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:
|
||||
/* 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 */
|
||||
* 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 */
|
||||
/* Read the database if we have not yet done so */
|
||||
|
||||
LINES = (long *)calloc(LINSIZ+1,sizeof(long));
|
||||
if(!LINES){
|
||||
|
@ -82,17 +82,17 @@ int main(int argc, char *argv[]) {
|
|||
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. */
|
||||
/* 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(0);
|
||||
|
||||
|
||||
|
||||
/* START-UP, DWARF STUFF */
|
||||
/* Start-up, dwarf stuff */
|
||||
|
||||
L1: SETUP= -1;
|
||||
I=RAN(-1);
|
||||
|
@ -103,7 +103,7 @@ L1: SETUP= -1;
|
|||
LIMIT=330;
|
||||
if(NOVICE)LIMIT=1000;
|
||||
|
||||
/* CAN'T LEAVE CAVE ONCE IT'S CLOSING (EXCEPT BY MAIN OFFICE). */
|
||||
/* Can't leave cave once it's closing (except by main office). */
|
||||
|
||||
L2: if(!OUTSID(NEWLOC) || NEWLOC == 0 || !CLOSNG) goto L71;
|
||||
RSPEAK(130);
|
||||
|
@ -111,9 +111,9 @@ L2: if(!OUTSID(NEWLOC) || NEWLOC == 0 || !CLOSNG) goto L71;
|
|||
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). */
|
||||
/* 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++) {
|
||||
|
@ -125,23 +125,23 @@ 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. */
|
||||
/* 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. */
|
||||
/* 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. */
|
||||
/* 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;
|
||||
|
@ -158,17 +158,17 @@ L6002: ODLOC[I]=DLOC[I];
|
|||
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. */
|
||||
/* 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. */
|
||||
/* Fill TK array with all the places this dwarf might go. */
|
||||
J=1;
|
||||
KK=DLOC[I];
|
||||
KK=KEY[KK];
|
||||
|
@ -193,15 +193,15 @@ L6016: TK[J]=ODLOC[I];
|
|||
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). */
|
||||
/* 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!). */
|
||||
/* 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;
|
||||
|
@ -212,7 +212,7 @@ L6020: if(HERE(J))K=1;
|
|||
goto L6030;
|
||||
|
||||
L6021: if(PLACE[CHEST] != 0) goto L6022;
|
||||
/* INSTALL CHEST ONLY ONCE, TO INSURE IT IS THE LAST TREASURE IN THE LIST. */
|
||||
/* Install chest only once, to insure it is the last treasure in the list. */
|
||||
MOVE(CHEST,CHLOC);
|
||||
MOVE(MESSAG,CHLOC2);
|
||||
L6022: RSPEAK(128);
|
||||
|
@ -232,7 +232,7 @@ L6025: RSPEAK(186);
|
|||
MOVE(MESSAG,CHLOC2);
|
||||
goto L6024;
|
||||
|
||||
/* THIS THREATENING LITTLE DWARF IS IN THE ROOM WITH HIM! */
|
||||
/* This threatening little dwarf is in the room with him! */
|
||||
|
||||
L6027: DTOTAL=DTOTAL+1;
|
||||
if(ODLOC[I] != DLOC[I]) goto L6030;
|
||||
|
@ -242,9 +242,9 @@ L6027: DTOTAL=DTOTAL+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. */
|
||||
/* 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);
|
||||
|
@ -266,9 +266,9 @@ L6030: /*etc*/ ;
|
|||
|
||||
|
||||
|
||||
/* DESCRIBE THE CURRENT LOCATION AND (MAYBE) GET NEXT COMMAND. */
|
||||
/* Describe the current location and (maybe) get next command. */
|
||||
|
||||
/* PRINT TEXT FOR CURRENT LOC. */
|
||||
/* Print text for current loc. */
|
||||
|
||||
L2000: if(LOC == 0) goto L99;
|
||||
KK=STEXT[LOC];
|
||||
|
@ -282,11 +282,11 @@ L2001: if(TOTING(BEAR))RSPEAK(141);
|
|||
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. */
|
||||
/* 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;
|
||||
|
@ -300,17 +300,17 @@ L2004: if(I == 0) goto L2012;
|
|||
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). */
|
||||
/* 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);
|
||||
|
@ -325,9 +325,9 @@ 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).
|
||||
/* 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;
|
||||
|
@ -339,11 +339,11 @@ L2600: if(COND[LOC] < CONDS) goto L2603;
|
|||
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). */
|
||||
/* 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);
|
||||
|
@ -355,8 +355,8 @@ L2605: WZDARK=DARK(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. */
|
||||
/* 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;
|
||||
|
@ -402,20 +402,20 @@ L2630: I=VOCAB(WD1,-1);
|
|||
case 3: goto L2010; }
|
||||
BUG(22);
|
||||
|
||||
/* GET SECOND WORD FOR ANALYSIS. */
|
||||
/* Get second word for analysis. */
|
||||
|
||||
L2800: WD1=WD2;
|
||||
WD1X=WD2X;
|
||||
WD2=0;
|
||||
goto L2620;
|
||||
|
||||
/* GEE, I DON'T UNDERSTAND. */
|
||||
/* Gee, I don't understand. */
|
||||
|
||||
L3000: SETPRM(1,WD1,WD1X);
|
||||
RSPEAK(254);
|
||||
goto L2600;
|
||||
|
||||
/* VERB AND OBJECT ANALYSIS MOVED TO SEPARATE MODULE. */
|
||||
/* Verb and object analysis moved to separate module. */
|
||||
|
||||
L4000: I=4000; goto Laction;
|
||||
L4090: I=4090; goto Laction;
|
||||
|
@ -439,7 +439,7 @@ Laction:
|
|||
}
|
||||
BUG(99);
|
||||
|
||||
/* RANDOM INTRANSITIVE VERBS COME HERE. CLEAR OBJ JUST IN CASE (SEE "ATTACK").
|
||||
/* Random intransitive verbs come here. Clear obj just in case (see "attack").
|
||||
*/
|
||||
|
||||
L8000: SETPRM(1,WD1,WD1X);
|
||||
|
@ -447,13 +447,13 @@ L8000: SETPRM(1,WD1,WD1X);
|
|||
OBJ=0;
|
||||
goto L2600;
|
||||
|
||||
/* FIGURE OUT THE NEW LOCATION
|
||||
/* 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.) */
|
||||
* 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;
|
||||
|
@ -495,17 +495,17 @@ L16: NEWLOC=MOD(LL,1000);
|
|||
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). */
|
||||
/* 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". */
|
||||
/* 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;
|
||||
|
@ -513,18 +513,18 @@ L30100: NEWLOC=99+100-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. */
|
||||
/* 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. */
|
||||
/* 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);
|
||||
|
@ -549,10 +549,10 @@ L30310: NEWLOC=PLAC[TROLL]+FIXD[TROLL]-LOC;
|
|||
OLDLC2=NEWLOC;
|
||||
goto L99;
|
||||
|
||||
/* END OF SPECIALS. */
|
||||
/* 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. */
|
||||
/* 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;
|
||||
|
@ -583,8 +583,8 @@ 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. */
|
||||
/* 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;
|
||||
|
@ -592,14 +592,14 @@ L30: if(DETAIL < 3)RSPEAK(15);
|
|||
ABB[LOC]=0;
|
||||
goto L2;
|
||||
|
||||
/* CAVE. DIFFERENT MESSAGES DEPENDING ON WHETHER ABOVE GROUND. */
|
||||
/* 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. */
|
||||
/* Non-applicable motion. Various messages depending on word given. */
|
||||
|
||||
L50: SPK=12;
|
||||
if(K >= 43 && K <= 50)SPK=52;
|
||||
|
@ -616,29 +616,29 @@ L50: SPK=12;
|
|||
|
||||
|
||||
|
||||
/* "YOU'RE DEAD, JIM."
|
||||
/* "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". */
|
||||
* 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. */
|
||||
/* 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. */
|
||||
/* Okay, he's dead. Let's get on with it. */
|
||||
|
||||
L99: if(CLOSNG) goto L95;
|
||||
NUMDIE=NUMDIE+1;
|
||||
|
@ -659,7 +659,7 @@ L98: /*etc*/ ;
|
|||
OLDLOC=LOC;
|
||||
goto L2000;
|
||||
|
||||
/* HE DIED DURING CLOSING TIME. NO RESURRECTION. TALLY UP A DEATH AND EXIT. */
|
||||
/* He died during closing time. No resurrection. Tally up a death and exit. */
|
||||
|
||||
L95: RSPEAK(131);
|
||||
NUMDIE=NUMDIE+1;
|
||||
|
@ -668,13 +668,13 @@ L95: RSPEAK(131);
|
|||
|
||||
|
||||
|
||||
/* HINTS */
|
||||
/* 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. */
|
||||
/* 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
|
||||
|
@ -693,7 +693,7 @@ L40010: HINTLC[HINT]=0;
|
|||
L40020: HINTLC[HINT]=0;
|
||||
L40030: goto L2602;
|
||||
|
||||
/* NOW FOR THE QUICK TESTS. SEE DATABASE DESCRIPTION FOR ONE-LINE NOTES. */
|
||||
/* Now for the quick tests. See database description for one-line notes. */
|
||||
|
||||
L40100: if(PROP[GRATE] == 0 && !HERE(KEYS)) goto L40010;
|
||||
goto L40020;
|
||||
|
@ -732,37 +732,37 @@ L41000: if(TALLY == 1 && PROP[JADE] < 0) goto L40010;
|
|||
|
||||
|
||||
|
||||
/* CAVE CLOSING AND SCORING */
|
||||
/* 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. */
|
||||
/* 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. */
|
||||
/* 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;
|
||||
|
@ -808,7 +808,7 @@ L11000: PROP[BOTTLE]=PUT(BOTTLE,115,1);
|
|||
OLDLOC=115;
|
||||
NEWLOC=115;
|
||||
|
||||
/* LEAVE THE GRATE WITH NORMAL (NON-NEGATIVE) PROPERTY. REUSE SIGN. */
|
||||
/* Leave the grate with normal (non-negative) property. reuse sign. */
|
||||
|
||||
I=PUT(GRATE,116,0);
|
||||
I=PUT(SIGN,116,0);
|
||||
|
@ -830,11 +830,11 @@ L11010: if(TOTING(I))DSTROY(I);
|
|||
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. */
|
||||
/* 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;
|
||||
|
@ -856,7 +856,7 @@ L12400: LIMIT= -1;
|
|||
if(HERE(LAMP))RSPEAK(184);
|
||||
goto L19999;
|
||||
|
||||
/* OH DEAR, HE'S DISTURBED THE DWARVES. */
|
||||
/* Oh dear, he's disturbed the dwarves. */
|
||||
|
||||
L18999: RSPEAK(SPK);
|
||||
L19000: RSPEAK(136);
|
||||
|
|
336
misc.c
336
misc.c
|
@ -7,14 +7,14 @@
|
|||
/* hack to ignore GCC Unused Result */
|
||||
#define IGNORE(r) do{if(r){}}while(0)
|
||||
|
||||
/* I/O ROUTINES (SPEAK, PSPEAK, RSPEAK, SETPRM, GETIN, YES) */
|
||||
/* I/O routines (SPEAK, PSPEAK, RSPEAK, SETPRM, GETIN, YES) */
|
||||
|
||||
#undef SPEAK
|
||||
void fSPEAK(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. */
|
||||
/* Print the message which starts at LINES(N). Precede it with a blank line
|
||||
* unless BLKLIN is false. */
|
||||
|
||||
|
||||
if(N == 0)return;
|
||||
|
@ -34,13 +34,13 @@ 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. */
|
||||
/* 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;
|
||||
|
@ -117,8 +117,8 @@ L40: if(BLANK)TYPE0();
|
|||
void fPSPEAK(long MSG,long 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). */
|
||||
/* 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];
|
||||
|
@ -139,7 +139,7 @@ L9: SPEAK(M);
|
|||
void fRSPEAK(long I) {
|
||||
;
|
||||
|
||||
/* PRINT THE I-TH "RANDOM" MESSAGE (SECTION 6 OF DATABASE). */
|
||||
/* Print the I-TH "random" message (section 6 of database). */
|
||||
|
||||
|
||||
if(I != 0)SPEAK(RTEXT[I]);
|
||||
|
@ -153,8 +153,8 @@ void fRSPEAK(long I) {
|
|||
void fSETPRM(long FIRST, long P1, long P2) {
|
||||
;
|
||||
|
||||
/* STORES PARAMETERS INTO THE PRMCOM PARMS ARRAY FOR USE BY SPEAK. P1 AND P2
|
||||
* ARE STORED INTO PARMS(FIRST) AND PARMS(FIRST+1). */
|
||||
/* 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);
|
||||
|
@ -174,11 +174,11 @@ void fSETPRM(long FIRST, long P1, long P2) {
|
|||
void fGETIN(long *wORD1, long *wORD1X, long *wORD2, long *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. */
|
||||
/* 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();
|
||||
|
@ -209,8 +209,8 @@ long fYES(long X, long Y, long 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. */
|
||||
/* 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);
|
||||
|
@ -230,25 +230,25 @@ L20: YES=false;
|
|||
|
||||
|
||||
|
||||
/* LINE-PARSING ROUTINES (GETNUM, GETTXT, MAKEWD, PUTTXT, SHFTXT, TYPE0)
|
||||
/* 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. */
|
||||
/* 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(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. */
|
||||
/* 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);
|
||||
|
@ -281,13 +281,13 @@ L42: GETNUM=GETNUM*SIGN;
|
|||
long fGETTXT(long SKIP,long ONEWRD, long UPPER, long HASH) {
|
||||
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. */
|
||||
/* 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;
|
||||
|
@ -329,12 +329,12 @@ L15: /*etc*/ ;
|
|||
long fMAKEWD(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. */
|
||||
/* 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;
|
||||
|
@ -358,16 +358,16 @@ L10: MAKEWD=MAKEWD+I*(MOD(L,50)+10);
|
|||
void fPUTTXT(long WORD, long *sTATE, long CASE, long HASH) {
|
||||
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). */
|
||||
/* 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;
|
||||
|
@ -403,8 +403,8 @@ L18: W=(W-BYTE*DIV)*64;
|
|||
void fSHFTXT(long FROM, long DELTA) {
|
||||
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. */
|
||||
/* 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;
|
||||
|
@ -425,8 +425,8 @@ L2: LNLENG=LNLENG+DELTA;
|
|||
void fTYPE0() {
|
||||
long TEMP;
|
||||
|
||||
/* TYPE A BLANK LINE. THIS PROCEDURE IS PROVIDED AS A CONVENIENCE FOR CALLERS
|
||||
* WHO OTHERWISE HAVE NO USE FOR MAPCOM. */
|
||||
/* Type a blank line. This procedure is provided as a convenience for callers
|
||||
* who otherwise have no use for MAPCOM. */
|
||||
|
||||
|
||||
TEMP=LNLENG;
|
||||
|
@ -441,12 +441,12 @@ long TEMP;
|
|||
#define TYPE0() fTYPE0()
|
||||
|
||||
|
||||
/* SUSPEND/RESUME I/O ROUTINES (SAVWDS, SAVARR, SAVWRD) */
|
||||
/* Suspend/resume I/O routines (SAVWDS, SAVARR, SAVWRD) */
|
||||
|
||||
#undef SAVWDS
|
||||
void fSAVWDS(long *W1, long *W2, long *W3, long *W4, long *W5, long *W6, long *W7) {
|
||||
|
||||
/* WRITE OR READ 7 VARIABLES. SEE SAVWRD. */
|
||||
/* Write or read 7 variables. See SAVWRD. */
|
||||
|
||||
|
||||
SAVWRD(0,(*W1));
|
||||
|
@ -465,7 +465,7 @@ void fSAVWDS(long *W1, long *W2, long *W3, long *W4, long *W5, long *W6, long *W
|
|||
void fSAVARR(long ARR[], long N) {
|
||||
long I;
|
||||
|
||||
/* WRITE OR READ AN ARRAY OF N WORDS. SEE SAVWRD. */
|
||||
/* Write or read an array of N words. See SAVWRD. */
|
||||
|
||||
|
||||
/* 1 */ for (I=1; I<=N; I++) {
|
||||
|
@ -482,14 +482,14 @@ L1: SAVWRD(0,ARR[I]);
|
|||
void fSAVWRD(long OP, long *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, 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 :
|
||||
|
@ -535,7 +535,7 @@ L32: N--; WORD=BUF[N]-CKSUM; N++;
|
|||
|
||||
|
||||
|
||||
/* DATA STRUC. ROUTINES (VOCAB, DSTROY, JUGGLE, MOVE, PUT, CARRY, DROP, ATDWRF)
|
||||
/* Data struc. routines (VOCAB, DSTROY, JUGGLE, MOVE, PUT, CARRY, DROP, ATDWRF)
|
||||
*/
|
||||
|
||||
#undef WORD
|
||||
|
@ -544,12 +544,12 @@ L32: N--; WORD=BUF[N]-CKSUM; N++;
|
|||
long fVOCAB(long ID, long 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. */
|
||||
/* 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 modulo 1000. */
|
||||
|
||||
HASH=10000;
|
||||
/* 1 */ for (I=1; I<=TABSIZ; I++) {
|
||||
|
@ -577,7 +577,7 @@ L3: VOCAB=KTAB[I];
|
|||
void fDSTROY(long OBJECT) {
|
||||
;
|
||||
|
||||
/* PERMANENTLY ELIMINATE "OBJECT" BY MOVING TO A NON-EXISTENT LOCATION. */
|
||||
/* Permanently eliminate "OBJECT" by moving to a non-existent location. */
|
||||
|
||||
|
||||
MOVE(OBJECT,0);
|
||||
|
@ -591,8 +591,8 @@ void fDSTROY(long OBJECT) {
|
|||
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. */
|
||||
/* 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];
|
||||
|
@ -609,9 +609,9 @@ long I, J;
|
|||
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. */
|
||||
/* 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;
|
||||
|
@ -630,8 +630,8 @@ L2: if(FROM > 0 && FROM <= 300)CARRY(OBJECT,FROM);
|
|||
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. */
|
||||
/* 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);
|
||||
|
@ -646,9 +646,9 @@ long PUT;
|
|||
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. */
|
||||
/* 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;
|
||||
|
@ -673,8 +673,8 @@ L8: LINK[TEMP]=LINK[OBJECT];
|
|||
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. */
|
||||
/* 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;
|
||||
|
@ -695,9 +695,9 @@ L2: if(WHERE <= 0)return;
|
|||
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). */
|
||||
/* 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;
|
||||
|
@ -720,13 +720,13 @@ L2: ATDWRF=I;
|
|||
|
||||
|
||||
|
||||
/* UTILITY ROUTINES (SETBIT, TSTBIT, RAN, RNDVOC, BUG) */
|
||||
/* 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. */
|
||||
/* Returns 2**bit for use in constructing bit-masks. */
|
||||
|
||||
|
||||
SETBIT=1;
|
||||
|
@ -744,7 +744,7 @@ L1: SETBIT=SETBIT+SETBIT;
|
|||
long fTSTBIT(MASK,BIT)long BIT, MASK; {
|
||||
long TSTBIT;
|
||||
|
||||
/* RETURNS TRUE IF THE SPECIFIED BIT IS SET IN THE MASK. */
|
||||
/* Returns true if the specified bit is set in the mask. */
|
||||
|
||||
|
||||
TSTBIT=MOD(MASK/SETBIT(BIT),2) != 0;
|
||||
|
@ -758,10 +758,10 @@ long TSTBIT;
|
|||
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. */
|
||||
/* 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;
|
||||
|
@ -783,10 +783,10 @@ L2: R=MOD(R*1093L+221587L,1048576L);
|
|||
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. */
|
||||
/* 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;
|
||||
|
@ -815,30 +815,30 @@ L8: ATAB[I]=RNDVOC+J*J;
|
|||
#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 */
|
||||
/* 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 %ld. See source code for interpretation.\n",
|
||||
NUM);
|
||||
|
@ -849,41 +849,41 @@ void fBUG(NUM)long NUM; {
|
|||
|
||||
|
||||
|
||||
/* MACHINE DEPENDENT ROUTINES (MAPLIN, TYPE, MPINIT, SAVEIO) */
|
||||
/* 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.
|
||||
/* 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.
|
||||
* 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.
|
||||
* 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. */
|
||||
* 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();
|
||||
|
@ -907,8 +907,8 @@ 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. */
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
@ -919,9 +919,9 @@ L25: if(INLINE[I] != 0)LNLENG=I;
|
|||
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. */
|
||||
/* 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;
|
||||
|
@ -963,7 +963,7 @@ L22: J--;
|
|||
L20: /*etc*/ ;
|
||||
} /* end loop */
|
||||
MAP1[128]=MAP1[10];
|
||||
/* FOR THIS VERSION, TAB (9) MAPS TO SPACE (32), SO DEL (127) USES TAB'S VALUE */
|
||||
/* For this version, tab (9) maps to space (32), so del (127) uses tab's value */
|
||||
MAP1[10]=MAP1[33];
|
||||
MAP1[11]=MAP1[33];
|
||||
|
||||
|
@ -983,13 +983,13 @@ L30: if(I >= 64)MAP2[VAL]=(I-64)*('B'-'A')+'@';
|
|||
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. */
|
||||
/* 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:
|
||||
|
|
62
score.c
62
score.c
|
@ -4,36 +4,36 @@
|
|||
#include "share.h"
|
||||
|
||||
/*
|
||||
* SCORING AND WRAP-UP
|
||||
* scoring and wrap-up
|
||||
*/
|
||||
|
||||
void score(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
|
||||
/* 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. */
|
||||
* 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. */
|
||||
/* 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;
|
||||
|
@ -46,12 +46,12 @@ L20000: SCORE=0;
|
|||
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). */
|
||||
/* 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;
|
||||
|
@ -68,17 +68,17 @@ L20010: /*etc*/ ;
|
|||
if(BONUS == 133)SCORE=SCORE+45;
|
||||
L20020: MXSCOR=MXSCOR+45;
|
||||
|
||||
/* DID HE COME TO WITT'S END AS HE SHOULD? */
|
||||
/* Did he come to Witt's End as he should? */
|
||||
|
||||
if(PLACE[MAGZIN] == 108)SCORE=SCORE+1;
|
||||
MXSCOR=MXSCOR+1;
|
||||
|
||||
/* ROUND IT OFF. */
|
||||
/* Round it off. */
|
||||
|
||||
SCORE=SCORE+2;
|
||||
MXSCOR=MXSCOR+2;
|
||||
|
||||
/* DEDUCT FOR HINTS/TURNS/SAVES. HINTS < 4 ARE SPECIAL; SEE DATABASE DESC. */
|
||||
/* 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];
|
||||
|
@ -87,11 +87,11 @@ L20030: if(HINTED[I])SCORE=SCORE-HINTS[I][2];
|
|||
if(CLSHNT)SCORE=SCORE-10;
|
||||
SCORE=SCORE-TRNLUZ-SAVED;
|
||||
|
||||
/* RETURN TO SCORE COMMAND IF THAT'S WHERE WE CAME FROM. */
|
||||
/* 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. */
|
||||
/* 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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue