xref: /netbsd-src/games/larn/object.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: object.c,v 1.16 2012/06/19 05:30:43 dholland Exp $	*/
2 
3 /* object.c		Larn is copyrighted 1986 by Noah Morgan. */
4 
5 #include <sys/cdefs.h>
6 #ifndef lint
7 __RCSID("$NetBSD: object.c,v 1.16 2012/06/19 05:30:43 dholland Exp $");
8 #endif				/* not lint */
9 #include "header.h"
10 #include "extern.h"
11 
12 static void finditem(int);
13 static void ostairs(int);
14 static void opotion(int);
15 static void oscroll(int);
16 static void oorb(void);
17 static void opit(void);
18 static void obottomless(void);
19 static void oelevator(int);
20 static void ostatue(void);
21 static void omirror(void);
22 static void obook(void);
23 static void ocookie(void);
24 static void ogold(int);
25 static void ohome(void);
26 
27 /*
28 	lookforobject
29 
30 	subroutine to look for an object and give the player his options
31 	if an object was found.
32  */
33 void
34 lookforobject(void)
35 {
36 	int    i, j;
37 	if (c[TIMESTOP])
38 		return;		/* can't find objects if time is stopped	 */
39 	i = item[playerx][playery];
40 	if (i == 0)
41 		return;
42 	showcell(playerx, playery);
43 	cursors();
44 	yrepcount = 0;
45 	switch (i) {
46 	case OGOLDPILE:
47 	case OMAXGOLD:
48 	case OKGOLD:
49 	case ODGOLD:
50 		lprcat("\n\nYou have found some gold!");
51 		ogold(i);
52 		break;
53 
54 	case OPOTION:
55 		lprcat("\n\nYou have found a magic potion");
56 		i = iarg[playerx][playery];
57 		if (potionname[i][0] != 0)
58 			lprintf(" of%s", potionname[i]);
59 		opotion(i);
60 		break;
61 
62 	case OSCROLL:
63 		lprcat("\n\nYou have found a magic scroll");
64 		i = iarg[playerx][playery];
65 		if (scrollname[i][0] != 0)
66 			lprintf(" of%s", scrollname[i]);
67 		oscroll(i);
68 		break;
69 
70 	case OALTAR:
71 		if (nearbymonst())
72 			return;
73 		lprcat("\n\nThere is a Holy Altar here!");
74 		oaltar();
75 		break;
76 
77 	case OBOOK:
78 		lprcat("\n\nYou have found a book.");
79 		obook();
80 		break;
81 
82 	case OCOOKIE:
83 		lprcat("\n\nYou have found a fortune cookie.");
84 		ocookie();
85 		break;
86 
87 	case OTHRONE:
88 		if (nearbymonst())
89 			return;
90 		lprintf("\n\nThere is %s here!", objectname[i]);
91 		othrone(0);
92 		break;
93 
94 	case OTHRONE2:
95 		if (nearbymonst())
96 			return;
97 		lprintf("\n\nThere is %s here!", objectname[i]);
98 		othrone(1);
99 		break;
100 
101 	case ODEADTHRONE:
102 		lprintf("\n\nThere is %s here!", objectname[i]);
103 		odeadthrone();
104 		break;
105 
106 	case OORB:
107 		lprcat("\n\nYou have found the Orb!!!!!");
108 		oorb();
109 		break;
110 
111 	case OPIT:
112 		lprcat("\n\nYou're standing at the top of a pit.");
113 		opit();
114 		break;
115 
116 	case OSTAIRSUP:
117 		lprcat("\n\nThere is a circular staircase here");
118 		ostairs(1);	/* up */
119 		break;
120 
121 	case OELEVATORUP:
122 		lprcat("\n\nYou feel heavy for a moment, but the feeling disappears");
123 		oelevator(1);	/* up  */
124 		break;
125 
126 	case OFOUNTAIN:
127 		if (nearbymonst())
128 			return;
129 		lprcat("\n\nThere is a fountain here");
130 		ofountain();
131 		break;
132 
133 	case OSTATUE:
134 		if (nearbymonst())
135 			return;
136 		lprcat("\n\nYou are standing in front of a statue");
137 		ostatue();
138 		break;
139 
140 	case OCHEST:
141 		lprcat("\n\nThere is a chest here");
142 		ochest();
143 		break;
144 
145 	case OIVTELETRAP:
146 		if (rnd(11) < 6)
147 			return;
148 		item[playerx][playery] = OTELEPORTER;
149 		know[playerx][playery] = 1;
150 
151 	case OTELEPORTER:
152 		lprcat("\nZaaaappp!  You've been teleported!\n");
153 		beep();
154 		nap(3000);
155 		oteleport(0);
156 		break;
157 
158 	case OSCHOOL:
159 		if (nearbymonst())
160 			return;
161 		lprcat("\n\nYou have found the College of Larn.");
162 		lprcat("\nDo you (g) go inside, or (i) stay here? ");
163 		i = 0;
164 		while ((i != 'g') && (i != 'i') && (i != '\33'))
165 			i = ttgetch();
166 		if (i == 'g') {
167 			oschool();	/* the college of larn	 */
168 		} else
169 			lprcat(" stay here");
170 		break;
171 
172 	case OMIRROR:
173 		if (nearbymonst())
174 			return;
175 		lprcat("\n\nThere is a mirror here");
176 		omirror();
177 		break;
178 
179 	case OBANK2:
180 	case OBANK:
181 		if (nearbymonst())
182 			return;
183 		if (i == OBANK)
184 			lprcat("\n\nYou have found the bank of Larn.");
185 		else
186 			lprcat("\n\nYou have found a branch office of the bank of Larn.");
187 		lprcat("\nDo you (g) go inside, or (i) stay here? ");
188 		j = 0;
189 		while ((j != 'g') && (j != 'i') && (j != '\33'))
190 			j = ttgetch();
191 		if (j == 'g') {
192 			if (i == OBANK)
193 				obank();
194 			else
195 				obank2();	/* the bank of larn  */
196 		} else
197 			lprcat(" stay here");
198 		break;
199 
200 	case ODEADFOUNTAIN:
201 		if (nearbymonst())
202 			return;
203 		lprcat("\n\nThere is a dead fountain here");
204 		break;
205 
206 	case ODNDSTORE:
207 		if (nearbymonst())
208 			return;
209 		lprcat("\n\nThere is a DND store here.");
210 		lprcat("\nDo you (g) go inside, or (i) stay here? ");
211 		i = 0;
212 		while ((i != 'g') && (i != 'i') && (i != '\33'))
213 			i = ttgetch();
214 		if (i == 'g')
215 			dndstore();	/* the dnd adventurers store  */
216 		else
217 			lprcat(" stay here");
218 		break;
219 
220 	case OSTAIRSDOWN:
221 		lprcat("\n\nThere is a circular staircase here");
222 		ostairs(-1);	/* down */
223 		break;
224 
225 	case OELEVATORDOWN:
226 		lprcat("\n\nYou feel light for a moment, but the feeling disappears");
227 		oelevator(-1);	/* down	 */
228 		break;
229 
230 	case OOPENDOOR:
231 		lprintf("\n\nYou have found %s", objectname[i]);
232 		lprcat("\nDo you (c) close it");
233 		iopts();
234 		i = 0;
235 		while ((i != 'c') && (i != 'i') && (i != '\33'))
236 			i = ttgetch();
237 		if ((i == '\33') || (i == 'i')) {
238 			ignore();
239 			break;
240 		}
241 		lprcat("close");
242 		forget();
243 		item[playerx][playery] = OCLOSEDDOOR;
244 		iarg[playerx][playery] = 0;
245 		playerx = lastpx;
246 		playery = lastpy;
247 		break;
248 
249 	case OCLOSEDDOOR:
250 		lprintf("\n\nYou have found %s", objectname[i]);
251 		lprcat("\nDo you (o) try to open it");
252 		iopts();
253 		i = 0;
254 		while ((i != 'o') && (i != 'i') && (i != '\33'))
255 			i = ttgetch();
256 		if ((i == '\33') || (i == 'i')) {
257 			ignore();
258 			playerx = lastpx;
259 			playery = lastpy;
260 			break;
261 		} else {
262 			lprcat("open");
263 			if (rnd(11) < 7) {
264 				switch (iarg[playerx][playery]) {
265 				case 6:
266 					c[AGGRAVATE] += rnd(400);
267 					break;
268 
269 				case 7:
270 					lprcat("\nYou are jolted by an electric shock ");
271 					lastnum = 274;
272 					losehp(rnd(20));
273 					bottomline();
274 					break;
275 
276 				case 8:
277 					loselevel();
278 					break;
279 
280 				case 9:
281 					lprcat("\nYou suddenly feel weaker ");
282 					if (c[STRENGTH] > 3)
283 						c[STRENGTH]--;
284 					bottomline();
285 					break;
286 
287 				default:
288 					break;
289 				}
290 				playerx = lastpx;
291 				playery = lastpy;
292 			} else {
293 				forget();
294 				item[playerx][playery] = OOPENDOOR;
295 			}
296 		}
297 		break;
298 
299 	case OENTRANCE:
300 		lprcat("\nYou have found ");
301 		lprcat(objectname[OENTRANCE]);
302 		lprcat("\nDo you (g) go inside");
303 		iopts();
304 		i = 0;
305 		while ((i != 'g') && (i != 'i') && (i != '\33'))
306 			i = ttgetch();
307 		if (i == 'g') {
308 			newcavelevel(1);
309 			playerx = 33;
310 			playery = MAXY - 2;
311 			item[33][MAXY - 1] = know[33][MAXY - 1] = mitem[33][MAXY - 1] = 0;
312 			draws(0, MAXX, 0, MAXY);
313 			bot_linex();
314 			return;
315 		} else
316 			ignore();
317 		break;
318 
319 	case OVOLDOWN:
320 		lprcat("\nYou have found ");
321 		lprcat(objectname[OVOLDOWN]);
322 		lprcat("\nDo you (c) climb down");
323 		iopts();
324 		i = 0;
325 		while ((i != 'c') && (i != 'i') && (i != '\33'))
326 			i = ttgetch();
327 		if ((i == '\33') || (i == 'i')) {
328 			ignore();
329 			break;
330 		}
331 		if (level != 0) {
332 			lprcat("\nThe shaft only extends 5 feet downward!");
333 			return;
334 		}
335 		if (packweight() > 45 + 3 * (c[STRENGTH] + c[STREXTRA])) {
336 			lprcat("\nYou slip and fall down the shaft");
337 			beep();
338 			lastnum = 275;
339 			losehp(30 + rnd(20));
340 			bottomhp();
341 		} else
342 			lprcat("climb down");
343 		nap(3000);
344 		newcavelevel(MAXLEVEL);
345 		for (i = 0; i < MAXY; i++)
346 			for (j = 0; j < MAXX; j++)	/* put player near
347 							 * volcano shaft */
348 				if (item[j][i] == OVOLUP) {
349 					playerx = j;
350 					playery = i;
351 					j = MAXX;
352 					i = MAXY;
353 					positionplayer();
354 				}
355 		draws(0, MAXX, 0, MAXY);
356 		bot_linex();
357 		return;
358 
359 	case OVOLUP:
360 		lprcat("\nYou have found ");
361 		lprcat(objectname[OVOLUP]);
362 		lprcat("\nDo you (c) climb up");
363 		iopts();
364 		i = 0;
365 		while ((i != 'c') && (i != 'i') && (i != '\33'))
366 			i = ttgetch();
367 		if ((i == '\33') || (i == 'i')) {
368 			ignore();
369 			break;
370 		}
371 		if (level != 11) {
372 			lprcat("\nThe shaft only extends 8 feet upwards before you find a blockage!");
373 			return;
374 		}
375 		if (packweight() > 45 + 5 * (c[STRENGTH] + c[STREXTRA])) {
376 			lprcat("\nYou slip and fall down the shaft");
377 			beep();
378 			lastnum = 275;
379 			losehp(15 + rnd(20));
380 			bottomhp();
381 			return;
382 		}
383 		lprcat("climb up");
384 		lflush();
385 		nap(3000);
386 		newcavelevel(0);
387 		for (i = 0; i < MAXY; i++)
388 			for (j = 0; j < MAXX; j++)	/* put player near
389 							 * volcano shaft */
390 				if (item[j][i] == OVOLDOWN) {
391 					playerx = j;
392 					playery = i;
393 					j = MAXX;
394 					i = MAXY;
395 					positionplayer();
396 				}
397 		draws(0, MAXX, 0, MAXY);
398 		bot_linex();
399 		return;
400 
401 	case OTRAPARROWIV:
402 		if (rnd(17) < 13)
403 			return;	/* for an arrow trap */
404 		item[playerx][playery] = OTRAPARROW;
405 		know[playerx][playery] = 0;
406 
407 	case OTRAPARROW:
408 		lprcat("\nYou are hit by an arrow");
409 		beep();		/* for an arrow trap */
410 		lastnum = 259;
411 		losehp(rnd(10) + level);
412 		bottomhp();
413 		return;
414 
415 	case OIVDARTRAP:
416 		if (rnd(17) < 13)
417 			return;	/* for a dart trap */
418 		item[playerx][playery] = ODARTRAP;
419 		know[playerx][playery] = 0;
420 
421 	case ODARTRAP:
422 		lprcat("\nYou are hit by a dart");
423 		beep();		/* for a dart trap */
424 		lastnum = 260;
425 		losehp(rnd(5));
426 		if ((--c[STRENGTH]) < 3)
427 			c[STRENGTH] = 3;
428 		bottomline();
429 		return;
430 
431 	case OIVTRAPDOOR:
432 		if (rnd(17) < 13)
433 			return;	/* for a trap door */
434 		item[playerx][playery] = OTRAPDOOR;
435 		know[playerx][playery] = 1;
436 
437 	case OTRAPDOOR:
438 		lastnum = 272;	/* a trap door */
439 		if ((level == MAXLEVEL - 1) || (level == MAXLEVEL + MAXVLEVEL - 1)) {
440 			lprcat("\nYou fell through a bottomless trap door!");
441 			beep();
442 			nap(3000);
443 			died(271);
444 		}
445 		lprcat("\nYou fall through a trap door!");
446 		beep();		/* for a trap door */
447 		losehp(rnd(5 + level));
448 		nap(2000);
449 		newcavelevel(level + 1);
450 		draws(0, MAXX, 0, MAXY);
451 		bot_linex();
452 		return;
453 
454 
455 	case OTRADEPOST:
456 		if (nearbymonst())
457 			return;
458 		lprcat("\nYou have found the Larn trading Post.");
459 		lprcat("\nDo you (g) go inside, or (i) stay here? ");
460 		i = 0;
461 		while ((i != 'g') && (i != 'i') && (i != '\33'))
462 			i = ttgetch();
463 		if (i == 'g')
464 			otradepost();
465 		else
466 			lprcat("stay here");
467 		return;
468 
469 	case OHOME:
470 		if (nearbymonst())
471 			return;
472 		lprcat("\nYou have found your way home.");
473 		lprcat("\nDo you (g) go inside, or (i) stay here? ");
474 		i = 0;
475 		while ((i != 'g') && (i != 'i') && (i != '\33'))
476 			i = ttgetch();
477 		if (i == 'g')
478 			ohome();
479 		else
480 			lprcat("stay here");
481 		return;
482 
483 	case OWALL:
484 		break;
485 
486 	case OANNIHILATION:
487 		died(283);
488 		return;		/* annihilated by sphere of annihilation */
489 
490 	case OLRS:
491 		if (nearbymonst())
492 			return;
493 		lprcat("\n\nThere is an LRS office here.");
494 		lprcat("\nDo you (g) go inside, or (i) stay here? ");
495 		i = 0;
496 		while ((i != 'g') && (i != 'i') && (i != '\33'))
497 			i = ttgetch();
498 		if (i == 'g')
499 			olrs();	/* the larn revenue service */
500 		else
501 			lprcat(" stay here");
502 		break;
503 
504 	default:
505 		finditem(i);
506 		break;
507 	};
508 }
509 
510 /*
511 	function to say what object we found and ask if player wants to take it
512  */
513 static void
514 finditem(int theitem)
515 {
516 	int             tmp, i;
517 	lprintf("\n\nYou have found %s ", objectname[theitem]);
518 	tmp = iarg[playerx][playery];
519 	switch (theitem) {
520 	case ODIAMOND:
521 	case ORUBY:
522 	case OEMERALD:
523 	case OSAPPHIRE:
524 	case OSPIRITSCARAB:
525 	case OORBOFDRAGON:
526 	case OCUBEofUNDEAD:
527 	case ONOTHEFT:
528 		break;
529 
530 	default:
531 		if (tmp > 0)
532 			lprintf("+ %ld", (long) tmp);
533 		else if (tmp < 0)
534 			lprintf(" %ld", (long) tmp);
535 	}
536 	lprcat("\nDo you want to (t) take it");
537 	iopts();
538 	i = 0;
539 	while (i != 't' && i != 'i' && i != '\33')
540 		i = ttgetch();
541 	if (i == 't') {
542 		lprcat("take");
543 		if (take(theitem, tmp) == 0)
544 			forget();
545 		return;
546 	}
547 	ignore();
548 }
549 
550 
551 
552 /*
553 	subroutine to process the stair cases
554 	if dir > 0 the up else down
555  */
556 static void
557 ostairs(int dir)
558 {
559 	int    k;
560 	lprcat("\nDo you (s) stay here  ");
561 	if (dir > 0)
562 		lprcat("(u) go up  ");
563 	else
564 		lprcat("(d) go down  ");
565 	lprcat("or (f) kick stairs? ");
566 
567 	while (1)
568 		switch (ttgetch()) {
569 		case '\33':
570 		case 's':
571 		case 'i':
572 			lprcat("stay here");
573 			return;
574 
575 		case 'f':
576 			lprcat("kick stairs");
577 			if (rnd(2) == 1)
578 				lprcat("\nI hope you feel better.  Showing anger rids you of frustration.");
579 			else {
580 				k = rnd((level + 1) << 1);
581 				lprintf("\nYou hurt your foot dumb dumb!  You suffer %ld hit points", (long) k);
582 				lastnum = 276;
583 				losehp(k);
584 				bottomline();
585 			}
586 			return;
587 
588 		case 'u':
589 			lprcat("go up");
590 			if (dir < 0)
591 				lprcat("\nThe stairs don't go up!");
592 			else if (level >= 2 && level != 11) {
593 				k = level;
594 				newcavelevel(level - 1);
595 				draws(0, MAXX, 0, MAXY);
596 				bot_linex();
597 			} else
598 				lprcat("\nThe stairs lead to a dead end!");
599 			return;
600 
601 		case 'd':
602 			lprcat("go down");
603 			if (dir > 0)
604 				lprcat("\nThe stairs don't go down!");
605 			else if (level != 0 && level != 10 && level != 13) {
606 				k = level;
607 				newcavelevel(level + 1);
608 				draws(0, MAXX, 0, MAXY);
609 				bot_linex();
610 			} else
611 				lprcat("\nThe stairs lead to a dead end!");
612 			return;
613 		};
614 }
615 
616 
617 
618 /*
619 	subroutine to handle a teleport trap +/- 1 level maximum
620  */
621 void
622 oteleport(int err)
623 {
624 	int    tmp;
625 	if (err)
626 		if (rnd(151) < 3)
627 			died(264);	/* stuck in a rock */
628 	c[TELEFLAG] = 1;	/* show ?? on bottomline if been teleported	 */
629 	if (level == 0)
630 		tmp = 0;
631 	else if (level < MAXLEVEL) {
632 		tmp = rnd(5) + level - 3;
633 		if (tmp >= MAXLEVEL)
634 			tmp = MAXLEVEL - 1;
635 		if (tmp < 1)
636 			tmp = 1;
637 	} else {
638 		tmp = rnd(3) + level - 2;
639 		if (tmp >= MAXLEVEL + MAXVLEVEL)
640 			tmp = MAXLEVEL + MAXVLEVEL - 1;
641 		if (tmp < MAXLEVEL)
642 			tmp = MAXLEVEL;
643 	}
644 	playerx = rnd(MAXX - 2);
645 	playery = rnd(MAXY - 2);
646 	if (level != tmp)
647 		newcavelevel(tmp);
648 	positionplayer();
649 	draws(0, MAXX, 0, MAXY);
650 	bot_linex();
651 }
652 
653 
654 /*
655 	function to process a potion
656  */
657 static void
658 opotion(int pot)
659 {
660 	lprcat("\nDo you (d) drink it, (t) take it");
661 	iopts();
662 	while (1)
663 		switch (ttgetch()) {
664 		case '\33':
665 		case 'i':
666 			ignore();
667 			return;
668 
669 		case 'd':
670 			lprcat("drink\n");
671 			forget();	/* destroy potion	 */
672 			quaffpotion(pot);
673 			return;
674 
675 		case 't':
676 			lprcat("take\n");
677 			if (take(OPOTION, pot) == 0)
678 				forget();
679 			return;
680 		};
681 }
682 
683 /*
684 	function to drink a potion
685  */
686 void
687 quaffpotion(int pot)
688 {
689 	int    i, j, k;
690 	if (pot < 0 || pot >= MAXPOTION)
691 		return;		/* check for within bounds */
692 	potionname[pot] = potionhide[pot];
693 	switch (pot) {
694 	case 9:
695 		lprcat("\nYou feel greedy . . .");
696 		nap(2000);
697 		for (i = 0; i < MAXY; i++)
698 			for (j = 0; j < MAXX; j++)
699 				if ((item[j][i] == OGOLDPILE) || (item[j][i] == OMAXGOLD)) {
700 					know[j][i] = 1;
701 					show1cell(j, i);
702 				}
703 		showplayer();
704 		return;
705 
706 	case 19:
707 		lprcat("\nYou feel greedy . . .");
708 		nap(2000);
709 		for (i = 0; i < MAXY; i++)
710 			for (j = 0; j < MAXX; j++) {
711 				k = item[j][i];
712 				if ((k == ODIAMOND) || (k == ORUBY) || (k == OEMERALD) || (k == OMAXGOLD)
713 				    || (k == OSAPPHIRE) || (k == OLARNEYE) || (k == OGOLDPILE)) {
714 					know[j][i] = 1;
715 					show1cell(j, i);
716 				}
717 			}
718 		showplayer();
719 		return;
720 
721 	case 20:
722 		c[HP] = c[HPMAX];
723 		break;		/* instant healing */
724 
725 	case 1:
726 		lprcat("\nYou feel better");
727 		if (c[HP] == c[HPMAX])
728 			raisemhp(1);
729 		else if ((c[HP] += rnd(20) + 20 + c[LEVEL]) > c[HPMAX])
730 			c[HP] = c[HPMAX];
731 		break;
732 
733 	case 2:
734 		lprcat("\nSuddenly, you feel much more skillful!");
735 		raiselevel();
736 		raisemhp(1);
737 		return;
738 
739 	case 3:
740 		lprcat("\nYou feel strange for a moment");
741 		c[rund(6)]++;
742 		break;
743 
744 	case 4:
745 		lprcat("\nYou feel more self confident!");
746 		c[WISDOM] += rnd(2);
747 		break;
748 
749 	case 5:
750 		lprcat("\nWow!  You feel great!");
751 		if (c[STRENGTH] < 12)
752 			c[STRENGTH] = 12;
753 		else
754 			c[STRENGTH]++;
755 		break;
756 
757 	case 6:
758 		lprcat("\nYour charm went up by one!");
759 		c[CHARISMA]++;
760 		break;
761 
762 	case 8:
763 		lprcat("\nYour intelligence went up by one!");
764 		c[INTELLIGENCE]++;
765 		break;
766 
767 	case 10:
768 		for (i = 0; i < MAXY; i++)
769 			for (j = 0; j < MAXX; j++)
770 				if (mitem[j][i]) {
771 					know[j][i] = 1;
772 					show1cell(j, i);
773 				}
774 		 /* monster detection	 */ return;
775 
776 	case 12:
777 		lprcat("\nThis potion has no taste to it");
778 		return;
779 
780 	case 15:
781 		lprcat("\nWOW!!!  You feel Super-fantastic!!!");
782 		if (c[HERO] == 0)
783 			for (i = 0; i < 6; i++)
784 				c[i] += 11;
785 		c[HERO] += 250;
786 		break;
787 
788 	case 16:
789 		lprcat("\nYou have a greater intestinal constitude!");
790 		c[CONSTITUTION]++;
791 		break;
792 
793 	case 17:
794 		lprcat("\nYou now have incredibly bulging muscles!!!");
795 		if (c[GIANTSTR] == 0)
796 			c[STREXTRA] += 21;
797 		c[GIANTSTR] += 700;
798 		break;
799 
800 	case 18:
801 		lprcat("\nYou feel a chill run up your spine!");
802 		c[FIRERESISTANCE] += 1000;
803 		break;
804 
805 	case 0:
806 		lprcat("\nYou fall asleep. . .");
807 		i = rnd(11) - (c[CONSTITUTION] >> 2) + 2;
808 		while (--i > 0) {
809 			parse2();
810 			nap(1000);
811 		}
812 		cursors();
813 		lprcat("\nYou woke up!");
814 		return;
815 
816 	case 7:
817 		lprcat("\nYou become dizzy!");
818 		if (--c[STRENGTH] < 3)
819 			c[STRENGTH] = 3;
820 		break;
821 
822 	case 11:
823 		lprcat("\nYou stagger for a moment . .");
824 		for (i = 0; i < MAXY; i++)
825 			for (j = 0; j < MAXX; j++)
826 				know[j][i] = 0;
827 		nap(2000);
828 		draws(0, MAXX, 0, MAXY);	/* potion of forgetfulness */
829 		return;
830 
831 	case 13:
832 		lprcat("\nYou can't see anything!");	/* blindness */
833 		c[BLINDCOUNT] += 500;
834 		return;
835 
836 	case 14:
837 		lprcat("\nYou feel confused");
838 		c[CONFUSE] += 20 + rnd(9);
839 		return;
840 
841 	case 21:
842 		lprcat("\nYou don't seem to be affected");
843 		return;		/* cure dianthroritis */
844 
845 	case 22:
846 		lprcat("\nYou feel a sickness engulf you");	/* poison */
847 		c[HALFDAM] += 200 + rnd(200);
848 		return;
849 
850 	case 23:
851 		lprcat("\nYou feel your vision sharpen");	/* see invisible */
852 		c[SEEINVISIBLE] += rnd(1000) + 400;
853 		monstnamelist[INVISIBLESTALKER] = 'I';
854 		return;
855 	};
856 	bottomline();		/* show new stats		 */
857 	return;
858 }
859 
860 
861 /*
862 	function to process a magic scroll
863  */
864 static void
865 oscroll(int typ)
866 {
867 	lprcat("\nDo you ");
868 	if (c[BLINDCOUNT] == 0)
869 		lprcat("(r) read it, ");
870 	lprcat("(t) take it");
871 	iopts();
872 	while (1)
873 		switch (ttgetch()) {
874 		case '\33':
875 		case 'i':
876 			ignore();
877 			return;
878 
879 		case 'r':
880 			if (c[BLINDCOUNT])
881 				break;
882 			lprcat("read");
883 			forget();
884 			if (typ == 2 || typ == 15) {
885 				show1cell(playerx, playery);
886 				cursors();
887 			}
888 			 /* destroy it	 */ read_scroll(typ);
889 			return;
890 
891 		case 't':
892 			lprcat("take");
893 			if (take(OSCROLL, typ) == 0)
894 				forget();	/* destroy it	 */
895 			return;
896 		};
897 }
898 
899 /*
900 	data for the function to read a scroll
901  */
902 static int      xh, yh, yl, xl;
903 static u_char     curse[] = {
904 	BLINDCOUNT, CONFUSE, AGGRAVATE, HASTEMONST, ITCHING,
905 	LAUGHING, DRAINSTRENGTH, CLUMSINESS, INFEEBLEMENT, HALFDAM
906 };
907 
908 static u_char     exten[] = {
909 	PROTECTIONTIME, DEXCOUNT, STRCOUNT, CHARMCOUNT, INVISIBILITY,
910 	CANCELLATION, HASTESELF, GLOBE, SCAREMONST, HOLDMONST, TIMESTOP
911 };
912 
913 static u_char time_change[] = {
914 	HASTESELF, HERO, ALTPRO, PROTECTIONTIME, DEXCOUNT, STRCOUNT,
915 	GIANTSTR, CHARMCOUNT, INVISIBILITY, CANCELLATION, HASTESELF,
916 	AGGRAVATE, SCAREMONST, STEALTH, AWARENESS, HOLDMONST,
917 	HASTEMONST, FIRERESISTANCE, GLOBE, SPIRITPRO, UNDEADPRO,
918 	HALFDAM, SEEINVISIBLE, ITCHING, CLUMSINESS, WTW
919 };
920 
921 /*
922  *	function to adjust time when time warping and taking courses in school
923  */
924 void
925 adjusttime(long tim)
926 {
927 	int    j;
928 	for (j = 0; j < 26; j++)/* adjust time related parameters */
929 		if (c[time_change[j]])
930 			if ((c[time_change[j]] -= tim) < 1)
931 				c[time_change[j]] = 1;
932 	regen();
933 }
934 
935 /*
936 	function to read a scroll
937  */
938 void
939 read_scroll(int typ)
940 {
941 	int    i, j;
942 	if (typ < 0 || typ >= MAXSCROLL)
943 		return;		/* be sure we are within bounds */
944 	scrollname[typ] = scrollhide[typ];
945 	switch (typ) {
946 	case 0:
947 		lprcat("\nYour armor glows for a moment");
948 		enchantarmor();
949 		return;
950 
951 	case 1:
952 		lprcat("\nYour weapon glows for a moment");
953 		enchweapon();
954 		return;		/* enchant weapon */
955 
956 	case 2:
957 		lprcat("\nYou have been granted enlightenment!");
958 		yh = min(playery + 7, MAXY);
959 		xh = min(playerx + 25, MAXX);
960 		yl = max(playery - 7, 0);
961 		xl = max(playerx - 25, 0);
962 		for (i = yl; i < yh; i++)
963 			for (j = xl; j < xh; j++)
964 				know[j][i] = 1;
965 		nap(2000);
966 		draws(xl, xh, yl, yh);
967 		return;
968 
969 	case 3:
970 		lprcat("\nThis scroll seems to be blank");
971 		return;
972 
973 	case 4:
974 		createmonster(makemonst(level + 1));
975 		return;		/* this one creates a monster  */
976 
977 	case 5:
978 		something(level);	/* create artifact		 */
979 		return;
980 
981 	case 6:
982 		c[AGGRAVATE] += 800;
983 		return;		/* aggravate monsters */
984 
985 	case 7:
986 		gltime += (i = rnd(1000) - 850);	/* time warp */
987 		if (i >= 0)
988 			lprintf("\nYou went forward in time by %ld mobuls", (long) ((i + 99) / 100));
989 		else
990 			lprintf("\nYou went backward in time by %ld mobuls", (long) (-(i + 99) / 100));
991 		adjusttime((long) i);	/* adjust time for time warping */
992 		return;
993 
994 	case 8:
995 		oteleport(0);
996 		return;		/* teleportation */
997 
998 	case 9:
999 		c[AWARENESS] += 1800;
1000 		return;		/* expanded awareness	 */
1001 
1002 	case 10:
1003 		c[HASTEMONST] += rnd(55) + 12;
1004 		return;		/* haste monster */
1005 
1006 	case 11:
1007 		for (i = 0; i < MAXY; i++)
1008 			for (j = 0; j < MAXX; j++)
1009 				if (mitem[j][i])
1010 					hitp[j][i] = monster[mitem[j][i]].hitpoints;
1011 		return;		/* monster healing */
1012 	case 12:
1013 		c[SPIRITPRO] += 300 + rnd(200);
1014 		bottomline();
1015 		return;		/* spirit protection */
1016 
1017 	case 13:
1018 		c[UNDEADPRO] += 300 + rnd(200);
1019 		bottomline();
1020 		return;		/* undead protection */
1021 
1022 	case 14:
1023 		c[STEALTH] += 250 + rnd(250);
1024 		bottomline();
1025 		return;		/* stealth */
1026 
1027 	case 15:
1028 		lprcat("\nYou have been granted enlightenment!");	/* magic mapping */
1029 		for (i = 0; i < MAXY; i++)
1030 			for (j = 0; j < MAXX; j++)
1031 				know[j][i] = 1;
1032 		nap(2000);
1033 		draws(0, MAXX, 0, MAXY);
1034 		return;
1035 
1036 	case 16:
1037 		c[HOLDMONST] += 30;
1038 		bottomline();
1039 		return;		/* hold monster */
1040 
1041 	case 17:
1042 		for (i = 0; i < 26; i++)	/* gem perfection */
1043 			switch (iven[i]) {
1044 			case ODIAMOND:
1045 			case ORUBY:
1046 			case OEMERALD:
1047 			case OSAPPHIRE:
1048 				j = ivenarg[i];
1049 				j &= 255;
1050 				j <<= 1;
1051 				if (j > 255)
1052 					j = 255;	/* double value */
1053 				ivenarg[i] = j;
1054 				break;
1055 			}
1056 		break;
1057 
1058 	case 18:
1059 		for (i = 0; i < 11; i++)
1060 			c[exten[i]] <<= 1;	/* spell extension */
1061 		break;
1062 
1063 	case 19:
1064 		for (i = 0; i < 26; i++) {	/* identify */
1065 			if (iven[i] == OPOTION)
1066 				potionname[ivenarg[i]] = potionhide[ivenarg[i]];
1067 			if (iven[i] == OSCROLL)
1068 				scrollname[ivenarg[i]] = scrollhide[ivenarg[i]];
1069 		}
1070 		break;
1071 
1072 	case 20:
1073 		for (i = 0; i < 10; i++)	/* remove curse */
1074 			if (c[curse[i]])
1075 				c[curse[i]] = 1;
1076 		break;
1077 
1078 	case 21:
1079 		annihilate();
1080 		break;		/* scroll of annihilation */
1081 
1082 	case 22:
1083 		godirect(22, 150, "The ray hits the %s", 0, ' ');	/* pulverization */
1084 		break;
1085 	case 23:
1086 		c[LIFEPROT]++;
1087 		break;		/* life protection */
1088 	};
1089 }
1090 
1091 
1092 
1093 static void
1094 oorb(void)
1095 {
1096 }
1097 
1098 static void
1099 opit(void)
1100 {
1101 	int    i;
1102 	if (rnd(101) < 81) {
1103 		if (rnd(70) > 9 * c[DEXTERITY] - packweight() || rnd(101) < 5) {
1104 			if (level == MAXLEVEL - 1)
1105 				obottomless();
1106 			else if (level == MAXLEVEL + MAXVLEVEL - 1)
1107 				obottomless();
1108 			else {
1109 				if (rnd(101) < 20) {
1110 					i = 0;
1111 					lprcat("\nYou fell into a pit!  Your fall is cushioned by an unknown force\n");
1112 				} else {
1113 					i = rnd(level * 3 + 3);
1114 					lprintf("\nYou fell into a pit!  You suffer %ld hit points damage", (long) i);
1115 					lastnum = 261;	/* if he dies scoreboard
1116 							 * will say so */
1117 				}
1118 				losehp(i);
1119 				nap(2000);
1120 				newcavelevel(level + 1);
1121 				draws(0, MAXX, 0, MAXY);
1122 			}
1123 		}
1124 	}
1125 }
1126 
1127 static void
1128 obottomless(void)
1129 {
1130 	lprcat("\nYou fell into a bottomless pit!");
1131 	beep();
1132 	nap(3000);
1133 	died(262);
1134 }
1135 
1136 static void
1137 oelevator(int dir)
1138 {
1139 #ifdef lint
1140 	int             x;
1141 	x = dir;
1142 	dir = x;
1143 #endif	/* lint */
1144 }
1145 
1146 static void
1147 ostatue(void)
1148 {
1149 }
1150 
1151 static void
1152 omirror(void)
1153 {
1154 }
1155 
1156 static void
1157 obook(void)
1158 {
1159 	lprcat("\nDo you ");
1160 	if (c[BLINDCOUNT] == 0)
1161 		lprcat("(r) read it, ");
1162 	lprcat("(t) take it");
1163 	iopts();
1164 	while (1)
1165 		switch (ttgetch()) {
1166 		case '\33':
1167 		case 'i':
1168 			ignore();
1169 			return;
1170 
1171 		case 'r':
1172 			if (c[BLINDCOUNT])
1173 				break;
1174 			lprcat("read");
1175 			 /* no more book	 */ readbook(iarg[playerx][playery]);
1176 			forget();
1177 			return;
1178 
1179 		case 't':
1180 			lprcat("take");
1181 			if (take(OBOOK, iarg[playerx][playery]) == 0)
1182 				forget();	/* no more book	 */
1183 			return;
1184 		};
1185 }
1186 
1187 /*
1188 	function to read a book
1189  */
1190 void
1191 readbook(int lev)
1192 {
1193 	int    i, tmp;
1194 	if (lev <= 3)
1195 		i = rund((tmp = splev[lev]) ? tmp : 1);
1196 	else
1197 		i = rnd((tmp = splev[lev] - 9) ? tmp : 1) + 9;
1198 	spelknow[i] = 1;
1199 	lprintf("\nSpell \"%s\":  %s\n%s", spelcode[i], spelname[i], speldescript[i]);
1200 	if (rnd(10) == 4) {
1201 		lprcat("\nYour int went up by one!");
1202 		c[INTELLIGENCE]++;
1203 		bottomline();
1204 	}
1205 }
1206 
1207 static void
1208 ocookie(void)
1209 {
1210 	const char *p;
1211 
1212 	lprcat("\nDo you (e) eat it, (t) take it");
1213 	iopts();
1214 	while (1)
1215 		switch (ttgetch()) {
1216 		case '\33':
1217 		case 'i':
1218 			ignore();
1219 			return;
1220 
1221 		case 'e':
1222 			lprcat("eat\nThe cookie tasted good.");
1223 			forget();	/* no more cookie	 */
1224 			if (c[BLINDCOUNT])
1225 				return;
1226 			if (!(p = fortune()))
1227 				return;
1228 			lprcat("  A message inside the cookie reads:\n");
1229 			lprcat(p);
1230 			return;
1231 
1232 		case 't':
1233 			lprcat("take");
1234 			if (take(OCOOKIE, 0) == 0)
1235 				forget();	/* no more book	 */
1236 			return;
1237 		};
1238 }
1239 
1240 
1241 /*
1242  * routine to pick up some gold -- if arg==OMAXGOLD then the pile is worth
1243  * 100* the argument
1244  */
1245 static void
1246 ogold(int arg)
1247 {
1248 	long   i;
1249 	i = iarg[playerx][playery];
1250 	if (arg == OMAXGOLD)
1251 		i *= 100;
1252 	else if (arg == OKGOLD)
1253 		i *= 1000;
1254 	else if (arg == ODGOLD)
1255 		i *= 10;
1256 	lprintf("\nIt is worth %ld!", (long) i);
1257 	c[GOLD] += i;
1258 	bottomgold();
1259 	item[playerx][playery] = know[playerx][playery] = 0;	/* destroy gold	 */
1260 }
1261 
1262 static void
1263 ohome(void)
1264 {
1265 	int    i;
1266 	nosignal = 1;		/* disable signals */
1267 	for (i = 0; i < 26; i++)
1268 		if (iven[i] == OPOTION)
1269 			if (ivenarg[i] == 21) {
1270 				iven[i] = 0;	/* remove the potion of cure
1271 						 * dianthroritis from
1272 						 * inventory */
1273 				clear();
1274 				lprcat("Congratulations.  You found a potion of cure dianthroritis.\n");
1275 				lprcat("\nFrankly, No one thought you could do it.  Boy!  Did you surprise them!\n");
1276 				if (gltime > TIMELIMIT) {
1277 					lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
1278 					lprcat("You didn't make it in time.  In your agony, you kill the doctor,\nyour wife, and yourself!  Too bad!\n");
1279 					nap(5000);
1280 					died(269);
1281 				} else {
1282 					lprcat("\nThe doctor is now administering the potion, and in a few moments\n");
1283 					lprcat("Your daughter should be well on her way to recovery.\n");
1284 					nap(6000);
1285 					lprcat("\nThe potion is");
1286 					nap(3000);
1287 					lprcat(" working!  The doctor thinks that\n");
1288 					lprcat("your daughter will recover in a few days.  Congratulations!\n");
1289 					beep();
1290 					nap(5000);
1291 					died(263);
1292 				}
1293 			}
1294 	while (1) {
1295 		clear();
1296 		lprintf("Welcome home %s.  Latest word from the doctor is not good.\n", logname);
1297 
1298 		if (gltime > TIMELIMIT) {
1299 			lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
1300 			lprcat("You didn't make it in time.  In your agony, you kill the doctor,\nyour wife, and yourself!  Too bad!\n");
1301 			nap(5000);
1302 			died(269);
1303 		}
1304 		lprcat("\nThe diagnosis is confirmed as dianthroritis.  He guesses that\n");
1305 		lprintf("your daughter has only %ld mobuls left in this world.  It's up to you,\n", (long) ((TIMELIMIT - gltime + 99) / 100));
1306 		lprintf("%s, to find the only hope for your daughter, the very rare\n", logname);
1307 		lprcat("potion of cure dianthroritis.  It is rumored that only deep in the\n");
1308 		lprcat("depths of the caves can this potion be found.\n\n\n");
1309 		lprcat("\n     ----- press ");
1310 		standout("return");
1311 		lprcat(" to continue, ");
1312 		standout("escape");
1313 		lprcat(" to leave ----- ");
1314 		i = ttgetch();
1315 		while (i != '\33' && i != '\n')
1316 			i = ttgetch();
1317 		if (i == '\33') {
1318 			drawscreen();
1319 			nosignal = 0;	/* enable signals */
1320 			return;
1321 		}
1322 	}
1323 }
1324 
1325 /* routine to save program space	 */
1326 void
1327 iopts(void)
1328 {
1329 	lprcat(", or (i) ignore it? ");
1330 }
1331 
1332 void
1333 ignore(void)
1334 {
1335 	lprcat("ignore\n");
1336 }
1337