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