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