xref: /dragonfly/games/adventure/subr.c (revision 650094e1)
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 }
1057