Home | History | Annotate | Line # | Download | only in adventure
      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
     63 toting(int objj)
     64 {
     65 	if (place[objj] == -1)
     66 		return (TRUE);
     67 	else
     68 		return (FALSE);
     69 }
     70 
     71 int
     72 here(int objj)
     73 {
     74 	if (place[objj] == loc || toting(objj))
     75 		return (TRUE);
     76 	else
     77 		return (FALSE);
     78 }
     79 
     80 int
     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
     90 liq2(int pbotl)
     91 {
     92 	return ((1 - pbotl) * water + (pbotl / 2) * (water + oil));
     93 }
     94 
     95 int
     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
    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
    119 bitset(int l, int n)
    120 {
    121 	if (cond[l] & setbit[n])
    122 		return (TRUE);
    123 	return (FALSE);
    124 }
    125 
    126 int
    127 forced(int locc)
    128 {
    129 	if (cond[locc] == 2)
    130 		return (TRUE);
    131 	return (FALSE);
    132 }
    133 
    134 int
    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
    143 pct(int n)
    144 {
    145 	if (ran(100) < n)
    146 		return (TRUE);
    147 	return (FALSE);
    148 }
    149 
    150 
    151 int
    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
    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
    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
    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
    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
    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
    498 bug(int n)
    499 {
    500 	printf("Please tell jim (at) rand.org that fatal bug %d happened.\n", n);
    501 	exit(1);
    502 }
    503 
    504 /* 2600 &c              */
    505 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
    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
    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
    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
    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
    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
    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
    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
    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
    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
   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
   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