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