xref: /netbsd-src/games/larn/object.c (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
1 /*	$NetBSD: object.c,v 1.15 2009/08/12 08:04:05 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.15 2009/08/12 08:04:05 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()
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(dir)
558 	int             dir;
559 {
560 	int    k;
561 	lprcat("\nDo you (s) stay here  ");
562 	if (dir > 0)
563 		lprcat("(u) go up  ");
564 	else
565 		lprcat("(d) go down  ");
566 	lprcat("or (f) kick stairs? ");
567 
568 	while (1)
569 		switch (ttgetch()) {
570 		case '\33':
571 		case 's':
572 		case 'i':
573 			lprcat("stay here");
574 			return;
575 
576 		case 'f':
577 			lprcat("kick stairs");
578 			if (rnd(2) == 1)
579 				lprcat("\nI hope you feel better.  Showing anger rids you of frustration.");
580 			else {
581 				k = rnd((level + 1) << 1);
582 				lprintf("\nYou hurt your foot dumb dumb!  You suffer %ld hit points", (long) k);
583 				lastnum = 276;
584 				losehp(k);
585 				bottomline();
586 			}
587 			return;
588 
589 		case 'u':
590 			lprcat("go up");
591 			if (dir < 0)
592 				lprcat("\nThe stairs don't go up!");
593 			else if (level >= 2 && level != 11) {
594 				k = level;
595 				newcavelevel(level - 1);
596 				draws(0, MAXX, 0, MAXY);
597 				bot_linex();
598 			} else
599 				lprcat("\nThe stairs lead to a dead end!");
600 			return;
601 
602 		case 'd':
603 			lprcat("go down");
604 			if (dir > 0)
605 				lprcat("\nThe stairs don't go down!");
606 			else if (level != 0 && level != 10 && level != 13) {
607 				k = level;
608 				newcavelevel(level + 1);
609 				draws(0, MAXX, 0, MAXY);
610 				bot_linex();
611 			} else
612 				lprcat("\nThe stairs lead to a dead end!");
613 			return;
614 		};
615 }
616 
617 
618 
619 /*
620 	subroutine to handle a teleport trap +/- 1 level maximum
621  */
622 void
623 oteleport(err)
624 	int             err;
625 {
626 	int    tmp;
627 	if (err)
628 		if (rnd(151) < 3)
629 			died(264);	/* stuck in a rock */
630 	c[TELEFLAG] = 1;	/* show ?? on bottomline if been teleported	 */
631 	if (level == 0)
632 		tmp = 0;
633 	else if (level < MAXLEVEL) {
634 		tmp = rnd(5) + level - 3;
635 		if (tmp >= MAXLEVEL)
636 			tmp = MAXLEVEL - 1;
637 		if (tmp < 1)
638 			tmp = 1;
639 	} else {
640 		tmp = rnd(3) + level - 2;
641 		if (tmp >= MAXLEVEL + MAXVLEVEL)
642 			tmp = MAXLEVEL + MAXVLEVEL - 1;
643 		if (tmp < MAXLEVEL)
644 			tmp = MAXLEVEL;
645 	}
646 	playerx = rnd(MAXX - 2);
647 	playery = rnd(MAXY - 2);
648 	if (level != tmp)
649 		newcavelevel(tmp);
650 	positionplayer();
651 	draws(0, MAXX, 0, MAXY);
652 	bot_linex();
653 }
654 
655 
656 /*
657 	function to process a potion
658  */
659 static void
660 opotion(pot)
661 	int             pot;
662 {
663 	lprcat("\nDo you (d) drink it, (t) take it");
664 	iopts();
665 	while (1)
666 		switch (ttgetch()) {
667 		case '\33':
668 		case 'i':
669 			ignore();
670 			return;
671 
672 		case 'd':
673 			lprcat("drink\n");
674 			forget();	/* destroy potion	 */
675 			quaffpotion(pot);
676 			return;
677 
678 		case 't':
679 			lprcat("take\n");
680 			if (take(OPOTION, pot) == 0)
681 				forget();
682 			return;
683 		};
684 }
685 
686 /*
687 	function to drink a potion
688  */
689 void
690 quaffpotion(pot)
691 	int             pot;
692 {
693 	int    i, j, k;
694 	if (pot < 0 || pot >= MAXPOTION)
695 		return;		/* check for within bounds */
696 	potionname[pot] = potionhide[pot];
697 	switch (pot) {
698 	case 9:
699 		lprcat("\nYou feel greedy . . .");
700 		nap(2000);
701 		for (i = 0; i < MAXY; i++)
702 			for (j = 0; j < MAXX; j++)
703 				if ((item[j][i] == OGOLDPILE) || (item[j][i] == OMAXGOLD)) {
704 					know[j][i] = 1;
705 					show1cell(j, i);
706 				}
707 		showplayer();
708 		return;
709 
710 	case 19:
711 		lprcat("\nYou feel greedy . . .");
712 		nap(2000);
713 		for (i = 0; i < MAXY; i++)
714 			for (j = 0; j < MAXX; j++) {
715 				k = item[j][i];
716 				if ((k == ODIAMOND) || (k == ORUBY) || (k == OEMERALD) || (k == OMAXGOLD)
717 				    || (k == OSAPPHIRE) || (k == OLARNEYE) || (k == OGOLDPILE)) {
718 					know[j][i] = 1;
719 					show1cell(j, i);
720 				}
721 			}
722 		showplayer();
723 		return;
724 
725 	case 20:
726 		c[HP] = c[HPMAX];
727 		break;		/* instant healing */
728 
729 	case 1:
730 		lprcat("\nYou feel better");
731 		if (c[HP] == c[HPMAX])
732 			raisemhp(1);
733 		else if ((c[HP] += rnd(20) + 20 + c[LEVEL]) > c[HPMAX])
734 			c[HP] = c[HPMAX];
735 		break;
736 
737 	case 2:
738 		lprcat("\nSuddenly, you feel much more skillful!");
739 		raiselevel();
740 		raisemhp(1);
741 		return;
742 
743 	case 3:
744 		lprcat("\nYou feel strange for a moment");
745 		c[rund(6)]++;
746 		break;
747 
748 	case 4:
749 		lprcat("\nYou feel more self confident!");
750 		c[WISDOM] += rnd(2);
751 		break;
752 
753 	case 5:
754 		lprcat("\nWow!  You feel great!");
755 		if (c[STRENGTH] < 12)
756 			c[STRENGTH] = 12;
757 		else
758 			c[STRENGTH]++;
759 		break;
760 
761 	case 6:
762 		lprcat("\nYour charm went up by one!");
763 		c[CHARISMA]++;
764 		break;
765 
766 	case 8:
767 		lprcat("\nYour intelligence went up by one!");
768 		c[INTELLIGENCE]++;
769 		break;
770 
771 	case 10:
772 		for (i = 0; i < MAXY; i++)
773 			for (j = 0; j < MAXX; j++)
774 				if (mitem[j][i]) {
775 					know[j][i] = 1;
776 					show1cell(j, i);
777 				}
778 		 /* monster detection	 */ return;
779 
780 	case 12:
781 		lprcat("\nThis potion has no taste to it");
782 		return;
783 
784 	case 15:
785 		lprcat("\nWOW!!!  You feel Super-fantastic!!!");
786 		if (c[HERO] == 0)
787 			for (i = 0; i < 6; i++)
788 				c[i] += 11;
789 		c[HERO] += 250;
790 		break;
791 
792 	case 16:
793 		lprcat("\nYou have a greater intestinal constitude!");
794 		c[CONSTITUTION]++;
795 		break;
796 
797 	case 17:
798 		lprcat("\nYou now have incredibly bulging muscles!!!");
799 		if (c[GIANTSTR] == 0)
800 			c[STREXTRA] += 21;
801 		c[GIANTSTR] += 700;
802 		break;
803 
804 	case 18:
805 		lprcat("\nYou feel a chill run up your spine!");
806 		c[FIRERESISTANCE] += 1000;
807 		break;
808 
809 	case 0:
810 		lprcat("\nYou fall asleep. . .");
811 		i = rnd(11) - (c[CONSTITUTION] >> 2) + 2;
812 		while (--i > 0) {
813 			parse2();
814 			nap(1000);
815 		}
816 		cursors();
817 		lprcat("\nYou woke up!");
818 		return;
819 
820 	case 7:
821 		lprcat("\nYou become dizzy!");
822 		if (--c[STRENGTH] < 3)
823 			c[STRENGTH] = 3;
824 		break;
825 
826 	case 11:
827 		lprcat("\nYou stagger for a moment . .");
828 		for (i = 0; i < MAXY; i++)
829 			for (j = 0; j < MAXX; j++)
830 				know[j][i] = 0;
831 		nap(2000);
832 		draws(0, MAXX, 0, MAXY);	/* potion of forgetfulness */
833 		return;
834 
835 	case 13:
836 		lprcat("\nYou can't see anything!");	/* blindness */
837 		c[BLINDCOUNT] += 500;
838 		return;
839 
840 	case 14:
841 		lprcat("\nYou feel confused");
842 		c[CONFUSE] += 20 + rnd(9);
843 		return;
844 
845 	case 21:
846 		lprcat("\nYou don't seem to be affected");
847 		return;		/* cure dianthroritis */
848 
849 	case 22:
850 		lprcat("\nYou feel a sickness engulf you");	/* poison */
851 		c[HALFDAM] += 200 + rnd(200);
852 		return;
853 
854 	case 23:
855 		lprcat("\nYou feel your vision sharpen");	/* see invisible */
856 		c[SEEINVISIBLE] += rnd(1000) + 400;
857 		monstnamelist[INVISIBLESTALKER] = 'I';
858 		return;
859 	};
860 	bottomline();		/* show new stats		 */
861 	return;
862 }
863 
864 
865 /*
866 	function to process a magic scroll
867  */
868 static void
869 oscroll(typ)
870 	int             typ;
871 {
872 	lprcat("\nDo you ");
873 	if (c[BLINDCOUNT] == 0)
874 		lprcat("(r) read it, ");
875 	lprcat("(t) take it");
876 	iopts();
877 	while (1)
878 		switch (ttgetch()) {
879 		case '\33':
880 		case 'i':
881 			ignore();
882 			return;
883 
884 		case 'r':
885 			if (c[BLINDCOUNT])
886 				break;
887 			lprcat("read");
888 			forget();
889 			if (typ == 2 || typ == 15) {
890 				show1cell(playerx, playery);
891 				cursors();
892 			}
893 			 /* destroy it	 */ read_scroll(typ);
894 			return;
895 
896 		case 't':
897 			lprcat("take");
898 			if (take(OSCROLL, typ) == 0)
899 				forget();	/* destroy it	 */
900 			return;
901 		};
902 }
903 
904 /*
905 	data for the function to read a scroll
906  */
907 static int      xh, yh, yl, xl;
908 static u_char     curse[] = {
909 	BLINDCOUNT, CONFUSE, AGGRAVATE, HASTEMONST, ITCHING,
910 	LAUGHING, DRAINSTRENGTH, CLUMSINESS, INFEEBLEMENT, HALFDAM
911 };
912 
913 static u_char     exten[] = {
914 	PROTECTIONTIME, DEXCOUNT, STRCOUNT, CHARMCOUNT, INVISIBILITY,
915 	CANCELLATION, HASTESELF, GLOBE, SCAREMONST, HOLDMONST, TIMESTOP
916 };
917 
918 static u_char time_change[] = {
919 	HASTESELF, HERO, ALTPRO, PROTECTIONTIME, DEXCOUNT, STRCOUNT,
920 	GIANTSTR, CHARMCOUNT, INVISIBILITY, CANCELLATION, HASTESELF,
921 	AGGRAVATE, SCAREMONST, STEALTH, AWARENESS, HOLDMONST,
922 	HASTEMONST, FIRERESISTANCE, GLOBE, SPIRITPRO, UNDEADPRO,
923 	HALFDAM, SEEINVISIBLE, ITCHING, CLUMSINESS, WTW
924 };
925 
926 /*
927  *	function to adjust time when time warping and taking courses in school
928  */
929 void
930 adjusttime(tim)
931 	long   tim;
932 {
933 	int    j;
934 	for (j = 0; j < 26; j++)/* adjust time related parameters */
935 		if (c[time_change[j]])
936 			if ((c[time_change[j]] -= tim) < 1)
937 				c[time_change[j]] = 1;
938 	regen();
939 }
940 
941 /*
942 	function to read a scroll
943  */
944 void
945 read_scroll(typ)
946 	int             typ;
947 {
948 	int    i, j;
949 	if (typ < 0 || typ >= MAXSCROLL)
950 		return;		/* be sure we are within bounds */
951 	scrollname[typ] = scrollhide[typ];
952 	switch (typ) {
953 	case 0:
954 		lprcat("\nYour armor glows for a moment");
955 		enchantarmor();
956 		return;
957 
958 	case 1:
959 		lprcat("\nYour weapon glows for a moment");
960 		enchweapon();
961 		return;		/* enchant weapon */
962 
963 	case 2:
964 		lprcat("\nYou have been granted enlightenment!");
965 		yh = min(playery + 7, MAXY);
966 		xh = min(playerx + 25, MAXX);
967 		yl = max(playery - 7, 0);
968 		xl = max(playerx - 25, 0);
969 		for (i = yl; i < yh; i++)
970 			for (j = xl; j < xh; j++)
971 				know[j][i] = 1;
972 		nap(2000);
973 		draws(xl, xh, yl, yh);
974 		return;
975 
976 	case 3:
977 		lprcat("\nThis scroll seems to be blank");
978 		return;
979 
980 	case 4:
981 		createmonster(makemonst(level + 1));
982 		return;		/* this one creates a monster  */
983 
984 	case 5:
985 		something(level);	/* create artifact		 */
986 		return;
987 
988 	case 6:
989 		c[AGGRAVATE] += 800;
990 		return;		/* aggravate monsters */
991 
992 	case 7:
993 		gltime += (i = rnd(1000) - 850);	/* time warp */
994 		if (i >= 0)
995 			lprintf("\nYou went forward in time by %ld mobuls", (long) ((i + 99) / 100));
996 		else
997 			lprintf("\nYou went backward in time by %ld mobuls", (long) (-(i + 99) / 100));
998 		adjusttime((long) i);	/* adjust time for time warping */
999 		return;
1000 
1001 	case 8:
1002 		oteleport(0);
1003 		return;		/* teleportation */
1004 
1005 	case 9:
1006 		c[AWARENESS] += 1800;
1007 		return;		/* expanded awareness	 */
1008 
1009 	case 10:
1010 		c[HASTEMONST] += rnd(55) + 12;
1011 		return;		/* haste monster */
1012 
1013 	case 11:
1014 		for (i = 0; i < MAXY; i++)
1015 			for (j = 0; j < MAXX; j++)
1016 				if (mitem[j][i])
1017 					hitp[j][i] = monster[mitem[j][i]].hitpoints;
1018 		return;		/* monster healing */
1019 	case 12:
1020 		c[SPIRITPRO] += 300 + rnd(200);
1021 		bottomline();
1022 		return;		/* spirit protection */
1023 
1024 	case 13:
1025 		c[UNDEADPRO] += 300 + rnd(200);
1026 		bottomline();
1027 		return;		/* undead protection */
1028 
1029 	case 14:
1030 		c[STEALTH] += 250 + rnd(250);
1031 		bottomline();
1032 		return;		/* stealth */
1033 
1034 	case 15:
1035 		lprcat("\nYou have been granted enlightenment!");	/* magic mapping */
1036 		for (i = 0; i < MAXY; i++)
1037 			for (j = 0; j < MAXX; j++)
1038 				know[j][i] = 1;
1039 		nap(2000);
1040 		draws(0, MAXX, 0, MAXY);
1041 		return;
1042 
1043 	case 16:
1044 		c[HOLDMONST] += 30;
1045 		bottomline();
1046 		return;		/* hold monster */
1047 
1048 	case 17:
1049 		for (i = 0; i < 26; i++)	/* gem perfection */
1050 			switch (iven[i]) {
1051 			case ODIAMOND:
1052 			case ORUBY:
1053 			case OEMERALD:
1054 			case OSAPPHIRE:
1055 				j = ivenarg[i];
1056 				j &= 255;
1057 				j <<= 1;
1058 				if (j > 255)
1059 					j = 255;	/* double value */
1060 				ivenarg[i] = j;
1061 				break;
1062 			}
1063 		break;
1064 
1065 	case 18:
1066 		for (i = 0; i < 11; i++)
1067 			c[exten[i]] <<= 1;	/* spell extension */
1068 		break;
1069 
1070 	case 19:
1071 		for (i = 0; i < 26; i++) {	/* identify */
1072 			if (iven[i] == OPOTION)
1073 				potionname[ivenarg[i]] = potionhide[ivenarg[i]];
1074 			if (iven[i] == OSCROLL)
1075 				scrollname[ivenarg[i]] = scrollhide[ivenarg[i]];
1076 		}
1077 		break;
1078 
1079 	case 20:
1080 		for (i = 0; i < 10; i++)	/* remove curse */
1081 			if (c[curse[i]])
1082 				c[curse[i]] = 1;
1083 		break;
1084 
1085 	case 21:
1086 		annihilate();
1087 		break;		/* scroll of annihilation */
1088 
1089 	case 22:
1090 		godirect(22, 150, "The ray hits the %s", 0, ' ');	/* pulverization */
1091 		break;
1092 	case 23:
1093 		c[LIFEPROT]++;
1094 		break;		/* life protection */
1095 	};
1096 }
1097 
1098 
1099 
1100 static void
1101 oorb()
1102 {
1103 }
1104 
1105 static void
1106 opit()
1107 {
1108 	int    i;
1109 	if (rnd(101) < 81) {
1110 		if (rnd(70) > 9 * c[DEXTERITY] - packweight() || rnd(101) < 5) {
1111 			if (level == MAXLEVEL - 1)
1112 				obottomless();
1113 			else if (level == MAXLEVEL + MAXVLEVEL - 1)
1114 				obottomless();
1115 			else {
1116 				if (rnd(101) < 20) {
1117 					i = 0;
1118 					lprcat("\nYou fell into a pit!  Your fall is cushioned by an unknown force\n");
1119 				} else {
1120 					i = rnd(level * 3 + 3);
1121 					lprintf("\nYou fell into a pit!  You suffer %ld hit points damage", (long) i);
1122 					lastnum = 261;	/* if he dies scoreboard
1123 							 * will say so */
1124 				}
1125 				losehp(i);
1126 				nap(2000);
1127 				newcavelevel(level + 1);
1128 				draws(0, MAXX, 0, MAXY);
1129 			}
1130 		}
1131 	}
1132 }
1133 
1134 static void
1135 obottomless()
1136 {
1137 	lprcat("\nYou fell into a bottomless pit!");
1138 	beep();
1139 	nap(3000);
1140 	died(262);
1141 }
1142 
1143 static void
1144 oelevator(dir)
1145 	int             dir;
1146 {
1147 #ifdef lint
1148 	int             x;
1149 	x = dir;
1150 	dir = x;
1151 #endif	/* lint */
1152 }
1153 
1154 static void
1155 ostatue()
1156 {
1157 }
1158 
1159 static void
1160 omirror()
1161 {
1162 }
1163 
1164 static void
1165 obook()
1166 {
1167 	lprcat("\nDo you ");
1168 	if (c[BLINDCOUNT] == 0)
1169 		lprcat("(r) read it, ");
1170 	lprcat("(t) take it");
1171 	iopts();
1172 	while (1)
1173 		switch (ttgetch()) {
1174 		case '\33':
1175 		case 'i':
1176 			ignore();
1177 			return;
1178 
1179 		case 'r':
1180 			if (c[BLINDCOUNT])
1181 				break;
1182 			lprcat("read");
1183 			 /* no more book	 */ readbook(iarg[playerx][playery]);
1184 			forget();
1185 			return;
1186 
1187 		case 't':
1188 			lprcat("take");
1189 			if (take(OBOOK, iarg[playerx][playery]) == 0)
1190 				forget();	/* no more book	 */
1191 			return;
1192 		};
1193 }
1194 
1195 /*
1196 	function to read a book
1197  */
1198 void
1199 readbook(lev)
1200 	int    lev;
1201 {
1202 	int    i, tmp;
1203 	if (lev <= 3)
1204 		i = rund((tmp = splev[lev]) ? tmp : 1);
1205 	else
1206 		i = rnd((tmp = splev[lev] - 9) ? tmp : 1) + 9;
1207 	spelknow[i] = 1;
1208 	lprintf("\nSpell \"%s\":  %s\n%s", spelcode[i], spelname[i], speldescript[i]);
1209 	if (rnd(10) == 4) {
1210 		lprcat("\nYour int went up by one!");
1211 		c[INTELLIGENCE]++;
1212 		bottomline();
1213 	}
1214 }
1215 
1216 static void
1217 ocookie(void)
1218 {
1219 	const char *p;
1220 
1221 	lprcat("\nDo you (e) eat it, (t) take it");
1222 	iopts();
1223 	while (1)
1224 		switch (ttgetch()) {
1225 		case '\33':
1226 		case 'i':
1227 			ignore();
1228 			return;
1229 
1230 		case 'e':
1231 			lprcat("eat\nThe cookie tasted good.");
1232 			forget();	/* no more cookie	 */
1233 			if (c[BLINDCOUNT])
1234 				return;
1235 			if (!(p = fortune()))
1236 				return;
1237 			lprcat("  A message inside the cookie reads:\n");
1238 			lprcat(p);
1239 			return;
1240 
1241 		case 't':
1242 			lprcat("take");
1243 			if (take(OCOOKIE, 0) == 0)
1244 				forget();	/* no more book	 */
1245 			return;
1246 		};
1247 }
1248 
1249 
1250 /*
1251  * routine to pick up some gold -- if arg==OMAXGOLD then the pile is worth
1252  * 100* the argument
1253  */
1254 static void
1255 ogold(arg)
1256 	int             arg;
1257 {
1258 	long   i;
1259 	i = iarg[playerx][playery];
1260 	if (arg == OMAXGOLD)
1261 		i *= 100;
1262 	else if (arg == OKGOLD)
1263 		i *= 1000;
1264 	else if (arg == ODGOLD)
1265 		i *= 10;
1266 	lprintf("\nIt is worth %ld!", (long) i);
1267 	c[GOLD] += i;
1268 	bottomgold();
1269 	item[playerx][playery] = know[playerx][playery] = 0;	/* destroy gold	 */
1270 }
1271 
1272 static void
1273 ohome()
1274 {
1275 	int    i;
1276 	nosignal = 1;		/* disable signals */
1277 	for (i = 0; i < 26; i++)
1278 		if (iven[i] == OPOTION)
1279 			if (ivenarg[i] == 21) {
1280 				iven[i] = 0;	/* remove the potion of cure
1281 						 * dianthroritis from
1282 						 * inventory */
1283 				clear();
1284 				lprcat("Congratulations.  You found a potion of cure dianthroritis.\n");
1285 				lprcat("\nFrankly, No one thought you could do it.  Boy!  Did you surprise them!\n");
1286 				if (gltime > TIMELIMIT) {
1287 					lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
1288 					lprcat("You didn't make it in time.  In your agony, you kill the doctor,\nyour wife, and yourself!  Too bad!\n");
1289 					nap(5000);
1290 					died(269);
1291 				} else {
1292 					lprcat("\nThe doctor is now administering the potion, and in a few moments\n");
1293 					lprcat("Your daughter should be well on her way to recovery.\n");
1294 					nap(6000);
1295 					lprcat("\nThe potion is");
1296 					nap(3000);
1297 					lprcat(" working!  The doctor thinks that\n");
1298 					lprcat("your daughter will recover in a few days.  Congratulations!\n");
1299 					beep();
1300 					nap(5000);
1301 					died(263);
1302 				}
1303 			}
1304 	while (1) {
1305 		clear();
1306 		lprintf("Welcome home %s.  Latest word from the doctor is not good.\n", logname);
1307 
1308 		if (gltime > TIMELIMIT) {
1309 			lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
1310 			lprcat("You didn't make it in time.  In your agony, you kill the doctor,\nyour wife, and yourself!  Too bad!\n");
1311 			nap(5000);
1312 			died(269);
1313 		}
1314 		lprcat("\nThe diagnosis is confirmed as dianthroritis.  He guesses that\n");
1315 		lprintf("your daughter has only %ld mobuls left in this world.  It's up to you,\n", (long) ((TIMELIMIT - gltime + 99) / 100));
1316 		lprintf("%s, to find the only hope for your daughter, the very rare\n", logname);
1317 		lprcat("potion of cure dianthroritis.  It is rumored that only deep in the\n");
1318 		lprcat("depths of the caves can this potion be found.\n\n\n");
1319 		lprcat("\n     ----- press ");
1320 		standout("return");
1321 		lprcat(" to continue, ");
1322 		standout("escape");
1323 		lprcat(" to leave ----- ");
1324 		i = ttgetch();
1325 		while (i != '\33' && i != '\n')
1326 			i = ttgetch();
1327 		if (i == '\33') {
1328 			drawscreen();
1329 			nosignal = 0;	/* enable signals */
1330 			return;
1331 		}
1332 	}
1333 }
1334 
1335 /* routine to save program space	 */
1336 void
1337 iopts()
1338 {
1339 	lprcat(", or (i) ignore it? ");
1340 }
1341 
1342 void
1343 ignore()
1344 {
1345 	lprcat("ignore\n");
1346 }
1347