xref: /dragonfly/games/larn/object.c (revision f02303f9)
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 	***************
23 	LOOK_FOR_OBJECT
24 	***************
25 
26 	subroutine to look for an object and give the player his options
27 	if an object was found.
28  */
29 void
30 lookforobject(void)
31 {
32 int i,j;
33 if (c[TIMESTOP])  return;	/* can't find objects is time is stopped	*/
34 i=item[playerx][playery];	if (i==0) return;
35 showcell(playerx,playery);  cursors();  yrepcount=0;
36 switch(i)
37 	{
38 	case OGOLDPILE:	case OMAXGOLD:
39 	case OKGOLD:	case ODGOLD:	lprcat("\n\nYou have found some gold!");	ogold(i);	break;
40 
41 	case OPOTION:	lprcat("\n\nYou have found a magic potion");
42 				i = iarg[playerx][playery];
43 				if (potionname[i][0]) lprintf(" of %s",potionname[i]);  opotion(i);  break;
44 
45 	case OSCROLL:	lprcat("\n\nYou have found a magic scroll");
46 				i = iarg[playerx][playery];
47 				if (scrollname[i][0])	lprintf(" of %s",scrollname[i]);
48 				oscroll(i);  break;
49 
50 	case OALTAR:	if (nearbymonst()) return;
51 					lprcat("\n\nThere is a Holy Altar here!"); oaltar(); break;
52 
53 	case OBOOK:	lprcat("\n\nYou have found a book."); obook(); break;
54 
55 	case OCOOKIE:	lprcat("\n\nYou have found a fortune cookie."); ocookie(); break;
56 
57 	case OTHRONE:	if (nearbymonst()) return;
58 					lprintf("\n\nThere is %s here!",objectname[i]); othrone(0); break;
59 
60 	case OTHRONE2:	if (nearbymonst()) return;
61 					lprintf("\n\nThere is %s here!",objectname[i]); othrone(1); break;
62 
63 	case ODEADTHRONE: lprintf("\n\nThere is %s here!",objectname[i]); odeadthrone(); break;
64 
65 	case OORB:		lprcat("\n\nYou have found the Orb!!!!!"); oorb(); break;
66 
67 	case OPIT:		lprcat("\n\nYou're standing at the top of a pit."); opit(); break;
68 
69 	case OSTAIRSUP:		lprcat("\n\nThere is a circular staircase here"); ostairs(1);  /* up */ break;
70 
71 	case OELEVATORUP:	lprcat("\n\nYou feel heavy for a moment, but the feeling disappears");
72 				oelevator(1);  /*  up  */  break;
73 
74 	case OFOUNTAIN:	if (nearbymonst()) return;
75 					lprcat("\n\nThere is a fountain here"); ofountain(); break;
76 
77 	case OSTATUE:	if (nearbymonst()) return;
78 					lprcat("\n\nYou are standing in front of a statue"); ostatue(); break;
79 
80 	case OCHEST:	lprcat("\n\nThere is a chest here");  ochest();  break;
81 
82 	case OIVTELETRAP:	if (rnd(11)<6) return;
83 						item[playerx][playery] = OTELEPORTER;
84 						know[playerx][playery] = 1;
85 
86 	case OTELEPORTER:	lprcat("\nZaaaappp!  You've been teleported!\n");
87 						beep(); nap(3000); oteleport(0);
88 						break;
89 
90 	case OSCHOOL:	if (nearbymonst()) return;
91 				lprcat("\n\nYou have found the College of Larn.");
92 				lprcat("\nDo you (g) go inside, or (i) stay here? ");
93 				i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchr();
94 				if (i == 'g') { oschool();  /*	the college of larn	*/ }
95 				else	lprcat(" stay here");
96 				break;
97 
98 	case OMIRROR:	if (nearbymonst()) return;
99 					lprcat("\n\nThere is a mirror here");	omirror();	break;
100 
101 	case OBANK2:
102 	case OBANK:	if (nearbymonst()) return;
103 				if (i==OBANK) lprcat("\n\nYou have found the bank of Larn.");
104 				else lprcat("\n\nYou have found a branch office of the bank of Larn.");
105 				lprcat("\nDo you (g) go inside, or (i) stay here? ");
106 				j=0; while ((j!='g') && (j!='i') && (j!='\33')) j=getchr();
107 				if (j == 'g') {  if (i==OBANK) obank(); else obank2(); /*  the bank of larn  */  }
108 				else   lprcat(" stay here");
109 				break;
110 
111 	case ODEADFOUNTAIN:	if (nearbymonst()) return;
112 						lprcat("\n\nThere is a dead fountain here"); break;
113 
114 	case ODNDSTORE:	if (nearbymonst()) return;
115 					lprcat("\n\nThere is a DND store here.");
116 					lprcat("\nDo you (g) go inside, or (i) stay here? ");
117 					i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchr();
118 					if (i == 'g')
119 						dndstore();  /*  the dnd adventurers store  */
120 					else  lprcat(" stay here");
121 					break;
122 
123 	case OSTAIRSDOWN:	lprcat("\n\nThere is a circular staircase here"); ostairs(-1); /* down */ break;
124 
125 	case OELEVATORDOWN:	lprcat("\n\nYou feel light for a moment, but the feeling disappears");
126 				oelevator(-1);	/*	down	*/
127 				break;
128 
129 	case OOPENDOOR:		lprintf("\n\nYou have found %s",objectname[i]);
130 						lprcat("\nDo you (c) close it"); iopts();
131 						i=0; while ((i!='c') && (i!='i') && (i!='\33')) i=getchr();
132 						if ((i=='\33') || (i=='i')) { ignore();  break; }
133 						lprcat("close");  forget();
134 						item[playerx][playery]=OCLOSEDDOOR;
135 						iarg[playerx][playery]=0;
136 						playerx = lastpx;  playery = lastpy;
137 						break;
138 
139 	case OCLOSEDDOOR:	lprintf("\n\nYou have found %s",objectname[i]);
140 						lprcat("\nDo you (o) try to open it"); iopts();
141 						i=0; while ((i!='o') && (i!='i') && (i!='\33')) i=getchr();
142 						if ((i=='\33') || (i=='i'))
143 							{ ignore();  playerx = lastpx;
144 							playery = lastpy; break; }
145 						else
146 						{
147 						lprcat("open");
148 						if (rnd(11)<7)
149 						  {
150 						  switch(iarg[playerx][playery])
151 							{
152 							case 6: c[AGGRAVATE] += rnd(400);	break;
153 
154 							case 7:	lprcat("\nYou are jolted by an electric shock ");
155 									lastnum=274; losehp(rnd(20));  bottomline();  break;
156 
157 							case 8:	loselevel();  break;
158 
159 							case 9:	lprcat("\nYou suddenly feel weaker ");
160 									if (c[STRENGTH]>3) c[STRENGTH]--;
161 									bottomline();  break;
162 
163 							default:	break;
164 							}
165 						  playerx = lastpx;  playery = lastpy;
166 						  }
167 						else
168 						  {
169 						  forget();  item[playerx][playery]=OOPENDOOR;
170 						  }
171 						}
172 						break;
173 
174 	case OENTRANCE:	lprcat("\nYou have found "); lprcat(objectname[OENTRANCE]);
175 					lprcat("\nDo you (g) go inside"); iopts();
176 					i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchr();
177 					if (i == 'g')
178 						{
179 						newcavelevel(1); playerx=33; playery=MAXY-2;
180 						item[33][MAXY-1]=know[33][MAXY-1]=mitem[33][MAXY-1]=0;
181 						draws(0,MAXX,0,MAXY); bot_linex(); return;
182 						}
183 					else   ignore();
184 					break;
185 
186 	case OVOLDOWN:	lprcat("\nYou have found "); lprcat(objectname[OVOLDOWN]);
187 						lprcat("\nDo you (c) climb down"); iopts();
188 						i=0; while ((i!='c') && (i!='i') && (i!='\33')) i=getchr();
189 						if ((i=='\33') || (i=='i')) { ignore();  break; }
190 					if (level!=0) { lprcat("\nThe shaft only extends 5 feet downward!"); return; }
191 					if (packweight() > 45+3*(c[STRENGTH]+c[STREXTRA])) { lprcat("\nYou slip and fall down the shaft"); beep();
192 											  lastnum=275;  losehp(30+rnd(20)); bottomhp(); }
193 
194 					else lprcat("climb down");  nap(3000);  newcavelevel(MAXLEVEL);
195 					for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++) /* put player near volcano shaft */
196 						if (item[j][i]==OVOLUP) { playerx=j; playery=i; j=MAXX; i=MAXY; positionplayer(); }
197 					draws(0,MAXX,0,MAXY); bot_linex(); return;
198 
199 	case OVOLUP:	lprcat("\nYou have found "); lprcat(objectname[OVOLUP]);
200 						lprcat("\nDo you (c) climb up"); iopts();
201 						i=0; while ((i!='c') && (i!='i') && (i!='\33')) i=getchr();
202 						if ((i=='\33') || (i=='i')) { ignore();  break; }
203 					if (level!=11) { lprcat("\nThe shaft only extends 8 feet upwards before you find a blockage!"); return; }
204 					if (packweight() > 45+5*(c[STRENGTH]+c[STREXTRA])) { lprcat("\nYou slip and fall down the shaft"); beep();
205 											  lastnum=275; losehp(15+rnd(20)); bottomhp(); return; }
206 					lprcat("climb up"); lflush(); nap(3000); newcavelevel(0);
207 					for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++) /* put player near volcano shaft */
208 						if (item[j][i]==OVOLDOWN) { playerx=j; playery=i; j=MAXX; i=MAXY; positionplayer(); }
209 					draws(0,MAXX,0,MAXY); bot_linex(); return;
210 
211 	case OTRAPARROWIV:	if (rnd(17)<13) return;	/* for an arrow trap */
212 						item[playerx][playery] = OTRAPARROW;
213 						know[playerx][playery] = 0;
214 
215 	case OTRAPARROW:	lprcat("\nYou are hit by an arrow"); beep();	/* for an arrow trap */
216 						lastnum=259;	losehp(rnd(10)+level);
217 						bottomhp();	return;
218 
219 	case OIVDARTRAP:	if (rnd(17)<13) return;		/* for a dart trap */
220 						item[playerx][playery] = ODARTRAP;
221 						know[playerx][playery] = 0;
222 
223 	case ODARTRAP:		lprcat("\nYou are hit by a dart"); beep();	/* for a dart trap */
224 						lastnum=260;	losehp(rnd(5));
225 						if ((--c[STRENGTH]) < 3) c[STRENGTH] = 3;
226 						bottomline();	return;
227 
228 	case OIVTRAPDOOR:	if (rnd(17)<13) return;		/* for a trap door */
229 						item[playerx][playery] = OTRAPDOOR;
230 						know[playerx][playery] = 1;
231 
232 	case OTRAPDOOR:		lastnum = 272; /* a trap door */
233 						if ((level==MAXLEVEL-1) || (level==MAXLEVEL+MAXVLEVEL-1))
234 							{ lprcat("\nYou fell through a bottomless trap door!"); beep();  nap(3000);  died(271); }
235 						lprcat("\nYou fall through a trap door!"); beep();	/* for a trap door */
236 						losehp(rnd(5+level));
237 						nap(2000);  newcavelevel(level+1);  draws(0,MAXX,0,MAXY); bot_linex();
238 						return;
239 
240 
241 	case OTRADEPOST:	if (nearbymonst()) return;
242 				lprcat("\nYou have found the Larn trading Post.");
243 				lprcat("\nDo you (g) go inside, or (i) stay here? ");
244 				i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchr();
245 				if (i == 'g')  otradepost();  else  lprcat("stay here");
246 				return;
247 
248 	case OHOME:	if (nearbymonst()) return;
249 				lprcat("\nYou have found your way home.");
250 				lprcat("\nDo you (g) go inside, or (i) stay here? ");
251 				i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchr();
252 				if (i == 'g')  ohome();  else  lprcat("stay here");
253 				return;
254 
255 	case OWALL:	break;
256 
257 	case OANNIHILATION:	died(283); return; 	/* annihilated by sphere of annihilation */
258 
259 	case OLRS:	if (nearbymonst()) return;
260 				lprcat("\n\nThere is an LRS office here.");
261 				lprcat("\nDo you (g) go inside, or (i) stay here? ");
262 				i=0; while ((i!='g') && (i!='i') && (i!='\33')) i=getchr();
263 				if (i == 'g')
264 					olrs();  /*  the larn revenue service */
265 				else  lprcat(" stay here");
266 				break;
267 
268 	default:	finditem(i); break;
269 	};
270 }
271 
272 /*
273 	function to say what object we found and ask if player wants to take it
274  */
275 static void
276 finditem(int obj)
277 	{
278 	int tmp,i;
279 	lprintf("\n\nYou have found %s ",objectname[obj]);
280 	tmp=iarg[playerx][playery];
281 	switch(obj)
282 		{
283 		case ODIAMOND:		case ORUBY:			case OEMERALD:
284 		case OSAPPHIRE:		case OSPIRITSCARAB:	case OORBOFDRAGON:
285 		case OCUBEofUNDEAD:	case ONOTHEFT:	break;
286 
287 		default:
288 		if (tmp>0) lprintf("+ %d",(long)tmp); else if (tmp<0) lprintf(" %d",(long)tmp);
289 		}
290 	lprcat("\nDo you want to (t) take it"); iopts();
291 	i=0; while (i!='t' && i!='i' && i!='\33') i=getchr();
292 	if (i == 't')
293 		{	lprcat("take");  if (take(obj,tmp)==0)  forget();	return;	}
294 	ignore();
295 	}
296 
297 
298 /*
299 	*******
300 	OSTAIRS
301 	*******
302 
303 	subroutine to process the stair cases
304 	if dir > 0 the up else down
305  */
306 static void
307 ostairs(int dir)
308 	{
309 	int k;
310 	lprcat("\nDo you (s) stay here  ");
311 	if (dir > 0)	lprcat("(u) go up  ");	else	lprcat("(d) go down  ");
312 	lprcat("or (f) kick stairs? ");
313 
314 	while (1) switch(getchr())
315 		{
316 		case '\33':
317 		case 's':	case 'i':	lprcat("stay here");	return;
318 
319 		case 'f':	lprcat("kick stairs");
320 					if (rnd(2) == 1)
321 						lprcat("\nI hope you feel better.  Showing anger rids you of frustration.");
322 					else
323 						{
324 						k=rnd((level+1)<<1);
325 						lprintf("\nYou hurt your foot dumb dumb!  You suffer %d hit points",(long)k);
326 						lastnum=276;  losehp(k);  bottomline();
327 						}
328 					return;
329 
330 		case 'u':	lprcat("go up");
331 					if (dir < 0)	lprcat("\nThe stairs don't go up!");
332 					else
333 					  if (level>=2 && level!=11)
334 						{
335 						k = level;  newcavelevel(level-1);
336 						draws(0,MAXX,0,MAXY); bot_linex();
337 						}
338 					  else lprcat("\nThe stairs lead to a dead end!");
339 					return;
340 
341 		case 'd':	lprcat("go down");
342 					if (dir > 0)	lprcat("\nThe stairs don't go down!");
343 					else
344 					  if (level!=0 && level!=10 && level!=13)
345 						{
346 						k = level;  newcavelevel(level+1);
347 						draws(0,MAXX,0,MAXY); bot_linex();
348 						}
349 					  else lprcat("\nThe stairs lead to a dead end!");
350 					return;
351 		};
352 	}
353 
354 
355 /*
356 	*********
357 	OTELEPORTER
358 	*********
359 
360 	subroutine to handle a teleport trap +/- 1 level maximum
361  */
362 void
363 oteleport(int err)
364 	{
365 	int tmp;
366 	if (err) if (rnd(151)<3)  died(264);  /*	stuck in a rock */
367 	c[TELEFLAG]=1;	/*	show ?? on bottomline if been teleported	*/
368 	if (level==0) tmp=0;
369 	else if (level < MAXLEVEL)
370 		{ tmp=rnd(5)+level-3; if (tmp>=MAXLEVEL) tmp=MAXLEVEL-1;
371 			if (tmp<1) tmp=1; }
372 	else
373 		{ tmp=rnd(3)+level-2; if (tmp>=MAXLEVEL+MAXVLEVEL) tmp=MAXLEVEL+MAXVLEVEL-1;
374 			if (tmp<MAXLEVEL) tmp=MAXLEVEL; }
375 	playerx = rnd(MAXX-2);	playery = rnd(MAXY-2);
376 	if (level != tmp)	newcavelevel(tmp);  positionplayer();
377 	draws(0,MAXX,0,MAXY); bot_linex();
378 	}
379 
380 /*
381 	*******
382 	OPOTION
383 	*******
384 
385 	function to process a potion
386  */
387 static void
388 opotion(int pot)
389 	{
390 	lprcat("\nDo you (d) drink it, (t) take it"); iopts();
391 	while (1) switch(getchr())
392 		{
393 		case '\33':
394 		case 'i':	ignore();  return;
395 
396 		case 'd':	lprcat("drink\n");	forget();	/*	destroy potion	*/
397 					quaffpotion(pot);		return;
398 
399 		case 't':	lprcat("take\n");	if (take(OPOTION,pot)==0)  forget();
400 					return;
401 		};
402 	}
403 
404 /*
405 	function to drink a potion
406  */
407 void
408 quaffpotion(int pot)
409 	{
410 	int i,j,k;
411 	if (pot<0 || pot>=MAXPOTION) return; /* check for within bounds */
412 	potionname[pot] = potionhide[pot];
413 	switch(pot)
414 		{
415 		case 9: lprcat("\nYou feel greedy . . .");   nap(2000);
416 				for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)
417 				  if ((item[j][i]==OGOLDPILE) || (item[j][i]==OMAXGOLD))
418 					{
419 					know[j][i]=1; show1cell(j,i);
420 					}
421 				showplayer();  return;
422 
423 		case 19: lprcat("\nYou feel greedy . . .");   nap(2000);
424 				for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)
425 					{
426 					k=item[j][i];
427 					if ((k==ODIAMOND) || (k==ORUBY) || (k==OEMERALD) || (k==OMAXGOLD)
428 						 || (k==OSAPPHIRE) || (k==OLARNEYE) || (k==OGOLDPILE))
429 						 {
430 						 know[j][i]=1; show1cell(j,i);
431 						 }
432 					}
433 				showplayer();  return;
434 
435 		case 20: c[HP] = c[HPMAX]; break;	/* instant healing */
436 
437 		case 1:	lprcat("\nYou feel better");
438 				if (c[HP] == c[HPMAX])  raisemhp(1);
439 				else if ((c[HP] += rnd(20)+20+c[LEVEL]) > c[HPMAX]) c[HP]=c[HPMAX];  break;
440 
441 		case 2:	lprcat("\nSuddenly, you feel much more skillful!");
442 				raiselevel();  raisemhp(1); return;
443 
444 		case 3:	lprcat("\nYou feel strange for a moment");
445 				c[rund(6)]++;  break;
446 
447 		case 4:	lprcat("\nYou feel more self confident!");
448 				c[WISDOM] += rnd(2);  break;
449 
450 		case 5:	lprcat("\nWow!  You feel great!");
451 				if (c[STRENGTH]<12) c[STRENGTH]=12; else c[STRENGTH]++;  break;
452 
453 		case 6:	lprcat("\nYour charm went up by one!");  c[CHARISMA]++;  break;
454 
455 		case 8:	lprcat("\nYour intelligence went up by one!");
456 				c[INTELLIGENCE]++;  break;
457 
458 		case 10: for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)
459 				   if (mitem[j][i])
460 					{
461 					know[j][i]=1; show1cell(j,i);
462 					}
463 				 /*	monster detection	*/  return;
464 
465 		case 12: lprcat("\nThis potion has no taste to it");  return;
466 
467 		case 15: lprcat("\nWOW!!!  You feel Super-fantastic!!!");
468 				 if (c[HERO]==0) for (i=0; i<6; i++) c[i] += 11;
469 					c[HERO] += 250;  break;
470 
471 		case 16: lprcat("\nYou have a greater intestinal constitude!");
472 				 c[CONSTITUTION]++;  break;
473 
474 		case 17: lprcat("\nYou now have incredibly bulging muscles!!!");
475 				 if (c[GIANTSTR]==0) c[STREXTRA] += 21;
476 				 c[GIANTSTR] += 700;  break;
477 
478 		case 18: lprcat("\nYou feel a chill run up your spine!");
479 				 c[FIRERESISTANCE] += 1000;  break;
480 
481 		case 0:	lprcat("\nYou fall asleep. . .");
482 				i=rnd(11)-(c[CONSTITUTION]>>2)+2;  while(--i>0) { parse2();  nap(1000); }
483 				cursors();  lprcat("\nYou woke up!");  return;
484 
485 		case 7:	lprcat("\nYou become dizzy!");
486 				if (--c[STRENGTH] < 3) c[STRENGTH]=3;  break;
487 
488 		case 11: lprcat("\nYou stagger for a moment . .");
489 				 for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)
490 					know[j][i]=0;
491 				 nap(2000);	draws(0,MAXX,0,MAXY); /* potion of forgetfulness */  return;
492 
493 		case 13: lprcat("\nYou can't see anything!");  /* blindness */
494 				 c[BLINDCOUNT]+=500;  return;
495 
496 		case 14: lprcat("\nYou feel confused"); c[CONFUSE]+= 20+rnd(9); return;
497 
498 		case 21: lprcat("\nYou don't seem to be affected");  return; /* cure dianthroritis */
499 
500 		case 22: lprcat("\nYou feel a sickness engulf you"); /* poison */
501 				 c[HALFDAM] += 200 + rnd(200);  return;
502 
503 		case 23: lprcat("\nYou feel your vision sharpen");	/* see invisible */
504 				 c[SEEINVISIBLE] += rnd(1000)+400;
505 				 monstnamelist[INVISIBLESTALKER] = 'I';  return;
506 		};
507 	bottomline();		/*	show new stats		*/  return;
508 	}
509 
510 /*
511 	*******
512 	OSCROLL
513 	*******
514 
515 	function to process a magic scroll
516  */
517 static void
518 oscroll(int typ)
519 	{
520 	lprcat("\nDo you ");
521 	if (c[BLINDCOUNT]==0) lprcat("(r) read it, "); lprcat("(t) take it"); iopts();
522 	while (1) switch(getchr())
523 		{
524 		case '\33':
525 		case 'i':	ignore();  return;
526 
527 		case 'r':	if (c[BLINDCOUNT]) break;
528 					lprcat("read"); forget();
529 					if (typ==2 || typ==15)  { show1cell(playerx,playery); cursors(); }
530 					/*	destroy it	*/	read_scroll(typ);  return;
531 
532 		case 't':	lprcat("take"); if (take(OSCROLL,typ)==0)	forget();	/*	destroy it	*/
533 					return;
534 		};
535 	}
536 
537 /*
538 	data for the function to read a scroll
539  */
540 static int xh,yh,yl,xl;
541 static char curse[] = { BLINDCOUNT, CONFUSE, AGGRAVATE, HASTEMONST, ITCHING,
542 	LAUGHING, DRAINSTRENGTH, CLUMSINESS, INFEEBLEMENT, HALFDAM };
543 static char exten[] = { PROTECTIONTIME, DEXCOUNT, STRCOUNT, CHARMCOUNT,
544 	INVISIBILITY, CANCELLATION, HASTESELF, GLOBE, SCAREMONST, HOLDMONST, TIMESTOP };
545 char time_change[] = { HASTESELF,HERO,ALTPRO,PROTECTIONTIME,DEXCOUNT,
546 	STRCOUNT,GIANTSTR,CHARMCOUNT,INVISIBILITY,CANCELLATION,
547 	HASTESELF,AGGRAVATE,SCAREMONST,STEALTH,AWARENESS,HOLDMONST,HASTEMONST,
548 	FIRERESISTANCE,GLOBE,SPIRITPRO,UNDEADPRO,HALFDAM,SEEINVISIBLE,
549 	ITCHING,CLUMSINESS, WTW };
550 /*
551  *	function to adjust time when time warping and taking courses in school
552  */
553 void
554 larn_adjtime(long tim)
555 	{
556 	int j;
557 	for (j=0; j<26; j++)	/* adjust time related parameters */
558 		if (c[(int)time_change[j]])
559 			if ((c[(int)time_change[j]] -= tim) < 1) c[(int)time_change[j]]=1;
560 	regen();
561 	}
562 
563 /*
564 	function to read a scroll
565  */
566 void
567 read_scroll(int typ)
568 	{
569 	int i,j;
570 	if (typ<0 || typ>=MAXSCROLL) return;  /* be sure we are within bounds */
571 	scrollname[typ] = scrollhide[typ];
572 	switch(typ)
573 	  {
574 	  case 0:	lprcat("\nYour armor glows for a moment");  enchantarmor(); return;
575 
576 	  case 1:	lprcat("\nYour weapon glows for a moment"); enchweapon(); return;  /* enchant weapon */
577 
578 	  case 2:	lprcat("\nYou have been granted enlightenment!");
579 				yh = min(playery+7,MAXY);	xh = min(playerx+25,MAXX);
580 				yl = max(playery-7,0);		xl = max(playerx-25,0);
581 				for (i=yl; i<yh; i++) for (j=xl; j<xh; j++)  know[j][i]=1;
582 				nap(2000);	draws(xl,xh,yl,yh);	return;
583 
584 	  case 3:	lprcat("\nThis scroll seems to be blank");	return;
585 
586 	  case 4:	createmonster(makemonst(level+1));  return;  /*  this one creates a monster  */
587 
588 	  case 5:	something(level);	/*	create artifact		*/  return;
589 
590 	  case 6:	c[AGGRAVATE]+=800; return; /* aggravate monsters */
591 
592 	  case 7:	gtime += (i = rnd(1000) - 850); /* time warp */
593 				if (i>=0) lprintf("\nYou went forward in time by %d mobuls",(long)((i+99)/100));
594 				else lprintf("\nYou went backward in time by %d mobuls",(long)(-(i+99)/100));
595 				larn_adjtime((long)i);	/* adjust time for time warping */
596 				return;
597 
598 	  case 8:	oteleport(0);	  return;	/*	teleportation */
599 
600 	  case 9:	c[AWARENESS] += 1800;  return;	/* expanded awareness	*/
601 
602 	  case 10:	c[HASTEMONST] += rnd(55)+12; return;	/* haste monster */
603 
604 	  case 11:	for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)
605 					if (mitem[j][i])
606 						hitp[j][i] = monster[(int)mitem[j][i]].hitpoints;
607 				return;	/* monster healing */
608 	  case 12:	c[SPIRITPRO] += 300 + rnd(200); bottomline(); return; /* spirit protection */
609 
610 	  case 13:	c[UNDEADPRO] += 300 + rnd(200); bottomline(); return; /* undead protection */
611 
612 	  case 14:	c[STEALTH] += 250 + rnd(250);  bottomline(); return; /* stealth */
613 
614 	  case 15:	lprcat("\nYou have been granted enlightenment!"); /* magic mapping */
615 				for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++)  know[j][i]=1;
616 				nap(2000);	draws(0,MAXX,0,MAXY);	return;
617 
618 	  case 16:	c[HOLDMONST] += 30; bottomline(); return; /* hold monster */
619 
620 	  case 17:	for (i=0; i<26; i++)	/* gem perfection */
621 					switch(iven[i])
622 						{
623 						case ODIAMOND:	case ORUBY:
624 						case OEMERALD:	case OSAPPHIRE:
625 							j = ivenarg[i];  j &= 255;  j <<= 1;
626 							if (j  > 255) j=255; /* double value */
627 							ivenarg[i] = j;	break;
628 						}
629 				break;
630 
631 	  case 18:	for (i=0; i<11; i++)	c[(int)exten[i]] <<= 1; /* spell extension */
632 				break;
633 
634 	  case 19:	for (i=0; i<26; i++)	/* identify */
635 					{
636 					if (iven[i]==OPOTION)  potionname[ivenarg[i]] = potionhide[ivenarg[i]];
637 					if (iven[i]==OSCROLL)  scrollname[ivenarg[i]] = scrollhide[ivenarg[i]];
638 					}
639 				break;
640 
641 	  case 20:	for (i=0; i<10; i++)	/* remove curse */
642 					if (c[(int)curse[i]]) c[(int)curse[i]] = 1;
643 				break;
644 
645 	  case 21:	annihilate();	break;	/* scroll of annihilation */
646 
647 	  case 22:	godirect(22,150,"The ray hits the %s",0,' ');	/* pulverization */
648 				break;
649 	  case 23:  c[LIFEPROT]++;  break; /* life protection */
650 	  };
651 	}
652 
653 
654 static void
655 oorb(void)
656 	{
657 	}
658 
659 static void
660 opit(void)
661 	{
662 	int i;
663 	if (rnd(101)<81)
664 	  if (rnd(70) > 9*c[DEXTERITY]-packweight() || rnd(101)<5)
665 	  {
666 		if (level==MAXLEVEL-1) obottomless(); else
667 		if (level==MAXLEVEL+MAXVLEVEL-1) obottomless(); else
668 			{
669 			if (rnd(101)<20)
670 				{
671 				i=0; lprcat("\nYou fell into a pit!  Your fall is cushioned by an unknown force\n");
672 				}
673 			else
674 				{
675 				i = rnd(level*3+3);
676 				lprintf("\nYou fell into a pit!  You suffer %d hit points damage",(long)i);
677 				lastnum=261; 	/*	if he dies scoreboard will say so */
678 				}
679 			losehp(i); nap(2000);  newcavelevel(level+1);  draws(0,MAXX,0,MAXY);
680 	  }
681 			}
682 	}
683 
684 static void
685 obottomless(void)
686 	{
687 	lprcat("\nYou fell into a bottomless pit!");  beep(); nap(3000);  died(262);
688 	}
689 
690 static void
691 oelevator(__unused int dir)
692 	{
693 #ifdef lint
694 	int x;
695 	x=dir;
696 	dir=x;
697 #endif /* lint */
698 	}
699 
700 static void
701 ostatue(void)
702 	{
703 	}
704 
705 static void
706 omirror(void)
707 	{
708 	}
709 
710 static void
711 obook(void)
712 	{
713 	lprcat("\nDo you ");
714 	if (c[BLINDCOUNT]==0) lprcat("(r) read it, "); lprcat("(t) take it"); iopts();
715 	while (1) switch(getchr())
716 		{
717 		case '\33':
718 		case 'i':	ignore();	return;
719 
720 		case 'r':	if (c[BLINDCOUNT]) break;
721 					lprcat("read");
722 					/* no more book	*/	readbook(iarg[playerx][playery]);  forget(); return;
723 
724 		case 't':	lprcat("take");  if (take(OBOOK,iarg[playerx][playery])==0)  forget();	/* no more book	*/
725 					return;
726 		};
727 	}
728 
729 /*
730 	function to read a book
731  */
732 void
733 readbook(int lev)
734 	{
735 	int i,tmp;
736 	if (lev<=3) i = rund((tmp=splev[lev])?tmp:1); else
737 		i = rnd((tmp=splev[lev]-9)?tmp:1) + 9;
738 	spelknow[i]=1;
739 	lprintf("\nSpell \"%s\":  %s\n%s",spelcode[i],spelname[i],speldescript[i]);
740 	if (rnd(10)==4)
741 	 { lprcat("\nYour int went up by one!"); c[INTELLIGENCE]++; bottomline(); }
742 	}
743 
744 static void
745 ocookie(void)
746 	{
747 	const char *p;
748 	lprcat("\nDo you (e) eat it, (t) take it"); iopts();
749 	while (1) switch(getchr())
750 		{
751 		case '\33':
752 		case 'i':	ignore();	return;
753 
754 		case 'e':	lprcat("eat\nThe cookie tasted good.");
755 					forget(); /* no more cookie	*/
756 					if (c[BLINDCOUNT]) return;
757 					if (!(p=fortune())) return;
758 					lprcat("  A message inside the cookie reads:\n"); lprcat(p);
759 					return;
760 
761 		case 't':	lprcat("take");  if (take(OCOOKIE,0)==0) forget();	/* no more book	*/
762 					return;
763 		};
764 	}
765 
766 
767 /* routine to pick up some gold -- if arg==OMAXGOLD then the pile is worth 100* the argument */
768 static void
769 ogold(int arg)
770 	{
771 	long i;
772 	i = iarg[playerx][playery];
773 	if (arg==OMAXGOLD) i *= 100;
774 		else if (arg==OKGOLD) i *= 1000;
775 			else if (arg==ODGOLD) i *= 10;
776 	lprintf("\nIt is worth %d!",(long)i);	c[GOLD] += i;  bottomgold();
777 	item[playerx][playery] = know[playerx][playery] = 0; /*	destroy gold	*/
778 	}
779 
780 static void
781 ohome(void)
782 	{
783 	int i;
784 	nosignal = 1;	/* disable signals */
785 	for (i=0; i<26; i++) if (iven[i]==OPOTION) if (ivenarg[i]==21)
786 		{
787 		iven[i]=0;	/* remove the potion of cure dianthroritis from inventory */
788 		clear(); lprcat("Congratulations.  You found a potion of cure dianthroritis.\n");
789 		lprcat("\nFrankly, No one thought you could do it.  Boy!  Did you surprise them!\n");
790 		if (gtime>TIMELIMIT)
791 			{
792 			lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
793 			lprcat("You didn't make it in time.  In your agony, you kill the doctor,\nyour wife, and yourself!  Too bad!\n");
794 			nap(5000); died(269);
795 			}
796 		else
797 			{
798 			lprcat("\nThe doctor is now administering the potion, and in a few moments\n");
799 			lprcat("Your daughter should be well on her way to recovery.\n");
800 			nap(6000);
801 			lprcat("\nThe potion is"); nap(3000); lprcat(" working!  The doctor thinks that\n");
802 			lprcat("your daughter will recover in a few days.  Congratulations!\n");
803 			beep(); nap(5000); died(263);
804 			}
805 		}
806 
807 	while (1)
808 		{
809 		clear(); lprintf("Welcome home %s.  Latest word from the doctor is not good.\n",logname);
810 
811 		if (gtime>TIMELIMIT)
812 			{
813 			lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
814 			lprcat("You didn't make it in time.  In your agony, you kill the doctor,\nyour wife, and yourself!  Too bad!\n");
815 			nap(5000); died(269);
816 			}
817 
818 		lprcat("\nThe diagnosis is confirmed as dianthroritis.  He guesses that\n");
819 		lprintf("your daughter has only %d mobuls left in this world.  It's up to you,\n",(long)((TIMELIMIT-gtime+99)/100));
820 		lprintf("%s, to find the only hope for your daughter, the very rare\n",logname);
821 		lprcat("potion of cure dianthroritis.  It is rumored that only deep in the\n");
822 		lprcat("depths of the caves can this potion be found.\n\n\n");
823 		lprcat("\n     ----- press "); standout("return");
824 		lprcat(" to continue, "); standout("escape");
825 		lprcat(" to leave ----- ");
826 		i=getchr();  while (i!='\33' && i!='\n') i=getchr();
827 		if (i=='\33') { drawscreen(); nosignal = 0; /* enable signals */ return; }
828 		}
829 	}
830 
831 /*	routine to save program space	*/
832 void
833 iopts(void)
834 	{	lprcat(", or (i) ignore it? ");	}
835 
836 void
837 ignore(void)
838 	{	lprcat("ignore\n");	}
839 
840