xref: /dragonfly/games/adventure/subr.c (revision 9348a738)
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 }
1056