Annotation of researchv10no/games/adv/adv.c, revision 1.1.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.