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 $ */
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);
22 subroutine to look for an object and give the player his options
23 if an object was found.
29 if (c
[TIMESTOP
]) /* can't find objects is time is stopped */
31 i
= item
[playerx
][playery
];
34 showcell(playerx
, playery
);
42 lprcat("\n\nYou have found some gold!");
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
]);
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
]);
65 lprcat("\n\nThere is a Holy Altar here!");
70 lprcat("\n\nYou have found a book.");
75 lprcat("\n\nYou have found a fortune cookie.");
82 lprintf("\n\nThere is %s here!", objectname
[i
]);
89 lprintf("\n\nThere is %s here!", objectname
[i
]);
94 lprintf("\n\nThere is %s here!", objectname
[i
]);
99 lprcat("\n\nYou have found the Orb!!!!!");
104 lprcat("\n\nYou're standing at the top of a pit.");
109 lprcat("\n\nThere is a circular staircase here");
114 lprcat("\n\nYou feel heavy for a moment, but the feeling disappears");
115 oelevator(1); /* up */
121 lprcat("\n\nThere is a fountain here");
128 lprcat("\n\nYou are standing in front of a statue");
133 lprcat("\n\nThere is a chest here");
140 item
[playerx
][playery
] = OTELEPORTER
;
141 know
[playerx
][playery
] = 1;
145 lprcat("\nZaaaappp! You've been teleported!\n");
154 lprcat("\n\nYou have found the College of Larn.");
155 lprcat("\nDo you (g) go inside, or (i) stay here? ");
157 while ((i
!= 'g') && (i
!= 'i') && (i
!= '\33'))
160 oschool(); /* the college of larn */
162 lprcat(" stay here");
168 lprcat("\n\nThere is a mirror here");
177 lprcat("\n\nYou have found the bank of Larn.");
179 lprcat("\n\nYou have found a branch office of the bank of Larn.");
180 lprcat("\nDo you (g) go inside, or (i) stay here? ");
182 while ((j
!= 'g') && (j
!= 'i') && (j
!= '\33'))
188 obank2(); /* the bank of larn */
190 lprcat(" stay here");
196 lprcat("\n\nThere is a dead fountain here");
202 lprcat("\n\nThere is a DND store here.");
203 lprcat("\nDo you (g) go inside, or (i) stay here? ");
205 while ((i
!= 'g') && (i
!= 'i') && (i
!= '\33'))
208 dndstore(); /* the dnd adventurers store */
210 lprcat(" stay here");
214 lprcat("\n\nThere is a circular staircase here");
215 ostairs(-1); /* down */
219 lprcat("\n\nYou feel light for a moment, but the feeling disappears");
220 oelevator(-1); /* down */
224 lprintf("\n\nYou have found %s", objectname
[i
]);
225 lprcat("\nDo you (c) close it");
228 while ((i
!= 'c') && (i
!= 'i') && (i
!= '\33'))
230 if ((i
== '\33') || (i
== 'i')) {
236 item
[playerx
][playery
] = OCLOSEDDOOR
;
237 iarg
[playerx
][playery
] = 0;
243 lprintf("\n\nYou have found %s", objectname
[i
]);
244 lprcat("\nDo you (o) try to open it");
247 while ((i
!= 'o') && (i
!= 'i') && (i
!= '\33'))
249 if ((i
== '\33') || (i
== 'i')) {
257 switch (iarg
[playerx
][playery
]) {
259 c
[AGGRAVATE
] += rnd(400);
263 lprcat("\nYou are jolted by an electric shock ");
274 lprcat("\nYou suddenly feel weaker ");
287 item
[playerx
][playery
] = OOPENDOOR
;
293 lprcat("\nYou have found ");
294 lprcat(objectname
[OENTRANCE
]);
295 lprcat("\nDo you (g) go inside");
298 while ((i
!= 'g') && (i
!= 'i') && (i
!= '\33'))
304 item
[33][MAXY
- 1] = know
[33][MAXY
- 1] = mitem
[33][MAXY
- 1] = 0;
305 draws(0, MAXX
, 0, MAXY
);
313 lprcat("\nYou have found ");
314 lprcat(objectname
[OVOLDOWN
]);
315 lprcat("\nDo you (c) climb down");
318 while ((i
!= 'c') && (i
!= 'i') && (i
!= '\33'))
320 if ((i
== '\33') || (i
== 'i')) {
325 lprcat("\nThe shaft only extends 5 feet downward!");
328 if (packweight() > 45 + 3 * (c
[STRENGTH
] + c
[STREXTRA
])) {
329 lprcat("\nYou slip and fall down the shaft");
332 losehp(30 + rnd(20));
335 lprcat("climb down");
337 newcavelevel(MAXLEVEL
);
338 for (i
= 0; i
< MAXY
; i
++)
339 for (j
= 0; j
< MAXX
; j
++) /* put player near volcano shaft */
340 if (item
[j
][i
] == OVOLUP
) {
347 draws(0, MAXX
, 0, MAXY
);
352 lprcat("\nYou have found ");
353 lprcat(objectname
[OVOLUP
]);
354 lprcat("\nDo you (c) climb up");
357 while ((i
!= 'c') && (i
!= 'i') && (i
!= '\33'))
359 if ((i
== '\33') || (i
== 'i')) {
364 lprcat("\nThe shaft only extends 8 feet upwards before you find a blockage!");
367 if (packweight() > 45 + 5 * (c
[STRENGTH
] + c
[STREXTRA
])) {
368 lprcat("\nYou slip and fall down the shaft");
371 losehp(15 + rnd(20));
379 for (i
= 0; i
< MAXY
; i
++)
380 for (j
= 0; j
< MAXX
; j
++) /* put player near volcano shaft */
381 if (item
[j
][i
] == OVOLDOWN
) {
388 draws(0, MAXX
, 0, MAXY
);
393 if (rnd(17) < 13) /* for an arrow trap */
395 item
[playerx
][playery
] = OTRAPARROW
;
396 know
[playerx
][playery
] = 0;
400 lprcat("\nYou are hit by an arrow");
401 beep(); /* for an arrow trap */
403 losehp(rnd(10) + level
);
408 if (rnd(17) < 13) /* for a dart trap */
410 item
[playerx
][playery
] = ODARTRAP
;
411 know
[playerx
][playery
] = 0;
415 lprcat("\nYou are hit by a dart");
416 beep(); /* for a dart trap */
419 if ((--c
[STRENGTH
]) < 3)
425 if (rnd(17) < 13) /* for a trap door */
427 item
[playerx
][playery
] = OTRAPDOOR
;
428 know
[playerx
][playery
] = 1;
432 lastnum
= 272; /* a trap door */
433 if ((level
== MAXLEVEL
- 1) || (level
== MAXLEVEL
+ MAXVLEVEL
- 1)) {
434 lprcat("\nYou fell through a bottomless trap door!");
439 lprcat("\nYou fall through a trap door!");
440 beep(); /* for a trap door */
441 losehp(rnd(5 + level
));
443 newcavelevel(level
+ 1);
444 draws(0, MAXX
, 0, MAXY
);
452 lprcat("\nYou have found the Larn trading Post.");
453 lprcat("\nDo you (g) go inside, or (i) stay here? ");
455 while ((i
!= 'g') && (i
!= 'i') && (i
!= '\33'))
466 lprcat("\nYou have found your way home.");
467 lprcat("\nDo you (g) go inside, or (i) stay here? ");
469 while ((i
!= 'g') && (i
!= 'i') && (i
!= '\33'))
482 return; /* annihilated by sphere of annihilation */
487 lprcat("\n\nThere is an LRS office here.");
488 lprcat("\nDo you (g) go inside, or (i) stay here? ");
490 while ((i
!= 'g') && (i
!= 'i') && (i
!= '\33'))
493 olrs(); /* the larn revenue service */
495 lprcat(" stay here");
505 function to say what object we found and ask if player wants to take it
511 lprintf("\n\nYou have found %s ", objectname
[obj
]);
512 tmp
= iarg
[playerx
][playery
];
526 lprintf("+ %d", (long)tmp
);
528 lprintf(" %d", (long)tmp
);
530 lprcat("\nDo you want to (t) take it");
533 while (i
!= 't' && i
!= 'i' && i
!= '\33')
537 if (take(obj
, tmp
) == 0)
545 subroutine to process the stair cases
546 if dir > 0 the up else down
552 lprcat("\nDo you (s) stay here ");
554 lprcat("(u) go up ");
556 lprcat("(d) go down ");
557 lprcat("or (f) kick stairs? ");
568 lprcat("kick stairs");
570 lprcat("\nI hope you feel better. Showing anger rids you of frustration.");
572 k
= rnd((level
+ 1) << 1);
573 lprintf("\nYou hurt your foot dumb dumb! You suffer %d hit points", (long)k
);
583 lprcat("\nThe stairs don't go up!");
584 else if (level
>= 2 && level
!= 11) {
586 newcavelevel(level
- 1);
587 draws(0, MAXX
, 0, MAXY
);
590 lprcat("\nThe stairs lead to a dead end!");
596 lprcat("\nThe stairs don't go down!");
597 else if (level
!= 0 && level
!= 10 && level
!= 13) {
599 newcavelevel(level
+ 1);
600 draws(0, MAXX
, 0, MAXY
);
603 lprcat("\nThe stairs lead to a dead end!");
609 subroutine to handle a teleport trap +/- 1 level maximum
616 if (rnd(151) < 3) /* stuck in a rock */
618 c
[TELEFLAG
] = 1; /* show ?? on bottomline if been teleported */
621 else if (level
< MAXLEVEL
) {
622 tmp
= rnd(5) + level
- 3;
628 tmp
= rnd(3) + level
- 2;
629 if (tmp
>= MAXLEVEL
+ MAXVLEVEL
)
630 tmp
= MAXLEVEL
+ MAXVLEVEL
- 1;
634 playerx
= rnd(MAXX
- 2);
635 playery
= rnd(MAXY
- 2);
639 draws(0, MAXX
, 0, MAXY
);
644 function to process a potion
649 lprcat("\nDo you (d) drink it, (t) take it");
660 forget(); /* destroy potion */
666 if (take(OPOTION
, pot
) == 0)
673 function to drink a potion
679 if (pot
< 0 || pot
>= MAXPOTION
) /* check for within bounds */
681 potionname
[pot
] = potionhide
[pot
];
684 lprcat("\nYou feel greedy . . .");
686 for (i
= 0; i
< MAXY
; i
++)
687 for (j
= 0; j
< MAXX
; j
++)
688 if ((item
[j
][i
] == OGOLDPILE
) || (item
[j
][i
] == OMAXGOLD
)) {
696 lprcat("\nYou feel greedy . . .");
698 for (i
= 0; i
< MAXY
; i
++)
699 for (j
= 0; j
< MAXX
; j
++) {
701 if ((k
== ODIAMOND
) || (k
== ORUBY
) || (k
== OEMERALD
) || (k
== OMAXGOLD
)
702 || (k
== OSAPPHIRE
) || (k
== OLARNEYE
) || (k
== OGOLDPILE
)) {
712 break; /* instant healing */
715 lprcat("\nYou feel better");
716 if (c
[HP
] == c
[HPMAX
])
718 else if ((c
[HP
] += rnd(20) + 20 + c
[LEVEL
]) > c
[HPMAX
])
723 lprcat("\nSuddenly, you feel much more skillful!");
729 lprcat("\nYou feel strange for a moment");
734 lprcat("\nYou feel more self confident!");
739 lprcat("\nWow! You feel great!");
740 if (c
[STRENGTH
] < 12)
747 lprcat("\nYour charm went up by one!");
752 lprcat("\nYour intelligence went up by one!");
757 for (i
= 0; i
< MAXY
; i
++)
758 for (j
= 0; j
< MAXX
; j
++)
763 /* monster detection */
767 lprcat("\nThis potion has no taste to it");
771 lprcat("\nWOW!!! You feel Super-fantastic!!!");
773 for (i
= 0; i
< 6; i
++)
779 lprcat("\nYou have a greater intestinal constitude!");
784 lprcat("\nYou now have incredibly bulging muscles!!!");
785 if (c
[GIANTSTR
] == 0)
791 lprcat("\nYou feel a chill run up your spine!");
792 c
[FIRERESISTANCE
] += 1000;
796 lprcat("\nYou fall asleep. . .");
797 i
= rnd(11) - (c
[CONSTITUTION
] >> 2) + 2;
803 lprcat("\nYou woke up!");
807 lprcat("\nYou become dizzy!");
808 if (--c
[STRENGTH
] < 3)
813 lprcat("\nYou stagger for a moment . .");
814 for (i
= 0; i
< MAXY
; i
++)
815 for (j
= 0; j
< MAXX
; j
++)
818 draws(0, MAXX
, 0, MAXY
); /* potion of forgetfulness */
822 lprcat("\nYou can't see anything!"); /* blindness */
823 c
[BLINDCOUNT
] += 500;
827 lprcat("\nYou feel confused");
828 c
[CONFUSE
] += 20 + rnd(9);
832 lprcat("\nYou don't seem to be affected");
833 return; /* cure dianthroritis */
836 lprcat("\nYou feel a sickness engulf you"); /* poison */
837 c
[HALFDAM
] += 200 + rnd(200);
841 lprcat("\nYou feel your vision sharpen"); /* see invisible */
842 c
[SEEINVISIBLE
] += rnd(1000) + 400;
843 monstnamelist
[INVISIBLESTALKER
] = 'I';
846 bottomline(); /* show new stats */
851 function to process a magic scroll
857 if (c
[BLINDCOUNT
] == 0)
858 lprcat("(r) read it, ");
859 lprcat("(t) take it");
873 if (typ
== 2 || typ
== 15) {
874 show1cell(playerx
, playery
);
883 if (take(OSCROLL
, typ
) == 0)
884 forget(); /* destroy it */
890 data for the function to read a scroll
892 static int xh
, yh
, yl
, xl
;
893 static char curse
[] = { BLINDCOUNT
, CONFUSE
, AGGRAVATE
, HASTEMONST
, ITCHING
,
894 LAUGHING
, DRAINSTRENGTH
, CLUMSINESS
, INFEEBLEMENT
, HALFDAM
};
895 static char exten
[] = { PROTECTIONTIME
, DEXCOUNT
, STRCOUNT
, CHARMCOUNT
,
896 INVISIBILITY
, CANCELLATION
, HASTESELF
, GLOBE
, SCAREMONST
, HOLDMONST
, TIMESTOP
};
897 char time_change
[] = { HASTESELF
, HERO
, ALTPRO
, PROTECTIONTIME
, DEXCOUNT
,
898 STRCOUNT
, GIANTSTR
, CHARMCOUNT
, INVISIBILITY
, CANCELLATION
,
899 HASTESELF
, AGGRAVATE
, SCAREMONST
, STEALTH
, AWARENESS
, HOLDMONST
, HASTEMONST
,
900 FIRERESISTANCE
, GLOBE
, SPIRITPRO
, UNDEADPRO
, HALFDAM
, SEEINVISIBLE
,
901 ITCHING
, CLUMSINESS
, WTW
};
903 * function to adjust time when time warping and taking courses in school
906 larn_adjtime(long tim
)
909 for (j
= 0; j
< 26; j
++) /* adjust time related parameters */
910 if (c
[(int)time_change
[j
]])
911 if ((c
[(int)time_change
[j
]] -= tim
) < 1)
912 c
[(int)time_change
[j
]] = 1;
917 function to read a scroll
923 if (typ
< 0 || typ
>= MAXSCROLL
) /* be sure we are within bounds */
925 scrollname
[typ
] = scrollhide
[typ
];
928 lprcat("\nYour armor glows for a moment");
933 lprcat("\nYour weapon glows for a moment");
935 return; /* enchant weapon */
938 lprcat("\nYou have been granted enlightenment!");
939 yh
= min(playery
+ 7, MAXY
);
940 xh
= min(playerx
+ 25, MAXX
);
941 yl
= max(playery
- 7, 0);
942 xl
= max(playerx
- 25, 0);
943 for (i
= yl
; i
< yh
; i
++)
944 for (j
= xl
; j
< xh
; j
++)
947 draws(xl
, xh
, yl
, yh
);
951 lprcat("\nThis scroll seems to be blank");
955 createmonster(makemonst(level
+ 1));
956 return; /* this one creates a monster */
959 something(level
); /* create artifact */
964 return; /* aggravate monsters */
967 gtime
+= (i
= rnd(1000) - 850); /* time warp */
969 lprintf("\nYou went forward in time by %d mobuls", (long)((i
+ 99) / 100));
971 lprintf("\nYou went backward in time by %d mobuls", (long)(-(i
+ 99) / 100));
972 larn_adjtime((long)i
); /* adjust time for time warping */
977 return; /* teleportation */
980 c
[AWARENESS
] += 1800;
981 return; /* expanded awareness */
984 c
[HASTEMONST
] += rnd(55) + 12;
985 return; /* haste monster */
988 for (i
= 0; i
< MAXY
; i
++)
989 for (j
= 0; j
< MAXX
; j
++)
991 hitp
[j
][i
] = monster
[(int)mitem
[j
][i
]].hitpoints
;
992 return; /* monster healing */
994 c
[SPIRITPRO
] += 300 + rnd(200);
996 return; /* spirit protection */
999 c
[UNDEADPRO
] += 300 + rnd(200);
1001 return; /* undead protection */
1004 c
[STEALTH
] += 250 + rnd(250);
1006 return; /* stealth */
1009 lprcat("\nYou have been granted enlightenment!"); /* magic mapping */
1010 for (i
= 0; i
< MAXY
; i
++)
1011 for (j
= 0; j
< MAXX
; j
++)
1014 draws(0, MAXX
, 0, MAXY
);
1020 return; /* hold monster */
1023 for (i
= 0; i
< 26; i
++) /* gem perfection */
1033 j
= 255; /* double value */
1040 for (i
= 0; i
< 11; i
++)
1041 c
[(int)exten
[i
]] <<= 1; /* spell extension */
1045 for (i
= 0; i
< 26; i
++) { /* identify */
1046 if (iven
[i
] == OPOTION
)
1047 potionname
[ivenarg
[i
]] = potionhide
[ivenarg
[i
]];
1048 if (iven
[i
] == OSCROLL
)
1049 scrollname
[ivenarg
[i
]] = scrollhide
[ivenarg
[i
]];
1054 for (i
= 0; i
< 10; i
++) /* remove curse */
1055 if (c
[(int)curse
[i
]])
1056 c
[(int)curse
[i
]] = 1;
1061 break; /* scroll of annihilation */
1064 godirect(22, 150, "The ray hits the %s", 0, ' '); /* pulverization */
1068 break; /* life protection */
1081 if (rnd(101) < 81) {
1082 if (rnd(70) > 9 * c
[DEXTERITY
] - packweight() || rnd(101) < 5) {
1083 if (level
== MAXLEVEL
- 1)
1085 else if (level
== MAXLEVEL
+ MAXVLEVEL
- 1)
1088 if (rnd(101) < 20) {
1090 lprcat("\nYou fell into a pit! Your fall is cushioned by an unknown force\n");
1092 i
= rnd(level
* 3 + 3);
1093 lprintf("\nYou fell into a pit! You suffer %d hit points damage", (long)i
);
1094 lastnum
= 261; /* if he dies scoreboard will say so */
1098 newcavelevel(level
+ 1);
1099 draws(0, MAXX
, 0, MAXY
);
1108 lprcat("\nYou fell into a bottomless pit!");
1115 oelevator(int dir __unused
)
1137 lprcat("\nDo you ");
1138 if (c
[BLINDCOUNT
] == 0)
1139 lprcat("(r) read it, ");
1140 lprcat("(t) take it");
1154 readbook(iarg
[playerx
][playery
]);
1160 if (take(OBOOK
, iarg
[playerx
][playery
]) == 0)
1161 forget(); /* no more book */
1167 function to read a book
1174 i
= rund((tmp
= splev
[lev
]) ? tmp
: 1);
1176 i
= rnd((tmp
= splev
[lev
] - 9) ? tmp
: 1) + 9;
1178 lprintf("\nSpell \"%s\": %s\n%s", spelcode
[i
], spelname
[i
], speldescript
[i
]);
1180 lprcat("\nYour int went up by one!");
1190 lprcat("\nDo you (e) eat it, (t) take it");
1200 lprcat("eat\nThe cookie tasted good.");
1201 forget(); /* no more cookie */
1204 if (!(p
= fortune()))
1206 lprcat(" A message inside the cookie reads:\n");
1212 if (take(OCOOKIE
, 0) == 0)
1213 forget(); /* no more book */
1219 /* routine to pick up some gold -- if arg==OMAXGOLD then the pile is worth 100* the argument */
1224 i
= iarg
[playerx
][playery
];
1225 if (arg
== OMAXGOLD
)
1227 else if (arg
== OKGOLD
)
1229 else if (arg
== ODGOLD
)
1231 lprintf("\nIt is worth %d!", (long)i
);
1235 item
[playerx
][playery
] = know
[playerx
][playery
] = 0;
1242 nosignal
= 1; /* disable signals */
1243 for (i
= 0; i
< 26; i
++)
1244 if (iven
[i
] == OPOTION
)
1245 if (ivenarg
[i
] == 21) {
1246 iven
[i
] = 0; /* remove the potion of cure dianthroritis from inventory */
1248 lprcat("Congratulations. You found a potion of cure dianthroritis.\n");
1249 lprcat("\nFrankly, No one thought you could do it. Boy! Did you surprise them!\n");
1250 if (gtime
> TIMELIMIT
) {
1251 lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
1252 lprcat("You didn't make it in time. In your agony, you kill the doctor,\nyour wife, and yourself! Too bad!\n");
1256 lprcat("\nThe doctor is now administering the potion, and in a few moments\n");
1257 lprcat("Your daughter should be well on her way to recovery.\n");
1259 lprcat("\nThe potion is");
1261 lprcat(" working! The doctor thinks that\n");
1262 lprcat("your daughter will recover in a few days. Congratulations!\n");
1271 lprintf("Welcome home %s. Latest word from the doctor is not good.\n", logname
);
1273 if (gtime
> TIMELIMIT
) {
1274 lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
1275 lprcat("You didn't make it in time. In your agony, you kill the doctor,\nyour wife, and yourself! Too bad!\n");
1280 lprcat("\nThe diagnosis is confirmed as dianthroritis. He guesses that\n");
1281 lprintf("your daughter has only %d mobuls left in this world. It's up to you,\n", (long)((TIMELIMIT
- gtime
+ 99) / 100));
1282 lprintf("%s, to find the only hope for your daughter, the very rare\n", logname
);
1283 lprcat("potion of cure dianthroritis. It is rumored that only deep in the\n");
1284 lprcat("depths of the caves can this potion be found.\n\n\n");
1285 lprcat("\n ----- press ");
1287 lprcat(" to continue, ");
1289 lprcat(" to leave ----- ");
1291 while (i
!= '\33' && i
!= '\n')
1295 nosignal
= 0; /* enable signals */
1301 /* routine to save program space */
1305 lprcat(", or (i) ignore it? ");