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