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