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