xref: /openbsd/games/adventure/main.c (revision d0bb6702)
1 /*	$OpenBSD: main.c,v 1.26 2021/01/27 01:59:39 deraadt Exp $	*/
2 /*	$NetBSD: main.c,v 1.5 1996/05/21 21:53:09 mrg 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: main program				*/
39 
40 #include <err.h>
41 #include <stdio.h>
42 #include <time.h>
43 #include <unistd.h>
44 
45 #include "extern.h"
46 #include "hdr.h"
47 
48 int     datfd;			/* message file descriptor	*/
49 volatile sig_atomic_t delhit;
50 int     yea;
51 
52 int     loc, newloc, oldloc, oldlc2, wzdark, gaveup, kq, k, k2;
53 int     verb, obj, spk;
54 time_t  savet;
55 int     mxscor, latncy;
56 
57 char	wd1[MAXSTR];		/* the complete words		*/
58 char	wd2[MAXSTR];
59 
60 struct hashtab voc[HTSIZE];
61 
62 struct text rtext[RTXSIZ];	/* random text messages		*/
63 
64 struct text mtext[MAGSIZ];	/* magic messages		*/
65 
66 int clsses;
67 struct text ctext[CLSMAX];	/* classes of adventurer	*/
68 int cval[CLSMAX];
69 
70 struct text ptext[101];		/* object descriptions		*/
71 
72 struct text ltext[LOCSIZ];	/* long loc description		*/
73 struct text stext[LOCSIZ];	/* short loc descriptions	*/
74 
75 struct travlist *travel[LOCSIZ],*tkk;	/* travel is closer to keys(...)*/
76 
77 int atloc[LOCSIZ];
78 
79 int	plac[101];		/* initial object placement	*/
80 int	fixd[101], fixed[101];	/* location fixed?		*/
81 
82 int	actspk[35];		/* rtext msg for verb <n>	*/
83 
84 int	cond[LOCSIZ];		/* various condition bits	*/
85 
86 int	hntmax;
87 int	hints[20][5];		/* info on hints		*/
88 int	hinted[20], hintlc[20];
89 
90 int	place[101], prop[101], linkx[201];
91 int	abb[LOCSIZ];
92 
93 int	maxtrs, tally, tally2;	/* treasure values		*/
94 
95 int	keys, lamp, grate, cage, rod, rod2, steps,	/* mnemonics */
96 	bird, door, pillow, snake, fissur, tablet, clam, oyster,
97 	magzin, dwarf, knife, food, bottle, water, oil, plant, plant2,
98 	axe, mirror, dragon, chasm, troll, troll2, bear, messag,
99 	vend, batter, nugget, coins, chest, eggs, tridnt, vase,
100 	emrald, pyram, pearl, rug, chain, spices, back, look, cave,
101 	null, entrnc, dprssn, enter, stream, pour, say, lock, throw,
102 	find, invent;
103 
104 int	chloc, chloc2, dseen[7], dloc[7],	/* dwarf stuff	*/
105 	odloc[7], dflag, daltlc;
106 
107 int	tk[21], stick, dtotal, attack;
108 int	turns, lmwarn, iwest, knfloc, detail,   /* various flags & counters */
109 	abbnum, maxdie, numdie, holdng, dkill, foobar, bonus, clock1,
110 	clock2, saved, closng, panic, closed, scorng;
111 
112 int	demo, limit;
113 
114 int
main(int argc,char * argv[])115 main(int argc, char *argv[])
116 {
117 	int     i;
118 	int     rval, ll;
119 	struct text *kk;
120 
121 	if (pledge("stdio rpath wpath cpath", NULL) == -1)
122 		err(1, "pledge");
123 
124 	init();		/* Initialize everything */
125 	signal(SIGINT, trapdel);
126 
127 	if (argc > 1) {	/* Restore file specified */
128 		/* Restart is label 8305 (Fortran) */
129 		i = restore(argv[1]);	/* See what we've got */
130 		switch (i) {
131 		case 0:			/* The restore worked fine */
132 			yea = Start();
133 			k = null;
134 			unlink(argv[1]);/* Don't re-use the save */
135 			goto l8;	/* Get where we're going */
136 		case 1:		/* Couldn't open it */
137 			errx(1, "can't open file");	/* So give up */
138 		case 2:		/* Oops -- file was altered */
139 			rspeak(202);	/* You dissolve */
140 			return 2;	/* File could be non-adventure */
141 		}			/* So don't unlink it. */
142 	}
143 
144 	startup();		/* prepare for a user		*/
145 
146 	for (;;) {		/* main command loop (label 2)	*/
147 		if (newloc < 9 && newloc != 0 && closng) {
148 			rspeak(130);	/* if closing leave only by	*/
149 			newloc = loc;	/*	main office		*/
150 			if (!panic)
151 				clock2 = 15;
152 			panic = TRUE;
153 		}
154 
155 		rval = fdwarf();		/* dwarf stuff			*/
156 		if (rval == 99)
157 			die(99);
158 
159 l2000:		if (loc == 0)
160 			die(99);	/* label 2000			*/
161 		kk = &stext[loc];
162 		if ((abb[loc] % abbnum) ==0 || kk->seekadr == 0)
163 			kk = &ltext[loc];
164 		if (!forced(loc) && dark()) {
165 			if (wzdark && pct(35)) {
166 				die(90);
167 				goto l2000;
168 			}
169 			kk = &rtext[16];
170 		}
171 		if (toting(bear))
172 			rspeak(141);	/* 2001			*/
173 		speak(kk);
174 		k = 1;
175 		if (forced(loc))
176 			goto l8;
177 		if (loc == 33 && pct(25) && !closng)
178 			rspeak(8);
179 		if (!dark()) {
180 			abb[loc]++;
181 			for (i = atloc[loc]; i != 0; i = linkx[i]) {	/*2004*/
182 				obj = i;
183 				if (obj > 100)
184 					obj -= 100;
185 				if (obj == steps && toting(nugget))
186 					continue;
187 				if (prop[obj] < 0) {
188 					if (closed)
189 						continue;
190 					prop[obj] = 0;
191 					if (obj == rug || obj == chain)
192 						prop[obj] = 1;
193 					tally--;
194 					if (tally == tally2 && tally != 0)
195 						if (limit > 35)
196 							limit = 35;
197 				}
198 				ll = prop[obj];	/* 2006	*/
199 				if (obj == steps && loc == fixed[steps])
200 					ll = 1;
201 				pspeak(obj, ll);
202 			}		/* 2008 */
203 			goto l2012;
204 l2009:		k = 54;			/* 2009			*/
205 l2010:		spk = k;
206 l2011:		rspeak(spk);
207 		}
208 l2012:		verb = 0;		/* 2012			*/
209 		obj = 0;
210 l2600:		checkhints();		/* to 2600-2602		*/
211 		if (closed) {
212 			if (prop[oyster] < 0 && toting(oyster))
213 				pspeak(oyster, 1);
214 			for (i = 1; i < 100; i++)
215 				if (toting(i) && prop[i] < 0)	/* 2604 */
216 					prop[i] = -1 - prop[i];
217 		}
218 		wzdark = dark();	/* 2605			*/
219 		if (knfloc > 0 && knfloc != loc)
220 			knfloc = 1;
221 		getin(wd1, sizeof(wd1), wd2, sizeof(wd2));
222 		if (delhit) {		/* user typed a DEL	*/
223 			delhit = 0;	/* reset counter	*/
224 			/* pretend he's quitting */
225 			strlcpy(wd1, "quit", sizeof(wd1));
226 			wd2[0] = 0;
227 		}
228 l2608:		if ((foobar = -foobar) > 0)
229 			foobar = 0;	/* 2608		*/
230 		/* should check here for "magic mode"		*/
231 		turns++;
232 		if (demo && turns >= SHORT)
233 			done(1);	/* to 13000	*/
234 
235 		if (verb == say && wd2[0] != 0)
236 			verb = 0;
237 		if (verb == say)
238 			goto l4090;
239 		if (tally == 0 && loc >= 15 && loc != 33)
240 			clock1--;
241 		if (clock1 == 0) {
242 			closing();			/* to 10000	*/
243 			goto l19999;
244 		}
245 		if (clock1 < 0)
246 			clock2--;
247 		if (clock2 == 0) {
248 			caveclose();		/* to 11000		*/
249 			continue;		/* back to 2		*/
250 		}
251 		if (prop[lamp] == 1)
252 			limit--;
253 		if (limit <= 30 && here(batter) && prop[batter] == 0
254 			&& here(lamp)) {
255 			rspeak(188);		/* 12000		*/
256 			prop[batter] = 1;
257 			if (toting(batter))
258 				drop(batter, loc);
259 			limit += 2500;
260 			lmwarn = FALSE;
261 			goto l19999;
262 		}
263 		if (limit == 0) {
264 			limit = -1;		/* 12400		*/
265 			prop[lamp] = 0;
266 			rspeak(184);
267 			goto l19999;
268 		}
269 		if (limit < 0 && loc <= 8) {
270 			rspeak(185);		/* 12600		*/
271 			gaveup = TRUE;
272 			done(2);		/* to 20000		*/
273 		}
274 		if (limit <= 30) {
275 			if (lmwarn || !here(lamp))
276 				goto l19999;	/*12200*/
277 			lmwarn = TRUE;
278 			spk = 187;
279 			if (place[batter] == 0)
280 				spk = 183;
281 			if (prop[batter] == 1)
282 				spk = 189;
283 			rspeak(spk);
284 		}
285 l19999:		k = 43;
286 		if (liqloc(loc) == water)
287 			k = 70;
288 		if (weq(wd1, "enter") &&
289 		    (weq(wd2, "strea") || weq(wd2, "water")))
290 			goto l2010;
291 		if (weq(wd1, "enter") && *wd2 != 0)
292 			goto l2800;
293 		if ((!weq(wd1, "water") && !weq(wd1, "oil"))
294 		    || (!weq(wd2, "plant") && !weq(wd2, "door")))
295 			goto l2610;
296 		if (at(vocab(wd2, 1, 0)))
297 			strlcpy(wd2, "pour", sizeof(wd2));
298 
299 l2610:		if (weq(wd1, "west"))
300 			if (++iwest == 10)
301 				rspeak(17);
302 l2630:		i = vocab(wd1, -1, 0);
303 		if (i== -1) {
304 			spk = 60;			/* 3000		*/
305 			if (pct(20))
306 				spk = 61;
307 			if (pct(20))
308 				spk = 13;
309 			rspeak(spk);
310 			goto l2600;
311 		}
312 		k = i % 1000;
313 		kq = i / 1000 + 1;
314 		switch (kq) {
315 		case 1: goto l8;
316 		case 2: goto l5000;
317 		case 3: goto l4000;
318 		case 4: goto l2010;
319 		default:
320 			bug(22);
321 		}
322 
323 l8:
324 		switch (march()) {
325 		case 2: continue;		/* i.e. goto l2		*/
326 		case 99:
327 			die(99);
328 			goto l2000;
329 		default: bug(110);
330 		}
331 
332 l2800:		strlcpy(wd1, wd2, sizeof(wd1));
333 		wd2[0] = 0;
334 		goto l2610;
335 
336 l4000:		verb = k;
337 		spk = actspk[verb];
338 		if (wd2[0] != 0 && verb != say)
339 			goto l2800;
340 		if (verb == say)
341 			obj = wd2[0];
342 		if (obj != 0)
343 			goto l4090;
344 
345 		switch (verb) {
346 		case 1:			/* take = 8010		*/
347 			if (atloc[loc] == 0 || linkx[atloc[loc]] != 0)
348 				goto l8000;
349 			for (i = 1; i <= 5; i++)
350 				if (dloc[i] == loc && dflag >= 2)
351 					goto l8000;
352 			obj = atloc[loc];
353 			goto l9010;
354 		case 2: case 3: case 9:		/* 8000 : drop, say, wave */
355 		case 10: case 16: case 17:	/* calm, rub, toss	*/
356 		case 19: case 21: case 28:	/* find, feed, break	*/
357 		case 29:			/* wake			*/
358 l8000:			printf("%s what?\n", wd1);
359 			obj = 0;
360 			goto l2600;
361 		case 4: case 6:		/* 8040 open, lock	*/
362 			spk = 28;
363 			if (here(clam))
364 				obj = clam;
365 			if (here(oyster))
366 				obj = oyster;
367 			if (at(door))
368 				obj = door;
369 			if (at(grate))
370 				obj = grate;
371 			if (obj != 0 && here(chain))
372 				goto l8000;
373 			if (here(chain))
374 				obj = chain;
375 			if (obj == 0)
376 				goto l2011;
377 			goto l9040;
378 		case 5: goto l2009;		/* nothing		*/
379 		case 7: goto l9070;		/* on			*/
380 		case 8: goto l9080;		/* off			*/
381 		case 11: goto l8000;	/* walk			*/
382 		case 12: goto l9120;	/* kill			*/
383 		case 13: goto l9130;	/* pour			*/
384 		case 14:			/* eat: 8140		*/
385 			if (!here(food))
386 				goto l8000;
387 l8142:			dstroy(food);
388 			spk = 72;
389 			goto l2011;
390 		case 15: goto l9150;	/* drink		*/
391 		case 18:			/* quit: 8180		*/
392 			gaveup = yes(22, 54, 54);
393 			if (gaveup)
394 				done(2);	/* 8185			*/
395 			goto l2012;
396 		case 20:			/* invent = 8200	*/
397 			spk = 98;
398 			for (i = 1; i <= 100; i++) {
399 				if (i != bear && toting(i)) {
400 					if (spk == 98)
401 						rspeak(99);
402 					blklin = FALSE;
403 					pspeak(i, -1);
404 					blklin = TRUE;
405 					spk = 0;
406 				}
407 			}
408 			if (toting(bear))
409 				spk = 141;
410 			goto l2011;
411 		case 22: goto l9220;	/* fill			*/
412 		case 23: goto l9230;	/* blast		*/
413 		case 24:			/* score: 8240		*/
414 			scorng = TRUE;
415 			printf("If you were to quit now, you would score");
416 			printf(" %d out of a possible ", score());
417 			printf("%d.", mxscor);
418 			scorng = FALSE;
419 			gaveup = yes(143, 54, 54);
420 			if (gaveup)
421 				done(2);
422 			goto l2012;
423 		case 25:			/* foo: 8250		*/
424 			k = vocab(wd1, 3, 0);
425 			spk = 42;
426 			if (foobar == 1 - k)
427 				goto l8252;
428 			if (foobar != 0)
429 				spk = 151;
430 			goto l2011;
431 l8252:			foobar = k;
432 			if (k != 4)
433 				goto l2009;
434 			foobar = 0;
435 			if (place[eggs] == plac[eggs]
436 				|| (toting(eggs) && loc == plac[eggs])) goto l2011;
437 			if (place[eggs] == 0 && place[troll] == 0 && prop[troll] == 0)
438 				prop[troll] = 1;
439 			k = 2;
440 			if (here(eggs))
441 				k = 1;
442 			if (loc == plac[eggs])
443 				k = 0;
444 			move(eggs, plac[eggs]);
445 			pspeak(eggs, k);
446 			goto l2012;
447 		case 26:			/* brief = 8260		*/
448 			spk = 156;
449 			abbnum = 10000;
450 			detail = 3;
451 			goto l2011;
452 		case 27:			/* read = 8270		*/
453 			if (here(magzin))
454 				obj = magzin;
455 			if (here(tablet))
456 				obj = obj * 100 + tablet;
457 			if (here(messag))
458 				obj = obj * 100 + messag;
459 			if (closed && toting(oyster))
460 				obj = oyster;
461 			if (obj > 100 || obj == 0 || dark())
462 				goto l8000;
463 			goto l9270;
464 		case 30:			/* suspend = 8300	*/
465 			spk = 201;
466 			if (demo)
467 				goto l2011;
468 			printf("I can suspend your adventure for you so");
469 			printf(" you can resume later, but\n");
470 			printf("you will have to wait at least");
471 			printf(" %d minutes before continuing.", latncy);
472 			if (!yes(200, 54, 54))
473 				goto l2012;
474 			time(&savet);
475 			ciao();		/* Do we quit? */
476 			continue;		/* Maybe not */
477 		case 31:			/* hours = 8310		*/
478 			printf("Colossal cave is closed 9am-5pm Mon ");
479 			printf("through Fri except holidays.\n");
480 			goto l2012;
481 		default:
482 			bug(23);
483 		}
484 
485 l4090:
486 		switch (verb) {
487 		case 1:			/* take = 9010		*/
488 l9010:			switch (trtake()) {
489 			case 2011: goto l2011;
490 			case 9220: goto l9220;
491 			case 2009: goto l2009;
492 			case 2012: goto l2012;
493 			default: bug(102);
494 			}
495 l9020:		case 2:			/* drop = 9020		*/
496 			switch (trdrop()) {
497 			case 2011: goto l2011;
498 			case 19000: done(3);
499 			case 2012: goto l2012;
500 			default: bug(105);
501 			}
502 		case 3:
503 			switch (trsay()) {
504 			case 2012: goto l2012;
505 			case 2630: goto l2630;
506 			default: bug(107);
507 			}
508 l9040:		case 4: case 6:		/* open, close		*/
509 			switch (tropen()) {
510 			case 2011: goto l2011;
511 			case 2010: goto l2010;
512 			default: bug(106);
513 			}
514 		case 5: goto l2009;	/* nothing		*/
515 		case 7:			/* on	9070		*/
516 l9070:			if (!here(lamp))
517 				goto l2011;
518 			spk = 184;
519 			if (limit < 0)
520 				goto l2011;
521 			prop[lamp] = 1;
522 			rspeak(39);
523 			if (wzdark)
524 				goto l2000;
525 			goto l2012;
526 
527 		case 8:			/* off			*/
528 l9080:			if (!here(lamp))
529 				goto l2011;
530 			prop[lamp] = 0;
531 			rspeak(40);
532 			if (dark())
533 				rspeak(16);
534 			goto l2012;
535 
536 		case 9:			/* wave			*/
537 			if ((!toting(obj)) && (obj != rod || !toting(rod2)))
538 				spk = 29;
539 			if (obj != rod || !at(fissur)||!toting(obj) || closng)
540 				goto l2011;
541 			prop[fissur] = 1-prop[fissur];
542 			pspeak(fissur, 2-prop[fissur]);
543 			goto l2012;
544 		case 10: case 11: case 18:	/* calm, walk, quit	*/
545 		case 24: case 25: case 26:	/* score, foo, brief	*/
546 		case 30: case 31:		/* suspend, hours	*/
547 			goto l2011;
548 l9120:		case 12:			/* kill			*/
549 			switch (trkill()) {
550 			case 8000: goto l8000;
551 			case 8: goto l8;
552 			case 2011: goto l2011;
553 			case 2608: goto l2608;
554 			case 19000: done(3);
555 			default: bug(112);
556 			}
557 l9130:		case 13:			/* pour			*/
558 			if (obj == bottle || obj == 0)
559 				obj = liq();
560 			if (obj == 0)
561 				goto l8000;
562 			if (!toting(obj))
563 				goto l2011;
564 			spk = 78;
565 			if (obj != oil && obj != water)
566 				goto l2011;
567 			prop[bottle] = 1;
568 			place[obj] = 0;
569 			spk = 77;
570 			if (!(at(plant) || at(door)))
571 				goto l2011;
572 			if (at(door)) {
573 				prop[door] = 0;	/* 9132			*/
574 				if (obj == oil)
575 					prop[door] = 1;
576 				spk = 113 + prop[door];
577 				goto l2011;
578 			}
579 			spk = 112;
580 			if (obj != water)
581 				goto l2011;
582 			pspeak(plant, prop[plant] + 1);
583 			prop[plant] = (prop[plant] + 2) % 6;
584 			prop[plant2] = prop[plant] / 2;
585 			k = null;
586 			goto l8;
587 		case 14:			/* 9140 - eat		*/
588 			if (obj == food)
589 				goto l8142;
590 			if (obj == bird || obj == snake || obj == clam || obj == oyster
591 			    || obj == dwarf || obj == dragon || obj == troll
592 			    || obj == bear) spk = 71;
593 			goto l2011;
594 l9150:		case 15:			/* 9150 - drink		*/
595 			if (obj == 0 && liqloc(loc) != water && (liq() != water
596 				|| !here(bottle)))
597 				goto l8000;
598 			if (obj != 0 && obj != water)
599 				spk = 110;
600 			if (spk == 110 || liq() != water || !here(bottle))
601 				goto l2011;
602 			prop[bottle] = 1;
603 			place[water] = 0;
604 			spk = 74;
605 			goto l2011;
606 		case 16:			/* 9160: rub		*/
607 			if (obj != lamp)
608 				spk = 76;
609 			goto l2011;
610 		case 17:			/* 9170: throw		*/
611 			switch (trtoss()) {
612 			case 2011: goto l2011;
613 			case 9020: goto l9020;
614 			case 9120: goto l9120;
615 			case 8: goto l8;
616 			case 9210: goto l9210;
617 			default: bug(113);
618 			}
619 		case 19: case 20:		/* 9190: find, invent	*/
620 			if (at(obj) || (liq() == obj && at(bottle))
621 				|| k == liqloc(loc))
622 				spk = 94;
623 			for (i = 1; i <= 5; i++)
624 				if (dloc[i] == loc && dflag >= 2 && obj == dwarf)
625 					spk = 94;
626 			if (closed)
627 				spk = 138;
628 			if (toting(obj))
629 				spk = 24;
630 			goto l2011;
631 l9210:		case 21:			/* feed			*/
632 			switch (trfeed()) {
633 			case 2011: goto l2011;
634 			default: bug(114);
635 			}
636 l9220:		case 22:			/* fill			*/
637 			switch (trfill()) {
638 			case 2011: goto l2011;
639 			case 8000: goto l8000;
640 			case 9020: goto l9020;
641 			default: bug(115);
642 			}
643 l9230:		case 23:			/* blast		*/
644 			if (prop[rod2] < 0 || !closed)
645 				goto l2011;
646 			bonus = 133;
647 			if (loc == 115)
648 				bonus = 134;
649 			if (here(rod2))
650 				bonus = 135;
651 			rspeak(bonus);
652 			done(2);
653 l9270:		case 27:			/* read			*/
654 			if (dark())
655 				goto l5190;
656 			if (obj == magzin)
657 				spk = 190;
658 			if (obj == tablet)
659 				spk = 196;
660 			if (obj == messag)
661 				spk = 191;
662 			if (obj == oyster && hinted[2] && toting(oyster))
663 				spk = 194;
664 			if (obj != oyster || hinted[2] || !toting(oyster)
665 				|| !closed) goto l2011;
666 			hinted[2] = yes(192, 193, 54);
667 			goto l2012;
668 		case 28:			/* break		*/
669 			if (obj == mirror)
670 				spk = 148;
671 			if (obj == vase && prop[vase] == 0) {
672 				spk = 198;
673 				if (toting(vase))
674 					drop(vase, loc);
675 				prop[vase] = 2;
676 				fixed[vase] = -1;
677 				goto l2011;
678 			}
679 			if (obj != mirror||!closed)
680 				goto l2011;
681 			rspeak(197);
682 			done(3);
683 		case 29:			/* wake			*/
684 			if (obj != dwarf||!closed)
685 				goto l2011;
686 			rspeak(199);
687 			done(3);
688 
689 		default: bug(24);
690 		}
691 
692 l5000:
693 		obj = k;
694 		if (fixed[k] != loc && !here(k))
695 			goto l5100;
696 l5010:		if (wd2[0] != 0)
697 			goto l2800;
698 		if (verb != 0)
699 			goto l4090;
700 		printf("What do you want to do with the %s?\n", wd1);
701 		goto l2600;
702 l5100:		if (k != grate)
703 			goto l5110;
704 		if (loc == 1 || loc == 4 || loc == 7)
705 			k = dprssn;
706 		if (loc > 9 && loc < 15)
707 			k = entrnc;
708 		if (k != grate)
709 			goto l8;
710 l5110:		if (k != dwarf)
711 			goto l5120;
712 		for (i = 1; i <= 5; i++)
713 			if (dloc[i] == loc && dflag >= 2)
714 				goto l5010;
715 l5120:		if ((liq() == k && here(bottle)) || k == liqloc(loc))
716 			goto l5010;
717 		if (obj != plant || !at(plant2) || prop[plant2] == 0)
718 			goto l5130;
719 		obj = plant2;
720 		goto l5010;
721 l5130:		if (obj != knife || knfloc != loc)
722 			goto l5140;
723 		knfloc = -1;
724 		spk = 116;
725 		goto l2011;
726 l5140:		if (obj != rod || !here(rod2))
727 			goto l5190;
728 		obj = rod2;
729 		goto l5010;
730 l5190:		if ((verb == find || verb == invent) && wd2[0] == 0)
731 			goto l5010;
732 		printf("I see no %s here\n", wd1);
733 		goto l2012;
734 	}
735 }
736