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