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