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