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