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