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