Home | History | Annotate | Line # | Download | only in adventure
subr.c revision 1.11
      1 /*	$NetBSD: subr.c,v 1.11 2005/07/01 00:03:36 jmc 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.11 2005/07/01 00:03:36 jmc 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 /*              Statement functions     */
     54 int
     55 toting(int objj)
     56 {
     57 	if (place[objj] == -1)
     58 		return (TRUE);
     59 	else
     60 		return (FALSE);
     61 }
     62 
     63 int
     64 here(int objj)
     65 {
     66 	if (place[objj] == loc || toting(objj))
     67 		return (TRUE);
     68 	else
     69 		return (FALSE);
     70 }
     71 
     72 int
     73 at(int objj)
     74 {
     75 	if (place[objj] == loc || fixed[objj] == loc)
     76 		return (TRUE);
     77 	else
     78 		return (FALSE);
     79 }
     80 
     81 int
     82 liq2(int pbotl)
     83 {
     84 	return ((1 - pbotl) * water + (pbotl / 2) * (water + oil));
     85 }
     86 
     87 int
     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
    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 int
    111 bitset(int l, int n)
    112 {
    113 	if (cond[l] & setbit[n])
    114 		return (TRUE);
    115 	return (FALSE);
    116 }
    117 
    118 int
    119 forced(int locc)
    120 {
    121 	if (cond[locc] == 2)
    122 		return (TRUE);
    123 	return (FALSE);
    124 }
    125 
    126 int
    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
    135 pct(int n)
    136 {
    137 	if (ran(100) < n)
    138 		return (TRUE);
    139 	return (FALSE);
    140 }
    141 
    142 
    143 int
    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] = daltlc;
    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 == pyram && (loc == plac[pyram]
    216 					|| loc == plac[emrald]))
    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[messag] == 0)
    231 				move(chest, chloc);
    232 			move(messag, chloc2);
    233 			for (j = 50; j <= maxtrs; j++) { /* loop to 6023 */
    234 				if (j == pyram && (loc == plac[pyram]
    235 					|| loc == plac[emrald]))
    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(messag, 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 		oldlc2 = loc;
    282 		return (99);
    283 	}
    284 	rspeak(5);
    285 	k = 52;
    286 	goto l82;
    287 }
    288 
    289 
    290 /* label 8              */
    291 int
    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 		wzdark = 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 	oldlc2 = 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 int
    377 mback(void)
    378 {
    379 	struct travlist *tk2, *j;
    380 	int     ll;
    381 	if (forced(k = oldloc))
    382 		k = oldlc2;	/* k=location           */
    383 	oldlc2 = 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 int
    415 specials(void)
    416 {
    417 	switch (newloc -= 300) {
    418 		case 1:		/* 30100                */
    419 		newloc = 99 + 100 - loc;
    420 		if (holdng == 0 || (holdng == 1 && toting(emrald)))
    421 			return (2);
    422 		newloc = loc;
    423 		rspeak(117);
    424 		return (2);
    425 	case 2:		/* 30200                */
    426 		drop(emrald, loc);
    427 		return (12);
    428 	case 3:		/* to 30300             */
    429 		return (trbridge());
    430 	default:
    431 		bug(29);
    432 	}
    433 }
    434 
    435 /* 30300                */
    436 int
    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 	oldlc2 = newloc;
    464 	return (99);
    465 }
    466 
    467 /* 20                   */
    468 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
    490 bug(int n)
    491 {
    492 	printf("Please tell jim (at) rand.org that fatal bug %d happened.\n", n);
    493 	exit(1);
    494 }
    495 
    496 /* 2600 &c              */
    497 void
    498 checkhints(void)
    499 {
    500 	int     hint;
    501 	for (hint = 4; hint <= hntmax; 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[oldlc2] == 0 && holdng > 1)
    525 				goto l40010;
    526 			goto l40020;
    527 		case 8:	/* 40800 */
    528 			if (prop[emrald] != -1 && prop[pyram] == -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
    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
    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 (holdng >= 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 int
    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
    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 		dstroy(snake);
    648 		prop[snake] = 1;
    649 		return (dropper());
    650 	}
    651 	if (obj == coins && here(vend)) {	/* 9024                 */
    652 		dstroy(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 		dstroy(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
    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(tridnt))
    700 			spk = 122 + k;
    701 		if (verb == lock)
    702 			spk = 61;
    703 		if (spk != 124)
    704 			return (2011);
    705 		dstroy(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 (closng) {
    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
    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 		dstroy(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
    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
    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 		dstroy(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 		dstroy(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
    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
    994 closing(void)
    995 {
    996 	int     i;
    997 
    998 	prop[grate] = prop[fissur] = 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 		dstroy(bear);
   1010 	prop[chain] = 0;
   1011 	fixed[chain] = 0;
   1012 	prop[axe] = 0;
   1013 	fixed[axe] = 0;
   1014 	rspeak(129);
   1015 	clock1 = -1;
   1016 	closng = TRUE;
   1017 }
   1018 
   1019 /* 11000 */
   1020 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 			dstroy(i);
   1047 	rspeak(132);
   1048 	closed = TRUE;
   1049 }
   1050