Pull more globals into the game state block.

This commit is contained in:
Eric S. Raymond 2017-06-07 05:10:20 -04:00
parent 91ad0185ff
commit dda636bbc1
6 changed files with 141 additions and 134 deletions

View file

@ -201,8 +201,8 @@ L9040: if(OBJ == CLAM || OBJ == OYSTER) goto L9046;
if(OBJ == CHAIN) goto L9048; if(OBJ == CHAIN) goto L9048;
if(!game.closng) goto L9043; if(!game.closng) goto L9043;
K=130; K=130;
if(!PANIC)game.clock2=15; if(!game.panic)game.clock2=15;
PANIC=true; game.panic=true;
return(2010); return(2010);
L9043: K=34+PROP[GRATE]; L9043: K=34+PROP[GRATE];
@ -302,7 +302,7 @@ L9090: if((!TOTING(OBJ)) && (OBJ != ROD || !TOTING(ROD2)))SPK=29;
L9094: DROP(JADE,LOC); L9094: DROP(JADE,LOC);
PROP[JADE]=0; PROP[JADE]=0;
TALLY=TALLY-1; game.tally=game.tally-1;
SPK=208; SPK=208;
return(2011); return(2011);
@ -381,7 +381,7 @@ L9160: if(OBJ != LAMP)SPK=76;
DSTROY(URN); DSTROY(URN);
DROP(AMBER,LOC); DROP(AMBER,LOC);
PROP[AMBER]=1; PROP[AMBER]=1;
TALLY=TALLY-1; game.tally=game.tally-1;
DROP(CAVITY,LOC); DROP(CAVITY,LOC);
SPK=216; SPK=216;
return(2011); return(2011);
@ -436,7 +436,7 @@ L9230: if(PROP[ROD2] < 0 || !game.closed) return(2011);
L8240: score(-1); L8240: score(-1);
SETPRM(1,SCORE,MXSCOR); SETPRM(1,SCORE,MXSCOR);
SETPRM(3,TURNS,TURNS); SETPRM(3,game.turns,game.turns);
RSPEAK(259); RSPEAK(259);
return(2012); return(2012);
@ -481,11 +481,11 @@ L8270: for (I=1; I<=NOBJECTS; I++) {
L9270: if(DARK(0)) goto L5190; L9270: if(DARK(0)) goto L5190;
if(OBJTXT[OBJ] == 0 || PROP[OBJ] < 0) return(2011); if(OBJTXT[OBJ] == 0 || PROP[OBJ] < 0) return(2011);
if(OBJ == OYSTER && !CLSHNT) goto L9275; if(OBJ == OYSTER && !game.clshnt) goto L9275;
PSPEAK(OBJ,OBJTXT[OBJ]+PROP[OBJ]); PSPEAK(OBJ,OBJTXT[OBJ]+PROP[OBJ]);
return(2012); return(2012);
L9275: CLSHNT=YES(input,192,193,54); L9275: game.clshnt=YES(input,192,193,54);
return(2012); 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. */
@ -515,7 +515,7 @@ L9290: if(OBJ != DWARF || !game.closed) return(2011);
L8300: SPK=201; L8300: SPK=201;
RSPEAK(260); RSPEAK(260);
if(!YES(input,200,54,54)) return(2012); if(!YES(input,200,54,54)) return(2012);
SAVED=SAVED+5; game.saved=game.saved+5;
KK= -1; KK= -1;
/* This next part is shared with the "resume" code. The two cases are /* This next part is shared with the "resume" code. The two cases are
@ -535,12 +535,12 @@ L8305: DATIME(&I,&K);
* with junk variables to bring it up to 7 values. */ * with junk variables to bring it up to 7 values. */
SAVWDS(game.abbnum,game.blklin,game.bonus,game.clock1,game.clock2,game.closed,game.closng); SAVWDS(game.abbnum,game.blklin,game.bonus,game.clock1,game.clock2,game.closed,game.closng);
SAVWDS(game.detail,game.dflag,game.dkill,game.dtotal,game.foobar,game.holdng,game.iwest); SAVWDS(game.detail,game.dflag,game.dkill,game.dtotal,game.foobar,game.holdng,game.iwest);
SAVWDS(game.knfloc,game.limit,LL,game.lmwarn,LOC,NEWLOC,NUMDIE); SAVWDS(game.knfloc,game.limit,LL,game.lmwarn,LOC,game.newloc,game.numdie);
SAVWDS(OBJ,game.oldlc2,game.oldloc,OLDOBJ,PANIC,SAVED,SETUP); SAVWDS(OBJ,game.oldlc2,game.oldloc,game.oldobj,game.panic,game.saved,SETUP);
SAVWDS(SPK,TALLY,THRESH,TRNDEX,TRNLUZ,TURNS,OBJTXT[OYSTER]); SAVWDS(SPK,game.tally,game.thresh,game.trndex,game.trnluz,game.turns,OBJTXT[OYSTER]);
SAVWDS(VERB,WD1,WD1X,WD2,game.wzdark,game.zzword,OBJSND[BIRD]); SAVWDS(VERB,WD1,WD1X,WD2,game.wzdark,game.zzword,OBJSND[BIRD]);
SAVWDS(OBJTXT[SIGN],CLSHNT,NOVICE,K,K,K,K); SAVWDS(OBJTXT[SIGN],game.clshnt,game.novice,K,K,K,K);
SAVARR(ABB,LOCSIZ); SAVARR(game.abbrev,LOCSIZ);
SAVARR(ATLOC,LOCSIZ); SAVARR(ATLOC,LOCSIZ);
SAVARR(game.dloc,NDWARVES); SAVARR(game.dloc,NDWARVES);
SAVARR(game.dseen,NDWARVES); SAVARR(game.dseen,NDWARVES);
@ -562,7 +562,7 @@ L8305: DATIME(&I,&K);
/* Resume. Read a suspended game back from a file. */ /* Resume. Read a suspended game back from a file. */
L8310: KK=1; L8310: KK=1;
if(LOC == 1 && ABB[1] == 1) goto L8305; if(LOC == 1 && game.abbrev[1] == 1) goto L8305;
RSPEAK(268); RSPEAK(268);
if(!YES(input,200,54,54)) return(2012); if(!YES(input,200,54,54)) return(2012);
goto L8305; goto L8305;
@ -587,7 +587,7 @@ L9320: if(OBJ != RUG) return(2011);
if(PROP[RUG] != 2) return(2011); if(PROP[RUG] != 2) return(2011);
game.oldlc2=game.oldloc; game.oldlc2=game.oldloc;
game.oldloc=LOC; game.oldloc=LOC;
NEWLOC=PLACE[RUG]+FIXED[RUG]-LOC; game.newloc=PLACE[RUG]+FIXED[RUG]-LOC;
SPK=226; SPK=226;
if(PROP[SAPPH] >= 0)SPK=227; if(PROP[SAPPH] >= 0)SPK=227;
RSPEAK(SPK); RSPEAK(SPK);
@ -618,7 +618,7 @@ L8340: if(!AT(RESER) && LOC != FIXED[RESER]-1) return(2011);
PROP[RESER]=1-PROP[RESER]; PROP[RESER]=1-PROP[RESER];
if(AT(RESER)) return(2012); if(AT(RESER)) return(2012);
game.oldlc2=LOC; game.oldlc2=LOC;
NEWLOC=0; game.newloc=0;
RSPEAK(241); RSPEAK(241);
return(2); return(2);

View file

@ -21,6 +21,7 @@ struct game_t {
long chloc2; long chloc2;
long clock1; long clock1;
long clock2; long clock2;
long clshnt;
long closed; long closed;
long closng; long closng;
long conds; long conds;
@ -34,10 +35,22 @@ struct game_t {
long knfloc; long knfloc;
long limit; long limit;
long lmwarn; long lmwarn;
long newloc;
long novice;
long numdie;
long oldloc; long oldloc;
long oldlc2; long oldlc2;
long oldobj;
long panic;
long saved;
long tally;
long thresh;
long trndex;
long trnluz;
long turns;
long wzdark; long wzdark;
long zzword; long zzword;
long abbrev[185+1]; /* FIXME: LOCSIZE in the compiler */
long dseen[NDWARVES+1]; long dseen[NDWARVES+1];
long dloc[NDWARVES+1]; long dloc[NDWARVES+1];
long odloc[NDWARVES+1]; long odloc[NDWARVES+1];
@ -45,7 +58,7 @@ struct game_t {
extern struct game_t game; extern struct game_t game;
extern long ABB[], ATLOC[], FIXED[], extern long ATLOC[], FIXED[],
LINK[], LNLENG, LNPOSN, LINK[], LNLENG, LNPOSN,
PARMS[], PLACE[]; PARMS[], PLACE[];
extern char rawbuf[LINESIZE], INLINE[LINESIZE+1], MAP1[], MAP2[]; extern char rawbuf[LINESIZE], INLINE[LINESIZE+1], MAP1[], MAP2[];
@ -111,19 +124,17 @@ extern long randrange(long);
extern void score(long); extern void score(long);
extern long AMBER, ATTACK, AXE, BACK, BATTER, BEAR, extern long AMBER, ATTACK, AXE, BACK, BATTER, BEAR,
BIRD, BLOOD, BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST, BIRD, BLOOD, BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST,
CLAM, CLSHNT, COINS, DALTLC, DOOR, DPRSSN, DRAGON, DWARF, EGGS, CLAM, COINS, DALTLC, DOOR, DPRSSN, DRAGON, DWARF, EGGS,
EMRALD, ENTER, ENTRNC, FIND, FISSUR, FOOD, EMRALD, ENTER, ENTRNC, FIND, FISSUR, FOOD,
GRATE, HINT, HINTED[], HINTLC[], GRATE, HINT, HINTED[], HINTLC[],
I, INVENT, IGO, J, JADE, K, K2, KEYS, KK, I, INVENT, IGO, J, JADE, K, K2, KEYS, KK,
KNIFE, KQ, L, LAMP, LL, LOC, LOCK, LOOK, KNIFE, KQ, L, LAMP, LL, LOC, LOCK, LOOK,
MAGZIN, MAXDIE, MAXTRS, MESSAG, MIRROR, MXSCOR, MAGZIN, MAXDIE, MAXTRS, MESSAG, MIRROR, MXSCOR, NUGGET, NUL, OBJ,
NEWLOC, NOVICE, NUGGET, NUL, NUMDIE, OBJ,
OGRE, OIL, OLDOBJ, OYSTER, OGRE, OIL, OLDOBJ, OYSTER,
PANIC, PEARL, PILLOW, PLANT, PLANT2, PROP[], PYRAM, PANIC, PEARL, PILLOW, PLANT, PLANT2, PROP[], PYRAM,
RESER, ROD, ROD2, RUBY, RUG, SAPPH, SAVED, SAY, RESER, ROD, ROD2, RUBY, RUG, SAPPH, SAY,
SCORE, SECT, SETUP, SIGN, SNAKE, SPK, STEPS, STICK, SCORE, SECT, SETUP, SIGN, SNAKE, SPK, STEPS, STICK,
STREAM, TALLY, THRESH, THROW, TK[], TRIDNT, STREAM, THROW, TK[], TRIDNT, TROLL, TROLL2,
TRNDEX, TRNLUZ, TROLL, TROLL2, URN, V1, V2, VASE, VEND, VERB,
TURNS, URN, V1, V2, VASE, VEND, VERB,
VOLCAN, VRSION, WATER, WD1, WD1X, WD2, WD2X; VOLCAN, VRSION, WATER, WD1, WD1X, WD2, WD2X;

View file

@ -502,7 +502,7 @@ void read_sound_text(FILE* database)
* to set up ATLOC(N) as the first object at location N, and * 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. * LINK(OBJ) as the next object at the same location as OBJ.
* (OBJ>NOBJECTS indicates that FIXED(OBJ-NOBJECTS)=LOC; LINK(OBJ) is * (OBJ>NOBJECTS indicates that FIXED(OBJ-NOBJECTS)=LOC; LINK(OBJ) is
* still the correct link to use.) ABB is zeroed; it controls * still the correct link to use.) game.abbrev is zeroed; it controls
* whether the abbreviated description is printed. Counts modulo 5 * whether the abbreviated description is printed. Counts modulo 5
* unless "LOOK" is used. */ * unless "LOOK" is used. */

40
init.c
View file

@ -15,7 +15,7 @@
* 12600 words of message text (LINES, LINSIZ). * 12600 words of message text (LINES, LINSIZ).
* 885 travel options (TRAVEL, TRVSIZ). * 885 travel options (TRAVEL, TRVSIZ).
* 330 vocabulary words (KTAB, ATAB, TABSIZ). * 330 vocabulary words (KTAB, ATAB, TABSIZ).
* 185 locations (LTEXT, STEXT, KEY, COND, ABB, ATLOC, LOCSND, LOCSIZ). * 185 locations (LTEXT, STEXT, KEY, COND, abbrev, ATLOC, LOCSND, LOCSIZ).
* 100 objects (PLAC, PLACE, FIXD, FIXED, LINK (TWICE), PTEXT, PROP, * 100 objects (PLAC, PLACE, FIXD, FIXED, LINK (TWICE), PTEXT, PROP,
* OBJSND, OBJTXT). * OBJSND, OBJTXT).
* 35 "action" verbs (ACTSPK, VRBSIZ). * 35 "action" verbs (ACTSPK, VRBSIZ).
@ -186,7 +186,7 @@ static int finish_init(void) {
} /* end loop */ } /* end loop */
/* 1102 */ for (I=1; I<=LOCSIZ; I++) { /* 1102 */ for (I=1; I<=LOCSIZ; I++) {
ABB[I]=0; game.abbrev[I]=0;
if(LTEXT[I] == 0 || KEY[I] == 0) goto L1102; if(LTEXT[I] == 0 || KEY[I] == 0) goto L1102;
K=KEY[I]; K=KEY[I];
if(MOD(labs(TRAVEL[K]),1000) == 1)COND[I]=2; if(MOD(labs(TRAVEL[K]),1000) == 1)COND[I]=2;
@ -216,14 +216,14 @@ L1106: /*etc*/ ;
/* Treasures, as noted earlier, are objects 50 through MAXTRS (CURRENTLY 79). /* 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 * 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 * described. game.tally keeps track of how many are not yet found, so we know
* when to close the cave. */ * when to close the cave. */
MAXTRS=79; MAXTRS=79;
TALLY=0; game.tally=0;
for (I=50; I<=MAXTRS; I++) { for (I=50; I<=MAXTRS; I++) {
if(PTEXT[I] != 0)PROP[I]= -1; if(PTEXT[I] != 0)PROP[I]= -1;
TALLY=TALLY-PROP[I]; game.tally=game.tally-PROP[I];
} /* end loop */ } /* end loop */
/* Clear the hint stuff. HINTLC(I) is how long he's been at LOC with cond bit /* Clear the hint stuff. HINTLC(I) is how long he's been at LOC with cond bit
@ -357,18 +357,18 @@ L1106: /*etc*/ ;
* game.knfloc 0 if no knife here, loc if knife here, -1 after caveat * game.knfloc 0 if no knife here, loc if knife here, -1 after caveat
* game.limit Lifetime of lamp (not set here) * game.limit Lifetime of lamp (not set here)
* MAXDIE Number of reincarnation messages available (up to 5) * MAXDIE Number of reincarnation messages available (up to 5)
* NUMDIE Number of times killed so far * game.numdie Number of times killed so far
* THRESH Next #turns threshhold (-1 if none) * game.thresh Next #turns threshhold (-1 if none)
* TRNDEX Index in TRNVAL of next threshhold (section 14 of database) * game.trndex Index in TRNVAL of next threshhold (section 14 of database)
* TRNLUZ # points lost so far due to number of turns used * game.trnluz # points lost so far due to number of turns used
* TURNS Tallies how many commands he's given (ignores yes/no) * game.turns Tallies how many commands he's given (ignores yes/no)
* Logicals were explained earlier */ * Logicals were explained earlier */
TURNS=0; game.turns=0;
TRNDEX=1; game.trndex=1;
THRESH= -1; game.thresh= -1;
if(TRNVLS > 0)THRESH=MOD(TRNVAL[1],100000)+1; if(TRNVLS > 0)game.thresh=MOD(TRNVAL[1],100000)+1;
TRNLUZ=0; game.trnluz=0;
game.lmwarn=false; game.lmwarn=false;
IGO=0; IGO=0;
game.iwest=0; game.iwest=0;
@ -378,7 +378,7 @@ L1106: /*etc*/ ;
for (I=0; I<=4; I++) { for (I=0; I<=4; I++) {
{long x = 2*I+81; if(RTEXT[x] != 0)MAXDIE=I+1;} {long x = 2*I+81; if(RTEXT[x] != 0)MAXDIE=I+1;}
} /* end loop */ } /* end loop */
NUMDIE=0; game.numdie=0;
game.holdng=0; game.holdng=0;
game.dkill=0; game.dkill=0;
game.foobar=0; game.foobar=0;
@ -386,12 +386,12 @@ L1106: /*etc*/ ;
game.clock1=30; game.clock1=30;
game.clock2=50; game.clock2=50;
game.conds=SETBIT(11); game.conds=SETBIT(11);
SAVED=0; game.saved=0;
game.closng=false; game.closng=false;
PANIC=false; game.panic=false;
game.closed=false; game.closed=false;
CLSHNT=false; game.clshnt=false;
NOVICE=false; game.novice=false;
SETUP=1; SETUP=1;
game.blklin=true; game.blklin=true;

158
main.c
View file

@ -14,8 +14,7 @@
struct game_t game; struct game_t game;
long ABB[186], ATLOC[186], long ATLOC[186], FIXED[NOBJECTS+1],
FIXED[NOBJECTS+1],
LINK[NOBJECTS*2 + 1], LNLENG, LNPOSN, LINK[NOBJECTS*2 + 1], LNLENG, LNPOSN,
PARMS[26], PLACE[NOBJECTS+1], PARMS[26], PLACE[NOBJECTS+1],
SETUP = 0; SETUP = 0;
@ -23,21 +22,18 @@ char rawbuf[LINESIZE], INLINE[LINESIZE+1], MAP1[129], MAP2[129];
long AMBER, ATTACK, AXE, BACK, BATTER, BEAR, BIRD, BLOOD, long AMBER, ATTACK, AXE, BACK, BATTER, BEAR, BIRD, BLOOD,
BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST, BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST,
CLAM, CLSHNT, COINS, DALTLC, CLAM, COINS, DALTLC, DOOR, DPRSSN, DRAGON, DWARF, EGGS,
DOOR, DPRSSN, DRAGON, DWARF, EGGS,
EMRALD, ENTER, ENTRNC, FIND, FISSUR, FOOD, EMRALD, ENTER, ENTRNC, FIND, FISSUR, FOOD,
GRATE, HINT, HINTED[21], HINTLC[21], GRATE, HINT, HINTED[21], HINTLC[21],
I, INVENT, IGO, J, JADE, K, K2, KEYS, KK, I, INVENT, IGO, J, JADE, K, K2, KEYS, KK,
KNIFE, KQ, L, LAMP, LL, LOC, LOCK, LOOK, KNIFE, KQ, L, LAMP, LL, LOC, LOCK, LOOK,
MAGZIN, MAXDIE, MAXTRS, MESSAG, MIRROR, MXSCOR, MAGZIN, MAXDIE, MAXTRS, MESSAG, MIRROR, MXSCOR,
NEWLOC, NOVICE, NUGGET, NUL, NUMDIE, OBJ, NUGGET, NUL, OBJ, OGRE, OIL, OYSTER, PEARL, PILLOW,
OGRE, OIL, OLDOBJ, OYSTER, PLANT, PLANT2, PROP[NOBJECTS+1], PYRAM,
PANIC, PEARL, PILLOW, PLANT, PLANT2, PROP[NOBJECTS+1], PYRAM, RESER, ROD, ROD2, RUBY, RUG, SAPPH, SAY,
RESER, ROD, ROD2, RUBY, RUG, SAPPH, SAVED, SAY,
SCORE, SECT, SIGN, SNAKE, SPK, STEPS, STICK, SCORE, SECT, SIGN, SNAKE, SPK, STEPS, STICK,
STREAM, TALLY, THRESH, THROW, TK[21], TRIDNT, STREAM, THROW, TK[21], TRIDNT, TROLL, TROLL2,
TRNDEX, TRNLUZ, TROLL, TROLL2, URN, V1, V2, VASE, VEND, VERB,
TURNS, URN, V1, V2, VASE, VEND, VERB,
VOLCAN, VRSION = 25, WATER, WD1, WD1X, WD2, WD2X; VOLCAN, VRSION = 25, WATER, WD1, WD1X, WD2, WD2X;
FILE *logfp; FILE *logfp;
bool oldstyle = false; bool oldstyle = false;
@ -94,10 +90,10 @@ int main(int argc, char *argv[]) {
* *
* game.closed says whether we're all the way closed * game.closed says whether we're all the way closed
* game.closng says whether it's closing time yet * game.closng says whether it's closing time yet
* CLSHNT says whether he's read the clue in the endgame * game.clshnt says whether he's read the clue in the endgame
* game.lmwarn says whether he's been warned about lamp going dim * game.lmwarn says whether he's been warned about lamp going dim
* NOVICE says whether he asked for instructions at start-up * game.novice says whether he asked for instructions at start-up
* PANIC says whether he's found out he's trapped in the cave * game.panic says whether he's found out he's trapped in the cave
* game.wzdark says whether the loc he's leaving was dark */ * game.wzdark says whether the loc he's leaving was dark */
#include "funcs.h" #include "funcs.h"
@ -130,11 +126,11 @@ int main(int argc, char *argv[]) {
L1: SETUP= -1; L1: SETUP= -1;
I=0; I=0;
game.zzword=RNDVOC(3,0); game.zzword=RNDVOC(3,0);
NOVICE=YES(stdin, 65,1,0); game.novice=YES(stdin, 65,1,0);
NEWLOC=1; game.newloc=1;
LOC=1; LOC=1;
game.limit=330; game.limit=330;
if(NOVICE)game.limit=1000; if(game.novice)game.limit=1000;
if (logfp) if (logfp)
fprintf(logfp, "seed %ld\n", seedval); fprintf(logfp, "seed %ld\n", seedval);
@ -154,7 +150,7 @@ static bool fallback_handler(char *buf)
set_seed(sv); set_seed(sv);
printf("Seed set to %ld\n", sv); printf("Seed set to %ld\n", sv);
// autogenerated, so don't charge user time for it. // autogenerated, so don't charge user time for it.
--TURNS; --game.turns;
// here we reconfigure any global game state that uses random numbers // here we reconfigure any global game state that uses random numbers
game.zzword=RNDVOC(3,0); game.zzword=RNDVOC(3,0);
return true; return true;
@ -166,37 +162,37 @@ static bool do_command(FILE *cmdin) {
/* Can't leave cave once it's closing (except by main office). */ /* Can't leave cave once it's closing (except by main office). */
if(!OUTSID(NEWLOC) || NEWLOC == 0 || !game.closng) goto L71; if(!OUTSID(game.newloc) || game.newloc == 0 || !game.closng) goto L71;
RSPEAK(130); RSPEAK(130);
NEWLOC=LOC; game.newloc=LOC;
if(!PANIC)game.clock2=15; if(!game.panic)game.clock2=15;
PANIC=true; game.panic=true;
/* See if a dwarf has seen him and has come from where he wants to go. If so, /* 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 * the dwarf's blocking his way. If coming from place forbidden to pirate
* (dwarves rooted in place) let him get out (and attacked). */ * (dwarves rooted in place) let him get out (and attacked). */
L71: if(NEWLOC == LOC || FORCED(LOC) || CNDBIT(LOC,3)) goto L74; L71: if(game.newloc == LOC || FORCED(LOC) || CNDBIT(LOC,3)) goto L74;
/* 73 */ for (I=1; I<=NDWARVES-1; I++) { /* 73 */ for (I=1; I<=NDWARVES-1; I++) {
if(game.odloc[I] != NEWLOC || !game.dseen[I]) goto L73; if(game.odloc[I] != game.newloc || !game.dseen[I]) goto L73;
NEWLOC=LOC; game.newloc=LOC;
RSPEAK(2); RSPEAK(2);
goto L74; goto L74;
L73: /*etc*/ ; L73: /*etc*/ ;
} /* end loop */ } /* end loop */
L74: LOC=NEWLOC; L74: LOC=game.newloc;
/* Dwarf stuff. See earlier comments for description of variables. Remember /* Dwarf stuff. See earlier comments for description of variables. Remember
* sixth dwarf is pirate and is thus very different except for motion rules. */ * 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 /* 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). * 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 * If game.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 * 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 * 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. */ * 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(LOC == 0 || FORCED(LOC) || CNDBIT(game.newloc,3)) goto L2000;
if(game.dflag != 0) goto L6000; if(game.dflag != 0) goto L6000;
if(INDEEP(LOC))game.dflag=1; if(INDEEP(LOC))game.dflag=1;
goto L2000; goto L2000;
@ -234,13 +230,13 @@ L6010: game.dtotal=0;
KK=game.dloc[I]; KK=game.dloc[I];
KK=KEY[KK]; KK=KEY[KK];
if(KK == 0) goto L6016; if(KK == 0) goto L6016;
L6012: NEWLOC=MOD(labs(TRAVEL[KK])/1000,1000); L6012: game.newloc=MOD(labs(TRAVEL[KK])/1000,1000);
{long x = J-1; {long x = J-1;
if(NEWLOC > 300 || !INDEEP(NEWLOC) || NEWLOC == game.odloc[I] || (J > 1 && if(game.newloc > 300 || !INDEEP(game.newloc) || game.newloc == game.odloc[I] || (J > 1 &&
NEWLOC == TK[x]) || J >= 20 || NEWLOC == game.dloc[I] || game.newloc == TK[x]) || J >= 20 || game.newloc == game.dloc[I] ||
FORCED(NEWLOC) || (I == 6 && CNDBIT(NEWLOC,3)) || FORCED(game.newloc) || (I == 6 && CNDBIT(game.newloc,3)) ||
labs(TRAVEL[KK])/1000000 == 100) goto L6014;} labs(TRAVEL[KK])/1000000 == 100) goto L6014;}
TK[J]=NEWLOC; TK[J]=game.newloc;
J=J+1; J=J+1;
L6014: KK=KK+1; L6014: KK=KK+1;
{long x = KK-1; if(TRAVEL[x] >= 0) goto L6012;} {long x = KK-1; if(TRAVEL[x] >= 0) goto L6012;}
@ -267,7 +263,7 @@ L6016: TK[J]=game.odloc[I];
if(TOTING(J)) goto L6021; if(TOTING(J)) goto L6021;
L6020: if(HERE(J))K=1; L6020: if(HERE(J))K=1;
} /* end loop */ } /* end loop */
if(TALLY == 1 && K == 0 && PLACE[CHEST] == 0 && HERE(LAMP) && PROP[LAMP] if(game.tally == 1 && K == 0 && PLACE[CHEST] == 0 && HERE(LAMP) && PROP[LAMP]
== 1) goto L6025; == 1) goto L6025;
if(game.odloc[6] != game.dloc[6] && PCT(20))RSPEAK(127); if(game.odloc[6] != game.dloc[6] && PCT(20))RSPEAK(127);
goto L6030; goto L6030;
@ -333,7 +329,7 @@ L6030: /*etc*/ ;
L2000: if(LOC == 0) goto L99; L2000: if(LOC == 0) goto L99;
KK=STEXT[LOC]; KK=STEXT[LOC];
if(MOD(ABB[LOC],game.abbnum) == 0 || KK == 0)KK=LTEXT[LOC]; if(MOD(game.abbrev[LOC],game.abbnum) == 0 || KK == 0)KK=LTEXT[LOC];
if(FORCED(LOC) || !DARK(0)) goto L2001; if(FORCED(LOC) || !DARK(0)) goto L2001;
if(game.wzdark && PCT(35)) goto L90; if(game.wzdark && PCT(35)) goto L90;
KK=RTEXT[16]; KK=RTEXT[16];
@ -350,7 +346,7 @@ L2001: if(TOTING(BEAR))RSPEAK(141);
* are because PROP=0 is needed to get full score. */ * are because PROP=0 is needed to get full score. */
if(DARK(0)) goto L2012; if(DARK(0)) goto L2012;
ABB[LOC]=ABB[LOC]+1; game.abbrev[LOC]=game.abbrev[LOC]+1;
I=ATLOC[LOC]; I=ATLOC[LOC];
L2004: if(I == 0) goto L2012; L2004: if(I == 0) goto L2012;
OBJ=I; OBJ=I;
@ -360,7 +356,7 @@ L2004: if(I == 0) goto L2012;
if(game.closed) goto L2008; if(game.closed) goto L2008;
PROP[OBJ]=0; PROP[OBJ]=0;
if(OBJ == RUG || OBJ == CHAIN)PROP[OBJ]=1; if(OBJ == RUG || OBJ == CHAIN)PROP[OBJ]=1;
TALLY=TALLY-1; game.tally=game.tally-1;
/* Note: There used to be a test here to see whether the player had blown it /* 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 * 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; * the lamp was zapped to 35 turns. But the tests were too simple-minded;
@ -383,7 +379,7 @@ L2010: SPK=K;
L2011: RSPEAK(SPK); L2011: RSPEAK(SPK);
L2012: VERB=0; L2012: VERB=0;
OLDOBJ=OBJ; game.oldobj=OBJ;
OBJ=0; OBJ=0;
/* Check if this loc is eligible for any hints. If been here long enough, /* Check if this loc is eligible for any hints. If been here long enough,
@ -420,18 +416,18 @@ L2605: game.wzdark=DARK(0);
* make neg. If neg, he skipped a word, so make it zero. */ * make neg. If neg, he skipped a word, so make it zero. */
L2607: game.foobar=(game.foobar>0 ? -game.foobar : 0); L2607: game.foobar=(game.foobar>0 ? -game.foobar : 0);
TURNS=TURNS+1; game.turns=game.turns+1;
if(TURNS == THRESH) { if(game.turns == game.thresh) {
SPEAK(TTEXT[TRNDEX]); SPEAK(TTEXT[game.trndex]);
TRNLUZ=TRNLUZ+TRNVAL[TRNDEX]/100000; game.trnluz=game.trnluz+TRNVAL[game.trndex]/100000;
TRNDEX=TRNDEX+1; game.trndex=game.trndex+1;
THRESH= -1; game.thresh= -1;
if(TRNDEX <= TRNVLS) if(game.trndex <= TRNVLS)
THRESH=MOD(TRNVAL[TRNDEX],100000)+1; game.thresh=MOD(TRNVAL[game.trndex],100000)+1;
} }
if(VERB == SAY && WD2 > 0)VERB=0; if(VERB == SAY && WD2 > 0)VERB=0;
if(VERB == SAY) goto L4090; if(VERB == SAY) goto L4090;
if(TALLY == 0 && INDEEP(LOC) && LOC != 33)game.clock1=game.clock1-1; if(game.tally == 0 && INDEEP(LOC) && LOC != 33)game.clock1=game.clock1-1;
if(game.clock1 == 0) goto L10000; if(game.clock1 == 0) goto L10000;
if(game.clock1 < 0)game.clock2=game.clock2-1; if(game.clock1 < 0)game.clock2=game.clock2-1;
if(game.clock2 == 0) goto L11000; if(game.clock2 == 0) goto L11000;
@ -516,15 +512,15 @@ L8000: SETPRM(1,WD1,WD1X);
/* Figure out the new location /* Figure out the new location
* *
* Given the current location in "LOC", and a motion verb number in * Given the current location in "LOC", and a motion verb number in
* "K", put the new location in "NEWLOC". The current loc is saved * "K", put the new location in "game.newloc". The current loc is saved
* in "game.olddloc" in case he wants to retreat. The current * in "game.olddloc" in case he wants to retreat. The current
* game.oldloc is saved in game.oldlc2, in case he dies. (if he * game.oldloc is saved in game.oldlc2, in case he dies. (if he
* does, NEWLOC will be limbo, and OLgame.dloc will be what killed * does, game.newloc will be limbo, and OLgame.dloc will be what killed
* him, so we need game.oldlc2, which is the last place he was * him, so we need game.oldlc2, which is the last place he was
* safe.) */ * safe.) */
L8: KK=KEY[LOC]; L8: KK=KEY[LOC];
NEWLOC=LOC; game.newloc=LOC;
if(KK == 0)BUG(26); if(KK == 0)BUG(26);
if(K == NUL) return true; if(K == NUL) return true;
if(K == BACK) goto L20; if(K == BACK) goto L20;
@ -540,34 +536,34 @@ L9: LL=labs(TRAVEL[KK]);
goto L9; goto L9;
L10: LL=LL/1000; L10: LL=LL/1000;
L11: NEWLOC=LL/1000; L11: game.newloc=LL/1000;
K=MOD(NEWLOC,100); /* ESR: an instance of NOBJECTS? */ K=MOD(game.newloc,100); /* ESR: an instance of NOBJECTS? */
if(NEWLOC <= 300) goto L13; if(game.newloc <= 300) goto L13;
if(PROP[K] != NEWLOC/100-3) goto L16; if(PROP[K] != game.newloc/100-3) goto L16;
L12: if(TRAVEL[KK] < 0)BUG(25); L12: if(TRAVEL[KK] < 0)BUG(25);
KK=KK+1; KK=KK+1;
NEWLOC=labs(TRAVEL[KK])/1000; game.newloc=labs(TRAVEL[KK])/1000;
if(NEWLOC == LL) goto L12; if(game.newloc == LL) goto L12;
LL=NEWLOC; LL=game.newloc;
goto L11; goto L11;
L13: if(NEWLOC <= 100) goto L14; /* ESR: an instance of NOBJECTS? */ L13: if(game.newloc <= 100) goto L14; /* ESR: an instance of NOBJECTS? */
if(TOTING(K) || (NEWLOC > 200 && AT(K))) goto L16; if(TOTING(K) || (game.newloc > 200 && AT(K))) goto L16;
goto L12; goto L12;
L14: if(NEWLOC != 0 && !PCT(NEWLOC)) goto L12; L14: if(game.newloc != 0 && !PCT(game.newloc)) goto L12;
L16: NEWLOC=MOD(LL,1000); L16: game.newloc=MOD(LL,1000);
if(NEWLOC <= 300) return true; if(game.newloc <= 300) return true;
if(NEWLOC <= 500) goto L30000; if(game.newloc <= 500) goto L30000;
RSPEAK(NEWLOC-500); RSPEAK(game.newloc-500);
NEWLOC=LOC; game.newloc=LOC;
return true; return true;
/* Special motions come here. Labelling convention: statement numbers NNNXX /* Special motions come here. Labelling convention: statement numbers NNNXX
* (XX=00-99) are used for special case number NNN (NNN=301-500). */ * (XX=00-99) are used for special case number NNN (NNN=301-500). */
L30000: NEWLOC=NEWLOC-300; L30000: game.newloc=game.newloc-300;
switch (NEWLOC) { case 1: goto L30100; case 2: goto L30200; case 3: goto switch (game.newloc) { case 1: goto L30100; case 2: goto L30200; case 3: goto
L30300; } L30300; }
BUG(20); BUG(20);
@ -575,9 +571,9 @@ L30000: NEWLOC=NEWLOC-300;
* table must include "useless" entries going through passage, which can never * table must include "useless" entries going through passage, which can never
* be used for actual motion, but can be spotted by "go back". */ * be used for actual motion, but can be spotted by "go back". */
L30100: NEWLOC=99+100-LOC; /* ESR: an instance of NOBJECTS? */ L30100: game.newloc=99+100-LOC; /* ESR: an instance of NOBJECTS? */
if(game.holdng == 0 || (game.holdng == 1 && TOTING(EMRALD))) return true; if(game.holdng == 0 || (game.holdng == 1 && TOTING(EMRALD))) return true;
NEWLOC=LOC; game.newloc=LOC;
RSPEAK(117); RSPEAK(117);
return true; return true;
@ -602,19 +598,19 @@ L30300: if(PROP[TROLL] != 1) goto L30310;
MOVE(TROLL,PLAC[TROLL]); MOVE(TROLL,PLAC[TROLL]);
MOVE(TROLL+NOBJECTS,FIXD[TROLL]); MOVE(TROLL+NOBJECTS,FIXD[TROLL]);
JUGGLE(CHASM); JUGGLE(CHASM);
NEWLOC=LOC; game.newloc=LOC;
return true; return true;
L30310: NEWLOC=PLAC[TROLL]+FIXD[TROLL]-LOC; L30310: game.newloc=PLAC[TROLL]+FIXD[TROLL]-LOC;
if(PROP[TROLL] == 0)PROP[TROLL]=1; if(PROP[TROLL] == 0)PROP[TROLL]=1;
if(!TOTING(BEAR)) return true; if(!TOTING(BEAR)) return true;
RSPEAK(162); RSPEAK(162);
PROP[CHASM]=1; PROP[CHASM]=1;
PROP[TROLL]=2; PROP[TROLL]=2;
DROP(BEAR,NEWLOC); DROP(BEAR,game.newloc);
FIXED[BEAR]= -1; FIXED[BEAR]= -1;
PROP[BEAR]=3; PROP[BEAR]=3;
game.oldlc2=NEWLOC; game.oldlc2=game.newloc;
goto L99; goto L99;
/* End of specials. */ /* End of specials. */
@ -661,7 +657,7 @@ L23: KK=K2;
L30: if(game.detail < 3)RSPEAK(15); L30: if(game.detail < 3)RSPEAK(15);
game.detail=game.detail+1; game.detail=game.detail+1;
game.wzdark=false; game.wzdark=false;
ABB[LOC]=0; game.abbrev[LOC]=0;
return true; return true;
/* Cave. Different messages depending on whether above ground. */ /* Cave. Different messages depending on whether above ground. */
@ -709,9 +705,9 @@ L90: RSPEAK(23);
/* Okay, he's dead. Let's get on with it. */ /* Okay, he's dead. Let's get on with it. */
L99: if(game.closng) goto L95; L99: if(game.closng) goto L95;
NUMDIE=NUMDIE+1; game.numdie=game.numdie+1;
if(!YES(cmdin,79+NUMDIE*2,80+NUMDIE*2,54)) score(0); if(!YES(cmdin,79+game.numdie*2,80+game.numdie*2,54)) score(0);
if(NUMDIE == MAXDIE) score(0); if(game.numdie == MAXDIE) score(0);
PLACE[WATER]=0; PLACE[WATER]=0;
PLACE[OIL]=0; PLACE[OIL]=0;
if(TOTING(LAMP))PROP[LAMP]=0; if(TOTING(LAMP))PROP[LAMP]=0;
@ -730,7 +726,7 @@ L98: /*etc*/ ;
/* 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); L95: RSPEAK(131);
NUMDIE=NUMDIE+1; game.numdie=game.numdie+1;
score(0); score(0);
@ -766,7 +762,7 @@ L40030: goto L2602;
L40100: if(PROP[GRATE] == 0 && !HERE(KEYS)) goto L40010; L40100: if(PROP[GRATE] == 0 && !HERE(KEYS)) goto L40010;
goto L40020; goto L40020;
L40200: if(PLACE[BIRD] == LOC && TOTING(ROD) && OLDOBJ == BIRD) goto L40010; L40200: if(PLACE[BIRD] == LOC && TOTING(ROD) && game.oldobj == BIRD) goto L40010;
goto L40030; goto L40030;
L40300: if(HERE(SNAKE) && !HERE(BIRD)) goto L40010; L40300: if(HERE(SNAKE) && !HERE(BIRD)) goto L40010;
@ -793,7 +789,7 @@ L40900: I=ATDWRF(LOC);
if(HERE(OGRE) && I == 0) goto L40010; if(HERE(OGRE) && I == 0) goto L40010;
goto L40030; goto L40030;
L41000: if(TALLY == 1 && PROP[JADE] < 0) goto L40010; L41000: if(game.tally == 1 && PROP[JADE] < 0) goto L40010;
goto L40020; goto L40020;
@ -874,7 +870,7 @@ L11000: PROP[BOTTLE]=PUT(BOTTLE,115,1);
PROP[DWARF]=PUT(DWARF,115,0); PROP[DWARF]=PUT(DWARF,115,0);
LOC=115; LOC=115;
game.oldloc=115; game.oldloc=115;
NEWLOC=115; game.newloc=115;
/* Leave the grate with normal (non-negative) property. Reuse sign. */ /* Leave the grate with normal (non-negative) property. Reuse sign. */

16
score.c
View file

@ -45,14 +45,14 @@ void score(long MODE) {
L20010: /*etc*/ ; L20010: /*etc*/ ;
} /* end loop */ } /* end loop */
/* Now look at how he finished and how far he got. MAXDIE and NUMDIE tell us /* Now look at how he finished and how far he got. MAXDIE and game.numdie tell us
* how well he survived. game.dflag will * how well he survived. game.dflag will
* tell us if he ever got suitably deep into the cave. game.closng still indicates * tell us if he ever got suitably deep into the cave. game.closng still indicates
* whether he reached the endgame. And if he got as far as "cave closed" * whether he reached the endgame. And if he got as far as "cave closed"
* (indicated by "game.closed"), then bonus is zero for mundane exits or 133, 134, * (indicated by "game.closed"), then bonus is zero for mundane exits or 133, 134,
* 135 if he blew it (so to speak). */ * 135 if he blew it (so to speak). */
SCORE=SCORE+(MAXDIE-NUMDIE)*10; SCORE=SCORE+(MAXDIE-game.numdie)*10;
MXSCOR=MXSCOR+MAXDIE*10; MXSCOR=MXSCOR+MAXDIE*10;
if(MODE == 0)SCORE=SCORE+4; if(MODE == 0)SCORE=SCORE+4;
MXSCOR=MXSCOR+4; MXSCOR=MXSCOR+4;
@ -82,9 +82,9 @@ L20020: MXSCOR=MXSCOR+45;
for (I=1; I<=HNTMAX; I++) { for (I=1; I<=HNTMAX; I++) {
if(HINTED[I])SCORE=SCORE-HINTS[I][2]; if(HINTED[I])SCORE=SCORE-HINTS[I][2];
} /* end loop */ } /* end loop */
if(NOVICE)SCORE=SCORE-5; if(game.novice)SCORE=SCORE-5;
if(CLSHNT)SCORE=SCORE-10; if(game.clshnt)SCORE=SCORE-10;
SCORE=SCORE-TRNLUZ-SAVED; SCORE=SCORE-game.trnluz-game.saved;
/* Return to score command if that's where we came from. */ /* Return to score command if that's where we came from. */
@ -92,10 +92,10 @@ L20020: MXSCOR=MXSCOR+45;
/* 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+game.trnluz+1 >= MXSCOR && game.trnluz != 0)RSPEAK(242);
if(SCORE+SAVED+1 >= MXSCOR && SAVED != 0)RSPEAK(143); if(SCORE+game.saved+1 >= MXSCOR && game.saved != 0)RSPEAK(143);
SETPRM(1,SCORE,MXSCOR); SETPRM(1,SCORE,MXSCOR);
SETPRM(3,TURNS,TURNS); SETPRM(3,game.turns,game.turns);
RSPEAK(262); RSPEAK(262);
for (I=1; I<=CLSSES; I++) { for (I=1; I<=CLSSES; I++) {
if(CVAL[I] >= SCORE) goto L20210; if(CVAL[I] >= SCORE) goto L20210;