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