- 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+100; LINK[x]=0;}
- } /* end loop */
-
- /* 1102 */ for (I=1; I<=LOCSIZ; I++) {
- ABB[I]=0;
- if(LTEXT[I] == 0 || KEY[I] == 0) goto L1102;
- K=KEY[I];
- if(MOD(IABS(TRAVEL[K]),1000) == 1)COND[I]=2;
-L1102: ATLOC[I]=0;
- } /* end loop */
-
-/* Set up the ATLOC and LINK arrays as described above. We'll use the DROP
- * subroutine, which prefaces new objects on the lists. Since we want things
- * in the other order, we'll run the loop backwards. If the object is in two
- * locs, we drop it twice. This also sets up "PLACE" and "fixed" as copies of
- * "PLAC" and "FIXD". Also, since two-placed objects are typically best
- * described last, we'll drop them first. */
-
- /* 1106 */ for (I=1; I<=100; I++) {
- K=101-I;
- if(FIXD[K] <= 0) goto L1106;
- DROP(K+100,FIXD[K]);
- DROP(K,PLAC[K]);
-L1106: /*etc*/ ;
- } /* end loop */
-
- for (I=1; I<=100; I++) {
- K=101-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);
-
-/* Objects from 50 through whatever are treasures. Here are a few. */
-
- AMBER=VOCWRD(113020518,1);
- CHAIN=VOCWRD(308010914,1);
- CHEST=VOCWRD(308051920,1);
- COINS=VOCWRD(315091419,1);
- EGGS=VOCWRD(5070719,1);
- EMRALD=VOCWRD(513051801,1);
- JADE=VOCWRD(10010405,1);
- NUGGET=VOCWRD(7151204,1);
- PEARL=VOCWRD(1605011812,1);
- PYRAM=VOCWRD(1625180113,1);
- RUBY=VOCWRD(18210225,1);
- RUG=VOCWRD(182107,1);
- SAPPH=VOCWRD(1901161608,1);
- TRIDNT=VOCWRD(2018090405,1);
- VASE=VOCWRD(22011905,1);
-
-/* These are motion-verb numbers. */
-
- BACK=VOCWRD(2010311,0);
- CAVE=VOCWRD(3012205,0);
- DPRSSN=VOCWRD(405161805,0);
- ENTER=VOCWRD(514200518,0);
- ENTRNC=VOCWRD(514201801,0);
- LOOK=VOCWRD(12151511,0);
- NUL=VOCWRD(14211212,0);
- STREAM=VOCWRD(1920180501,0);
-
-/* And some action verbs. */
-
- FIND=VOCWRD(6091404,2);
- INVENT=VOCWRD(914220514,2);
- LOCK=VOCWRD(12150311,2);
- SAY=VOCWRD(190125,2);
- THROW=VOCWRD(2008181523,2);
-
-/* Initialise the dwarves. DLOC is loc of dwarves, hard-wired in. ODLOC is
- * prior loc of each dwarf, initially garbage. DALTLC is alternate initial loc
- * for dwarf, in case one of them starts out on top of the adventurer. (No 2
- * of the 5 initial locs are adjacent.) DSEEN is true if dwarf has seen him.
- * DFLAG controls the level of activation of all this:
- * 0 No dwarf stuff yet (wait until reaches Hall Of Mists)
- * 1 Reached Hall Of Mists, but hasn't met first dwarf
- * 2 Met first dwarf, others start moving, no knives thrown yet
- * 3 A knife has been thrown (first set always misses)
- * 3+ Dwarves are mad (increases their accuracy)
- * Sixth dwarf is special (the pirate). He always starts at his chest's
- * eventual location inside the maze. This loc is saved in CHLOC for ref.
- * the dead end in the other maze has its loc stored in CHLOC2. */
-
- CHLOC=114;
- CHLOC2=140;
- for (I=1; I<=6; I++) {
- DSEEN[I]=false;
- } /* end loop */
- DFLAG=0;
- DLOC[1]=19;
- DLOC[2]=27;
- DLOC[3]=33;
- DLOC[4]=44;
- DLOC[5]=64;
- DLOC[6]=CHLOC;
- DALTLC=18;
-
-/* Other random flags and counters, as follows:
- * ABBNUM How often we should print non-abbreviated descriptions
- * BONUS Used to determine amount of bonus if he reaches closing
- * CLOCK1 Number of turns from finding last treasure till closing
- * CLOCK2 Number of turns from first warning till blinding flash
- * CONDS Min value for cond(loc) if loc has any hints
- * DETAIL How often we've said "not allowed to give more detail"
- * DKILL Number of dwarves killed (unused in scoring, needed for msg)
- * FOOBAR Current progress in saying "FEE FIE FOE FOO".
- * HOLDNG Number of objects being carried
- * IGO How many times he's said "go XXX" instead of "XXX"
- * IWEST How many times he's said "west" instead of "w"
- * KNFLOC 0 if no knife here, loc if knife here, -1 after caveat
- * LIMIT Lifetime of lamp (not set here)
- * MAXDIE Number of reincarnation messages available (up to 5)
- * NUMDIE Number of times killed so far
- * THRESH Next #turns threshhold (-1 if none)
- * TRNDEX Index in TRNVAL of next threshhold (section 14 of database)
- * TRNLUZ # points lost so far due to number of turns used
- * TURNS Tallies how many commands he's given (ignores yes/no)
- * Logicals were explained earlier */
-
- TURNS=0;
- TRNDEX=1;
- THRESH= -1;
- if(TRNVLS > 0)THRESH=MOD(TRNVAL[1],100000)+1;
- TRNLUZ=0;
- LMWARN=false;
- IGO=0;
- IWEST=0;
- KNFLOC=0;
- DETAIL=0;
- ABBNUM=5;
- for (I=0; I<=4; I++) {
- {long x = 2*I+81; if(RTEXT[x] != 0)MAXDIE=I+1;}
- } /* end loop */
- NUMDIE=0;
- HOLDNG=0;
- DKILL=0;
- FOOBAR=0;
- BONUS=0;
- CLOCK1=30;
- CLOCK2=50;
- CONDS=SETBIT(11);
- SAVED=0;
- CLOSNG=false;
- PANIC=false;
- CLOSED=false;
- CLSHNT=false;
- NOVICE=false;
- SETUP=1;
-
- /* if we can ever think of how, we should save it at this point */
-
- return(0); /* then we won't actually return from initialisation */
+ }
+
+ srand(time(NULL));
+ int seedval = (int)rand();
+ set_seed(seedval);
+
+ for (int i = 1; i <= NDWARVES; i++) {
+ game.dwarves[i].loc = dwarflocs[i - 1];
+ }
+
+ for (int i = 1; i <= NOBJECTS; i++) {
+ game.objects[i].place = LOC_NOWHERE;
+ }
+
+ for (int i = 1; i <= NLOCATIONS; i++) {
+ if (!(locations[i].description.big == 0 || tkey[i] == 0)) {
+ int k = tkey[i];
+ if (travel[k].motion == HERE) {
+ conditions[i] |= (1 << COND_FORCED);
+ }
+ }
+ }
+
+ /* Set up the game.locs atloc and game.link arrays.
+ * 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.
+ * Also, since two-placed objects are typically best described
+ * last, we'll drop them first. */
+ for (int i = NOBJECTS; i >= 1; i--) {
+ if (objects[i].fixd > 0) {
+ drop(i + NOBJECTS, objects[i].fixd);
+ drop(i, objects[i].plac);
+ }
+ }
+
+ for (int i = 1; i <= NOBJECTS; i++) {
+ int k = NOBJECTS + 1 - i;
+ game.objects[k].fixed = objects[k].fixd;
+ if (objects[k].plac != 0 && objects[k].fixd <= 0) {
+ drop(k, objects[k].plac);
+ }
+ }
+
+ /* Treasure props are initially STATE_NOTFOUND, and are set to
+ * STATE_FOUND 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.
+ * (ESR) Non-treasures are set to STATE_FOUND explicitly so we
+ * don't rely on the value of uninitialized storage. This is to
+ * make translation to future languages easier. */
+ for (int object = 1; object <= NOBJECTS; object++) {
+ if (objects[object].is_treasure) {
+ ++game.tally;
+ if (objects[object].inventory != NULL) {
+ OBJECT_SET_NOT_FOUND(object);
+ }
+ } else {
+ OBJECT_SET_FOUND(object);
+ }
+ }
+ game.conds = setbit(COND_HBASE);
+
+ return seedval;