Annotation of researchv10no/games/adv/adv.c, revision 1.1

1.1     ! root        1: /* Adventure (3/6/79 17:32:41 1.20)
        !             2:    Current limits:
        !             3:         999 lines, linsiz of message text (lines).
        !             4:         750 travel options (travel, trvsiz).
        !             5:         300 vocabulary words (ktab, atab, tabsiz).
        !             6:         150 locations (ltext, stext, key, cond, abb, atloc, locsiz).
        !             7:         100 objects (plac, place, fixd, fixed, rlink (twice), ptext,
        !             8:                     prop).
        !             9:          35 "action" verbs (actspk, vrbsiz).
        !            10:         205 random messages (rtext, rtxsiz).
        !            11:          12 different player classifications (ctext, cval, clsmax).
        !            12:          20 hints, less 3 (hintlc, hinted, hints, hntsiz).
        !            13:          35 magic messages (mtext, magsiz).
        !            14:    there are also limits which cannot be exceeded due to the
        !            15:    structure of the database.  (e.g., the vocabulary uses
        !            16:    n/1000 to determine word type, so there can't be more
        !            17:    than 1000 words.) these upper limits are:
        !            18:         1000 non-synonymous vocabulary words
        !            19:         300 locations
        !            20:         100 objects
        !            21:  */
        !            22: #include <stdio.h>
        !            23: #include <signal.h>
        !            24: 
        !            25: long longabs(x)
        !            26:        long x;
        !            27: {
        !            28:        return x<0? -x: x;
        !            29: }
        !            30: 
        !            31: long getl (file)
        !            32:        register FILE *file;
        !            33: {
        !            34:        long l;
        !            35:        l = getw (file);
        !            36:        l <<= 16;
        !            37:        l |= getw (file);
        !            38:        return l;
        !            39: }
        !            40: 
        !            41: putl (l, file)
        !            42:        long l;
        !            43:        register FILE *file;
        !            44: {
        !            45:        putw ((int) (l >> 16), file);
        !            46:        putw ((int) l, file);
        !            47: }
        !            48: 
        !            49: FILE *caves, *suspfd;
        !            50: long tvec, xtime, time();
        !            51: long ftell();
        !            52: struct passwd *pwbuf;
        !            53: char suspbeg;  /* Start of variables to write during suspension */
        !            54: char tkword[10];
        !            55: char wd2x[5];
        !            56: char wd2[5];
        !            57: char wd1x[5];
        !            58: char wd1[5];
        !            59: char atab[300+1][6];
        !            60: char linebuf[100];     /* For reading cave description, etc */
        !            61: char chr;
        !            62: char *cp1, *cp2;
        !            63: int rtext[205];
        !            64: long newloc = 0L;
        !            65: long lines[1000];      /* Assumed initialized to zero */
        !            66: int blklin = 1;
        !            67: int dseen[6];
        !            68: int odloc[6];
        !            69: int dloc[6];
        !            70: int tk[20+1];
        !            71: int hinted[20+1];
        !            72: int hinted[20+1];      /* Assumed initialized to 0 */
        !            73: int hints[12+1][4+1];  /* Assumed initialized to 0 */
        !            74: int cval[12+1];        /* Assumed initialized to 0 */
        !            75: int ctext[12+1];       /* Assumed initialized to 0 */
        !            76: int actspk[35+1];      /* Assumed initialized to 0 */
        !            77: int prop[100+1];       /* Assumed initialized to 0 */
        !            78: int fixd[100+1];       /* Assumed initialized to 0 */
        !            79: int plac[100+1];       /* Assumed initialized to 0 */
        !            80: int cond[150+1];       /* Assumed initialized to 0 */
        !            81: int key[150+1];        /* Assumed initialized to 0 */
        !            82: int stext[150+1];      /* Assumed initialized to 0 */
        !            83: int ltext[150+1];      /* Assumed initialized to 0 */
        !            84: long travel[750+1];    /* Assumed initialized to 0 */
        !            85: int hintlc[21+1];      /* Assumed initialized to zero */
        !            86: int abb[150+1];
        !            87: int holdng;
        !            88: int fixed[100+1];
        !            89: int place[100+1];
        !            90: int rlink[200+1];
        !            91: int atloc[150+1];
        !            92: int tabsiz = 300;
        !            93: int ktab[300+1];
        !            94: int ptext[100+1];
        !            95: #ifdef INITBUG
        !            96: int clssiz = 12;
        !            97: int linsiz = 999;
        !            98: int vrbsiz = 35;
        !            99: #endif INITBUG
        !           100: int trvsiz = 750;
        !           101: int locsiz = 150;
        !           102: int rtxsiz = 205;
        !           103: int clsmax = 12;
        !           104: int hntsiz = 20;
        !           105: int wzdark;
        !           106: int lmwarn;
        !           107: int closng;
        !           108: int panic;
        !           109: int closed;
        !           110: int gaveup;
        !           111: int scorng;
        !           112: int yea;
        !           113: long ll;
        !           114: 
        !           115: #ifdef unix
        !           116: #include <pwd.h>
        !           117: #define GETPWUID() pwbuf=getpwuid(getuid());cp2=pwbuf->pw_dir;while(*cp1++ = *cp2++);cp1--;
        !           118: #define HOURS "Colossal Cave is always open\n"
        !           119: #ifndef        CAVE
        !           120: #define CAVE "/usr/games/lib/cave"
        !           121: #endif CAVE
        !           122: #define SUSPREAD "r"
        !           123: #define SUSPWRITE "w"
        !           124: #endif
        !           125: #ifdef gcos
        !           126: #define CLOSED "Colossal Cave is closed weekdays between 8 AM and 6 PM.\n"
        !           127: #define GETPWUID()  if(lmsgrd()<3){printf(CLOSED);return(0);}fprompt("\r\n");
        !           128: #define HOURS CLOSED
        !           129: #define CAVE "cc/adve/cave$abracadabra"
        !           130: #define SUSPREAD "ri"
        !           131: #define SUSPWRITE "wi"
        !           132: #endif
        !           133: 
        !           134: #define abbnum ints[0]
        !           135: #define iy     ints[1]
        !           136: #define axe    ints[2]
        !           137: #define back   ints[3]
        !           138: #define batter ints[4]
        !           139: #define bear   ints[5]
        !           140: #define bird   ints[6]
        !           141: #define bonus  ints[7]
        !           142: #define bottle ints[8]
        !           143: #define cage   ints[9]
        !           144: #define cave   ints[10]
        !           145: #define ccode  ints[11]
        !           146: #define ch     ints[12]
        !           147: #define chain  ints[13]
        !           148: #define chasm  ints[14]
        !           149: #define chest  ints[15]
        !           150: #define chloc  ints[16]
        !           151: #define chloc2 ints[17]
        !           152: #define clam   ints[18]
        !           153: #define clock1 ints[19]
        !           154: #define clock2 ints[20]
        !           155: #define clsses ints[21]
        !           156: #define coins  ints[22]
        !           157: #define daltlc ints[23]
        !           158: #define detail ints[24]
        !           159: #define dflag  ints[25]
        !           160: #define dkill  ints[26]
        !           161: #define door   ints[27]
        !           162: #define dprssn ints[28]
        !           163: #define dragon ints[29]
        !           164: #define dtotal ints[30]
        !           165: #define dwarf  ints[31]
        !           166: #define eggs   ints[32]
        !           167: #define emrald ints[33]
        !           168: #define entrnc ints[34]
        !           169: #define find   ints[35]
        !           170: #define fissur ints[36]
        !           171: #define foo    ints[37]
        !           172: #define foobar ints[38]
        !           173: #define food   ints[39]
        !           174: #define from   ints[40]
        !           175: #define grate  ints[41]
        !           176: #define hint   ints[42]
        !           177: #define hntmax ints[43]
        !           178: #define i      ints[44]
        !           179: #define inlen  ints[45]
        !           180: #define invent ints[46]
        !           181: #define iwest  ints[47]
        !           182: #define j      ints[48]
        !           183: #define k      ints[49]
        !           184: #define keys   ints[50]
        !           185: #define kk     ints[51]
        !           186: #define knfloc ints[52]
        !           187: #define knife  ints[53]
        !           188: #define kq     ints[54]
        !           189: #define k2     ints[55]
        !           190: #define l      ints[56]
        !           191: #define lamp   ints[57]
        !           192: #define limit  ints[58]
        !           193: #define linuse ints[59]
        !           194: #define hungup ints[60]
        !           195: #define loc    ints[61]
        !           196: #define lock   ints[62]
        !           197: #define look   ints[63]
        !           198: #define m      ints[64]
        !           199: #define magzin ints[65]
        !           200: #define maxdie ints[66]
        !           201: #define maxtrs ints[67]
        !           202: #define messag ints[68]
        !           203: #define mirror ints[69]
        !           204: #define mxscor ints[70]
        !           205: #define nugget ints[71]
        !           206: #define nullx  ints[72]
        !           207: #define numdie ints[73]
        !           208: #define obj    ints[74]
        !           209: #define oil    ints[75]
        !           210: #define oldlc2 ints[76]
        !           211: #define oldloc ints[77]
        !           212: #define oyster ints[78]
        !           213: #define pearl  ints[79]
        !           214: #define pillow ints[80]
        !           215: #define plant  ints[81]
        !           216: #define plant2 ints[82]
        !           217: #define posn   ints[83]
        !           218: #define pyram  ints[84]
        !           219: #define rod    ints[85]
        !           220: #define rod2   ints[86]
        !           221: #define rug    ints[87]
        !           222: #define say    ints[88]
        !           223: #define score  ints[89]
        !           224: #define sect   ints[90]
        !           225: #define snake  ints[91]
        !           226: #define spices ints[92]
        !           227: #define spk    ints[93]
        !           228: #define steps  ints[94]
        !           229: #define stick  ints[95]
        !           230: #define tablet ints[96]
        !           231: #define tabndx ints[97]
        !           232: #define tally  ints[98]
        !           233: #define tally2 ints[99]
        !           234: #define temp   ints[100]
        !           235: #define throw  ints[101]
        !           236: #define attack ints[102]
        !           237: #define tridnt ints[103]
        !           238: #define troll  ints[104]
        !           239: #define troll2 ints[105]
        !           240: #define trvs   ints[106]
        !           241: #define turns  ints[107]
        !           242: #define vase   ints[108]
        !           243: #define vend   ints[109]
        !           244: #define verb   ints[110]
        !           245: #define water  ints[111]
        !           246: #define word   ints[112]
        !           247: #define wordend        ints[113]
        !           248: #define wordsize       ints[114]
        !           249: #define wordstrt       ints[115]
        !           250: #define logon  ints[116]
        !           251: #define        srel    ints[117]
        !           252: #define        slev    ints[118]
        !           253: #define        tleft   ints[119]
        !           254: #define        tright  ints[120]
        !           255: int ints[121];
        !           256: 
        !           257: char suspend;  /* End of variables to write during suspension */
        !           258: 
        !           259: /*
        !           260:    wzdark says whether the loc he's leaving was dark
        !           261:    lmwarn says whether he's been warned about lamp going dim
        !           262:    closng says whether its closing time yet
        !           263:    panic says whether he's found out he's trapped in the cave
        !           264:    closed says whether we're all the way closed
        !           265:    gaveup says whether he exited via "quit"
        !           266:    scorng indicates to the score routine whether we're doing
        !           267:    a "score" command
        !           268:    yea is random yes/no reply
        !           269:    hungup says whether he hung up the phone
        !           270:  */
        !           271: 
        !           272: sethup()
        !           273: {
        !           274:        hungup = 1;
        !           275:        signal (SIGHUP, SIG_IGN);
        !           276: 
        !           277: #ifndef        INITBUG
        !           278:        signal (SIGINT, SIG_IGN);
        !           279:        signal (SIGQUIT, SIG_IGN);
        !           280: #endif INITBUG
        !           281: 
        !           282: }
        !           283: 
        !           284: main()
        !           285: {
        !           286:        char suspfile[100];
        !           287:        static char outbuf[BUFSIZ];
        !           288:        struct passwd *getpwuid();
        !           289: 
        !           290:        setbuf(stdout, outbuf);
        !           291:        setbuf(stderr, NULL);
        !           292:        printf ("@(#)Adventure 1.20\n" + 4);
        !           293: 
        !           294:        cp1 = suspfile;
        !           295:        GETPWUID();
        !           296:        cp2 = "/adv.susp";
        !           297:        while (*cp1++ = *cp2++);
        !           298: 
        !           299: #ifndef        INITBUG
        !           300:        if (signal (SIGINT, SIG_IGN) != SIG_IGN)
        !           301:                signal (SIGINT, sethup);
        !           302:        if (signal (SIGQUIT, sethup) != SIG_IGN)
        !           303:                signal (SIGQUIT, sethup);
        !           304: #endif INITBUG
        !           305: 
        !           306:        if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
        !           307:                signal (SIGHUP, sethup);
        !           308: 
        !           309: #ifdef LOG
        !           310:        logon = 1;
        !           311: #else
        !           312:        logon = 0;
        !           313: #endif
        !           314: 
        !           315:        if ((caves = fopen (CAVE, "r")) == NULL)
        !           316:                fatal ("Couldn't open cave file\n");
        !           317: 
        !           318:        /*  Description of the database format:
        !           319:           The data file contains several sections.  Each begins
        !           320:           with a line containing a number identifying the section,
        !           321:           and ends with a line containing "-1".
        !           322:           Section 1:  long form descriptions.  Each line contains a
        !           323:               location number, a tab, and a line of text.  The set
        !           324:               of (necessarily adjacent) lines whose numbers are x
        !           325:               form the long description of location x.
        !           326:           Section 2:  Short form descriptions.  Same format as long
        !           327:               form.  Not all places have short descriptions.
        !           328:           Section 3:  Travel table.  Each line contains a location
        !           329:               number (x), a second location number (y), and a list
        !           330:               of motion numbers (see section 4).  Each motion
        !           331:               represents a verb which will go to y if currently at
        !           332:               x.  y, in turn, is interpreted as follows:  Let
        !           333:               m=y/1000, n=y mod 1000.
        !           334:                       If n<=300       it is the location to go to.
        !           335:                       If 300<n<=500   n-300 is used in a computed
        !           336:                                       goto to a section of special
        !           337:                                       code.
        !           338:                       If n>500        message n-500 from section 6
        !           339:                                       is printed, and he stays
        !           340:                                       wherever he is.
        !           341:               Meanwhile, m specifies the conditions on the motion.
        !           342:                       If m=0          it's unconditional.
        !           343:                       If 0<m<100      it is done with m%
        !           344:                                       probability.
        !           345:                       If m=100        unconditional, but forbidden
        !           346:                                       to dwarves.
        !           347:                       If 100<m<=200   he must be carrying object
        !           348:                                       m-100.
        !           349:                       If 200<m<=300   must be carrying or in same
        !           350:                                       room as m-200.
        !           351:                       If 300<m<=400   prop(m mod 100) must NOT be
        !           352:                                       0.
        !           353:                       If 400<m<=500   prop(m mod 100) must NOT be
        !           354:                                       1.
        !           355:                       If 500<m<=600   prop(m mod 100) must NOT be
        !           356:                                       2, etc.
        !           357:               If the condition (if any) is not met, then the next
        !           358:               DIFFERENT "destination" value is used (unless it
        !           359:               fails to meet ITS conditions, in which case the
        !           360:               next is found, etc.).  Typically, the next dest will
        !           361:               be for one of the same verbs, so that its only use is
        !           362:               as the alternate destination for those verbs.  For
        !           363:               instance:
        !           364:                   15      110022  29      31      34      35      23      43
        !           365:                   15      14      29
        !           366:               This says that, from loc 15, any of the verbs 29, 31,
        !           367:               etc., will take him to 22 if he's carrying object 10,
        !           368:               and otherwise will go to 14.
        !           369:                       11      303008  49
        !           370:                       11      9       50
        !           371:               This says that, from 11, 49 takes him to 8 unless
        !           372:               prop(3)=0, in which case he goes to 9.  Verb 50 takes
        !           373:               him to 9 regardless of prop(3).
        !           374:           Section 4:  vocabulary.  Each line contains a number (n),
        !           375:               a tab, and a five-letter word.  Call m=n/1000.  If
        !           376:               m=0, then the word is a motion verb for use in
        !           377:               travelling (see section 3).  Else, if m=1, the word
        !           378:               is an object.  Else, if m=2, the word is an action
        !           379:               verb (such as "carry" or "attack").  Else, if m=3,
        !           380:               the word is a special case verb (such as "dig") and n
        !           381:               mod 1000 is an index into section 6.  Objects from 50
        !           382:               to (currently, anyway) 79 are considered treasures
        !           383:               (for pirate, closeout).
        !           384:           Section 5:  object descriptions.  Each line contains a
        !           385:               number (n), a tab, and a message.  If n is from 1 to
        !           386:               100, the message is the "inventory" message for
        !           387:               object n.  Otherwise, n should be 000, 100, 200,
        !           388:               etc., and the message should be the description of
        !           389:               the preceding object when its prop value is n/100.
        !           390:               The n/100 is used only to distinguish multiple
        !           391:               messages from multi-line messages; the prop info
        !           392:               actually requires all messages for an object to be
        !           393:               present and consecutive.  Properties which produce no
        !           394:               message should be given the message ">$<".
        !           395:           Section 6:  arbitrary messages.  Same format as sections
        !           396:               1, 2, and 5, except the numbers bear no relation to
        !           397:               anything (except for special verbs in section 4).
        !           398:           Section 7:  object locations.  Each line contains an
        !           399:               object number and its initial location (zero (or
        !           400:               omitted) if none).  If the object is immovable, the
        !           401:               location is followed by a "-1".  If it has two
        !           402:               locations (e.g.  the grate) the first location is
        !           403:               followed with the second, and the object is assumed
        !           404:               to be immovable.
        !           405:           Section 8:  action defaults.  Each line contains an
        !           406:               "action-verb" number and the index (in section 6) of
        !           407:               the default message for the verb.
        !           408:           Section 9:  liquid assets, etc.  Each line contains a
        !           409:               number (n) and up to 20 location numbers.  Bit n
        !           410:               (where 0 is the units bit) is set in cond(loc) for
        !           411:               each loc given.  The cond bits currently assigned
        !           412:               are:
        !           413:                       0       light
        !           414:                       1       if bit 2 is on:  on for oil, off for
        !           415:                               water
        !           416:                       2       liquid asset, see bit 1
        !           417:                       3       pirate doesn't go here unless
        !           418:                               following player
        !           419:               Other bits are used to indicate areas of interest to
        !           420:               "hint" routines:
        !           421:                       4       trying to get into cave
        !           422:                       5       trying to catch bird
        !           423:                       6       trying to deal with snake
        !           424:                       7       lost in maze
        !           425:                       8       pondering dark room
        !           426:                       9       at Witt's end
        !           427:               cond(loc) is set to 2, overriding all other bits, if
        !           428:               loc has forced motion.
        !           429:           Section 10:  class messages.  Each line contains a number
        !           430:               (n), a tab, and a message describing a classification
        !           431:               of player.  The scoring section selects the
        !           432:               appropriate message, where each message is considered
        !           433:               to apply to players whose scores are higher than the
        !           434:               previous n but not higher than this n.  Note that
        !           435:               these scores probably change with every modification
        !           436:               (and particularly expansion) of the program.
        !           437:           Section 11:  hints.  Each line contains a hint number
        !           438:               (corresponding to a cond bit, see section 9), the
        !           439:               number of turns he must be at the right loc(s) before
        !           440:               triggering the hint, the points deducted for taking
        !           441:               the hint, the message number (section 6) of the
        !           442:               question, and the message number of the hint.  These
        !           443:               values are stashed in the "hints" array.  hntmax is
        !           444:               set to the max hint number (<= hntsiz).  Numbers 1-3
        !           445:               are unusable since cond bits are otherwise assigned,
        !           446:               so 2 is used to remember if he's read the clue in the
        !           447:               repository, and 3 is used to remember whether he
        !           448:               asked for instructions (gets more turns, but loses
        !           449:               points).
        !           450:           Section 12:  magic messages.  Identical to section 6
        !           451:               except put in a separate section for easier
        !           452:               reference.  Magic messages are used by the startup,
        !           453:               maintenance mode, and related routines.
        !           454:           Section 0:  end of database.
        !           455:         */
        !           456: 
        !           457:        /*  Read the database */
        !           458: 
        !           459:        printf("Initializing...  ");
        !           460:        fflush(stdout);
        !           461: 
        !           462:        /*
        !           463:           Clear out the various text-pointer arrays.  All text is
        !           464:           stored in array lines; each line is preceded by a word
        !           465:           pointing to the next pointer (i.e.  the word following
        !           466:           the end of the line).  The pointer is negative if this is
        !           467:           first line of a message.  The text-pointer arrays contain
        !           468:           indices of pointer-words in lines.  stext(n) is short
        !           469:           description of location n.  ltext(n) is long description.
        !           470:           ptext(n) points to message for prop(n)=0.  Successive
        !           471:           prop messages are found by chasing pointers.  rtext
        !           472:           contains section 6's stuff.  ctext(n) points to a
        !           473:           player-class message.  mtext is for section 12.  we also
        !           474:           clear cond.  see description of section 9 for details.
        !           475:         */
        !           476:        for (i=1; i<=300; i++) {
        !           477:                if (i <= 100) ptext[i] = 0;
        !           478:                if (i <= rtxsiz) rtext[i] = 0;
        !           479:                if (i <= clsmax) ctext[i] = 0;
        !           480:                if (i <= locsiz) {
        !           481:                        stext[i]=0;
        !           482:                        ltext[i]=0;
        !           483:                        cond[i]=0;
        !           484:                }
        !           485:        }
        !           486:        /* key=0; */
        !           487:        linuse=1;
        !           488:        trvs=1;
        !           489:        clsses=1;
        !           490: 
        !           491:        /* Start new data section.  sect is the section number. */
        !           492: l1002:
        !           493:        fscanf (caves, "%d", &sect);
        !           494:        oldloc= -1;
        !           495: 
        !           496: #ifdef INITBUG
        !           497:        fprintf(stderr, "\nSect=%d\n", sect);
        !           498: #endif INITBUG
        !           499: 
        !           500:        switch (sect) {
        !           501:        case 0:  
        !           502:                goto l1100;        /* (0) */
        !           503:        case 1:  
        !           504:        case 2:  
        !           505:        case 5:  
        !           506:        case 6:  
        !           507:        case 10:  
        !           508:                goto l1004;        /* 1, 2, 5, 6, 10 */
        !           509:        case 3:  
        !           510:                goto l1030;        /* (3) */
        !           511:        case 4:  
        !           512:                goto l1040;        /* (4) */
        !           513:        case 7:  
        !           514:                goto l1050;        /* (7) */
        !           515:        case 8:  
        !           516:                goto l1060;        /* (8) */
        !           517:        case 9:  
        !           518:                goto l1070;        /* (9) */
        !           519:        case 11:  
        !           520:                goto l1080;       /* (11) */
        !           521:        }
        !           522: 
        !           523:        bug(9);
        !           524: 
        !           525:        /* Sections 1, 2, 5, 6, 10.  Read messages and set up pointers. */
        !           526: l1004:
        !           527:        fscanf (caves, "%d", &loc);
        !           528: #ifdef INITBUG
        !           529:        fprintf(stderr, "Sect=%d; Loc=%d\n", sect, loc);
        !           530: #endif INITBUG
        !           531:        while ((chr = getc (caves)) == ' ' || chr == '\t')
        !           532:                ;
        !           533:        ungetc (chr, caves);
        !           534:        lines[linuse] = ftell (caves);
        !           535:        fgets (linebuf, sizeof linebuf, caves);
        !           536:        if (loc == -1) goto l1002;
        !           537:        if (loc != oldloc) {
        !           538:                lines[linuse] = -lines[linuse];
        !           539:                if (sect == 10) {
        !           540:                        ctext[clsses] = linuse;
        !           541:                        cval[clsses] = loc;
        !           542:                        clsses++;
        !           543:                }
        !           544:                else if (sect == 6) {
        !           545:                        if (loc > rtxsiz) bug(6);
        !           546:                        rtext[loc] = linuse;
        !           547:                }
        !           548:                else if (sect == 5) {
        !           549:                        if (loc > 0 && loc <= 100) ptext[loc] = linuse;
        !           550:                }
        !           551:                else if (sect == 1) {
        !           552:                        ltext[loc] = linuse;
        !           553:                }
        !           554:                else
        !           555:                        stext[loc] = linuse;
        !           556:        }
        !           557:        linuse++;
        !           558:        oldloc = loc;
        !           559:        goto l1004;
        !           560:        /*
        !           561:           The stuff for section 3 is encoded here.  Each
        !           562:           "from-location" gets a contiguous section of the "travel"
        !           563:           array.  Each entry in travel is newloc*1000 + keyword
        !           564:           (from section 4, motion verbs), and is negated if this is
        !           565:           the last entry for this location.  key[n] is the index in
        !           566:           travel of the first option at location n.
        !           567:        */
        !           568: l1030:
        !           569:        fscanf (caves, "%d\t%ld", &loc, &newloc);
        !           570: #ifdef INITBUG
        !           571:        fprintf(stderr, "Sect=%d; Loc=%d; newloc=%d\n", sect, loc, newloc);
        !           572: #endif INITBUG
        !           573:        i = 0;
        !           574:        while ((chr = getc (caves)) != '\n') {
        !           575:                ungetc (chr, caves);
        !           576:                fscanf (caves, "%d", &tk[i++]);
        !           577:        }
        !           578:        if (loc == -1) goto l1002;
        !           579:        if (key[loc])
        !           580:                travel[trvs-1] = -travel[trvs-1];
        !           581:        else
        !           582:                key[loc] = trvs;
        !           583:        for (l=0; l<i; l++) {
        !           584:                travel[trvs] = newloc * 1000L + tk[l];
        !           585:                trvs++;
        !           586:                if (trvs >= trvsiz) bug(3);
        !           587:        }
        !           588:        travel[trvs-1]= -travel[trvs-1];
        !           589:        goto l1030;
        !           590:        /*
        !           591:           Here we read in the vocabulary.  ktab[n] is the word
        !           592:           number, atab[n] is the corresponding word.  The -1 at the
        !           593:           end of section 4 is left in ktab as an end-marker.
        !           594:        */
        !           595: l1040:
        !           596:        for (tabndx = 1; tabndx <= tabsiz; tabndx++) {
        !           597:                char str[6];
        !           598:                fscanf (caves, "%d\t%s", &ktab[tabndx], str);
        !           599: #ifdef INITBUG
        !           600:                fprintf(stderr, "Sect=%d; k=%d; str=%s\n", sect, ktab[tabndx], str);
        !           601: #endif INITBUG
        !           602:                while ((chr = getc(caves)) != '\n')
        !           603:                        ;
        !           604:                cpy (&atab[tabndx][0], str);
        !           605:                if (ktab[tabndx] == -1) goto l1002;
        !           606:        }
        !           607:        bug(4);
        !           608:        /*
        !           609:           Read in the initial locations for each object.  Also the
        !           610:           immovability info.  plac contains initial locations of
        !           611:           objects.  fixd is -1 for immovable objects (including the
        !           612:           snake), or = second loc for two-placed objects.
        !           613:        */
        !           614: l1050:
        !           615:        while (fscanf (caves, "%d\t%d\t%d", &obj, &j, &k), obj != -1) {
        !           616: #ifdef INITBUG
        !           617:                fprintf(stderr, "Sect=%d; obj=%d; plac=%d; fixd=%d\n", sect, obj, j, k);
        !           618: #endif INITBUG
        !           619:                plac[obj]=j;
        !           620:                fixd[obj]=k;
        !           621:        }
        !           622:        goto l1002;
        !           623: 
        !           624:        /* Read default message numbers for action verbs, store in actspk. */
        !           625: l1060:
        !           626:        while (fscanf (caves, "%d\t%d", &verb, &j), verb != -1) {
        !           627: #ifdef INITBUG
        !           628:                fprintf(stderr, "Sect=%d; verb=%d; j=%d\n", sect, verb, j);
        !           629: #endif INITBUG
        !           630:                actspk[verb]=j;
        !           631:        }
        !           632:        goto l1002;
        !           633: 
        !           634:        /* Read info about available liquids and other conditions,
        !           635:           store in cond.  */
        !           636: l1070:
        !           637:        while (fscanf (caves, "%d", &k), k != -1) {
        !           638: #ifdef INITBUG
        !           639:                fprintf(stderr, "Sect=%d; cond=%d\n", sect, k);
        !           640: #endif INITBUG
        !           641:                i = 0;
        !           642:                while ((chr = getc(caves)) != '\n') {
        !           643:                        ungetc(chr, caves);
        !           644:                        fscanf (caves, "%d", &i);
        !           645:                        if (bitset (i, k)) {
        !           646:                                int z;
        !           647:                                for (z=0; z<10; z++)
        !           648:                                        printf ("cond[%d]=%d\n", z, cond[z]);
        !           649:                                fatal ("Duplicate bit\n");
        !           650:                        }
        !           651:                        cond[i] |= (1 << k);
        !           652:                }
        !           653:        }
        !           654:        goto l1002;
        !           655: 
        !           656:        /* Read data for hints. */
        !           657: l1080:  
        !           658:        hntmax=0;
        !           659: 
        !           660:        while (fscanf (caves, "%d\t%d\t%d\t%d\t%d",
        !           661:                &k, &tk[1], &tk[2], &tk[3], &tk[4]), k != -1) {
        !           662: #ifdef INITBUG
        !           663:                fprintf(stderr, "Sect=%d; k=%d; tk=[%d,%d,%d,%d]\n",
        !           664:                        sect, k, tk[1], tk[2], tk[3], tk[4]);
        !           665: #endif INITBUG
        !           666:                if (k != 0) {
        !           667:                        if (k < 0 || k > hntsiz) bug(7);
        !           668:                        for (i=1; i<=4; i++)
        !           669:                                hints[k][i]=tk[i];
        !           670:                        if (k > hntmax)
        !           671:                                hntmax = k;
        !           672:                }
        !           673:        }
        !           674:        goto l1002;
        !           675: 
        !           676:        /*
        !           677:           Finish constructing internal data format
        !           678:           Having read in the database, certain things are now
        !           679:           constructed.  Props are set to zero.  We finish setting
        !           680:           up cond by checking for forced-motion travel entries.
        !           681:           The plac and fixd arrays are used to set up atloc[n] as
        !           682:           the first object at location n, and rlink[obj] as the next
        !           683:           object at the same location as obj.  (obj>100 indicates
        !           684:           that fixed[obj-100]=loc; rlink[obj] is still the correct
        !           685:           link to use.) abb is zeroed; it controls whether the
        !           686:           abbreviated description is printed.  Counts mod 5 unless
        !           687:           "look" is used.
        !           688:        */
        !           689: l1100:
        !           690: 
        !           691:        printf("Linking...  ");
        !           692:        fflush(stdout);
        !           693: 
        !           694:        for (i=1; i<=100; i++) {
        !           695:                place[i]=0;
        !           696:                prop[i]=0;
        !           697:                rlink[i]=0;
        !           698:                rlink[i+100]=0;
        !           699:        }
        !           700:        for (i=1; i<=locsiz; i++) {
        !           701:                abb[i]=0;
        !           702:                if (ltext[i] != 0 && key[i] != 0) {
        !           703:                        k=key[i];
        !           704:                        if (longabs(travel[k]) % 1000 == 1)
        !           705:                                cond[i]=2;
        !           706:                }
        !           707:                atloc[i]=0;
        !           708:        }
        !           709:        /*
        !           710:           Set up the atloc and rlink arrays as described above.
        !           711:           We'll use the drop subroutine, which prefaces new objects
        !           712:           on the lists.  Since we want things in the other order,
        !           713:           we'll run the loop backwards.  If the object is in two
        !           714:           locs, we drop it twice.  This also sets up "place" and
        !           715:           "fixed" as copies of "plac" and "fixd".  Also, since
        !           716:           two-placed objects are typically best described last,
        !           717:           we'll drop them first.
        !           718:        */
        !           719:        for (i=1; i<=100; i++) {
        !           720:                k=101-i;
        !           721:                if (fixd[k] > 0) {
        !           722:                        drop (k+100,fixd[k]);
        !           723:                        drop (k,plac[k]);
        !           724:                }
        !           725:        }
        !           726:        for (i=1; i<=100; i++) {
        !           727:                k=101-i;
        !           728:                fixed[k]=fixd[k];
        !           729:                if (plac[k] != 0 && fixd[k] <= 0) drop(k,plac[k]);
        !           730:        }
        !           731:        /*
        !           732:           Treasures, as noted earlier, are objects 50 through
        !           733:           maxtrs (currently 79).  Their props are initially -1, and
        !           734:           are set to 0 the first time they are described.  Tally
        !           735:           keeps track of how many are not yet found, so we know
        !           736:           when to close the cave.  Tally2 counts how many can never
        !           737:           be found (e.g.  if lost bird or bridge).
        !           738:        */
        !           739:        maxtrs=79;
        !           740:        tally=0;
        !           741:        tally2=0;
        !           742:        for (i=50; i<=maxtrs; i++) {
        !           743:                if (ptext[i] != 0) prop[i]= -1;
        !           744:                tally -= prop[i];
        !           745:        }
        !           746:        /*
        !           747:           Clear the hint stuff.  hintlc[i] is how long he's been at
        !           748:           loc with cond bit i.  hinted(i) is true iff hint i has
        !           749:           been used.
        !           750:        */
        !           751:        for (i = 1; i<=hntmax; i++)
        !           752:                hinted[i] = hintlc[i] = 0;
        !           753:        /* Define some handy mnemonics.  these correspond to object numbers. */
        !           754:        keys=vocab("keys",1);
        !           755:        lamp=vocab("lamp",1);
        !           756:        grate=vocab("grate",1);
        !           757:        cage=vocab("cage",1);
        !           758:        rod=vocab("rod",1);
        !           759:        rod2=rod+1;
        !           760:        steps=vocab("steps",1);
        !           761:        bird=vocab("bird",1);
        !           762:        door=vocab("door",1);
        !           763:        pillow=vocab("pillo",1);
        !           764:        snake=vocab("snake",1);
        !           765:        fissur=vocab("fissu",1);
        !           766:        tablet=vocab("table",1);
        !           767:        clam=vocab("clam",1);
        !           768:        oyster=vocab("oyste",1);
        !           769:        magzin=vocab("magaz",1);
        !           770:        dwarf=vocab("dwarf",1);
        !           771:        knife=vocab("knife",1);
        !           772:        food=vocab("food",1);
        !           773:        bottle=vocab("bottl",1);
        !           774:        water=vocab("water",1);
        !           775:        oil=vocab("oil",1);
        !           776:        plant=vocab("plant",1);
        !           777:        plant2=plant+1;
        !           778:        axe=vocab("axe",1);
        !           779:        mirror=vocab("mirro",1);
        !           780:        dragon=vocab("drago",1);
        !           781:        chasm=vocab("chasm",1);
        !           782:        troll=vocab("troll",1);
        !           783:        troll2=troll+1;
        !           784:        bear=vocab("bear",1);
        !           785:        messag=vocab("messa",1);
        !           786:        vend=vocab("vendi",1);
        !           787:        batter=vocab("batte",1);
        !           788:        /* Objects from 50 through whatever are treasures.  here are a few. */
        !           789:        nugget=vocab("gold",1);
        !           790:        coins=vocab("coins",1);
        !           791:        chest=vocab("chest",1);
        !           792:        eggs=vocab("eggs",1);
        !           793:        tridnt=vocab("tride",1);
        !           794:        vase=vocab("vase",1);
        !           795:        emrald=vocab("emera",1);
        !           796:        pyram=vocab("pyram",1);
        !           797:        pearl=vocab("pearl",1);
        !           798:        rug=vocab("rug",1);
        !           799:        chain=vocab("chain",1);
        !           800:        /* These are motion-verb numbers. */
        !           801:        back=vocab("back",0);
        !           802:        look=vocab("look",0);
        !           803:        cave=vocab("cave",0);
        !           804:        nullx=vocab("null",0);
        !           805:        entrnc=vocab("entra",0);
        !           806:        dprssn=vocab("depre",0);
        !           807:        /* And some action verbs. */
        !           808:        say=vocab("say",2);
        !           809:        lock=vocab("lock",2);
        !           810:        throw=vocab("throw",2);
        !           811:        find=vocab("find",2);
        !           812:        invent=vocab("inven",2);
        !           813:        /*
        !           814:           Initialize the dwarves.  dloc is loc of dwarves,
        !           815:           hard-wired in.  odloc is prior loc of each dwarf,
        !           816:           initially garbage.  daltlc is alternate initial loc for
        !           817:           dwarf, in case one of them starts out on top of the
        !           818:           adventurer.  (no 2 of the 5 initial locs are adjacent.)
        !           819:           dseen is true if dwarf has seen him.  dflag controls the
        !           820:           level of activation of all this:
        !           821:                0       no dwarf stuff yet (wait until reaches hall
        !           822:                        of mists)
        !           823:                1       reached hall of mists, but hasn't met first dwarf
        !           824:                2       met first dwarf, others start moving, no
        !           825:                        knives thrown yet
        !           826:                3       a knife has been thrown (first set always
        !           827:                        misses)
        !           828:                3+      dwarves are mad (increases their accuracy)
        !           829:           Sixth dwarf is special (the pirate).  He always starts at
        !           830:           his chest's eventual location inside the maze.  This loc
        !           831:           is saved in chloc for ref.  The dead end in the other
        !           832:           maze has its loc stored in chloc2.
        !           833:        */
        !           834:        chloc=114;
        !           835:        chloc2=140;
        !           836:        for (i=1; i<=6; i++)
        !           837:                dseen[i] = 0;
        !           838:        dflag=0;
        !           839:        dloc[1]=19;
        !           840:        dloc[2]=27;
        !           841:        dloc[3]=33;
        !           842:        dloc[4]=44;
        !           843:        dloc[5]=64;
        !           844:        dloc[6]=chloc;
        !           845:        daltlc=18;
        !           846:        /*
        !           847:           Other random flags and counters, as follows:
        !           848:                turns   tallies how many commands he's given
        !           849:                        (ignores yes/no)
        !           850:                limit   lifetime of lamp (not set here)
        !           851:                iwest   how many times he's said "west" instead of
        !           852:                        "w"
        !           853:                knfloc  0 if no knife here, loc if knife here, -1
        !           854:                        after caveat
        !           855:                detail  how often we've said "not allowed to give
        !           856:                        more detail"
        !           857:                abbnum  how often we should print non-abbreviated
        !           858:                        descriptions
        !           859:                maxdie  number of reincarnation messages available
        !           860:                        (up to 5)
        !           861:                numdie  number of times killed so far
        !           862:                holdng  number of objects being carried
        !           863:                dkill   number of dwarves killed (unused in scoring,
        !           864:                        needed for msg)
        !           865:                foobar  current progress in saying "fee fie foe
        !           866:                        foo".
        !           867:                bonus   used to determine amount of bonus if he
        !           868:                        reaches closing
        !           869:                clock1  number of turns from finding last treasure
        !           870:                        till closing
        !           871:                clock2  number of turns from first warning till
        !           872:                        blinding flash
        !           873:                logicals were explained earlier
        !           874:        */
        !           875:        turns=0;
        !           876:        lmwarn=0;
        !           877:        iwest=0;
        !           878:        knfloc=0;
        !           879:        detail=0;
        !           880:        abbnum=5;
        !           881:        for (i=0; i<=4; i++)
        !           882:                if (rtext[2*i+81] != 0) maxdie=i+1;
        !           883:        numdie=0;
        !           884:        /*holdng=0; */
        !           885:        dkill=0;
        !           886:        foobar=0;
        !           887:        bonus=0;
        !           888:        clock1=30;
        !           889:        clock2=50;
        !           890:        closng=0;
        !           891:        panic=0;
        !           892:        closed=0;
        !           893:        gaveup=0;
        !           894:        scorng=0;
        !           895:        /* Report on amount of arrays actually used,
        !           896:           to permit reductions. */
        !           897:        for (kk = locsiz; kk > 0; kk--) {
        !           898:                if (ltext[kk] != 0)
        !           899:                        break;
        !           900:        }
        !           901:        obj=0;
        !           902:        for (k = 1; k <= 100; k++) {
        !           903:                if (ptext[k] != 0) obj++;
        !           904:        }
        !           905:        for (k = 1; k <= tabndx; k++) {
        !           906:                if (ktab[k]/1000 == 2) verb=ktab[k]-2000;
        !           907:        }
        !           908:        for (j = rtxsiz; j > 0; j--) {
        !           909:                if (rtext[j] != 0)
        !           910:                        break;
        !           911:        }
        !           912:        k=100;
        !           913: #ifdef INITBUG
        !           914:        printf ("%d of %d messages; ", linuse, linsiz);
        !           915:        printf ("%d of %d travel options;\n", trvs, trvsiz);
        !           916:        printf ("%d of %d vocabulary words; ", tabndx, tabsiz);
        !           917:        printf ("%d of %d locations;\n", kk, locsiz);
        !           918:        printf ("%d of %d objects; ", obj, k);
        !           919:        printf ("%d of %d action verbs;\n", verb, vrbsiz);
        !           920:        printf ("%d of %d rtext messages; ", j, rtxsiz);
        !           921:        printf ("%d of %d class messages;\n", clsses, clssiz);
        !           922:        printf ("%d of %d hints.\n", hntmax, hntsiz);
        !           923: #endif INITBUG
        !           924:        /* Finally, since we're clearly setting things up for the first time */
        !           925:        printf ("Done!\n");
        !           926:        tvec = time((long *) 0);
        !           927:        srand ((int) (tvec % 32768L));
        !           928:        if ((suspfd = fopen (suspfile, SUSPREAD)) != NULL) {
        !           929:                /* check if we suspended in this release */
        !           930:                srel = getw (suspfd);
        !           931:                slev = getw (suspfd);
        !           932:                if (srel != 1 || slev != 20) {
        !           933:                        printf("I deleted a suspend file from version %d.%d\n",
        !           934:                                srel, slev);
        !           935:                        unlink (suspfile);
        !           936:                        hinted[3] = yes (65, 1, 0);
        !           937:                        loc = newloc = 1;
        !           938:                        limit = hinted[3]? 1000: 330;
        !           939:                }
        !           940:                else
        !           941:                    {
        !           942:                        /* When did we suspend? */
        !           943:                        xtime = getl (suspfd);
        !           944: #ifndef NOTIME
        !           945:                        tvec = time((long *) 0);
        !           946:                        if (tvec - xtime < 1800) {
        !           947:                                printf ("You cannot restart a suspended game");
        !           948:                                printf ("for at least half an hour.\n");
        !           949:                                exit (1);
        !           950:                        }
        !           951: #endif
        !           952: 
        !           953:                        /* Delete the suspend file */
        !           954:                        if (unlink (suspfile) == -1)
        !           955:                                fatal ("can't unlink suspend file");
        !           956: 
        !           957:                        fread (&suspbeg, sizeof suspbeg, &suspend - &suspbeg, suspfd);
        !           958:                        fclose (suspfd);
        !           959:                        printf ("Restarting a suspended game...\n");
        !           960:                        newloc = loc;
        !           961:                }
        !           962:        }
        !           963:        else
        !           964:            {
        !           965:                hinted[3]=yes(65,1,0);
        !           966:                loc=newloc=1;
        !           967:                limit = hinted[3]? 1000: 330;
        !           968:        }
        !           969:        /*  Can't leave cave once it's closing (except by main office). */
        !           970: l2:     
        !           971:        if (newloc < 9 && newloc != 0 &&  closng) {
        !           972:                rspeak(130);
        !           973:                newloc=loc;
        !           974:                if (!panic) clock2=15;
        !           975:                panic=1;
        !           976:        }
        !           977:        /*
        !           978:                   See if a dwarf has seen him and has come from where he
        !           979:                   wants to go.  If so, the dwarf's blocking his way.  If
        !           980:                   coming from place forbidden to pirate (dwarves rooted in
        !           981:                   place) let him get out (and attacked).
        !           982:                */
        !           983:        if (newloc != loc && !forced(loc) && !bitset(loc,3)) {
        !           984:                for (i = 1; i <= 5; i++) {
        !           985:                        if (!(odloc[i] != newloc ||  !dseen[i])) {
        !           986:                                newloc=loc;
        !           987:                                rspeak(2);
        !           988:                                break;
        !           989:                        }
        !           990:                }
        !           991:        }
        !           992:        loc=newloc;
        !           993:        /*
        !           994:                   Dwarf stuff.  See earlier comments for description of
        !           995:                   variables.  Remember sixth dwarf is pirate and is thus
        !           996:                   very different except for motion rules.
        !           997:                   First off, don't let the dwarves follow him into a pit or
        !           998:                   a wall.  Activate the whole mess the first time he gets
        !           999:                   as far as the hall of mists (loc 15).  If newloc is
        !          1000:                   forbidden to pirate (in particular, if it's beyond the
        !          1001:                   troll bridge), bypass dwarf stuff.  That way pirate can't
        !          1002:                   steal return toll, and dwarves can't meet the bear.  Also
        !          1003:                   means dwarves won't follow him into dead end in maze, but
        !          1004:                   c'est la vie.  They'll wait for him outside the dead end.
        !          1005:                */
        !          1006:        if (loc == 0 || forced(loc) || bitset((int)newloc,3)) goto l2000;
        !          1007:        if (dflag == 0) {
        !          1008:                if (loc >= 15) dflag=1;
        !          1009:                goto l2000;
        !          1010:        }
        !          1011:        /*
        !          1012:                   When we encounter the first dwarf, we kill 0, 1, or 2 of
        !          1013:                   the 5 dwarves.  If any of the survivors is at loc,
        !          1014:                   replace him with the alternate.
        !          1015:                */
        !          1016:        if (dflag == 1) {
        !          1017:                if (loc < 15 || pct(95)) goto l2000;
        !          1018:                dflag=2;
        !          1019:                for (i = 1; i <= 2; i++) {
        !          1020:                        j=1+ran(5);
        !          1021:                        if (pct(50)) dloc[j]=0;
        !          1022:                }
        !          1023:                for (i = 1; i <= 5; i++) {
        !          1024:                        if (dloc[i] == loc) dloc[i]=daltlc;
        !          1025:                        odloc[i]=dloc[i];
        !          1026:                }
        !          1027:                rspeak(3);
        !          1028:                drop(axe,loc);
        !          1029:                goto l2000;
        !          1030:        }
        !          1031:        /*
        !          1032:                   Things are in full swing.  Move each dwarf at random,
        !          1033:                   except if he's seen us he sticks with us.  Dwarves never
        !          1034:                   go to locs <15.  If wandering at random, they don't back
        !          1035:                   up unless there's no alternative.  If they don't have to
        !          1036:                   move, they attack.  And, of course, dead dwarves don't do
        !          1037:                   much of anything.
        !          1038:                */
        !          1039:        dtotal=0;
        !          1040:        attack=0;
        !          1041:        stick=0;
        !          1042:        for (i = 1; i <= 6; i++) {
        !          1043:                if (dloc[i] == 0) goto l6030;
        !          1044:                j=1;
        !          1045:                kk=dloc[i];
        !          1046:                kk=key[kk];
        !          1047:                if (kk != 0) {
        !          1048:                        do 
        !          1049:                            {
        !          1050:                                newloc=longabs(travel[kk])/1000 % 1000;
        !          1051:                                if (newloc <= 300 && newloc >=15 && newloc != odloc[i]
        !          1052:                                    && !(j > 1 && newloc == tk[j-1]) && j < 20
        !          1053:                                    && newloc != dloc[i] && !forced((int)newloc)
        !          1054:                                    && !(i == 6 && bitset((int)newloc,3))
        !          1055:                                    && longabs(travel[kk] / 1000000) != 100) {
        !          1056:                                        tk[j]=newloc;
        !          1057:                                        j++;
        !          1058:                                }
        !          1059:                                kk++;
        !          1060:                        } 
        !          1061:                        while (travel[kk-1] >= 0);
        !          1062:                }
        !          1063:                tk[j]=odloc[i];
        !          1064:                if (j >= 2) j--;
        !          1065:                j=1+ran(j);
        !          1066:                odloc[i]=dloc[i];
        !          1067:                dloc[i]=tk[j];
        !          1068:                dseen[i]=(dseen[i] && loc >= 15)
        !          1069:                        || (dloc[i] == loc || odloc[i] == loc);
        !          1070:                if (!dseen[i]) goto l6030;
        !          1071:                dloc[i]=loc;
        !          1072:                if (i != 6) goto l6027;
        !          1073:                /*
        !          1074:                                The pirate's spotted him.  He leaves him alone once we've
        !          1075:                                found chest.  k counts if a treasure is here.  If not,
        !          1076:                                and tally=tally2 plus one for an unseen chest, let the
        !          1077:                                pirate be spotted.
        !          1078:                                */
        !          1079:                if (loc == chloc || prop[chest] >= 0) goto l6030;
        !          1080:                k=0;
        !          1081:                for (j = 50; j <= maxtrs; j++) {
        !          1082:                        /* Pirate won't take pyramid from plover room or dark room (too easy!).  */
        !          1083:                        if (j != pyram || !(loc == plac[pyram]
        !          1084:                            || loc == plac[emrald])) {
        !          1085:                                if (toting(j)) goto l6022;
        !          1086:                        }
        !          1087:                        if (here(j)) k=1;
        !          1088:                }
        !          1089:                if (tally == tally2+1 && k == 0 && place[chest] == 0
        !          1090:                    && here(lamp) && prop[lamp] == 1) goto l6025;
        !          1091:                if (odloc[6] != dloc[6] && pct(20)) rspeak(127);
        !          1092:                goto l6030;
        !          1093: l6022:      
        !          1094:                rspeak(128);
        !          1095:                /* Don't steal chest back from troll! */
        !          1096:                if (place[messag] == 0) move(chest,chloc);
        !          1097:                move(messag,chloc2);
        !          1098:                for (j = 50; j <= maxtrs; j++) {
        !          1099:                        if (j == pyram && (loc == plac[pyram]
        !          1100:                            || loc == plac[emrald])) goto l6023;
        !          1101:                        if (at(j) && fixed[j] == 0) carry(j,loc);
        !          1102:                        if (toting(j)) drop(j,chloc);
        !          1103: l6023:          
        !          1104:                        ; 
        !          1105:                }
        !          1106: l6024:      
        !          1107:                dloc[6]=chloc;
        !          1108:                odloc[6]=chloc;
        !          1109:                dseen[6]=0;
        !          1110:                goto l6030;
        !          1111: l6025:      
        !          1112:                rspeak(186);
        !          1113:                move(chest,chloc);
        !          1114:                move(messag,chloc2);
        !          1115:                goto l6024;
        !          1116:                /* This threatening little dwarf is in the room with him! */
        !          1117: l6027:     
        !          1118:                dtotal++;
        !          1119:                if (odloc[i] != dloc[i]) goto l6030;
        !          1120:                attack++;
        !          1121:                if (knfloc >= 0) knfloc=loc;
        !          1122:                if (ran(1000) < 95*(dflag-2))stick++;
        !          1123: l6030:      
        !          1124:                ; 
        !          1125:        }
        !          1126:        /* Now we know what's happening.  let's tell the poor sucker about it.  */
        !          1127:        if (dtotal == 0) goto l2000;
        !          1128:        if (dtotal != 1) {
        !          1129:                printf ("There are %d threatening little dwarves", dtotal);
        !          1130:                printf (" in the room with you.\n");
        !          1131:        } else
        !          1132:                rspeak(4);
        !          1133:        if (attack == 0) goto l2000;
        !          1134:        if (dflag == 2) dflag=3;
        !          1135:        /*
        !          1136:                   Dwarves get VERY mad!
        !          1137:                */
        !          1138:        if (attack == 1) {
        !          1139:                rspeak(5);
        !          1140:                k=52;
        !          1141:        }
        !          1142:        else {
        !          1143:                printf ("%d of them throw knives at you!\n", attack);
        !          1144:                k=6;
        !          1145:        }
        !          1146:        if (stick <= 1) {
        !          1147:                rspeak(k+stick);
        !          1148:                if (stick == 0) goto l2000;
        !          1149:        }
        !          1150:        else
        !          1151:            printf ("%d of them get you!\n", stick);
        !          1152:        oldlc2=loc;
        !          1153:        goto l99;
        !          1154:        /* Describe the current location and (maybe) get next command. */
        !          1155:        /* Print text for current loc. */
        !          1156: l2000:  
        !          1157:        if (loc == 0) goto l99;
        !          1158:        kk=stext[loc];
        !          1159:        if (abb[loc] % abbnum == 0 || kk == 0) kk=ltext[loc];
        !          1160:        if (forced(loc) ||  ! dark()) goto l2001;
        !          1161:        if (wzdark && pct(35)) goto l90;
        !          1162:        kk=rtext[16];
        !          1163: l2001:  
        !          1164:        if (toting(bear)) rspeak(141);
        !          1165:        speak(kk);
        !          1166:        k=1;
        !          1167:        if (forced(loc)) goto l8;
        !          1168:        if (loc == 33 && pct(25) &&  ! closng) rspeak(8);
        !          1169:        /*
        !          1170:                   Print out descriptions of objects at this location.  If
        !          1171:                   not closing and property value is negative, tally off
        !          1172:                   another treasure.  Rug is special case; once seen, its
        !          1173:                   prop is 1 (dragon on it) till dragon is killed.
        !          1174:                   Similarly for chain; prop is initially 1 (locked to
        !          1175:                   bear).  These hacks are because prop=0 is needed to get
        !          1176:                   full score.
        !          1177:                */
        !          1178:        if (dark()) goto l2012;
        !          1179:        abb[loc]++;
        !          1180:        i=atloc[loc];
        !          1181:        for(;;) {
        !          1182:                if (i == 0) goto l2012;
        !          1183:                obj=i;
        !          1184:                if (obj > 100) obj -= 100;
        !          1185:                if (obj == steps && toting(nugget)) goto l2008;
        !          1186:                if (prop[obj] < 0) {
        !          1187:                        if (closed) goto l2008;
        !          1188:                        prop[obj]=0;
        !          1189:                        if (obj == rug || obj == chain) prop[obj]=1;
        !          1190:                        tally--;
        !          1191:                        /* If remaining treasures too elusive, zap his lamp. */
        !          1192:                        if (tally == tally2 && tally != 0)
        !          1193:                                limit = limit > 35? 35: limit;
        !          1194:                }
        !          1195:                kk=prop[obj];
        !          1196:                if (obj == steps && loc == fixed[steps]) kk=1;
        !          1197:                pspeak(obj,kk);
        !          1198: l2008:  
        !          1199:                i=rlink[i];
        !          1200:        }
        !          1201: l2009:  
        !          1202:        k=54;
        !          1203: l2010:  
        !          1204:        spk=k;
        !          1205: l2011:  
        !          1206:        rspeak(spk);
        !          1207: l2012:  
        !          1208:        verb=0;
        !          1209:        obj=0;
        !          1210:        /*
        !          1211:                   Check if this loc is eligible for any hints.  If been
        !          1212:                   here long enough, branch to help section (on later page).
        !          1213:                   Hints all come back here eventually to finish the loop.
        !          1214:                   Ignore "hints" < 4 (special stuff, see database notes).
        !          1215:                */
        !          1216: l2600:
        !          1217:        for (hint = 4; hint <= hntmax; hint++) {
        !          1218:                if (! (hinted[hint])) {
        !          1219:                        if (!bitset(loc,hint)) hintlc[hint]= -1;
        !          1220:                        hintlc[hint]++;
        !          1221:                        if (hintlc[hint] >= hints[hint][1]) goto l40000;
        !          1222:                }
        !          1223:        }
        !          1224:        /*
        !          1225:                   Kick the random number generator just to add variety to
        !          1226:                   the chase.  Also, if closing time, check for any objects
        !          1227:                   being toted with prop < 0 and set the prop to -1-prop.
        !          1228:                   This way objects won't be described until they've been
        !          1229:                   picked up and put down separate from their respective
        !          1230:                   piles.  Don't tick clock1 unless well into cave (and not
        !          1231:                   at Y2).
        !          1232:                */
        !          1233: l2602:  
        !          1234:        if (!closed) goto l2605;
        !          1235:        if (prop[oyster] < 0 && toting(oyster)
        !          1236:            ) pspeak(oyster,1);
        !          1237:        for (i = 1; i <= 100; i++) {
        !          1238:                if (toting(i) && prop[i] < 0) prop[i]= -1-prop[i];
        !          1239:        }
        !          1240: l2605:  
        !          1241:        wzdark=dark();
        !          1242:        if (knfloc > 0 && knfloc != loc) knfloc=0;
        !          1243:        i=ran(1);
        !          1244:        getin(wd1,wd1x,wd2,wd2x);
        !          1245:        /*
        !          1246:                   Every input, check "foobar" flag.  If zero, nothing's
        !          1247:                   going on.  If pos, make neg.  If neg, he skipped a word,
        !          1248:                   so make it zero.
        !          1249:                */
        !          1250: l2608:
        !          1251:        foobar = foobar < 0? 0: -foobar;
        !          1252:        turns++;
        !          1253:        if (verb == say && !blankp(wd2)) verb=0;
        !          1254:        if (verb == say) goto l4090;
        !          1255:        if (tally == 0 && loc >= 15 && loc != 33) clock1--;
        !          1256:        if (clock1 == 0) goto l10000;
        !          1257:        if (clock1 < 0) clock2--;
        !          1258:        if (clock2 == 0) goto l11000;
        !          1259:        if (prop[lamp] == 1) limit--;
        !          1260:        if (limit <= 30 && here(batter) && prop[batter] == 0
        !          1261:            && here(lamp)) goto l12000;
        !          1262:        if (limit == 0) goto l12400;
        !          1263:        if (limit < 0 && loc <= 8) goto l12600;
        !          1264:        if (limit <= 30) goto l12200;
        !          1265: l19999: 
        !          1266:        k=43;
        !          1267:        if (liqloc(loc) == water) k=70;
        !          1268:        if (eqp (wd1, "enter") && (eqp (wd2, "strea") || eqp (wd2, "water")))
        !          1269:                goto l2010;
        !          1270:        if (eqp (wd1, "enter") && !blankp(wd2)) goto l2800;
        !          1271:        if (!eqp (wd1, "water") && !eqp (wd1, "oil")
        !          1272:            || (!eqp (wd2, "plant") && !eqp (wd2, "door "))) goto l2610;
        !          1273:        if (at(vocab(wd2,1))) cpy (wd2, "pour ");
        !          1274: l2610:  
        !          1275:        if (!eqp(wd1, "west ")) goto l2630;
        !          1276:        iwest++;
        !          1277:        if (iwest == 10) rspeak(17);
        !          1278: l2630:  
        !          1279:        i=vocab(wd1,-1);
        !          1280:        if (i == -1) goto l3000;
        !          1281:        k=i % 1000;
        !          1282:        kq=i/1000+1;
        !          1283:        switch (kq - 1) {
        !          1284:        case 0: 
        !          1285:                goto l8;
        !          1286:        case 1: 
        !          1287:                goto l5000;
        !          1288:        case 2: 
        !          1289:                goto l4000;
        !          1290:        case 3: 
        !          1291:                goto l2010;
        !          1292:        }
        !          1293:        bug(22);
        !          1294:        /* Get second word for analysis. */
        !          1295: l2800:  
        !          1296:        cpy (wd1, wd2);
        !          1297:        cpy (wd1x, wd2x);
        !          1298:        cpy (wd2, "     ");
        !          1299:        goto l2610;
        !          1300:        /* Gee, I don't understand. */
        !          1301: l3000:  
        !          1302:        spk=60;
        !          1303:        if (pct(20)) spk=61;
        !          1304:        if (pct(20)) spk=13;
        !          1305:        rspeak(spk);
        !          1306:        goto l2600;
        !          1307:        /*
        !          1308:                   Analyse a verb.  remember what it was, go back for object
        !          1309:                   if second word unless verb is "say", which snarfs
        !          1310:                   arbitrary second word.
        !          1311:                */
        !          1312: l4000:  
        !          1313:        verb=k;
        !          1314:        spk=actspk[verb];
        !          1315:        if (!blankp(wd2) && verb != say) goto l2800;
        !          1316:        if (verb == say)
        !          1317:                if (blankp (wd2)) goto l4080;
        !          1318:                else goto l4090;
        !          1319:        if (obj != 0) goto l4090;
        !          1320:        /* Analyse an intransitive verb (ie, no object given yet). */
        !          1321: l4080:  
        !          1322:        switch (verb) {
        !          1323:        case 1: 
        !          1324:                goto l8010;       /* take */
        !          1325:        case 2: 
        !          1326:                goto l8000;       /* drop */
        !          1327:        case 3: 
        !          1328:                goto l8000;       /* say */
        !          1329:        case 4: 
        !          1330:                goto l8040;       /* open */
        !          1331:        case 5: 
        !          1332:                goto l2009;       /* noth */
        !          1333:        case 6: 
        !          1334:                goto l8040;       /* lock */
        !          1335:        case 7: 
        !          1336:                goto l9070;       /* on */
        !          1337:        case 8: 
        !          1338:                goto l9080;       /* off */
        !          1339:        case 9: 
        !          1340:                goto l8000;       /* wave */
        !          1341:        case 10: 
        !          1342:                goto l8000;       /* calm */
        !          1343:        case 11: 
        !          1344:                goto l2011;       /* walk */
        !          1345:        case 12: 
        !          1346:                goto l9120;       /* kill */
        !          1347:        case 13: 
        !          1348:                goto l9130;       /* pour */
        !          1349:        case 14: 
        !          1350:                goto l8140;       /* eat */
        !          1351:        case 15: 
        !          1352:                goto l9150;       /* drnk */
        !          1353:        case 16: 
        !          1354:                goto l8000;       /* rub */
        !          1355:        case 17: 
        !          1356:                goto l8000;       /* toss */
        !          1357:        case 18: 
        !          1358:                goto l8180;       /* quit */
        !          1359:        case 19: 
        !          1360:                goto l8000;       /* find */
        !          1361:        case 20: 
        !          1362:                goto l8200;       /* invn */
        !          1363:        case 21: 
        !          1364:                goto l8000;       /* feed */
        !          1365:        case 22: 
        !          1366:                goto l9220;       /* fill */
        !          1367:        case 23: 
        !          1368:                goto l9230;       /* blst */
        !          1369:        case 24: 
        !          1370:                goto l8240;       /* scor */
        !          1371:        case 25: 
        !          1372:                goto l8250;       /* foo */
        !          1373:        case 26: 
        !          1374:                goto l8260;       /* brf */
        !          1375:        case 27: 
        !          1376:                goto l8270;       /* read */
        !          1377:        case 28: 
        !          1378:                goto l8000;       /* brek */
        !          1379:        case 29: 
        !          1380:                goto l8000;       /* wake */
        !          1381:        case 30: 
        !          1382:                goto l8300;       /* susp */
        !          1383:        case 31: 
        !          1384:                goto l8310;       /* hour */
        !          1385:        case 32: 
        !          1386:                goto setlog;      /* log  */
        !          1387:        }
        !          1388:        bug(23);
        !          1389:        /* Analyse a transitive verb. */
        !          1390: l4090:  
        !          1391:        switch (verb) {
        !          1392:        case 1: 
        !          1393:                goto l9010;       /* take */
        !          1394:        case 2: 
        !          1395:                goto l9020;       /* drop */
        !          1396:        case 3: 
        !          1397:                goto l9030;       /* say */
        !          1398:        case 4: 
        !          1399:                goto l9040;       /* open */
        !          1400:        case 5: 
        !          1401:                goto l2009;       /* noth */
        !          1402:        case 6: 
        !          1403:                goto l9040;       /* lock */
        !          1404:        case 7: 
        !          1405:                goto l9070;       /* on */
        !          1406:        case 8: 
        !          1407:                goto l9080;       /* off */
        !          1408:        case 9: 
        !          1409:                goto l9090;       /* wave */
        !          1410:        case 10: 
        !          1411:                goto l2011;       /* calm */
        !          1412:        case 11: 
        !          1413:                goto l2011;       /* walk */
        !          1414:        case 12: 
        !          1415:                goto l9120;       /* kill */
        !          1416:        case 13: 
        !          1417:                goto l9130;       /* pour */
        !          1418:        case 14: 
        !          1419:                goto l9140;       /* eat */
        !          1420:        case 15: 
        !          1421:                goto l9150;       /* drnk */
        !          1422:        case 16: 
        !          1423:                goto l9160;       /* rub */
        !          1424:        case 17: 
        !          1425:                goto l9170;       /* toss */
        !          1426:        case 18: 
        !          1427:                goto l2011;       /* quit */
        !          1428:        case 19: 
        !          1429:                goto l9190;       /* find */
        !          1430:        case 20: 
        !          1431:                goto l9190;       /* invn */
        !          1432:        case 21: 
        !          1433:                goto l9210;       /* feed */
        !          1434:        case 22: 
        !          1435:                goto l9220;       /* fill */
        !          1436:        case 23: 
        !          1437:                goto l9230;       /* blst */
        !          1438:        case 24: 
        !          1439:                goto l2011;       /* scor */
        !          1440:        case 25: 
        !          1441:                goto l2011;       /* foo */
        !          1442:        case 26: 
        !          1443:                goto l2011;       /* brf */
        !          1444:        case 27: 
        !          1445:                goto l9270;       /* read */
        !          1446:        case 28: 
        !          1447:                goto l9280;       /* brek */
        !          1448:        case 29: 
        !          1449:                goto l9290;       /* wake */
        !          1450:        case 30: 
        !          1451:                goto l2011;       /* susp */
        !          1452:        case 31: 
        !          1453:                goto l2011;       /* hour */
        !          1454:        case 32: 
        !          1455:                goto l2011;       /* log  */
        !          1456:        }
        !          1457:        bug(24);
        !          1458:        /*
        !          1459:                   Analyze an object word.  See if the thing is here,
        !          1460:                   whether we've got a verb yet, and so on.  Object must be
        !          1461:                   here unless verb is "find" or "invent(ory)" (and no new
        !          1462:                   verb yet to be analyzed).  Water and oil are also funny,
        !          1463:                   since they are never actually dropped at any location,
        !          1464:                   but might be here inside the bottle or as a feature of
        !          1465:                   the location.
        !          1466:                */
        !          1467: l5000:  
        !          1468:        obj=k;
        !          1469:        if (fixed[k] != loc &&  ! here(k)) goto l5100;
        !          1470: l5010:  
        !          1471:        if (!blankp(wd2)) goto l2800;
        !          1472:        if (verb != 0) goto l4090;
        !          1473:        a5toa1(wd1,wd1x,tkword);
        !          1474:        printf ("What do you want to do with the %s?\n", tkword);
        !          1475:        goto l2600;
        !          1476: l5100:  
        !          1477:        if (k != grate) goto l5110;
        !          1478:        if (loc == 1 || loc == 4 || loc == 7) k=dprssn;
        !          1479:        if (loc > 9 && loc < 15) k=entrnc;
        !          1480:        if (k != grate) goto l8;
        !          1481: l5110:  
        !          1482:        if (k != dwarf) goto l5120;
        !          1483:        for (i = 1; i <= 5; i++) {
        !          1484:                if (dloc[i] == loc && dflag >= 2) goto l5010;
        !          1485:        }
        !          1486: l5120:  
        !          1487:        if ((liq() == k && here(bottle))
        !          1488:            || k == liqloc(loc)) goto l5010;
        !          1489:        if (obj != plant ||  ! at(plant2) || prop[plant2] == 0
        !          1490:            ) goto l5130;
        !          1491:        obj=plant2;
        !          1492:        goto l5010;
        !          1493: l5130:  
        !          1494:        if (obj == knife && knfloc == loc) {
        !          1495:                knfloc= -1;
        !          1496:                spk=116;
        !          1497:                goto l2011;
        !          1498:        }
        !          1499:        if (obj != rod ||  !here(rod2)) goto l5190;
        !          1500:        obj=rod2;
        !          1501:        goto l5010;
        !          1502: l5190:  
        !          1503:        if ((verb == find || verb == invent) && blankp (wd2)
        !          1504:            ) goto l5010;
        !          1505:        a5toa1(wd1,wd1x,tkword);
        !          1506:        printf ("I see no %s here!\n", tkword);
        !          1507:        goto l2012;
        !          1508:        /*
        !          1509:                   Figure out the new location
        !          1510:                   Given the current location in "loc", and a motion verb
        !          1511:                   number in "k", put the new location in "newloc".  The
        !          1512:                   current loc is saved in "oldloc" in case he wants to
        !          1513:                   retreat.  The current oldloc is saved in oldlc2, in case
        !          1514:                   he dies.  (if he does, newloc will be limbo, and oldloc
        !          1515:                   will be what killed him, so we need oldlc2, which is the
        !          1516:                   last place he was safe.)
        !          1517:                */
        !          1518: l8:     
        !          1519:        kk=key[loc];
        !          1520:        newloc=loc;
        !          1521:        if (kk == 0) bug(26);
        !          1522:        if (k == nullx) goto l2;
        !          1523:        if (k == back) goto l20;
        !          1524:        if (k == look) goto l30;
        !          1525:        if (k == cave) goto l40;
        !          1526:        oldlc2=oldloc;
        !          1527:        oldloc=loc;
        !          1528: l9:     
        !          1529:        ll=longabs(travel[kk]);
        !          1530:        if (ll % 1000 == 1 || ll % 1000 == k) goto l10;
        !          1531:        if (travel[kk] < 0) goto l50;
        !          1532:        kk++;
        !          1533:        goto l9;
        !          1534: l10:    
        !          1535:        ll/=1000;
        !          1536: l11:    
        !          1537:        newloc=ll/1000;
        !          1538:        k=newloc % 100;
        !          1539:        if (newloc <= 300) goto l13;
        !          1540:        if (prop[k] != newloc/100-3) goto l16;
        !          1541: l12:    
        !          1542:        if (travel[kk] < 0) bug(25);
        !          1543:        kk++;
        !          1544:        newloc=longabs(travel[kk])/1000;
        !          1545:        if (newloc == ll) goto l12;
        !          1546:        ll=newloc;
        !          1547:        goto l11;
        !          1548: l13:    
        !          1549:        if (newloc <= 100) goto l14;
        !          1550:        if (toting(k) || (newloc > 200 && at(k))) goto l16;
        !          1551:        goto l12;
        !          1552: l14:    
        !          1553:        if (newloc != 0 &&  !pct((int)newloc)) goto l12;
        !          1554: l16:    
        !          1555:        newloc=ll % 1000;
        !          1556:        if (newloc <= 300) goto l2;
        !          1557:        if (newloc <= 500) goto l30000;
        !          1558:        rspeak((int)newloc-500);
        !          1559:        newloc=loc;
        !          1560:        goto l2;
        !          1561:        /*
        !          1562:                   Special motions come here.  Labelling convention:
        !          1563:                   statement numbers nnnxx (xx=00-99) are used for special
        !          1564:                   case number nnn (nnn=301-500).
        !          1565:                */
        !          1566: l30000: 
        !          1567:        newloc=newloc-300;
        !          1568:        switch ((int) newloc-1) {
        !          1569:        case 0: 
        !          1570:                goto l30100;
        !          1571:        case 1: 
        !          1572:                goto l30200;
        !          1573:        case 2: 
        !          1574:                goto l30300;
        !          1575:        }
        !          1576:        bug(20);
        !          1577:        /*
        !          1578:                   Travel 301.  Plover-alcove passage.  can carry only
        !          1579:                   emerald.  Note:  travel table must include "useless"
        !          1580:                   entries going through passage, which can never be used
        !          1581:                   for actual motion, but can be spotted by "go back".
        !          1582:                */
        !          1583: l30100: 
        !          1584:        newloc=99+100-loc;
        !          1585:        if (holdng == 0 || (holdng == 1 && toting(emrald))) goto l2;
        !          1586:        newloc=loc;
        !          1587:        rspeak(117);
        !          1588:        goto l2;
        !          1589:        /*
        !          1590:                   Travel 302.  Plover transport.  Drop the emerald (only
        !          1591:                   use special travel if toting it), so he's forced to use
        !          1592:                   the plover-passage to get it out.  Having dropped it, go
        !          1593:                   back and pretend he wasn't carrying it after all.
        !          1594:                */
        !          1595: l30200: 
        !          1596:        drop(emrald,loc);
        !          1597:        goto l12;
        !          1598:        /*
        !          1599:                   Travel 303.  Troll bridge.  Must be done only as special
        !          1600:                   motion so that dwarves won't wander across and encounter
        !          1601:                   the bear.  (They won't follow the player there because
        !          1602:                   that region is forbidden to the pirate.) If
        !          1603:                   prop(troll)=1, he's crossed since paying, so step out and
        !          1604:                   block him.  (Standard travel entries check for
        !          1605:                   prop(troll)=0.) Special stuff for bear.
        !          1606:                */
        !          1607: l30300: 
        !          1608:        if (prop[troll] != 1) goto l30310;
        !          1609:        pspeak(troll,1);
        !          1610:        prop[troll]=0;
        !          1611:        move(troll2,0);
        !          1612:        move(troll2+100,0);
        !          1613:        move(troll,plac[troll]);
        !          1614:        move(troll+100,fixd[troll]);
        !          1615:        juggle(chasm);
        !          1616:        newloc=loc;
        !          1617:        goto l2;
        !          1618: l30310: 
        !          1619:        newloc=plac[troll]+fixd[troll]-loc;
        !          1620:        if (prop[troll] == 0) prop[troll]=1;
        !          1621:        if (!toting(bear)) goto l2;
        !          1622:        rspeak(162);
        !          1623:        prop[chasm]=1;
        !          1624:        prop[troll]=2;
        !          1625:        drop(bear,(int)newloc);
        !          1626:        fixed[bear]= -1;
        !          1627:        prop[bear]=3;
        !          1628:        if (prop[spices] < 0)tally2++;
        !          1629:        oldlc2=newloc;
        !          1630:        goto l99;
        !          1631:        /* End of specials. */
        !          1632:        /*
        !          1633:                   Handle "go back".  Look for verb which goes from loc to
        !          1634:                   oldloc, or to oldlc2 if oldloc has forced-motion.  k2
        !          1635:                   saves entry -> forced loc -> previous loc.
        !          1636:                */
        !          1637: l20:    
        !          1638:        k=oldloc;
        !          1639:        if (forced(k)) k=oldlc2;
        !          1640:        oldlc2=oldloc;
        !          1641:        oldloc=loc;
        !          1642:        k2=0;
        !          1643:        if (k != loc) goto l21;
        !          1644:        rspeak(91);
        !          1645:        goto l2;
        !          1646: l21:    
        !          1647:        ll=(longabs(travel[kk])/1000) % 1000;
        !          1648:        if (ll == k) goto l25;
        !          1649:        if (ll > 300) goto l22;
        !          1650:        j=key[ll];
        !          1651:        if (forced((int)ll) && (longabs(travel[j])/1000) % 1000 == k
        !          1652:            ) k2=kk;
        !          1653: l22:    
        !          1654:        if (travel[kk] < 0) goto l23;
        !          1655:        kk++;
        !          1656:        goto l21;
        !          1657: l23:    
        !          1658:        kk=k2;
        !          1659:        if (kk != 0) goto l25;
        !          1660:        rspeak(140);
        !          1661:        goto l2;
        !          1662: l25:    
        !          1663:        k=longabs(travel[kk]) % 1000;
        !          1664:        kk=key[loc];
        !          1665:        goto l9;
        !          1666:        /*
        !          1667:                   Look.  Can't give more detail.  Pretend it wasn't dark
        !          1668:                   (though it may "now" be dark) so he won't fall into a pit
        !          1669:                   while staring into the gloom.
        !          1670:                */
        !          1671: l30:    
        !          1672:        if (detail < 3) rspeak(15);
        !          1673:        detail++;
        !          1674:        wzdark=0;
        !          1675:        abb[loc]=0;
        !          1676:        goto l2;
        !          1677:        /* Cave.  Different messages depending on whether above ground. */
        !          1678: l40:    
        !          1679:        if (loc < 8) rspeak(57);
        !          1680:        if (loc >= 8) rspeak(58);
        !          1681:        goto l2;
        !          1682:        /* Non-applicable motion.  Various messages depending on word given.  */
        !          1683: l50:    
        !          1684:        spk=12;
        !          1685:        if (k >= 43 && k <= 50) spk=9;
        !          1686:        if (k == 29 || k == 30) spk=9;
        !          1687:        if (k == 7 || k == 36 || k == 37) spk=10;
        !          1688:        if (k == 11 || k == 19) spk=11;
        !          1689:        if (verb == find || verb == invent) spk=59;
        !          1690:        if (k == 62 || k == 65) spk=42;
        !          1691:        if (k == 17) spk=80;
        !          1692:        rspeak(spk);
        !          1693:        goto l2;
        !          1694:        /*
        !          1695:                   "You're dead, Jim."
        !          1696:                   If the current loc is zero, it means the clown got
        !          1697:                   himself killed.  We'll allow this maxdie times.  maxdie
        !          1698:                   is automatically set based on the number of snide
        !          1699:                   messages available.  Each death results in a message (81,
        !          1700:                   83, etc.) which offers reincarnation; if accepted, this
        !          1701:                   results in message 82, 84, etc.  The last time, if he
        !          1702:                   wants another chance, he gets a snide remark as we exit.
        !          1703:                   When reincarnated, all objects being carried get dropped
        !          1704:                   at oldlc2 (presumably the last place prior to being
        !          1705:                   killed) without change of props.  The loop runs backwards
        !          1706:                   to assure that the bird is dropped before the cage.
        !          1707:                   (This kluge could be changed once we're sure all
        !          1708:                   references to bird and cage are done by keywords.) The
        !          1709:                   lamp is a special case (it wouldn't do to leave it in the
        !          1710:                   cave).  It is turned off and left outside the building
        !          1711:                   (only if he was carrying it, of course).  He himself is
        !          1712:                   left inside the building (and heaven help him if he tries
        !          1713:                   to xyzzy back into the cave without the lamp!).  oldloc
        !          1714:                   is zapped so he can't just "retreat".
        !          1715:                   The easiest way to get killed is to fall into a pit in
        !          1716:                   pitch darkness.
        !          1717:                */
        !          1718: l90:    
        !          1719:        rspeak(23);
        !          1720:        oldlc2=loc;
        !          1721:        /* Okay, he's dead.  Let's get on with it. */
        !          1722: l99:    
        !          1723:        if (closng) goto l95;
        !          1724:        yea=yes(81+numdie*2,82+numdie*2,54);
        !          1725:        numdie++;
        !          1726:        if (numdie == maxdie ||  !yea) goto l20000;
        !          1727:        place[water]=0;
        !          1728:        place[oil]=0;
        !          1729:        if (toting(lamp)) prop[lamp]=0;
        !          1730:        for (j = 1; j <= 100; j++) {
        !          1731:                i=101-j;
        !          1732:                if (!toting(i)) goto l98;
        !          1733:                k=oldlc2;
        !          1734:                if (i == lamp) k=1;
        !          1735:                drop(i,k);
        !          1736: l98:        
        !          1737:                ;
        !          1738:        }
        !          1739:        loc=3;
        !          1740:        oldloc=loc;
        !          1741:        goto l2000;
        !          1742:        /* He died during closing time.  No resurrection.  tally up
        !          1743:                   a death and exit.  */
        !          1744: l95:    
        !          1745:        rspeak(131);
        !          1746:        numdie++;
        !          1747:        goto l20000;
        !          1748:        /*
        !          1749:                   Routines for performing the various action verbs
        !          1750:                   Statement numbers in this section are 8000 for
        !          1751:                   intransitive verbs, 9000 for transitive, plus ten times
        !          1752:                   the verb number.  Many intransitive verbs use the
        !          1753:                   transitive code, and some verbs use code for other verbs,
        !          1754:                   as noted below.
        !          1755:                   Random intransitive verbs come here.  Clear obj just in
        !          1756:                   case (see "attack").
        !          1757:                */
        !          1758: l8000:  
        !          1759:        a5toa1(wd1,wd1x,tkword);
        !          1760:        printf ("%s what?\n", tkword);
        !          1761:        obj=0;
        !          1762:        goto l2600;
        !          1763:        /* Carry, no object given yet.  OK if only one object present. */
        !          1764: l8010:  
        !          1765:        if (atloc[loc] == 0 || rlink[atloc[loc]] != 0) goto l8000;
        !          1766:        for (i = 1; i <= 5; i++) {
        !          1767:                if (dloc[i] == loc && dflag >= 2) goto l8000;
        !          1768:        }
        !          1769:        obj=atloc[loc];
        !          1770:        /*
        !          1771:                   Carry an object.  Special cases for bird and cage (if
        !          1772:                   bird in cage, can't take one without the other.  Liquids
        !          1773:                   also special, since they depend on status of bottle.
        !          1774:                   Also various side effects, etc.
        !          1775:                */
        !          1776: l9010:  
        !          1777:        if (toting(obj)) goto l2011;
        !          1778:        spk=25;
        !          1779:        if (obj == plant && prop[plant] <= 0) spk=115;
        !          1780:        if (obj == bear && prop[bear] == 1) spk=169;
        !          1781:        if (obj == chain && prop[bear] != 0) spk=170;
        !          1782:        if (fixed[obj] != 0) goto l2011;
        !          1783:        if (obj != water && obj != oil) goto l9017;
        !          1784:        if (here(bottle) && liq() == obj) goto l9018;
        !          1785:        obj=bottle;
        !          1786:        if (toting(bottle) && prop[bottle] == 1) goto l9220;
        !          1787:        if (prop[bottle] != 1) spk=105;
        !          1788:        if (!toting(bottle)) spk=104;
        !          1789:        goto l2011;
        !          1790: l9018:  
        !          1791:        obj=bottle;
        !          1792: l9017:  
        !          1793:        if (holdng < 7) goto l9016;
        !          1794:        rspeak(92);
        !          1795:        goto l2012;
        !          1796: l9016:  
        !          1797:        if (obj != bird) goto l9014;
        !          1798:        if (prop[bird] != 0) goto l9014;
        !          1799:        if (!toting(rod)) goto l9013;
        !          1800:        rspeak(26);
        !          1801:        goto l2012;
        !          1802: l9013:  
        !          1803:        if (toting(cage)) goto l9015;
        !          1804:        rspeak(27);
        !          1805:        goto l2012;
        !          1806: l9015:  
        !          1807:        prop[bird]=1;
        !          1808: l9014:  
        !          1809:        if ((obj == bird || obj == cage) && prop[bird] != 0
        !          1810:            ) carry(bird+cage-obj,loc);
        !          1811:        carry(obj,loc);
        !          1812:        k=liq();
        !          1813:        if (obj == bottle && k != 0) place[k]= -1;
        !          1814:        goto l2009;
        !          1815:        /*
        !          1816:                   Discard object.  "Throw" also comes here for most
        !          1817:                   objects.  Special cases for bird (might attack snake or
        !          1818:                   dragon) and cage (might contain bird) and vase.  Drop
        !          1819:                   coins at vending machine for extra batteries.
        !          1820:                */
        !          1821: l9020:  
        !          1822:        if (toting(rod2) && obj == rod && ! toting(rod)) obj=rod2;
        !          1823:        if (!toting(obj)) goto l2011;
        !          1824:        if (obj != bird ||  ! here(snake)) goto l9024;
        !          1825:        rspeak(30);
        !          1826:        if (closed) goto l19000;
        !          1827:        dstroy(snake);
        !          1828:        /* Set prop for use by travel options */
        !          1829:        prop[snake]=1;
        !          1830: l9021:  
        !          1831:        k=liq();
        !          1832:        if (k == obj) obj=bottle;
        !          1833:        if (obj == bottle && k != 0) place[k]=0;
        !          1834:        if (obj == cage && prop[bird] != 0) drop(bird,loc);
        !          1835:        if (obj == bird) prop[bird]=0;
        !          1836:        drop(obj,loc);
        !          1837:        goto l2012;
        !          1838: l9024:  
        !          1839:        if (obj != coins ||  ! here(vend)) goto l9025;
        !          1840:        dstroy(coins);
        !          1841:        drop(batter,loc);
        !          1842:        pspeak(batter,0);
        !          1843:        goto l2012;
        !          1844: l9025:  
        !          1845:        if (obj != bird ||  ! at(dragon) || prop[dragon] != 0
        !          1846:            ) goto l9026;
        !          1847:        rspeak(154);
        !          1848:        dstroy(bird);
        !          1849:        prop[bird]=0;
        !          1850:        if (place[snake] == plac[snake])tally2++;
        !          1851:        goto l2012;
        !          1852: l9026:  
        !          1853:        if (obj != bear ||  !at(troll)) goto l9027;
        !          1854:        rspeak(163);
        !          1855:        move(troll,0);
        !          1856:        move(troll+100,0);
        !          1857:        move(troll2,plac[troll]);
        !          1858:        move(troll2+100,fixd[troll]);
        !          1859:        juggle(chasm);
        !          1860:        prop[troll]=2;
        !          1861:        goto l9021;
        !          1862: l9027:  
        !          1863:        if (obj == vase && loc != plac[pillow]) goto l9028;
        !          1864:        rspeak(54);
        !          1865:        goto l9021;
        !          1866: l9028:  
        !          1867:        prop[vase]=2;
        !          1868:        if (at(pillow)) prop[vase]=0;
        !          1869:        pspeak(vase,prop[vase]+1);
        !          1870:        if (prop[vase] != 0) fixed[vase]= -1;
        !          1871:        goto l9021;
        !          1872:        /* Say.  Echo wd2 (or wd1 if no wd2 (say what?, etc.).)
        !          1873:                   Magic words override.  */
        !          1874: l9030:  
        !          1875:        a5toa1(wd2,wd2x,tkword);
        !          1876:        if (blankp(wd2)) a5toa1(wd1,wd1x,tkword);
        !          1877:        else cpy(wd1,wd2);
        !          1878:        i=vocab(wd1,-1);
        !          1879:        if (i == 62 || i == 65 || i == 71 || i == 2025) goto l9035;
        !          1880:        printf ("Okay, \"%s\"\n", tkword);
        !          1881:        goto l2012;
        !          1882: l9035:  
        !          1883:        cpy(wd2, "     ");
        !          1884:        obj=0;
        !          1885:        goto l2630;
        !          1886:        /* Lock, unlock, no object given.  Assume various things if present.  */
        !          1887: l8040:  
        !          1888:        spk=28;
        !          1889:        if (here(clam)) obj=clam;
        !          1890:        if (here(oyster)) obj=oyster;
        !          1891:        if (at(door)) obj=door;
        !          1892:        if (at(grate)) obj=grate;
        !          1893:        if (obj != 0 && here(chain)) goto l8000;
        !          1894:        if (here(chain)) obj=chain;
        !          1895:        if (obj == 0) goto l2011;
        !          1896:        /* Lock, unlock object.  Special stuff for opening
        !          1897:                   clam/oyster and for chain.  */
        !          1898: l9040:  
        !          1899:        if (obj == clam || obj == oyster) goto l9046;
        !          1900:        if (obj == door) spk=111;
        !          1901:        if (obj == door && prop[door] == 1) spk=54;
        !          1902:        if (obj == cage) spk=32;
        !          1903:        if (obj == keys) spk=55;
        !          1904:        if (obj == grate || obj == chain) spk=31;
        !          1905:        if (spk != 31 ||  ! here(keys)) goto l2011;
        !          1906:        if (obj == chain) goto l9048;
        !          1907:        if (!closng) goto l9043;
        !          1908:        k=130;
        !          1909:        if (!panic) clock2=15;
        !          1910:        panic=1;
        !          1911:        goto l2010;
        !          1912: l9043:  
        !          1913:        k=34+prop[grate];
        !          1914:        prop[grate]=1;
        !          1915:        if (verb == lock) prop[grate]=0;
        !          1916:        k=k+2*prop[grate];
        !          1917:        goto l2010;
        !          1918:        /* Clam/oyster. */
        !          1919: l9046:  
        !          1920:        k=0;
        !          1921:        if (obj == oyster) k=1;
        !          1922:        spk=124+k;
        !          1923:        if (toting(obj)) spk=120+k;
        !          1924:        if (!toting(tridnt)) spk=122+k;
        !          1925:        if (verb == lock) spk=61;
        !          1926:        if (spk != 124) goto l2011;
        !          1927:        dstroy(clam);
        !          1928:        drop(oyster,loc);
        !          1929:        drop(pearl,105);
        !          1930:        goto l2011;
        !          1931:        /* Chain. */
        !          1932: l9048:  
        !          1933:        if (verb == lock) goto l9049;
        !          1934:        spk=171;
        !          1935:        if (prop[bear] == 0) spk=41;
        !          1936:        if (prop[chain] == 0) spk=37;
        !          1937:        if (spk != 171) goto l2011;
        !          1938:        prop[chain]=0;
        !          1939:        fixed[chain]=0;
        !          1940:        if (prop[bear] != 3) prop[bear]=2;
        !          1941:        fixed[bear]=2-prop[bear];
        !          1942:        goto l2011;
        !          1943: l9049:  
        !          1944:        spk=172;
        !          1945:        if (prop[chain] != 0) spk=34;
        !          1946:        if (loc != plac[chain]) spk=173;
        !          1947:        if (spk != 172) goto l2011;
        !          1948:        prop[chain]=2;
        !          1949:        if (toting(chain)) drop(chain,loc);
        !          1950:        fixed[chain]= -1;
        !          1951:        goto l2011;
        !          1952:        /* Light lamp */
        !          1953: l9070:  
        !          1954:        if(!here(lamp)) goto l2011;
        !          1955:        spk=184;
        !          1956:        if(limit < 0) goto l2011;
        !          1957:        prop[lamp]=1;
        !          1958:        rspeak(39);
        !          1959:        if(wzdark) goto l2000;
        !          1960:        goto l2012;
        !          1961:        /* Lamp off */
        !          1962: l9080:  
        !          1963:        if(!here(lamp)) goto l2011;
        !          1964:        prop[lamp]=0;
        !          1965:        rspeak(40);
        !          1966:        if(dark()) rspeak(16);
        !          1967:        goto l2012;
        !          1968:        /* Wave.  No effect unless waving rod at fissure. */
        !          1969: l9090:  
        !          1970:        if ((!toting(obj)) && (obj != rod ||  ! toting(rod2))
        !          1971:            ) spk=29;
        !          1972:        if (obj != rod ||  ! at(fissur) ||  ! toting(obj)
        !          1973:            || closng) goto l2011;
        !          1974:        prop[fissur]=1-prop[fissur];
        !          1975:        pspeak(fissur,2-prop[fissur]);
        !          1976:        goto l2012;
        !          1977:        /*
        !          1978:                   Attack.  Assume target if unambiguous.  "throw" also
        !          1979:                   links here.  Attackable objects fall into two categories:
        !          1980:                   enemies (snake, dwarf, etc.) and others (bird, clam).
        !          1981:                   Ambiguous if two enemies, or if no enemies but two
        !          1982:                   others.
        !          1983:                */
        !          1984: l9120:  
        !          1985:        for (i = 1; i <= 5; i++) {
        !          1986:                if(dloc[i] == loc && dflag >= 2) goto l9122;
        !          1987:        }
        !          1988:        i=0;
        !          1989: l9122:  
        !          1990:        if(obj != 0) goto l9124;
        !          1991:        if(i != 0) obj=dwarf;
        !          1992:        if(here(snake)) obj=obj*100+snake;
        !          1993:        if(at(dragon) && prop[dragon] == 0) obj=obj*100+dragon;
        !          1994:        if(at(troll)) obj=obj*100+troll;
        !          1995:        if(here(bear) && prop[bear] == 0) obj=obj*100+bear;
        !          1996:        if(obj > 100) goto l8000;
        !          1997:        if(obj != 0) goto l9124;
        !          1998:        /* Can't attack bird by throwing axe. */
        !          1999:        if(here(bird) && verb != throw) obj=bird;
        !          2000:        /* Clam and oyster both treated as clam for intransitive
        !          2001:                   case; no harm done.  */
        !          2002:        if(here(clam) || here(oyster)) obj=100*obj+clam;
        !          2003:        if(obj > 100) goto l8000;
        !          2004: l9124:  
        !          2005:        if(obj != bird) goto l9125;
        !          2006:        spk=137;
        !          2007:        if(closed) goto l2011;
        !          2008:        dstroy(bird);
        !          2009:        prop[bird]=0;
        !          2010:        if(place[snake] == plac[snake])tally2++;
        !          2011:        spk=45;
        !          2012: l9125:  
        !          2013:        if(obj == 0) spk=44;
        !          2014:        if(obj == clam || obj == oyster) spk=150;
        !          2015:        if(obj == snake) spk=46;
        !          2016:        if(obj == dwarf) spk=49;
        !          2017:        if(obj == dwarf && closed) goto l19000;
        !          2018:        if(obj == dragon) spk=167;
        !          2019:        if(obj == troll) spk=157;
        !          2020:        if(obj == bear) spk=165+(prop[bear]+1)/2;
        !          2021:        if(obj != dragon || prop[dragon] != 0) goto l2011;
        !          2022:        /*
        !          2023:                   Fun stuff for dragon.  If he insists on attacking it,
        !          2024:                   win!  Set prop to dead, move dragon to central loc (still
        !          2025:                   fixed), move rug there (not fixed), and move him there,
        !          2026:                   too.  Then do a null motion to get new description.
        !          2027:                */
        !          2028:        rspeak(49);
        !          2029:        verb=0;
        !          2030:        obj=0;
        !          2031:        getin(wd1,wd1x,wd2,wd2x);
        !          2032:        if (!eqp (wd1, "y") && !eqp (wd1, "yes")) goto l2608;
        !          2033:        pspeak(dragon,1);
        !          2034:        prop[dragon]=2;
        !          2035:        prop[rug]=0;
        !          2036:        k=(plac[dragon]+fixd[dragon])/2;
        !          2037:        move(dragon+100,-1);
        !          2038:        move(rug+100,0);
        !          2039:        move(dragon,k);
        !          2040:        move(rug,k);
        !          2041:        for (obj=1; obj<=100; obj++) {
        !          2042:                if (place[obj] == plac[dragon] || place[obj] == fixd[dragon]
        !          2043:                    ) move(obj,k);
        !          2044:        }
        !          2045:        loc=k;
        !          2046:        k=nullx;
        !          2047:        goto l8;
        !          2048:        /*
        !          2049:                   Pour.  If no object, or object is bottle, assume contents
        !          2050:                   of bottle.  Special tests for pouring water or oil on
        !          2051:                   plant or rusty door.
        !          2052:                */
        !          2053: l9130:  
        !          2054:        if(obj == bottle || obj == 0) obj=liq();
        !          2055:        if(obj == 0) goto l8000;
        !          2056:        if(!toting(obj)) goto l2011;
        !          2057:        spk=78;
        !          2058:        if(obj != oil && obj != water) goto l2011;
        !          2059:        prop[bottle]=1;
        !          2060:        place[obj]=0;
        !          2061:        spk=77;
        !          2062:        if(!(at(plant) || at(door))) goto l2011;
        !          2063:        if(at(door)) goto l9132;
        !          2064:        spk=112;
        !          2065:        if(obj != water) goto l2011;
        !          2066:        pspeak(plant,prop[plant]+1);
        !          2067:        prop[plant]=(prop[plant]+2) % 6;
        !          2068:        prop[plant2]=prop[plant]/2;
        !          2069:        k=nullx;
        !          2070:        goto l8;
        !          2071: l9132:  
        !          2072:        prop[door]=0;
        !          2073:        if(obj == oil) prop[door]=1;
        !          2074:        spk=113+prop[door];
        !          2075:        goto l2011;
        !          2076:        /*
        !          2077:                   Eat.  Intransitive:  assume food if present, else ask
        !          2078:                   what.  Transitive:  food ok, some things lose appetite,
        !          2079:                   rest are ridiculous.
        !          2080:                */
        !          2081: l8140:  
        !          2082:        if(!here(food)) goto l8000;
        !          2083: l8142:  
        !          2084:        dstroy(food);
        !          2085:        spk=72;
        !          2086:        goto l2011;
        !          2087: l9140:  
        !          2088:        if(obj == food) goto l8142;
        !          2089:        if (obj == bird || obj == snake || obj == clam || obj == oyster
        !          2090:            || obj == dwarf || obj == dragon || obj == troll
        !          2091:            || obj == bear) spk=71;
        !          2092:        goto l2011;
        !          2093:        /*
        !          2094:                   Drink.  If no object, assume water and look for it here.
        !          2095:                   if water is in the bottle, drink that, else must be at a
        !          2096:                   water loc, so drink stream.
        !          2097:                */
        !          2098: l9150:  
        !          2099:        if (obj == 0 && liqloc(loc) != water && (liq() != water
        !          2100:            ||  ! here(bottle))) goto l8000;
        !          2101:        if(obj != 0 && obj != water) spk=110;
        !          2102:        if (spk == 110 || liq() != water ||  ! here(bottle)
        !          2103:            ) goto l2011;
        !          2104:        prop[bottle]=1;
        !          2105:        place[water]=0;
        !          2106:        spk=74;
        !          2107:        goto l2011;
        !          2108:        /* Rub.  Yields various snide remarks. */
        !          2109: l9160:  
        !          2110:        if(obj != lamp) spk=76;
        !          2111:        goto l2011;
        !          2112:        /*
        !          2113:                   Throw.  Same as discard unless axe.  Then same as attack
        !          2114:                   except ignore bird, and if dwarf is present then one
        !          2115:                   might be killed.  (only way to do so!) Axe also special
        !          2116:                   for dragon, bear, and troll.  Treasures special for
        !          2117:                   troll.
        !          2118:                */
        !          2119: l9170:  
        !          2120:        if(toting(rod2) && obj == rod &&  ! toting(rod)) obj=rod2;
        !          2121:        if(!toting(obj)) goto l2011;
        !          2122:        if(obj >= 50 && obj <= maxtrs && at(troll)) goto l9178;
        !          2123:        if(obj == food && here(bear)) goto l9177;
        !          2124:        if(obj != axe) goto l9020;
        !          2125:        for (i = 1; i <= 5; i++) {
        !          2126:                /* Needn't check dflag if axe is here. */
        !          2127:                if(dloc[i] == loc) goto l9172;
        !          2128:        }
        !          2129:        spk=152;
        !          2130:        if(at(dragon) && prop[dragon] == 0) goto l9175;
        !          2131:        spk=158;
        !          2132:        if(at(troll)) goto l9175;
        !          2133:        if(here(bear) && prop[bear] == 0) goto l9176;
        !          2134:        obj=0;
        !          2135:        goto l9120;
        !          2136: l9172:  
        !          2137:        spk=48;
        !          2138:        if(ran(3) == 0) goto l9175;
        !          2139:        dseen[i]=0;
        !          2140:        dloc[i]=0;
        !          2141:        spk=47;
        !          2142:        dkill++;
        !          2143:        if(dkill == 1) spk=149;
        !          2144: l9175:  
        !          2145:        rspeak(spk);
        !          2146:        drop(axe,loc);
        !          2147:        k=nullx;
        !          2148:        goto l8;
        !          2149:        /* This'll teach him to throw the axe at the bear! */
        !          2150: l9176:  
        !          2151:        spk=164;
        !          2152:        drop(axe,loc);
        !          2153:        fixed[axe]= -1;
        !          2154:        prop[axe]=1;
        !          2155:        juggle(bear);
        !          2156:        goto l2011;
        !          2157:        /* But throwing food is another story. */
        !          2158: l9177:  
        !          2159:        obj=bear;
        !          2160:        goto l9210;
        !          2161: l9178:  
        !          2162:        spk=159;
        !          2163:        /* Snarf a treasure for the troll. */
        !          2164:        drop(obj,0);
        !          2165:        move(troll,0);
        !          2166:        move(troll+100,0);
        !          2167:        drop(troll2,plac[troll]);
        !          2168:        drop(troll2+100,fixd[troll]);
        !          2169:        juggle(chasm);
        !          2170:        goto l2011;
        !          2171:        /* Quit.  Intransitive only.  Verify intent and exit if
        !          2172:                   that's what he wants.  */
        !          2173: l8180:  
        !          2174:        gaveup=yes(22,54,54);
        !          2175:        if(gaveup) goto l20000;
        !          2176:        goto l2012;
        !          2177:        /* Find.  Might be carrying it, or it might be here.  Else give caveat. */
        !          2178: l9190:  
        !          2179:        if (at(obj) || (liq() == obj && at(bottle))
        !          2180:            || k == liqloc(loc)) spk=94;
        !          2181:        for (i = 1; i <= 5; i++) {
        !          2182:                if(dloc[i] == loc && dflag >= 2 && obj == dwarf) spk=94;
        !          2183:        }
        !          2184:        if(closed) spk=138;
        !          2185:        if(toting(obj)) spk=24;
        !          2186:        goto l2011;
        !          2187:        /* Inventory.  If object, treat same as find.  Else report
        !          2188:                   on current burden.  */
        !          2189: l8200:  
        !          2190:        spk=98;
        !          2191:        for (i = 1; i <= 100; i++) {
        !          2192:                if(i == bear ||  ! toting(i)) goto l8201;
        !          2193:                if(spk == 98) rspeak(99);
        !          2194:                blklin=0;
        !          2195:                pspeak(i,-1);
        !          2196:                blklin=1;
        !          2197:                spk=0;
        !          2198: l8201:     
        !          2199:                ;
        !          2200:        }
        !          2201:        if(toting(bear)) spk=141;
        !          2202:        goto l2011;
        !          2203:        /*
        !          2204:                Feed.  If bird, no seed.  snake, dragon, troll:  quip.  If
        !          2205:                   dwarf, make him mad.  Bear, special.
        !          2206:                */
        !          2207: l9210:  
        !          2208:        if(obj != bird) goto l9212;
        !          2209:        spk=100;
        !          2210:        goto l2011;
        !          2211: l9212:  
        !          2212:        if(obj != snake && obj != dragon && obj != troll) goto l9213;
        !          2213:        spk=102;
        !          2214:        if(obj == dragon && prop[dragon] != 0) spk=110;
        !          2215:        if(obj == troll) spk=182;
        !          2216:        if(obj != snake || closed ||  ! here(bird)) goto l2011;
        !          2217:        spk=101;
        !          2218:        dstroy(bird);
        !          2219:        prop[bird]=0;
        !          2220:        tally2++;
        !          2221:        goto l2011;
        !          2222: l9213:  
        !          2223:        if(obj != dwarf) goto l9214;
        !          2224:        if(!here(food)) goto l2011;
        !          2225:        spk=103;
        !          2226:        dflag++;
        !          2227:        goto l2011;
        !          2228: l9214:  
        !          2229:        if(obj != bear) goto l9215;
        !          2230:        if(prop[bear] == 0) spk=102;
        !          2231:        if(prop[bear] == 3) spk=110;
        !          2232:        if(!here(food)) goto l2011;
        !          2233:        dstroy(food);
        !          2234:        prop[bear]=1;
        !          2235:        fixed[axe]=0;
        !          2236:        prop[axe]=0;
        !          2237:        spk=168;
        !          2238:        goto l2011;
        !          2239: l9215:  
        !          2240:        spk=14;
        !          2241:        goto l2011;
        !          2242:        /* Fill.  Bottle must be empty, and some liquid available.
        !          2243:                   (vase is nasty.) */
        !          2244: l9220:  
        !          2245:        if(obj == vase) goto l9222;
        !          2246:        if(obj != 0 && obj != bottle) goto l2011;
        !          2247:        if(obj == 0 &&  ! here(bottle)) goto l8000;
        !          2248:        spk=107;
        !          2249:        if(liqloc(loc) == 0) spk=106;
        !          2250:        if(liq() != 0) spk=105;
        !          2251:        if(spk != 107) goto l2011;
        !          2252:        prop[bottle]=(cond[loc] % 4)/2;
        !          2253:        prop[bottle]=prop[bottle]*2;
        !          2254:        k=liq();
        !          2255:        if(toting(bottle)) place[k]= -1;
        !          2256:        if(k == oil) spk=108;
        !          2257:        goto l2011;
        !          2258: l9222:  
        !          2259:        spk=29;
        !          2260:        if(liqloc(loc) == 0) spk=144;
        !          2261:        if(liqloc(loc) == 0 ||  !toting(vase)) goto l2011;
        !          2262:        rspeak(145);
        !          2263:        prop[vase]=2;
        !          2264:        fixed[vase]= -1;
        !          2265:        goto l9024;
        !          2266:        /* Blast.  No effect unless you've got dynamite, which is a
        !          2267:                   neat trick!  */
        !          2268: l9230:  
        !          2269:        if(prop[rod2] < 0 ||  ! closed) goto l2011;
        !          2270:        bonus=133;
        !          2271:        if(loc == 115) bonus=134;
        !          2272:        if(here(rod2)) bonus=135;
        !          2273:        rspeak(bonus);
        !          2274:        goto l20000;
        !          2275:        /* Score.  Go to scoring section, which will return to 8241
        !          2276:                   if scorng is true.  */
        !          2277: l8240:  
        !          2278:        scorng=1;
        !          2279:        goto l20000;
        !          2280: l8241:  
        !          2281:        scorng=0;
        !          2282:        printf ("If you were to quit now, you would score ");
        !          2283:        printf ("%d out of a possible %d in %d turns.\n",
        !          2284:        score, mxscor, turns+1);
        !          2285:        goto l2012;
        !          2286:        /*
        !          2287:                   Fee fie foe foo (and fum).  Advance to next state if given
        !          2288:                   in proper order.  Look up wd1 in section 3 of vocab to
        !          2289:                   determine which word we've got.  Last word zips the eggs
        !          2290:                   back to the giant room (unless already there).
        !          2291:                */
        !          2292: l8250:  
        !          2293:        k=vocab(wd1,3);
        !          2294:        spk=42;
        !          2295:        if(foobar == 1-k) goto l8252;
        !          2296:        if(foobar != 0) spk=151;
        !          2297:        goto l2011;
        !          2298: l8252:  
        !          2299:        foobar=k;
        !          2300:        if(k != 4) goto l2009;
        !          2301:        foobar=0;
        !          2302:        if (place[eggs] == plac[eggs]
        !          2303:            || (toting(eggs) && loc == plac[eggs])) goto l2011;
        !          2304:        /* Bring back troll if we steal the eggs back from him
        !          2305:                   before crossing.  */
        !          2306:        if (place[eggs] == 0 && place[troll] == 0 && prop[troll] == 0
        !          2307:            ) prop[troll]=1;
        !          2308:        k=2;
        !          2309:        if(here(eggs)) k=1;
        !          2310:        if(loc == plac[eggs]) k=0;
        !          2311:        move(eggs,plac[eggs]);
        !          2312:        pspeak(eggs,k);
        !          2313:        goto l2012;
        !          2314:        /* Brief.  Intransitive only.  Suppress long descriptions
        !          2315:                   after first time.  */
        !          2316: l8260:  
        !          2317:        spk=156;
        !          2318:        abbnum=10000;
        !          2319:        detail=3;
        !          2320:        goto l2011;
        !          2321:        /* Read.  Magazines in dwarvish, message we've seen, and .
        !          2322:                   .  .  oyster?  */
        !          2323: l8270:  
        !          2324:        if(here(magzin)) obj=magzin;
        !          2325:        if(here(tablet)) obj=obj*100+tablet;
        !          2326:        if(here(messag)) obj=obj*100+messag;
        !          2327:        if(closed && toting(oyster)) obj=oyster;
        !          2328:        if(obj > 100 || obj == 0 || dark()) goto l8000;
        !          2329: l9270:  
        !          2330:        if(dark()) goto l5190;
        !          2331:        if(obj == magzin) spk=190;
        !          2332:        if(obj == tablet) spk=196;
        !          2333:        if(obj == messag) spk=191;
        !          2334:        if(obj == oyster && hinted[2] && toting(oyster)) spk=194;
        !          2335:        if (obj != oyster || hinted[2] ||  !toting(oyster)
        !          2336:            ||  !closed) goto l2011;
        !          2337:        hinted[2]=yes(192,193,54);
        !          2338:        goto l2012;
        !          2339:        /* Break.  Only works for mirror in repository and, of
        !          2340:                   course, the vase.  */
        !          2341: l9280:  
        !          2342:        if(obj == mirror) spk=148;
        !          2343:        if(obj == vase && prop[vase] == 0) goto l9282;
        !          2344:        if(obj != mirror ||  !closed) goto l2011;
        !          2345:        rspeak(197);
        !          2346:        goto l19000;
        !          2347: l9282:  
        !          2348:        spk=198;
        !          2349:        if(toting(vase)) drop(vase,loc);
        !          2350:        prop[vase]=2;
        !          2351:        fixed[vase]= -1;
        !          2352:        goto l2011;
        !          2353:        /* Wake.  Only use is to disturb the dwarves. */
        !          2354: l9290:  
        !          2355:        if(obj != dwarf ||  !closed) goto l2011;
        !          2356:        rspeak(199);
        !          2357:        goto l19000;
        !          2358:        /*
        !          2359:                        Suspend. Exit leaving things restartable.
        !          2360:                */
        !          2361: l8300:
        !          2362:        if ((suspfd = fopen (suspfile, SUSPWRITE)) == NULL) {
        !          2363:                printf ("Something's wrong...I can't suspend.\n");
        !          2364:                if (hungup) {
        !          2365:                        hungup = 0;
        !          2366:                        goto l20000;
        !          2367:                }
        !          2368:                goto l2012;
        !          2369:        }
        !          2370:        hungup = 0;
        !          2371:        printf ("OK...I'm suspending this game in %s\n", suspfile);
        !          2372: 
        !          2373:        /* Block interrupts to ensure completion of suspension */
        !          2374:        signal (SIGINT, SIG_IGN);
        !          2375:        signal (SIGQUIT, SIG_IGN);
        !          2376:        signal (SIGHUP, SIG_IGN);
        !          2377: 
        !          2378:        /* Write the release and level into the suspend file */
        !          2379:        putw (1, suspfd);
        !          2380:        putw (20, suspfd);
        !          2381: 
        !          2382:        /* Write the time to prevent premature resumption */
        !          2383:        tvec = time(0);
        !          2384:        putl (tvec, suspfd);
        !          2385: 
        !          2386:        /* Write the suspend data into the file */
        !          2387:        fwrite (&suspbeg, sizeof suspbeg, &suspend - &suspbeg, suspfd);
        !          2388: 
        !          2389:        /* Make sure everything went ok */
        !          2390:        if (ferror (suspfd))
        !          2391:                fatal ("I/O error during suspension");
        !          2392: 
        !          2393:        fclose (suspfd);
        !          2394: #ifdef NOTIME
        !          2395:        printf ("Play will resume automatically next time.\n");
        !          2396: #else
        !          2397:        printf ("You may resume play half an hour from now.\n");
        !          2398: #endif
        !          2399:        exit(0);
        !          2400:        /* Hours.  Report current non-prime-time hours. */
        !          2401: l8310:
        !          2402:        printf (HOURS);
        !          2403:        goto l2012;
        !          2404:        /* Log.  Toggle loggin either on or off */
        !          2405: setlog: 
        !          2406:        logon = ! logon;
        !          2407:        if (logon)
        !          2408:                printf ("Log on.\n");
        !          2409:        else
        !          2410:            printf ("Log off.\n");
        !          2411:        goto l2012;
        !          2412:        /*
        !          2413:                   hints
        !          2414:                   Come here if he's been long enough at required loc(s) for
        !          2415:                   some unused hint.  Hint number is in variable "hint".
        !          2416:                   branch to quick test for additional conditions, then come
        !          2417:                   back to do neat stuff.  goto 40010 if conditions are met
        !          2418:                   and we want to offer the hint.  goto 40020 to clear
        !          2419:                   hintlc back to zero, 40030 to take no action yet.
        !          2420:                */
        !          2421: l40000: 
        !          2422:        switch (hint-4) {
        !          2423:        case 0: 
        !          2424:                goto l40400;        /* cave */
        !          2425:        case 1: 
        !          2426:                goto l40500;        /* bird */
        !          2427:        case 2: 
        !          2428:                goto l40600;        /* snake */
        !          2429:        case 3: 
        !          2430:                goto l40700;        /* maze */
        !          2431:        case 4: 
        !          2432:                goto l40800;        /* dark */
        !          2433:        case 5: 
        !          2434:                goto l40900;        /* witt */
        !          2435:        }
        !          2436:        bug(27);
        !          2437: l40010: 
        !          2438:        hintlc[hint]=0;
        !          2439:        if(!yes(hints[hint][3],0,54)) goto l2602;
        !          2440:        printf ("I am prepared to give you a hint,");
        !          2441:        printf (" but it will cost you %d points.\n", hints[hint][2]);
        !          2442:        hinted[hint]=yes(175,hints[hint][4],54);
        !          2443:        if (hinted[hint] && limit > 30
        !          2444:            ) limit=limit+30*hints[hint][2];
        !          2445: l40020: 
        !          2446:        hintlc[hint]=0;
        !          2447: l40030: 
        !          2448:        goto l2602;
        !          2449:        /* Now for the quick tests.  See database description for
        !          2450:                   one-line notes.  */
        !          2451: l40400: 
        !          2452:        if(prop[grate] == 0 &&  ! here(keys)) goto l40010;
        !          2453:        goto l40020;
        !          2454: l40500: 
        !          2455:        if(here(bird) && toting(rod) && obj == bird) goto l40010;
        !          2456:        goto l40030;
        !          2457: l40600: 
        !          2458:        if(here(snake) &&  ! here(bird)) goto l40010;
        !          2459:        goto l40020;
        !          2460: l40700: 
        !          2461:        if (atloc[loc] == 0 && atloc[oldloc] == 0
        !          2462:            && atloc[oldlc2] == 0 && holdng > 1) goto l40010;
        !          2463:        goto l40020;
        !          2464: l40800: 
        !          2465:        if(prop[emrald] != -1 && prop[pyram] == -1) goto l40010;
        !          2466:        goto l40020;
        !          2467: l40900: 
        !          2468:        goto l40010;
        !          2469:        /*
        !          2470:                   Cave closing and scoring
        !          2471:                   These sections handle the closing of the cave.  The cave
        !          2472:                   closes "clock1" turns after the last treasure has been
        !          2473:                   located (including the pirate's chest, which may of
        !          2474:                   course never show up).  Note that the treasures need not
        !          2475:                   have been taken yet, just located.  Hence clock1 must be
        !          2476:                   large enough to get out of the cave (it only ticks while
        !          2477:                   inside the cave).  When it hits zero, we branch to 10000
        !          2478:                   to start closing the cave, and then sit back and wait for
        !          2479:                   him to try to get out.  If he doesn't within clock2
        !          2480:                   turns, we close the cave; if he does try, we assume he
        !          2481:                   panics, and give him a few additional turns to get
        !          2482:                   frantic before we close.  When clock2 hits zero, we
        !          2483:                   branch to 11000 to transport him into the final puzzle.
        !          2484:                   Note that the puzzle depends upon all sorts of random
        !          2485:                   things.  For instance, there must be no water or oil,
        !          2486:                   since there are beanstalks which we don't want to be able
        !          2487:                   to water, since the code can't handle it.  Also, we can
        !          2488:                   have no keys, since there is a grate (having moved the
        !          2489:                   fixed object!) there separating him from all the
        !          2490:                   treasures.  Most of these problems arise from the use of
        !          2491:                   negative prop numbers to suppress the object descriptions
        !          2492:                   until he's actually moved the objects.
        !          2493:                   When the first warning comes, we lock the grate, destroy
        !          2494:                   the bridge, kill all the dwarves (and the pirate), remove
        !          2495:                   the troll and bear (unless dead), and set "closng" to
        !          2496:                   true.  Leave the dragon; too much trouble to move it.
        !          2497:                   From now until clock2 runs out, he cannot unlock the
        !          2498:                   grate, move to any location outside the cave (loc<9), or
        !          2499:                   create the bridge.  Nor can he be resurrected if he dies.
        !          2500:                   Note that the snake is already gone, since he got to the
        !          2501:                   treasure accessible only via the hall of the mt.  king.
        !          2502:                   also, he's been in giant room (to get eggs), so we can
        !          2503:                   refer to it.  Also also, he's gotten the pearl, so we
        !          2504:                   know the bivalve is an oyster.  AND, the dwarves must
        !          2505:                   have been activated, since we've found chest.
        !          2506:                */
        !          2507: l10000: 
        !          2508:        prop[grate]=0;
        !          2509:        prop[fissur]=0;
        !          2510:        for (i = 1; i <= 6; i++) {
        !          2511:                dseen[i]=0;
        !          2512:        }
        !          2513:        move(troll,0);
        !          2514:        move(troll+100,0);
        !          2515:        move(troll2,plac[troll]);
        !          2516:        move(troll2+100,fixd[troll]);
        !          2517:        juggle(chasm);
        !          2518:        if(prop[bear] != 3) dstroy(bear);
        !          2519:        prop[chain]=0;
        !          2520:        fixed[chain]=0;
        !          2521:        prop[axe]=0;
        !          2522:        fixed[axe]=0;
        !          2523:        rspeak(129);
        !          2524:        clock1= -1;
        !          2525:        closng=1;
        !          2526:        goto l19999;
        !          2527:        /*
        !          2528:                   Once he's panicked, and clock2 has run out, we come here
        !          2529:                   to set up the storage room.  The room has two locs,
        !          2530:                   hardwired as 115 (ne) and 116 (sw).  At the ne end, we
        !          2531:                   place empty bottles, a nursery of plants, a bed of
        !          2532:                   oysters, a pile of lamps, rods with stars, sleeping
        !          2533:                   dwarves, and him.  At the sw end we place grate over
        !          2534:                   treasures, snake pit, covey of caged birds, more rods,
        !          2535:                   and pillows.  A mirror stretches across one wall.  Many
        !          2536:                   of the objects come from known locations and/or states
        !          2537:                   (e.g.  the snake is known to have been destroyed and
        !          2538:                   needn't be carried away from its old "place"), making the
        !          2539:                   various objects be handled differently.  We also drop all
        !          2540:                   other objects he might be carrying (lest he have some
        !          2541:                   which could cause trouble, such as the keys).  We
        !          2542:                   describe the flash of light and trundle back.
        !          2543:                */
        !          2544: l11000: 
        !          2545:        prop[bottle]=put(bottle,115,1);
        !          2546:        prop[plant]=put(plant,115,0);
        !          2547:        prop[oyster]=put(oyster,115,0);
        !          2548:        prop[lamp]=put(lamp,115,0);
        !          2549:        prop[rod]=put(rod,115,0);
        !          2550:        prop[dwarf]=put(dwarf,115,0);
        !          2551:        loc=115;
        !          2552:        oldloc=115;
        !          2553:        newloc=115;
        !          2554:        /* Leave the grate with normal (non-negative property). */
        !          2555:        foo=put(grate,116,0);
        !          2556:        prop[snake]=put(snake,116,1);
        !          2557:        prop[bird]=put(bird,116,1);
        !          2558:        prop[cage]=put(cage,116,0);
        !          2559:        prop[rod2]=put(rod2,116,0);
        !          2560:        prop[pillow]=put(pillow,116,0);
        !          2561:        prop[mirror]=put(mirror,115,0);
        !          2562:        fixed[mirror]=116;
        !          2563:        for (i = 1; i <= 100; i++) {
        !          2564:                if(toting(i)) dstroy(i);
        !          2565:        }
        !          2566:        rspeak(132);
        !          2567:        closed=1;
        !          2568:        goto l2;
        !          2569:        /*
        !          2570:                   Another way we can force an end to things is by having
        !          2571:                   the lamp give out.  When it gets close, we come here to
        !          2572:                   warn him.  We go to 12000 if the lamp and fresh batteries
        !          2573:                   are here, in which case we replace the batteries and
        !          2574:                   continue.  12200 is for other cases of lamp dying.  12400
        !          2575:                   is when it goes out, and 12600 is if he's wandered
        !          2576:                   outside and the lamp is used up, in which case we force
        !          2577:                   him to give up.
        !          2578:                */
        !          2579: l12000: 
        !          2580:        rspeak(188);
        !          2581:        prop[batter]=1;
        !          2582:        if(toting(batter)) drop(batter,loc);
        !          2583:        limit=limit+2500;
        !          2584:        lmwarn=0;
        !          2585:        goto l19999;
        !          2586: l12200: 
        !          2587:        if (lmwarn ||  !here(lamp)) goto l19999;
        !          2588:        lmwarn=1;
        !          2589:        spk=187;
        !          2590:        if (place[batter] == 0) spk=183;
        !          2591:        if (prop[batter] == 1) spk=189;
        !          2592:        rspeak(spk);
        !          2593:        goto l19999;
        !          2594: l12400: 
        !          2595:        limit= -1;
        !          2596:        prop[lamp]=0;
        !          2597:        if (here(lamp)) rspeak(184);
        !          2598:        goto l19999;
        !          2599: l12600: 
        !          2600:        rspeak(185);
        !          2601:        gaveup=1;
        !          2602:        goto l20000;
        !          2603:        /* Oh dear, he's disturbed the dwarves. */
        !          2604: l19000: 
        !          2605:        rspeak(136);
        !          2606:        /*
        !          2607:                   Exit code.
        !          2608:                   the present scoring algorithm is as follows:
        !          2609:                      objective:          points:        present total possible:
        !          2610:                   getting well into cave   25                    25
        !          2611:                   each treasure < chest    12                    60
        !          2612:                   treasure chest itself    14                    14
        !          2613:                   each treasure > chest    16                   144
        !          2614:                   surviving             (max-num)*10             30
        !          2615:                   not quitting              4                     4
        !          2616:                   reaching "closng"        25                    25
        !          2617:                   "closed": quit/killed    10
        !          2618:                             klutzed        25
        !          2619:                             wrong way      30
        !          2620:                             success        45                    45
        !          2621:                   came to witt's end        1                     1
        !          2622:                   round out the total       2                     2
        !          2623:                                                        total:   350
        !          2624:                   (points can also be deducted for using hints.)
        !          2625:                */
        !          2626: l20000: 
        !          2627:        score=0;
        !          2628:        mxscor=0;
        !          2629:        /*
        !          2630:                   First tally up the treasures.  Must be in building and
        !          2631:                   not broken.  Give the poor guy 2 points just for finding
        !          2632:                   each treasure.
        !          2633:                */
        !          2634:        for (i = 50; i <= maxtrs; i++) {
        !          2635:                if (ptext[i] != 0) {
        !          2636:                        k=12;
        !          2637:                        if (i == chest) k=14;
        !          2638:                        if (i > chest) k=16;
        !          2639:                        if (prop[i] >= 0) score=score+2;
        !          2640:                        if (place[i] == 3 && prop[i] == 0) score=score+k-2;
        !          2641:                        mxscor=mxscor+k;
        !          2642:                }
        !          2643:        }
        !          2644:        /*
        !          2645:                   Now look at how he finished and how far he got.  maxdie
        !          2646:                   and numdie tell us how well he survived.  gaveup says
        !          2647:                   whether he exited via quit.  dflag will tell us if he
        !          2648:                   ever got suitably deep into the cave.  closng still
        !          2649:                   indicates whether he reached the endgame.  And if he got
        !          2650:                   as far as "cave closed" (indicated by "closed"), then
        !          2651:                   bonus is zero for mundane exits or 133, 134, 135 if he
        !          2652:                   blew it (so to speak).
        !          2653:                */
        !          2654:        score=score+(maxdie-numdie)*10;
        !          2655:        mxscor=mxscor+maxdie*10;
        !          2656:        if (!(scorng || gaveup)) score=score+4;
        !          2657:        mxscor=mxscor+4;
        !          2658:        if (dflag != 0) score=score+25;
        !          2659:        mxscor=mxscor+25;
        !          2660:        if (closng) score=score+25;
        !          2661:        mxscor=mxscor+25;
        !          2662:        if (!closed) goto l20020;
        !          2663:        if (bonus == 0) score=score+10;
        !          2664:        if (bonus == 135) score=score+25;
        !          2665:        if (bonus == 134) score=score+30;
        !          2666:        if (bonus == 133) score=score+45;
        !          2667: l20020: 
        !          2668:        mxscor=mxscor+45;
        !          2669:        /* Did he come to Witt's End as he should? */
        !          2670:        if (place[magzin] == 108)score++;
        !          2671:        mxscor++;
        !          2672:        /* Round it off. */
        !          2673:        score=score+2;
        !          2674:        mxscor=mxscor+2;
        !          2675:        /* Deduct points for hints.  hints < 4 are special; see
        !          2676:                   database description.  */
        !          2677:        for (i = 1; i <= hntmax; i++) {
        !          2678:                if (hinted[i]) score=score-hints[i][2];
        !          2679:        }
        !          2680:        /* Return to score command if that's where we came from. */
        !          2681:        if (scorng) goto l8241;
        !          2682:        /* That should be good enough.  Let's tell him all about it. */
        !          2683:        printf ("You scored %d out of a possible %d using %d turn%s.\n",
        !          2684:        score, mxscor, turns, turns==1? "": "s");
        !          2685:        for (i = 1; i <= clsses; i++) {
        !          2686:                if (cval[i] >= score) goto l20210;
        !          2687:        }
        !          2688:        printf("You just went off my scale!!!\n");
        !          2689:        goto l25000;
        !          2690: l20210: 
        !          2691:        speak(ctext[i]);
        !          2692:        if (i == clsses-1) goto l20220;
        !          2693:        k=cval[i]+1-score;
        !          2694:        printf ("To achieve the next higher rating, you need %d more point%s.\n",
        !          2695:        k, k==1? "": "s");
        !          2696:        goto l25000;
        !          2697: l20220:
        !          2698:        printf ("To achieve the next higher rating would be a neat trick!\n");
        !          2699:        printf ("Congratulations!!\n");
        !          2700: l25000:
        !          2701:        if (logon) {
        !          2702:                /* Log this termination for the interest of other users */
        !          2703:                FILE *logfile;
        !          2704:                char *ctime();
        !          2705:                if ((logfile = fopen ("/usr/games/advlog", "a")) != NULL) {
        !          2706:                        tvec = time((long *) 0);
        !          2707:                        cp1 = ctime (&tvec);
        !          2708:                        /* Assumed format "Mon Jan 99 99:99:99 1999\n\0" */
        !          2709:                        cp1[10] = '\0';
        !          2710:                        fprintf (logfile, "%s; %s: %d in %d\n",
        !          2711:                        cp1 + 4, pwbuf -> pw_name,
        !          2712:                        score, turns);
        !          2713:                }
        !          2714:        }
        !          2715: }
        !          2716: 
        !          2717: /*
        !          2718:  *     subroutines/functions
        !          2719:  *     toting(obj)  = true if the obj is being carried
        !          2720:  *     here(obj)    = true if the obj is at "loc" (or is being carried)
        !          2721:  *     at(obj)      = true if on either side of two-placed object
        !          2722:  *     liq(dummy)   = object number of liquid in bottle
        !          2723:  *     liqloc(loc)  = object number of liquid (if any) at loc
        !          2724:  *     bitset(l,n)  = true if cond(l) has bit n set (bit 0 is units bit)
        !          2725:  *     forced(loc)  = true if loc moves without asking for input (cond=2)
        !          2726:  *     dark(dummy)  = true if location "loc" is dark
        !          2727:  *     pct(n)       = true n% of the time (n integer from 0 to 100)
        !          2728:  */
        !          2729: 
        !          2730: toting(ob)
        !          2731: {
        !          2732:        return place[ob] == -1;
        !          2733: }
        !          2734: 
        !          2735: here(ob)
        !          2736: {
        !          2737:        return place[ob] == loc || toting (ob);
        !          2738: }
        !          2739: 
        !          2740: at(ob)
        !          2741: {
        !          2742:        return place[ob] == loc || fixed[ob] == loc;
        !          2743: }
        !          2744: 
        !          2745: liq2(pbotl)
        !          2746: {
        !          2747:        int liq2temp;
        !          2748:        liq2temp = pbotl/2;
        !          2749:        return (1-pbotl)*water + liq2temp * (water+oil);
        !          2750: }
        !          2751: 
        !          2752: liq()
        !          2753: {
        !          2754:        int t;
        !          2755:        t = prop[bottle];
        !          2756:        return liq2(t>-1-t? t: -1-t);
        !          2757: }
        !          2758: 
        !          2759: liqloc(where)
        !          2760: {
        !          2761:        int t1, t2;
        !          2762:        t1 = cond[where] / 2;
        !          2763:        t1 = t1 * 2;
        !          2764:        t2 = cond[where] / 4;
        !          2765:        return liq2 (((t1 % 8)-5)*(t2%2)+1);
        !          2766: }
        !          2767: 
        !          2768: bitset (mm, n)
        !          2769: {
        !          2770:        return (cond[mm] >> n) & 1;
        !          2771: }
        !          2772: 
        !          2773: forced(where)
        !          2774: {
        !          2775:        return cond[where] == 2;
        !          2776: }
        !          2777: 
        !          2778: dark()
        !          2779: {
        !          2780:        return ((cond[loc] & 1) == 0) && (prop[lamp] == 0 || !here(lamp));
        !          2781: }
        !          2782: 
        !          2783: pct (n)
        !          2784: {
        !          2785:        return ran(100) < n;
        !          2786: }
        !          2787: 
        !          2788: /*
        !          2789:  *     Place any object anywhere by picking it up and dropping
        !          2790:  *     it. May already be toting, in which case the carry is
        !          2791:  *     a no-op. Mustn't pick up objects which are not at any
        !          2792:  *     loc, since carry wants to remove objects from atloc chains.
        !          2793:  */
        !          2794: move (object, where) {
        !          2795:        int source;
        !          2796:        if (object <= 100)
        !          2797:                source = place[object];
        !          2798:        else
        !          2799:                source = fixed[object-100];
        !          2800:        if (source > 0 && source <= 300)
        !          2801:                carry (object, source);
        !          2802:        drop (object, where);
        !          2803: }
        !          2804: 
        !          2805: dstroy (object)
        !          2806: {
        !          2807:        move (object, 0);
        !          2808: }
        !          2809: 
        !          2810: juggle (object)
        !          2811: {
        !          2812:        register int ii, jj;
        !          2813:        ii = place[object];
        !          2814:        jj = fixed [object];
        !          2815:        move (object, ii);
        !          2816:        move (object+100, jj);
        !          2817: }
        !          2818: 
        !          2819: put (object, where, pval)
        !          2820: {
        !          2821:        move (object, where);
        !          2822:        return -1-pval;
        !          2823: }
        !          2824: 
        !          2825: /*
        !          2826:  *     Start toting an object, removing it from the list of things at
        !          2827:  *     its former location. Increment holding unless it was already
        !          2828:  *     being toted. If object>100 (moving "fixed" second loc)
        !          2829:  *     don't change place or holdng.
        !          2830:  */
        !          2831: carry (object, where)
        !          2832: {
        !          2833:        int tmp;
        !          2834:        if (object <= 100) {
        !          2835:                if (place[object] == -1) return;
        !          2836:                place[object] = -1;
        !          2837:                holdng++;
        !          2838:        }
        !          2839:        if (atloc[where] == object) {
        !          2840:                atloc[where] = rlink[object];
        !          2841:                return;
        !          2842:        }
        !          2843:        tmp = atloc[where];
        !          2844:        while (rlink[tmp] != object)
        !          2845:                tmp = rlink[tmp];
        !          2846:        rlink[tmp] = rlink[object];
        !          2847: }
        !          2848: 
        !          2849: /*
        !          2850:  *     Place an object at a given loc, prefixing ot onto the atloc list.
        !          2851:  *     Decrement holdng if the object was being toted.
        !          2852:  */
        !          2853: drop (object, where)
        !          2854: {
        !          2855:        if (object > 100)
        !          2856:                fixed[object-100] = where;
        !          2857:        else
        !          2858:            {
        !          2859:                if (place[object] == -1) holdng--;
        !          2860:                place[object] = where;
        !          2861:        }
        !          2862:        if (where <= 0) return;
        !          2863:        rlink[object] = atloc[where];
        !          2864:        atloc[where] = object;
        !          2865: }
        !          2866: 
        !          2867: fatal(s)
        !          2868:        char *s;
        !          2869: {
        !          2870:        printf ("\nFatal error: %s\n", s);
        !          2871:        exit(1);
        !          2872: }
        !          2873: 
        !          2874: bug(n)
        !          2875: {
        !          2876:        printf ("Bug number %d\n", n);
        !          2877:        printf ("Program quits\n");
        !          2878:        exit(1);
        !          2879: }
        !          2880: 
        !          2881: /* Returns a random number between 0 and num-1 inclusive */
        !          2882: ran(num)
        !          2883: {
        !          2884:        return (((long) num * rand()) / 32768L);
        !          2885: }
        !          2886: 
        !          2887: /*
        !          2888:  *     return 1 if the five-character argument
        !          2889:  *     is entirely blank, 0 otherwise
        !          2890:  */
        !          2891: blankp(a5)
        !          2892: char *a5;
        !          2893: {
        !          2894:        return eqp (a5, "     ");
        !          2895: }
        !          2896: 
        !          2897: /*
        !          2898:  *     return 1 if a5 and b5 are equal, 0 otherwise.
        !          2899:  *     The lengths of a5 and b5 are limited to 5,
        !          2900:  *     but if either contains a null character, it is assumed
        !          2901:  *     to be padded out to length 5 with blanks.
        !          2902:  */
        !          2903: eqp(a5, b5)
        !          2904:        char *a5, *b5;
        !          2905: {
        !          2906:        register int z;
        !          2907:        register char *aa, *bb;
        !          2908:        aa = a5;
        !          2909:        bb = b5;
        !          2910:        z = 5;
        !          2911:        do {
        !          2912:                if ((*aa == '\0'? ' ': *aa++) !=
        !          2913:                    (*bb == '\0'? ' ': *bb++))
        !          2914:                        return 0;
        !          2915:        } while (--z);
        !          2916:        return 1;
        !          2917: }
        !          2918: 
        !          2919: /*
        !          2920:  *     copy the character string from "source" to "sink". Length is limited
        !          2921:  *     to 5 characters, and "sink" is blank padded if "source" is shorter.
        !          2922:  */
        !          2923: cpy (sink, source)
        !          2924:        register char *source, *sink;
        !          2925: {
        !          2926:        register n;
        !          2927:        n = 5;
        !          2928:        do {
        !          2929:                if (*source == '\0')
        !          2930:                        *sink++ = ' ';
        !          2931:                else
        !          2932:                    *sink++ = *source++;
        !          2933:        } while (--n);
        !          2934: }
        !          2935: 
        !          2936: /*
        !          2937:  *     Look up id in the vocabulary (atab) and return its "definition"
        !          2938:  *     (ktab), or -1 if not found. If init is positive, this is an
        !          2939:  *     initialization call setting up a keyword variable, and not finding
        !          2940:  *     it constitutes a bug. It also means that only ktab values which taken
        !          2941:  *     over 1000 equal init may be considered. Thus "steps", which is a
        !          2942:  *     motion verb as well as an object, may be located as an object. It also
        !          2943:  *     means the ktab value is taken mod 1000.
        !          2944:  */
        !          2945: vocab (id, init)
        !          2946: char *id;
        !          2947: {
        !          2948:        for (i=1; i<=tabsiz; i++) {
        !          2949:                if (ktab[i] == -1) goto l2;
        !          2950:                if ((init < 0 || init == ktab[i]/1000) && eqp(atab[i], id))
        !          2951:                        goto l3;
        !          2952:        }
        !          2953:        bug(21);
        !          2954: l2:
        !          2955:        if (init < 0) return -1;
        !          2956:        bug(5);
        !          2957: l3:
        !          2958:        return init<0? ktab[i]: ktab[i] % 1000;
        !          2959: }
        !          2960: 
        !          2961: /*
        !          2962:  *     This program catenates the characters of x and y, which are assumed to
        !          2963:  *     be 5-character fields, into z. The process stops at the first blank,
        !          2964:  *     and a null character is appended to the result.
        !          2965:  */
        !          2966: a5toa1 (x, y, z)
        !          2967:        char *x, *y, *z;
        !          2968: {
        !          2969:        register int n;
        !          2970:        n = 5;
        !          2971:        do {
        !          2972:                if (*x == ' ') {
        !          2973:                        *z++ = '\0';
        !          2974:                        return;
        !          2975:                }
        !          2976:                *z++ = *x++;
        !          2977:        } while (--n);
        !          2978:        n = 5;
        !          2979:        do {
        !          2980:                if (*y == ' ') {
        !          2981:                        *z++ = '\0';
        !          2982:                        return;
        !          2983:                }
        !          2984:                *z++ = *y++;
        !          2985:        } while (--n);
        !          2986:        *z++ = '\0';
        !          2987: }
        !          2988: 
        !          2989: /*
        !          2990:  *     Get a command from the terminal. The first word goes into pl and pr,
        !          2991:  *     and the second word goes into ql and qr. In each case the word is
        !          2992:  *     padded with blanks to 10 characters; the first 5 will be in the "l"
        !          2993:  *     variable and the second 5 will be in the "r" variable.
        !          2994:  *     If hungup is nonzero, indicating he hung up the phone, fudge
        !          2995:  *     pl, pr, ql, and qr to make it look as if he typed "suspend".
        !          2996:  */
        !          2997: getin (pl, pr, ql, qr)
        !          2998:        char *pl, *pr, *ql, *qr;
        !          2999: {
        !          3000:        register int p;
        !          3001:        cpy (pl, "");
        !          3002:        cpy (pr, "");
        !          3003:        cpy (ql, "");
        !          3004:        cpy (qr, "");
        !          3005:        fflush(stdout);
        !          3006:        /* Eat blank lines */
        !          3007:        if (!hungup) {
        !          3008:                while ((p = getchar()) == '\n');
        !          3009:                while (p == '!') {
        !          3010:                        char pl[512];
        !          3011:                        if (fgets (pl, sizeof(pl), stdin) == 0)
        !          3012:                                p = EOF;
        !          3013:                        if (strcmp (pwbuf->pw_name, "games") == 0)
        !          3014:                                printf ("No Shell escape from \"games\"\n");
        !          3015:                        else {
        !          3016:                                system (pl);
        !          3017:                                printf ("!\n");
        !          3018:                                fflush (stdout);
        !          3019:                        }
        !          3020:                        if (p != EOF)
        !          3021:                                p = getchar();
        !          3022:                }
        !          3023:                if (p == EOF) {
        !          3024:                        cpy (pl, "suspe");
        !          3025:                        cpy (pr, "nd");
        !          3026:                        hungup = 1;
        !          3027:                        return;
        !          3028:                }
        !          3029:                ungetc (p, stdin);
        !          3030:        }
        !          3031:        if (snarf (pl, pr) && snarf (ql, qr))
        !          3032:                while (getchar() != '\n');
        !          3033: }
        !          3034: 
        !          3035: /*
        !          3036:  *     This is a subroutine of getin
        !          3037:  */
        !          3038: snarf (left, right)
        !          3039:        char *left, *right;
        !          3040: {
        !          3041:        register int n;
        !          3042:        char s[10];
        !          3043:        register int p;
        !          3044:        /* Blank the array */
        !          3045:        for (n=0; n<10; n++)
        !          3046:                s[n] = ' ';
        !          3047:        /* If hung up phone, pretend he said 'suspend' followed by nl */
        !          3048:        if (hungup)
        !          3049:                goto susp;
        !          3050:        /* Skip leading blanks; if nl encountered, return immediately */
        !          3051:        while ((p=getchar()) == ' ');
        !          3052:        if (p == '\n') return 0;
        !          3053:        if (p == EOF) goto susp;
        !          3054:        /* Now eat characters until blank or newline */
        !          3055:        n = 0;
        !          3056:        do {
        !          3057:                if (n < 10)
        !          3058:                        s[n++] = p;
        !          3059:                p = getchar();
        !          3060:                if (p == EOF) goto susp;
        !          3061:        } while (p != ' ' && p != '\n');
        !          3062:        /* Break up the string into two five-character components */
        !          3063:        cpy (left, s);
        !          3064:        cpy (right, s+5);
        !          3065:        /* Indicate to caller whether we hit a blank or newline */
        !          3066:        return p == ' ';
        !          3067:        /* Abnormal exit for EOF */
        !          3068: susp:
        !          3069:        cpy (left, "suspe");
        !          3070:        cpy (right, "nd");
        !          3071:        hungup = 1;
        !          3072:        return 0;
        !          3073: }
        !          3074: 
        !          3075: /*
        !          3076:  *     Print the n-th "random" message (section 6)
        !          3077:  */
        !          3078: rspeak(n)
        !          3079: {
        !          3080:        if (n != 0)
        !          3081:                speak (rtext[n]);
        !          3082: }
        !          3083: 
        !          3084: /*
        !          3085:  *     Print the message which starts at lines[n]
        !          3086:  */
        !          3087: speak(n)
        !          3088: {
        !          3089:        long rec;
        !          3090:        do {
        !          3091:                rec = lines[n];
        !          3092:                if (rec < 0)
        !          3093:                        rec = -rec;
        !          3094:                fseek (caves, rec, 0);
        !          3095:                fgets (linebuf, sizeof linebuf, caves);
        !          3096:                if (linebuf[0] != '>')
        !          3097:                        fputs (linebuf, stdout);
        !          3098:        } while (++n < linuse && lines[n] >= 0);
        !          3099: }
        !          3100: 
        !          3101: /*
        !          3102:  *     Find the skip+1st message from msg and print it. Msg should be
        !          3103:  *     the index of the inventory message for object
        !          3104:  */
        !          3105: pspeak (msg, skip)
        !          3106: {
        !          3107:        int n, q;
        !          3108:        q = ptext[msg];
        !          3109:        if (skip >= 0)
        !          3110:                for (n=0; n<=skip; n++) {
        !          3111:                        while (lines[++q] >= 0);
        !          3112:                }
        !          3113:        speak(q);
        !          3114: }
        !          3115: 
        !          3116: /*
        !          3117:  *     Print message x, wait for yes/no. If yes, print message y and leave
        !          3118:  *     "yea" true; else print message z and leave "yea" false.
        !          3119:  *     If hungup is nonzero, he hung up the phone, so simulate an
        !          3120:  *     answer of "no".
        !          3121:  */
        !          3122: yes (x, y, z) {
        !          3123:        char reply[300];
        !          3124:        rspeak(x);
        !          3125:        fflush(stdout);
        !          3126:        if (scanf ("%s", reply) == EOF)
        !          3127:                hungup = 1;
        !          3128:        while (hungup == 0 && reply[0] != 'y' && reply[0] != 'n') {
        !          3129:                printf ("Please answer the question.\n");
        !          3130:                fflush(stdout);
        !          3131:                if (scanf ("%s", reply) == EOF)
        !          3132:                        hungup = 1;
        !          3133:        }
        !          3134:        if (yea = (reply[0] == 'y' && hungup == 0)) {
        !          3135:                if (y != 0)
        !          3136:                        rspeak(y);
        !          3137:        } else if (z != 0)
        !          3138:                rspeak (z);
        !          3139:        return yea;
        !          3140: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.