Merge from vendor branch OPENSSH:
[dragonfly.git] / games / larn / object.c
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 \f
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 \f
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 \f
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 \f
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 \f
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