#include <stdbool.h>
#include "advent.h"
-#include "funcs.h"
#include "database.h"
+#include "newdb.h"
/*
* Initialisation
* 12600 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).
+ * 185 locations (LTEXT, STEXT, KEY, COND, game.abbrev, game.atloc,
+ * LOCSND, LOCSIZ).
+ * 100 objects (PLAC, game.place, FIXD, game.fixed, game.link (twice),
+ * PTEXT, game.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).
+ * 20 hints (game.hintlc, game.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 */
-
-/* Note:
- * - the object count limit has been abstracted as NOBJECTS
- * - the random message limit has been abstracted as RTXSIZE
+ * 100 objects
+ * Note:
+ * - the object count limit has been abstracted as NOBJECTS
+ * - the random message limit has been abstracted as RTXSIZ
+ * - maximum locations limit has been abstracted as LOCSIZ
*/
/* Description of the database format
* 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 300<M<=400 game.prop(M % 100) must *not* be 0.
+ * If 400<M<=500 game.prop(M % 100) must *not* be 1.
+ * If 500<M<=600 game.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
* 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).
+ * This says that, from 11, 49 takes him to 8 unless game.prop(3)=0, in which
+ * case he goes to 9. Verb 50 takes him to 9 regardless of game.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
* 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
+ * number and S+game.prop(N) is the property message (from section 5) if he
+ * listens to the object, and T+game.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
* %B = Variable number of blanks
* %! = The entire message should be suppressed */
-static int finish_init(void);
-
-void initialise(void) {
- if (oldstyle)
- printf("Initialising...\n");
- finish_init();
-}
-
-static int finish_init(void) {
- for (I=1; I<=100; I++) {
- PLACE[I]=0;
- PROP[I]=0;
- LINK[I]=0;
- {long x = I+NOBJECTS; LINK[x]=0;}
- } /* end loop */
-
- /* 1102 */ for (I=1; I<=LOCSIZ; I++) {
- ABB[I]=0;
- if(LTEXT[I] == 0 || KEY[I] == 0) goto L1102;
- K=KEY[I];
- if(MOD(labs(TRAVEL[K]),1000) == 1)COND[I]=2;
-L1102: ATLOC[I]=0;
- } /* end loop */
-
-/* Set up the ATLOC and LINK arrays as described above. We'll use the DROP
- * subroutine, which prefaces new objects on the lists. Since we want things
- * in the other order, we'll run the loop backwards. If the object is in two
- * locs, we drop it twice. This also sets up "PLACE" and "fixed" as copies of
- * "PLAC" and "FIXD". Also, since two-placed objects are typically best
- * described last, we'll drop them first. */
-
- /* 1106 */ for (I=1; I<=NOBJECTS; I++) {
- K=NOBJECTS + 1 - I;
- if(FIXD[K] <= 0) goto L1106;
- DROP(K+NOBJECTS,FIXD[K]);
- DROP(K,PLAC[K]);
-L1106: /*etc*/ ;
- } /* end loop */
-
- for (I=1; I<=NOBJECTS; I++) {
- K=NOBJECTS + 1 - I;
- FIXED[K]=FIXD[K];
- if(PLAC[K] != 0 && FIXD[K] <= 0)DROP(K,PLAC[K]);
- } /* end loop */
-
-/* Treasures, as noted earlier, are objects 50 through MAXTRS (CURRENTLY 79).
- * Their props are initially -1, and are set to 0 the first time they are
- * described. TALLY keeps track of how many are not yet found, so we know
- * when to close the cave. */
-
- MAXTRS=79;
- TALLY=0;
- for (I=50; I<=MAXTRS; I++) {
- if(PTEXT[I] != 0)PROP[I]= -1;
- 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. */
-
- for (I=1; I<=HNTMAX; I++) {
- HINTED[I]=false;
- HINTLC[I]=0;
- } /* end loop */
-
-/* Define some handy mnemonics. These correspond to object numbers. */
-
- AXE=VOCWRD(12405,1);
- BATTER=VOCWRD(201202005,1);
- BEAR=VOCWRD(2050118,1);
- BIRD=VOCWRD(2091804,1);
- BLOOD=VOCWRD(212151504,1);
- BOTTLE=VOCWRD(215202012,1);
- CAGE=VOCWRD(3010705,1);
- CAVITY=VOCWRD(301220920,1);
- CHASM=VOCWRD(308011913,1);
- CLAM=VOCWRD(3120113,1);
- DOOR=VOCWRD(4151518,1);
- DRAGON=VOCWRD(418010715,1);
- DWARF=VOCWRD(423011806,1);
- FISSUR=VOCWRD(609191921,1);
- FOOD=VOCWRD(6151504,1);
- GRATE=VOCWRD(718012005,1);
- KEYS=VOCWRD(11052519,1);
- KNIFE=VOCWRD(1114090605,1);
- LAMP=VOCWRD(12011316,1);
- MAGZIN=VOCWRD(1301070126,1);
- MESSAG=VOCWRD(1305191901,1);
- MIRROR=VOCWRD(1309181815,1);
- OGRE=VOCWRD(15071805,1);
- OIL=VOCWRD(150912,1);
- OYSTER=VOCWRD(1525192005,1);
- PILLOW=VOCWRD(1609121215,1);
- PLANT=VOCWRD(1612011420,1);
- PLANT2=PLANT+1;
- RESER=VOCWRD(1805190518,1);
- ROD=VOCWRD(181504,1);
- ROD2=ROD+1;
- SIGN=VOCWRD(19090714,1);
- SNAKE=VOCWRD(1914011105,1);
- STEPS=VOCWRD(1920051619,1);
- TROLL=VOCWRD(2018151212,1);
- TROLL2=TROLL+1;
- URN=VOCWRD(211814,1);
- VEND=VOCWRD(1755140409,1);
- VOLCAN=VOCWRD(1765120301,1);
- WATER=VOCWRD(1851200518,1);
+void initialise(void)
+{
+ if (oldstyle)
+ printf("Initialising...\n");
-/* Objects from 50 through whatever are treasures. Here are a few. */
+ for (int i=1; i<=NOBJECTS; i++) {
+ game.place[i] = NOWHERE;
+ game.prop[i] = 0;
+ game.link[i+NOBJECTS]=game.link[i]=0;
+ }
- AMBER=VOCWRD(113020518,1);
- CHAIN=VOCWRD(308010914,1);
- CHEST=VOCWRD(308051920,1);
- COINS=VOCWRD(315091419,1);
- EGGS=VOCWRD(5070719,1);
- EMRALD=VOCWRD(513051801,1);
- JADE=VOCWRD(10010405,1);
- NUGGET=VOCWRD(7151204,1);
- PEARL=VOCWRD(1605011812,1);
- PYRAM=VOCWRD(1625180113,1);
- RUBY=VOCWRD(18210225,1);
- RUG=VOCWRD(182107,1);
- SAPPH=VOCWRD(1901161608,1);
- TRIDNT=VOCWRD(2018090405,1);
- VASE=VOCWRD(22011905,1);
+ for (int i=1; i<=LOCSIZ; i++) {
+ game.abbrev[i]=0;
+ if (!(locations[i].description.big == 0 || KEY[i] == 0)) {
+ int k=KEY[i];
+ if(MOD(labs(TRAVEL[k]),1000) == 1)COND[i]=2;
+ }
+ game.atloc[i]=0;
+ }
-/* These are motion-verb numbers. */
+ /* Set up the game.atloc and game.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 "game.place" and "fixed" as copies of "PLAC" and
+ * "FIXD". Also, since two-placed objects are typically best
+ * described last, we'll drop them first. */
+ for (int i=1; i<=NOBJECTS; i++) {
+ int k=NOBJECTS + 1 - i;
+ if(FIXD[k] > 0) {
+ DROP(k+NOBJECTS,FIXD[k]);
+ DROP(k,PLAC[k]);
+ }
+ }
- BACK=VOCWRD(2010311,0);
- CAVE=VOCWRD(3012205,0);
- DPRSSN=VOCWRD(405161805,0);
- ENTER=VOCWRD(514200518,0);
- ENTRNC=VOCWRD(514201801,0);
- LOOK=VOCWRD(12151511,0);
- NUL=VOCWRD(14211212,0);
- STREAM=VOCWRD(1920180501,0);
+ for (int i=1; i<=NOBJECTS; i++) {
+ int k=NOBJECTS + 1 - i;
+ game.fixed[k]=FIXD[k];
+ if(PLAC[k] != 0 && FIXD[k] <= 0)
+ DROP(k,PLAC[k]);
+ }
-/* And some action verbs. */
+ /* Treasures, as noted earlier, are objects MINTRS through MAXTRS
+ * Their props are initially -1, and are set to 0 the first time
+ * they are described. game.tally keeps track of how many are
+ * not yet found, so we know when to close the cave. */
+ game.tally=0;
+ for (int i=MINTRS; i<=MAXTRS; i++) {
+ if(object_descriptions[i].inventory != 0)
+ game.prop[i]= -1;
+ game.tally=game.tally-game.prop[i];
+ }
- FIND=VOCWRD(6091404,2);
- INVENT=VOCWRD(914220514,2);
- LOCK=VOCWRD(12150311,2);
- SAY=VOCWRD(190125,2);
- THROW=VOCWRD(2008181523,2);
+ /* Clear the hint stuff. game.hintlc[i] is how long he's been at LOC
+ * with cond bit i. game.hinted[i] is true iff hint i has been
+ * used. */
+ for (int i=1; i<=HNTMAX; i++) {
+ game.hinted[i]=false;
+ game.hintlc[i]=0;
+ }
-/* Initialise the dwarves. game.dloc is loc of dwarves, hard-wired in. game.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.) game.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 game.chloc for ref.
- * the dead end in the other maze has its loc stored in game.chloc2. */
+ /* Define some handy mnemonics. These correspond to object numbers. */
+ AXE=VOCWRD(12405,1);
+ BATTER=VOCWRD(201202005,1);
+ BEAR=VOCWRD(2050118,1);
+ BIRD=VOCWRD(2091804,1);
+ BLOOD=VOCWRD(212151504,1);
+ BOTTLE=VOCWRD(215202012,1);
+ CAGE=VOCWRD(3010705,1);
+ CAVITY=VOCWRD(301220920,1);
+ CHASM=VOCWRD(308011913,1);
+ CLAM=VOCWRD(3120113,1);
+ DOOR=VOCWRD(4151518,1);
+ DRAGON=VOCWRD(418010715,1);
+ DWARF=VOCWRD(423011806,1);
+ FISSUR=VOCWRD(609191921,1);
+ FOOD=VOCWRD(6151504,1);
+ GRATE=VOCWRD(718012005,1);
+ KEYS=VOCWRD(11052519,1);
+ KNIFE=VOCWRD(1114090605,1);
+ LAMP=VOCWRD(12011316,1);
+ MAGZIN=VOCWRD(1301070126,1);
+ MESSAG=VOCWRD(1305191901,1);
+ MIRROR=VOCWRD(1309181815,1);
+ OGRE=VOCWRD(15071805,1);
+ OIL=VOCWRD(150912,1);
+ OYSTER=VOCWRD(1525192005,1);
+ PILLOW=VOCWRD(1609121215,1);
+ PLANT=VOCWRD(1612011420,1);
+ PLANT2=PLANT+1;
+ RESER=VOCWRD(1805190518,1);
+ ROD=VOCWRD(181504,1);
+ ROD2=ROD+1;
+ SIGN=VOCWRD(19090714,1);
+ SNAKE=VOCWRD(1914011105,1);
+ STEPS=VOCWRD(1920051619,1);
+ TROLL=VOCWRD(2018151212,1);
+ TROLL2=TROLL+1;
+ URN=VOCWRD(211814,1);
+ VEND=VOCWRD(1755140409,1);
+ VOLCAN=VOCWRD(1765120301,1);
+ WATER=VOCWRD(1851200518,1);
- game.chloc=114;
- game.chloc2=140;
- for (I=1; I<=NDWARVES; I++) {
- game.dseen[I]=false;
- } /* end loop */
- DFLAG=0;
- game.dloc[1]=19;
- game.dloc[2]=27;
- game.dloc[3]=33;
- game.dloc[4]=44;
- game.dloc[5]=64;
- game.dloc[6]=game.chloc;
- DALTLC=18;
+ /* Objects from MINTRS through MAXTRS are treasures. Here are a few. */
+ AMBER=VOCWRD(113020518,1);
+ CHAIN=VOCWRD(308010914,1);
+ CHEST=VOCWRD(308051920,1);
+ COINS=VOCWRD(315091419,1);
+ EGGS=VOCWRD(5070719,1);
+ EMRALD=VOCWRD(513051801,1);
+ JADE=VOCWRD(10010405,1);
+ NUGGET=VOCWRD(7151204,1);
+ PEARL=VOCWRD(1605011812,1);
+ PYRAM=VOCWRD(1625180113,1);
+ RUBY=VOCWRD(18210225,1);
+ RUG=VOCWRD(182107,1);
+ SAPPH=VOCWRD(1901161608,1);
+ TRIDNT=VOCWRD(2018090405,1);
+ VASE=VOCWRD(22011905,1);
-/* Other random flags and counters, as follows:
- * game.abbnum How often we should print non-abbreviated descriptions
- * game.bonus Used to determine amount of bonus if he reaches closing
- * game.clock1 Number of turns from finding last treasure till closing
- * game.clock2 Number of turns from first warning till blinding flash
- * game.conds Min value for cond(loc) if loc has any hints
- * game.detail How often we've said "not allowed to give more detail"
- * game.dkill # 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 */
+ /* These are motion-verb numbers. */
+ BACK=VOCWRD(2010311,0);
+ CAVE=VOCWRD(3012205,0);
+ DPRSSN=VOCWRD(405161805,0);
+ ENTER=VOCWRD(514200518,0);
+ ENTRNC=VOCWRD(514201801,0);
+ LOOK=VOCWRD(12151511,0);
+ NUL=VOCWRD(14211212,0);
+ STREAM=VOCWRD(1920180501,0);
- TURNS=0;
- TRNDEX=1;
- THRESH= -1;
- if(TRNVLS > 0)THRESH=MOD(TRNVAL[1],100000)+1;
- TRNLUZ=0;
- LMWARN=false;
- IGO=0;
- IWEST=0;
- KNFLOC=0;
- game.detail=0;
- game.abbnum=5;
- for (I=0; I<=4; I++) {
- {long x = 2*I+81; if(RTEXT[x] != 0)MAXDIE=I+1;}
- } /* end loop */
- NUMDIE=0;
- HOLDNG=0;
- game.dkill=0;
- FOOBAR=0;
- game.bonus=0;
- game.clock1=30;
- game.clock2=50;
- game.conds=SETBIT(11);
- SAVED=0;
- game.closng=false;
- PANIC=false;
- game.closed=false;
- CLSHNT=false;
- NOVICE=false;
- SETUP=1;
- game.blklin=true;
+ /* And some action verbs. */
+ FIND=VOCWRD(6091404,2);
+ INVENT=VOCWRD(914220514,2);
+ LOCK=VOCWRD(12150311,2);
+ SAY=VOCWRD(190125,2);
+ THROW=VOCWRD(2008181523,2);
- /* if we can ever think of how, we should save it at this point */
+ /* Initialise the dwarves. game.dloc is loc of dwarves,
+ * hard-wired in. game.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.) game.dseen is true if
+ * dwarf has seen him. game.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 game.chloc for ref. the dead end in the other maze has its
+ * loc stored in game.chloc2. */
+ game.chloc = LOC_DEADEND12;
+ game.chloc2 = LOC_DEADEND13;
+ for (int i=1; i<=NDWARVES; i++) {
+ game.dseen[i]=false;
+ }
+ game.dflag=0;
+ game.dloc[1] = LOC_KINGHALL;
+ game.dloc[2] = LOC_WESTBANK;
+ game.dloc[3] = LOC_Y2;
+ game.dloc[4] = LOC_ALIKE3;
+ game.dloc[5] = LOC_COMPLEX;
+ game.dloc[6]=game.chloc;
- return(0); /* then we won't actually return from initialisation */
+ /* Other random flags and counters, as follows:
+ * game.abbnum How often we should print non-abbreviated descriptions
+ * game.bonus Used to determine amount of bonus if he reaches closing
+ * game.clock1 Number of turns from finding last treasure till closing
+ * game.clock2 Number of turns from first warning till blinding flash
+ * game.conds Min value for cond(loc) if loc has any hints
+ * game.detail How often we've said "not allowed to give more detail"
+ * game.dkill # of dwarves killed (unused in scoring, needed for msg)
+ * game.foobar Current progress in saying "FEE FIE FOE FOO".
+ * game.holdng Number of objects being carried
+ * igo How many times he's said "go XXX" instead of "XXX"
+ * game.iwest How many times he's said "west" instead of "w"
+ * game.knfloc 0 if no knife here, loc if knife here, -1 after caveat
+ * game.limit Lifetime of lamp (not set here)
+ * MAXDIE Number of reincarnation messages available (up to 5)
+ * game.numdie Number of times killed so far
+ * game.thresh Next #turns threshhold (-1 if none)
+ * game.trndex Index in TRNVAL of next threshold (db section 14)
+ * game.trnluz # points lost so far due to number of turns used
+ * game.turns Tallies how many commands he's given (ignores yes/no)
+ * Logicals were explained earlier */
+ game.turns=0;
+ game.trndex=1;
+ game.thresh= -1;
+ if (TRNVLS > 0)
+ game.thresh=MOD(TRNVAL[1],100000)+1;
+ game.trnluz=0;
+ game.lmwarn=false;
+ game.iwest=0;
+ game.knfloc=0;
+ game.detail=0;
+ game.abbnum=5;
+ game.numdie=0;
+ game.holdng=0;
+ game.dkill=0;
+ game.foobar=0;
+ game.bonus=0;
+ game.clock1=30;
+ game.clock2=50;
+ game.conds=SETBIT(11);
+ game.saved=0;
+ game.closng=false;
+ game.panic=false;
+ game.closed=false;
+ game.clshnt=false;
+ game.novice=false;
+ game.blklin=true;
}