1 /*        $NetBSD: subr.c,v 1.14 2021/05/02 12:50:43 rillig Exp $     */
2 
3 /*-
4  * Copyright (c) 1991, 1993
5  *        The Regents of the University of California.  All rights reserved.
6  *
7  * The game adventure was originally written in Fortran by Will Crowther
8  * and Don Woods.  It was later translated to C and enhanced by Jim
9  * Gillogly.  This code is derived from software contributed to Berkeley
10  * by Jim Gillogly at The Rand Corporation.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36 
37 #include <sys/cdefs.h>
38 #ifndef lint
39 #if 0
40 static char sccsid[] = "@(#)subr.c      8.1 (Berkeley) 5/31/93";
41 #else
42 __RCSID("$NetBSD: subr.c,v 1.14 2021/05/02 12:50:43 rillig Exp $");
43 #endif
44 #endif                                  /* not lint */
45 
46 /*      Re-coding of advent in C: subroutines from main                 */
47 
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include "hdr.h"
51 #include "extern.h"
52 
53 static void badmove(void);
54 static int bitset(int, int);
55 static int dropper(void);
56 static int liq2(int);
57 static int mback(void);
58 static int specials(void);
59 static int trbridge(void);
60 
61 /*              Statement functions     */
62 int
toting(int objj)63 toting(int objj)
64 {
65           if (place[objj] == -1)
66                     return (TRUE);
67           else
68                     return (FALSE);
69 }
70 
71 int
here(int objj)72 here(int objj)
73 {
74           if (place[objj] == loc || toting(objj))
75                     return (TRUE);
76           else
77                     return (FALSE);
78 }
79 
80 int
at(int objj)81 at(int objj)
82 {
83           if (place[objj] == loc || fixed[objj] == loc)
84                     return (TRUE);
85           else
86                     return (FALSE);
87 }
88 
89 static int
liq2(int pbotl)90 liq2(int pbotl)
91 {
92           return ((1 - pbotl) * water + (pbotl / 2) * (water + oil));
93 }
94 
95 int
liq(void)96 liq(void)
97 {
98           int     i;
99           i = prop[bottle];
100           if (i > -1 - i)
101                     return (liq2(i));
102           else
103                     return (liq2(-1 - i));
104 }
105 
106 /* may want to clean this one up a bit */
107 int
liqloc(int locc)108 liqloc(int locc)
109 {
110           int     i, j, l;
111           i = cond[locc] / 2;
112           j = ((i * 2) % 8) - 5;
113           l = cond[locc] / 4;
114           l = l % 2;
115           return (liq2(j * l + 1));
116 }
117 
118 static int
bitset(int l,int n)119 bitset(int l, int n)
120 {
121           if (cond[l] & setbit[n])
122                     return (TRUE);
123           return (FALSE);
124 }
125 
126 int
forced(int locc)127 forced(int locc)
128 {
129           if (cond[locc] == 2)
130                     return (TRUE);
131           return (FALSE);
132 }
133 
134 int
dark(void)135 dark(void)
136 {
137           if ((cond[loc] % 2) == 0 && (prop[lamp] == 0 || !here(lamp)))
138                     return (TRUE);
139           return (FALSE);
140 }
141 
142 int
pct(int n)143 pct(int n)
144 {
145           if (ran(100) < n)
146                     return (TRUE);
147           return (FALSE);
148 }
149 
150 
151 int
fdwarf(void)152 fdwarf(void)
153 {                                       /* 71 */
154           int     i, j;
155           struct travlist *kk;
156 
157           if (newloc != loc && !forced(loc) && !bitset(loc, 3)) {
158                     for (i = 1; i <= 5; i++) {
159                               if (odloc[i] != newloc || !dseen[i])
160                                         continue;
161                               newloc = loc;
162                               rspeak(2);
163                               break;
164                     }
165           }
166           loc = newloc;                 /* 74 */
167           if (loc == 0 || forced(loc) || bitset(newloc, 3))
168                     return (2000);
169           if (dflag == 0) {
170                     if (loc >= 15)
171                               dflag = 1;
172                     return (2000);
173           }
174           if (dflag == 1) {   /* 6000 */
175                     if (loc < 15 || pct(95))
176                               return (2000);
177                     dflag = 2;
178                     for (i = 1; i <= 2; i++) {
179                               j = 1 + ran(5);
180                               if (pct(50) && saved == -1)
181                                         dloc[j] = 0;        /* 6001 */
182                     }
183                     for (i = 1; i <= 5; i++) {
184                               if (dloc[i] == loc)
185                                         dloc[i] = daltloc;
186                               odloc[i] = dloc[i]; /* 6002 */
187                     }
188                     rspeak(3);
189                     drop(axe, loc);
190                     return (2000);
191           }
192           dtotal = attack = stick = 0;  /* 6010 */
193           for (i = 1; i <= 6; i++) {    /* loop to 6030 */
194                     if (dloc[i] == 0)
195                               continue;
196                     j = 1;
197                     for (kk = travel[dloc[i]]; kk != 0; kk = kk->next) {
198                               newloc = kk->tloc;
199                               if (newloc > 300 || newloc < 15 || newloc == odloc[i]
200                                   || (j > 1 && newloc == tk[j - 1]) || j >= 20
201                                   || newloc == dloc[i] || forced(newloc)
202                                   || (i == 6 && bitset(newloc, 3))
203                                   || kk->conditions == 100)
204                                         continue;
205                               tk[j++] = newloc;
206                     }
207                     tk[j] = odloc[i];   /* 6016 */
208                     if (j >= 2)
209                               j--;
210                     j = 1 + ran(j);
211                     odloc[i] = dloc[i];
212                     dloc[i] = tk[j];
213                     dseen[i] = (dseen[i] && loc >= 15) ||
214                         (dloc[i] == loc || odloc[i] == loc);
215                     if (!dseen[i])
216                               continue; /* i.e. goto 6030 */
217                     dloc[i] = loc;
218                     if (i == 6) {       /* pirate's spotted him */
219                               if (loc == chloc || prop[chest] >= 0)
220                                         continue;
221                               k = 0;
222                               for (j = 50; j <= maxtrs; j++) { /* loop to 6020 */
223                                         if (j == pyramid && (loc == plac[pyramid]
224                                                   || loc == plac[emerald]))
225                                                   goto l6020;
226                                         if (toting(j))
227                                                   goto l6022;
228                     l6020:              if (here(j))
229                                                   k = 1;
230                               }         /* 6020 */
231                               if (tally == tally2 + 1 && k == 0 && place[chest] == 0
232                                   && here(lamp) && prop[lamp] == 1)
233                                         goto l6025;
234                               if (odloc[6] != dloc[6] && pct(20))
235                                         rspeak(127);
236                               continue; /* to 6030 */
237           l6022:              rspeak(128);
238                               if (place[message] == 0)
239                                         move(chest, chloc);
240                               move(message, chloc2);
241                               for (j = 50; j <= maxtrs; j++) { /* loop to 6023 */
242                                         if (j == pyramid && (loc == plac[pyramid]
243                                                   || loc == plac[emerald]))
244                                                   continue;
245                                         if (at(j) && fixed[j] == 0)
246                                                   carry(j, loc);
247                                         if (toting(j))
248                                                   drop(j, chloc);
249                               }
250           l6024:              dloc[6] = odloc[6] = chloc;
251                               dseen[6] = FALSE;
252                               continue;
253           l6025:              rspeak(186);
254                               move(chest, chloc);
255                               move(message, chloc2);
256                               goto l6024;
257                     }
258                     dtotal++; /* 6027 */
259                     if (odloc[i] != dloc[i])
260                               continue;
261                     attack++;
262                     if (knfloc >= 0)
263                               knfloc = loc;
264                     if (ran(1000) < 95 * (dflag - 2))
265                               stick++;
266           }                             /* 6030 */
267           if (dtotal == 0)
268                     return (2000);
269           if (dtotal != 1) {
270                     printf("There are %d threatening little dwarves ", dtotal);
271                     printf("in the room with you.\n");
272           } else
273                     rspeak(4);
274           if (attack == 0)
275                     return (2000);
276           if (dflag == 2)
277                     dflag = 3;
278           if (saved != -1)
279                     dflag = 20;
280           if (attack != 1) {
281                     printf("%d of them throw knives at you!\n", attack);
282                     k = 6;
283 l82:                if (stick <= 1) {   /* 82 */
284                               rspeak(k + stick);
285                               if (stick == 0)
286                                         return (2000);
287                     } else
288                               printf("%d of them get you!\n", stick); /* 83 */
289                     oldloc2 = loc;
290                     return (99);
291           }
292           rspeak(5);
293           k = 52;
294           goto l82;
295 }
296 
297 
298 /* label 8              */
299 int
march(void)300 march(void)
301 {
302           int     ll1, ll2;
303 
304           if ((tkk = travel[newloc = loc]) == 0)
305                     bug(26);
306           if (k == null)
307                     return (2);
308           if (k == cave) {    /* 40                   */
309                     if (loc < 8)
310                               rspeak(57);
311                     if (loc >= 8)
312                               rspeak(58);
313                     return (2);
314           }
315           if (k == look) {    /* 30                   */
316                     if (detail++ < 3)
317                               rspeak(15);
318                     wasdark = FALSE;
319                     abb[loc] = 0;
320                     return (2);
321           }
322           if (k == back) {    /* 20                   */
323                     switch (mback()) {
324                     case 2:
325                               return (2);
326                     case 9:
327                               goto l9;
328                     default:
329                               bug(100);
330                     }
331           }
332           oldloc2 = oldloc;
333           oldloc = loc;
334 l9:
335           for (; tkk != 0; tkk = tkk->next)
336                     if (tkk->tverb == 1 || tkk->tverb == k)
337                               break;
338           if (tkk == 0) {
339                     badmove();
340                     return (2);
341           }
342 l11:      ll1 = tkk->conditions;        /* 11                   */
343           ll2 = tkk->tloc;
344           newloc = ll1;                 /* newloc=conditions    */
345           k = newloc % 100;   /* k used for prob      */
346           if (newloc <= 300) {
347                     if (newloc <= 100) {          /* 13                   */
348                               if (newloc != 0 && !pct(newloc))
349                                         goto l12; /* 14   */
350           l16:                newloc = ll2;       /* newloc=location      */
351                               if (newloc <= 300)
352                                         return (2);
353                               if (newloc <= 500)
354                                         switch (specials()) {         /* to 30000           */
355                                         case 2:
356                                                   return (2);
357                                         case 12:
358                                                   goto l12;
359                                         case 99:
360                                                   return (99);
361                                         default:
362                                                   bug(101);
363                                         }
364                               rspeak(newloc - 500);
365                               newloc = loc;
366                               return (2);
367                     }
368                     if (toting(k) || (newloc > 200 && at(k)))
369                               goto l16;
370                     goto l12;
371           }
372           if (prop[k] != (newloc / 100) - 3)
373                     goto l16; /* newloc still conditions */
374 l12:                                    /* alternative to probability move      */
375           for (; tkk != 0; tkk = tkk->next)
376                     if (tkk->tloc != ll2 || tkk->conditions != ll1)
377                               break;
378           if (tkk == 0)
379                     bug(25);
380           goto l11;
381 }
382 
383 /* 20                   */
384 static int
mback(void)385 mback(void)
386 {
387           struct travlist *tk2, *j;
388           int     ll;
389           if (forced(k = oldloc))
390                     k = oldloc2;        /* k=location           */
391           oldloc2 = oldloc;
392           oldloc = loc;
393           tk2 = 0;
394           if (k == loc) {
395                     rspeak(91);
396                     return (2);
397           }
398           for (; tkk != 0; tkk = tkk->next) {     /* 21                   */
399                     ll = tkk->tloc;
400                     if (ll == k) {
401                               k = tkk->tverb;     /* k back to verb       */
402                               tkk = travel[loc];
403                               return (9);
404                     }
405                     if (ll <= 300) {
406                               j = travel[loc];
407                               if (forced(ll) && k == j->tloc)
408                                         tk2 = tkk;
409                     }
410           }
411           tkk = tk2;                    /* 23                   */
412           if (tkk != 0) {
413                     k = tkk->tverb;
414                     tkk = travel[loc];
415                     return (9);
416           }
417           rspeak(140);
418           return (2);
419 }
420 
421 /* 30000                */
422 static int
specials(void)423 specials(void)
424 {
425           switch (newloc -= 300) {
426                     case 1:             /* 30100                */
427                     newloc = 99 + 100 - loc;
428                     if (holding == 0 || (holding == 1 && toting(emerald)))
429                               return (2);
430                     newloc = loc;
431                     rspeak(117);
432                     return (2);
433           case 2:             /* 30200                */
434                     drop(emerald, loc);
435                     return (12);
436           case 3:             /* to 30300             */
437                     return (trbridge());
438           default:
439                     bug(29);
440           }
441 }
442 
443 /* 30300                */
444 static int
trbridge(void)445 trbridge(void)
446 {
447           if (prop[troll] == 1) {
448                     pspeak(troll, 1);
449                     prop[troll] = 0;
450                     move(troll2, 0);
451                     move(troll2 + 100, 0);
452                     move(troll, plac[troll]);
453                     move(troll + 100, fixd[troll]);
454                     juggle(chasm);
455                     newloc = loc;
456                     return (2);
457           }
458           newloc = plac[troll] + fixd[troll] - loc;         /* 30310    */
459           if (prop[troll] == 0)
460                     prop[troll] = 1;
461           if (!toting(bear))
462                     return (2);
463           rspeak(162);
464           prop[chasm] = 1;
465           prop[troll] = 2;
466           drop(bear, newloc);
467           fixed[bear] = -1;
468           prop[bear] = 3;
469           if (prop[spices] < 0)
470                     tally2++;
471           oldloc2 = newloc;
472           return (99);
473 }
474 
475 /* 20                   */
476 static void
badmove(void)477 badmove(void)
478 {
479           spk = 12;
480           if (k >= 43 && k <= 50)
481                     spk = 9;
482           if (k == 29 || k == 30)
483                     spk = 9;
484           if (k == 7 || k == 36 || k == 37)
485                     spk = 10;
486           if (k == 11 || k == 19)
487                     spk = 11;
488           if (verb == find || verb == invent)
489                     spk = 59;
490           if (k == 62 || k == 65)
491                     spk = 42;
492           if (k == 17)
493                     spk = 80;
494           rspeak(spk);
495 }
496 
497 void
bug(int n)498 bug(int n)
499 {
500           printf("Please tell jim@rand.org that fatal bug %d happened.\n", n);
501           exit(1);
502 }
503 
504 /* 2600 &c              */
505 void
checkhints(void)506 checkhints(void)
507 {
508           int     hint;
509           for (hint = 4; hint <= hintmax; hint++) {
510                     if (hinted[hint])
511                               continue;
512                     if (!bitset(loc, hint))
513                               hintlc[hint] = -1;
514                     hintlc[hint]++;
515                     if (hintlc[hint] < hints[hint][1])
516                               continue;
517                     switch (hint) {
518                     case 4:   /* 40400 */
519                               if (prop[grate] == 0 && !here(keys))
520                                         goto l40010;
521                               goto l40020;
522                     case 5:   /* 40500 */
523                               if (here(bird) && toting(rod) && obj == bird)
524                                         goto l40010;
525                               continue; /* i.e. goto l40030 */
526                     case 6:   /* 40600 */
527                               if (here(snake) && !here(bird))
528                                         goto l40010;
529                               goto l40020;
530                     case 7:   /* 40700 */
531                               if (atloc[loc] == 0 && atloc[oldloc] == 0
532                                   && atloc[oldloc2] == 0 && holding > 1)
533                                         goto l40010;
534                               goto l40020;
535                     case 8:   /* 40800 */
536                               if (prop[emerald] != -1 && prop[pyramid] == -1)
537                                         goto l40010;
538                               goto l40020;
539                     case 9:
540                               goto l40010;        /* 40900 */
541                     default:
542                               bug(27);
543                     }
544 l40010:   hintlc[hint] = 0;
545                     if (!yes(hints[hint][3], 0, 54))
546                               continue;
547                     printf("I am prepared to give you a hint, but it will ");
548                     printf("cost you %d points.\n", hints[hint][2]);
549                     hinted[hint] = yes(175, hints[hint][4], 54);
550 l40020:   hintlc[hint] = 0;
551           }
552 }
553 
554 /* 9030                 */
555 int
trsay(void)556 trsay(void)
557 {
558           int     i;
559           if (*wd2 != 0)
560                     copystr(wd2, wd1);
561           i = vocab(wd1, -1, 0);
562           if (i == 62 || i == 65 || i == 71 || i == 2025) {
563                     *wd2 = 0;
564                     obj = 0;
565                     return (2630);
566           }
567           printf("\nOkay, \"%s\".\n", wd2);
568           return (2012);
569 }
570 
571 /* 9010                 */
572 int
trtake(void)573 trtake(void)
574 {
575           if (toting(obj))
576                     return (2011);      /* 9010 */
577           spk = 25;
578           if (obj == plant && prop[plant] <= 0)
579                     spk = 115;
580           if (obj == bear && prop[bear] == 1)
581                     spk = 169;
582           if (obj == chain && prop[bear] != 0)
583                     spk = 170;
584           if (fixed[obj] != 0)
585                     return (2011);
586           if (obj == water || obj == oil) {
587                     if (here(bottle) && liq() == obj) {
588                               obj = bottle;
589                               goto l9017;
590                     }
591                     obj = bottle;
592                     if (toting(bottle) && prop[bottle] == 1)
593                               return (9220);
594                     if (prop[bottle] != 1)
595                               spk = 105;
596                     if (!toting(bottle))
597                               spk = 104;
598                     return (2011);
599           }
600 l9017:    if (holding >= 7) {
601                     rspeak(92);
602                     return (2012);
603           }
604           if (obj == bird) {
605                     if (prop[bird] != 0)
606                               goto l9014;
607                     if (toting(rod)) {
608                               rspeak(26);
609                               return (2012);
610                     }
611                     if (!toting(cage)) {          /* 9013 */
612                               rspeak(27);
613                               return (2012);
614                     }
615                     prop[bird] = 1;     /* 9015 */
616           }
617 l9014:    if ((obj == bird || obj == cage) && prop[bird] != 0)
618                     carry(bird + cage - obj, loc);
619           carry(obj, loc);
620           k = liq();
621           if (obj == bottle && k != 0)
622                     place[k] = -1;
623           return (2009);
624 }
625 
626 /* 9021                 */
627 static int
dropper(void)628 dropper(void)
629 {
630           k = liq();
631           if (k == obj)
632                     obj = bottle;
633           if (obj == bottle && k != 0)
634                     place[k] = 0;
635           if (obj == cage && prop[bird] != 0)
636                     drop(bird, loc);
637           if (obj == bird)
638                     prop[bird] = 0;
639           drop(obj, loc);
640           return (2012);
641 }
642 
643 /* 9020                 */
644 int
trdrop(void)645 trdrop(void)
646 {
647           if (toting(rod2) && obj == rod && !toting(rod))
648                     obj = rod2;
649           if (!toting(obj))
650                     return (2011);
651           if (obj == bird && here(snake)) {
652                     rspeak(30);
653                     if (closed)
654                               return (19000);
655                     destroy(snake);
656                     prop[snake] = 1;
657                     return (dropper());
658           }
659           if (obj == coins && here(vend)) {       /* 9024                 */
660                     destroy(coins);
661                     drop(batter, loc);
662                     pspeak(batter, 0);
663                     return (2012);
664           }
665           if (obj == bird && at(dragon) && prop[dragon] == 0) {       /* 9025 */
666                     rspeak(154);
667                     destroy(bird);
668                     prop[bird] = 0;
669                     if (place[snake] == plac[snake])
670                               tally2--;
671                     return (2012);
672           }
673           if (obj == bear && at(troll)) {         /* 9026                 */
674                     rspeak(163);
675                     move(troll, 0);
676                     move(troll + 100, 0);
677                     move(troll2, plac[troll]);
678                     move(troll2 + 100, fixd[troll]);
679                     juggle(chasm);
680                     prop[troll] = 2;
681                     return (dropper());
682           }
683           if (obj != vase || loc == plac[pillow]) { /* 9027       */
684                     rspeak(54);
685                     return (dropper());
686           }
687           prop[vase] = 2;               /* 9028                 */
688           if (at(pillow))
689                     prop[vase] = 0;
690           pspeak(vase, prop[vase] + 1);
691           if (prop[vase] != 0)
692                     fixed[vase] = -1;
693           return (dropper());
694 }
695 
696 /* 9040                 */
697 int
tropen(void)698 tropen(void)
699 {
700           if (obj == clam || obj == oyster) {
701                     k = 0;              /* 9046                 */
702                     if (obj == oyster)
703                               k = 1;
704                     spk = 124 + k;
705                     if (toting(obj))
706                               spk = 120 + k;
707                     if (!toting(trident))
708                               spk = 122 + k;
709                     if (verb == lock)
710                               spk = 61;
711                     if (spk != 124)
712                               return (2011);
713                     destroy(clam);
714                     drop(oyster, loc);
715                     drop(pearl, 105);
716                     return (2011);
717           }
718           if (obj == door)
719                     spk = 111;
720           if (obj == door && prop[door] == 1)
721                     spk = 54;
722           if (obj == cage)
723                     spk = 32;
724           if (obj == keys)
725                     spk = 55;
726           if (obj == grate || obj == chain)
727                     spk = 31;
728           if (spk != 31 || !here(keys))
729                     return (2011);
730           if (obj == chain) {
731                     if (verb == lock) {
732                               spk = 172;          /* 9049: lock           */
733                               if (prop[chain] != 0)
734                                         spk = 34;
735                               if (loc != plac[chain])
736                                         spk = 173;
737                               if (spk != 172)
738                                         return (2011);
739                               prop[chain] = 2;
740                               if (toting(chain))
741                                         drop(chain, loc);
742                               fixed[chain] = -1;
743                               return (2011);
744                     }
745                     spk = 171;
746                     if (prop[bear] == 0)
747                               spk = 41;
748                     if (prop[chain] == 0)
749                               spk = 37;
750                     if (spk != 171)
751                               return (2011);
752                     prop[chain] = 0;
753                     fixed[chain] = 0;
754                     if (prop[bear] != 3)
755                               prop[bear] = 2;
756                     fixed[bear] = 2 - prop[bear];
757                     return (2011);
758           }
759           if (isclosing) {
760                     k = 130;
761                     if (!panic)
762                               clock2 = 15;
763                     panic = TRUE;
764                     return (2010);
765           }
766           k = 34 + prop[grate];         /* 9043                 */
767           prop[grate] = 1;
768           if (verb == lock)
769                     prop[grate] = 0;
770           k = k + 2 * prop[grate];
771           return (2010);
772 }
773 
774 /* 9120                         */
775 int
trkill(void)776 trkill(void)
777 {
778           int     i;
779           for (i = 1; i <= 5; i++)
780                     if (dloc[i] == loc && dflag >= 2)
781                               break;
782           if (i == 6)
783                     i = 0;
784           if (obj == 0) {               /* 9122                         */
785                     if (i != 0)
786                               obj = dwarf;
787                     if (here(snake))
788                               obj = obj * 100 + snake;
789                     if (at(dragon) && prop[dragon] == 0)
790                               obj = obj * 100 + dragon;
791                     if (at(troll))
792                               obj = obj * 100 + troll;
793                     if (here(bear) && prop[bear] == 0)
794                               obj = obj * 100 + bear;
795                     if (obj > 100)
796                               return (8000);
797                     if (obj == 0) {
798                               if (here(bird) && verb != throw)
799                                         obj = bird;
800                               if (here(clam) || here(oyster))
801                                         obj = 100 * obj + clam;
802                               if (obj > 100)
803                                         return (8000);
804                     }
805           }
806           if (obj == bird) {  /* 9124                         */
807                     spk = 137;
808                     if (closed)
809                               return (2011);
810                     destroy(bird);
811                     prop[bird] = 0;
812                     if (place[snake] == plac[snake])
813                               tally2++;
814                     spk = 45;
815           }
816           if (obj == 0)
817                     spk = 44; /* 9125                         */
818           if (obj == clam || obj == oyster)
819                     spk = 150;
820           if (obj == snake)
821                     spk = 46;
822           if (obj == dwarf)
823                     spk = 49;
824           if (obj == dwarf && closed)
825                     return (19000);
826           if (obj == dragon)
827                     spk = 147;
828           if (obj == troll)
829                     spk = 157;
830           if (obj == bear)
831                     spk = 165 + (prop[bear] + 1) / 2;
832           if (obj != dragon || prop[dragon] != 0)
833                     return (2011);
834           rspeak(49);
835           verb = 0;
836           obj = 0;
837           getin(&wd1, &wd2);
838           if (!weq(wd1, "y") && !weq(wd1, "yes"))
839                     return (2608);
840           pspeak(dragon, 1);
841           prop[dragon] = 2;
842           prop[rug] = 0;
843           k = (plac[dragon] + fixd[dragon]) / 2;
844           move(dragon + 100, -1);
845           move(rug + 100, 0);
846           move(dragon, k);
847           move(rug, k);
848           for (obj = 1; obj <= 100; obj++)
849                     if (place[obj] == plac[dragon] || place[obj] == fixd[dragon])
850                               move(obj, k);
851           loc = k;
852           k = null;
853           return (8);
854 }
855 
856 /* 9170: throw                  */
857 int
trtoss(void)858 trtoss(void)
859 {
860           int     i;
861           if (toting(rod2) && obj == rod && !toting(rod))
862                     obj = rod2;
863           if (!toting(obj))
864                     return (2011);
865           if (obj >= 50 && obj <= maxtrs && at(troll)) {
866                     spk = 159;          /* 9178                 */
867                     drop(obj, 0);
868                     move(troll, 0);
869                     move(troll + 100, 0);
870                     drop(troll2, plac[troll]);
871                     drop(troll2 + 100, fixd[troll]);
872                     juggle(chasm);
873                     return (2011);
874           }
875           if (obj == food && here(bear)) {
876                     obj = bear;         /* 9177                 */
877                     return (9210);
878           }
879           if (obj != axe)
880                     return (9020);
881           for (i = 1; i <= 5; i++) {
882                     if (dloc[i] == loc) {
883                               spk = 48; /* 9172                 */
884                               if (ran(3) == 0 || saved != -1)
885           l9175:              {
886                                         rspeak(spk);
887                                         drop(axe, loc);
888                                         k = null;
889                                         return (8);
890                               }
891                               dseen[i] = FALSE;
892                               dloc[i] = 0;
893                               spk = 47;
894                               dkill++;
895                               if (dkill == 1)
896                                         spk = 149;
897                               goto l9175;
898                     }
899           }
900           spk = 152;
901           if (at(dragon) && prop[dragon] == 0)
902                     goto l9175;
903           spk = 158;
904           if (at(troll))
905                     goto l9175;
906           if (here(bear) && prop[bear] == 0) {
907                     spk = 164;
908                     drop(axe, loc);
909                     fixed[axe] = -1;
910                     prop[axe] = 1;
911                     juggle(bear);
912                     return (2011);
913           }
914           obj = 0;
915           return (9120);
916 }
917 
918 /* 9210                 */
919 int
trfeed(void)920 trfeed(void)
921 {
922           if (obj == bird) {
923                     spk = 100;
924                     return (2011);
925           }
926           if (obj == snake || obj == dragon || obj == troll) {
927                     spk = 102;
928                     if (obj == dragon && prop[dragon] != 0)
929                               spk = 110;
930                     if (obj == troll)
931                               spk = 182;
932                     if (obj != snake || closed || !here(bird))
933                               return (2011);
934                     spk = 101;
935                     destroy(bird);
936                     prop[bird] = 0;
937                     tally2++;
938                     return (2011);
939           }
940           if (obj == dwarf) {
941                     if (!here(food))
942                               return (2011);
943                     spk = 103;
944                     dflag++;
945                     return (2011);
946           }
947           if (obj == bear) {
948                     if (prop[bear] == 0)
949                               spk = 102;
950                     if (prop[bear] == 3)
951                               spk = 110;
952                     if (!here(food))
953                               return (2011);
954                     destroy(food);
955                     prop[bear] = 1;
956                     fixed[axe] = 0;
957                     prop[axe] = 0;
958                     spk = 168;
959                     return (2011);
960           }
961           spk = 14;
962           return (2011);
963 }
964 
965 /* 9220 */
966 int
trfill(void)967 trfill(void)
968 {
969           if (obj == vase) {
970                     spk = 29;
971                     if (liqloc(loc) == 0)
972                               spk = 144;
973                     if (liqloc(loc) == 0 || !toting(vase))
974                               return (2011);
975                     rspeak(145);
976                     prop[vase] = 2;
977                     fixed[vase] = -1;
978                     return (9020);      /* advent/10 goes to 9024 */
979           }
980           if (obj != 0 && obj != bottle)
981                     return (2011);
982           if (obj == 0 && !here(bottle))
983                     return (8000);
984           spk = 107;
985           if (liqloc(loc) == 0)
986                     spk = 106;
987           if (liq() != 0)
988                     spk = 105;
989           if (spk != 107)
990                     return (2011);
991           prop[bottle] = ((cond[loc] % 4) / 2) * 2;
992           k = liq();
993           if (toting(bottle))
994                     place[k] = -1;
995           if (k == oil)
996                     spk = 108;
997           return (2011);
998 }
999 
1000 /* 10000 */
1001 void
closing(void)1002 closing(void)
1003 {
1004           int     i;
1005 
1006           prop[grate] = prop[fissure] = 0;
1007           for (i = 1; i <= 6; i++) {
1008                     dseen[i] = FALSE;
1009                     dloc[i] = 0;
1010           }
1011           move(troll, 0);
1012           move(troll + 100, 0);
1013           move(troll2, plac[troll]);
1014           move(troll2 + 100, fixd[troll]);
1015           juggle(chasm);
1016           if (prop[bear] != 3)
1017                     destroy(bear);
1018           prop[chain] = 0;
1019           fixed[chain] = 0;
1020           prop[axe] = 0;
1021           fixed[axe] = 0;
1022           rspeak(129);
1023           clock1 = -1;
1024           isclosing = TRUE;
1025 }
1026 
1027 /* 11000 */
1028 void
caveclose(void)1029 caveclose(void)
1030 {
1031           int     i;
1032           prop[bottle] = put(bottle, 115, 1);
1033           prop[plant] = put(plant, 115, 0);
1034           prop[oyster] = put(oyster, 115, 0);
1035           prop[lamp] = put(lamp, 115, 0);
1036           prop[rod] = put(rod, 115, 0);
1037           prop[dwarf] = put(dwarf, 115, 0);
1038           loc = 115;
1039           oldloc = 115;
1040           newloc = 115;
1041 
1042           put(grate, 116, 0);
1043           prop[snake] = put(snake, 116, 1);
1044           prop[bird] = put(bird, 116, 1);
1045           prop[cage] = put(cage, 116, 0);
1046           prop[rod2] = put(rod2, 116, 0);
1047           prop[pillow] = put(pillow, 116, 0);
1048 
1049           prop[mirror] = put(mirror, 115, 0);
1050           fixed[mirror] = 116;
1051 
1052           for (i = 1; i <= 100; i++)
1053                     if (toting(i))
1054                               destroy(i);
1055           rspeak(132);
1056           closed = TRUE;
1057 }
1058