1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.potion.c - version 1.0.3 */
3 /* $FreeBSD: src/games/hack/hack.potion.c,v 1.5 1999/11/16 10:26:37 marcel Exp $ */
6 extern struct monst youmonst
;
8 static void ghost_from_bottle(void);
13 struct obj
*otmp
, *objs
;
15 int unkn
= 0, nothing
= 0;
17 otmp
= getobj("!", "drink");
20 if (!strcmp(objects
[otmp
->otyp
].oc_descr
, "smoky") && !rn2(13)) {
25 case POT_RESTORE_STRENGTH
:
27 pline("Wow! This makes you feel great!");
28 if (u
.ustr
< u
.ustrmax
) {
35 pline("Ooph! This tastes like liquid fire!");
37 /* the whiskey makes us feel better */
39 losehp(-1, "bottle of whiskey");
41 pline("You pass out.");
43 nomovemsg
= "You awake with a headache.";
46 case POT_INVISIBILITY
:
47 if (Invis
|| See_invisible
)
51 pline("Gee! All of a sudden, you can't see yourself.");
53 pline("You feel rather airy."), unkn
++;
59 pline("This tastes like fruit juice.");
63 pline("You begin to feel better.");
68 if (Blind
) /* see on next move */
75 pline("You are motionlessly suspended.");
77 pline("Your feet are frozen to the floor!");
78 nomul(-(rn1(10, 25)));
80 case POT_MONSTER_DETECTION
:
82 strange_feeling(otmp
, "You feel threatened.");
86 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
88 at(mtmp
->mx
, mtmp
->my
, mtmp
->data
->mlet
);
90 pline("You sense the presence of monsters.");
95 case POT_OBJECT_DETECTION
:
97 strange_feeling(otmp
, "You feel a pull downward.");
100 for (objs
= fobj
; objs
; objs
= objs
->nobj
)
101 if (objs
->ox
!= u
.ux
|| objs
->oy
!= u
.uy
)
103 pline("You sense the presence of objects close nearby.");
107 for (objs
= fobj
; objs
; objs
= objs
->nobj
)
108 at(objs
->ox
, objs
->oy
, objs
->olet
);
110 pline("You sense the presence of objects.");
116 pline("Yech! This stuff tastes like poison.");
117 if (Poison_resistance
)
118 pline("(But in fact it was biologically contaminated orange juice.)");
120 losehp(rnd(10), "contaminated potion");
124 pline("Huh, What? Where am I?");
127 Confusion
+= rn1(7, 16);
129 case POT_GAIN_STRENGTH
:
130 pline("Wow do you feel strong!");
131 if (u
.ustr
>= 118) /* > 118 is impossible */
134 u
.ustr
+= rnd(118 - u
.ustr
);
137 if (u
.ustr
> u
.ustrmax
)
147 if (!(Fast
& ~INTRINSIC
))
148 pline("You are suddenly moving much faster.");
150 pline("Your legs get new energy."), unkn
++;
151 Fast
+= rn1(10, 100);
155 pline("A cloud of darkness falls upon you.");
158 Blind
+= rn1(100, 250);
164 case POT_EXTRA_HEALING
:
165 pline("You feel much better.");
167 u
.uhp
+= d(2, 20) + 1;
168 if (u
.uhp
> u
.uhpmax
)
169 u
.uhp
= (u
.uhpmax
+= 2);
180 Levitation
+= rnd(100);
181 u
.uprops
[PROP(RIN_LEVITATION
)].p_tofn
= float_down
;
184 impossible("What a funny potion! (%u)", otmp
->otyp
);
189 pline("You have a peculiar feeling for a moment, then it passes.");
191 if (otmp
->dknown
&& !objects
[otmp
->otyp
].oc_name_known
) {
193 objects
[otmp
->otyp
].oc_name_known
= 1;
194 more_experienced(0, 10);
195 } else if (!objects
[otmp
->otyp
].oc_uname
)
208 pline("You feel more experienced.");
213 u
.uexp
= newuexp() + 1;
214 pline("Welcome to experience level %u.", ++u
.ulevel
);
220 strange_feeling(struct obj
*obj
, const char *txt
)
223 pline("You have a strange feeling for a moment, then it passes.");
226 if (!objects
[obj
->otyp
].oc_name_known
&& !objects
[obj
->otyp
].oc_uname
)
231 static const char *bottlenames
[] = {
232 "bottle", "phial", "flagon", "carafe", "flask", "jar", "vial"
236 potionhit(struct monst
*mon
, struct obj
*obj
)
238 const char *botlnam
= bottlenames
[rn2(SIZE(bottlenames
))];
239 boolean uclose
, isyou
= (mon
== &youmonst
);
243 pline("The %s crashes on your head and breaks into shivers.",
245 losehp(rnd(2), "thrown potion");
247 uclose
= (dist(mon
->mx
, mon
->my
) < 3);
248 /* perhaps 'E' and 'a' have no head? */
249 pline("The %s crashes on %s's head and breaks into shivers.",
250 botlnam
, monnam(mon
));
251 if (rn2(5) && mon
->mhp
> 1)
254 pline("The %s evaporates.", xname(obj
));
256 if (!isyou
&& !rn2(3))
258 case POT_RESTORE_STRENGTH
:
259 case POT_GAIN_STRENGTH
:
261 case POT_EXTRA_HEALING
:
262 if (mon
->mhp
< mon
->mhpmax
) {
263 mon
->mhp
= mon
->mhpmax
;
264 pline("%s looks sound and hale again!", Monnam(mon
));
277 case POT_INVISIBILITY
:
289 mon
->mblinded
|= 64 + rn2(64);
292 * case POT_GAIN_LEVEL:
293 * case POT_LEVITATION:
294 * case POT_FRUIT_JUICE:
295 * case POT_MONSTER_DETECTION:
296 * case POT_OBJECT_DETECTION:
300 if (uclose
&& rn2(5))
306 potionbreathe(struct obj
*obj
)
309 case POT_RESTORE_STRENGTH
:
310 case POT_GAIN_STRENGTH
:
311 if (u
.ustr
< u
.ustrmax
) {
317 case POT_EXTRA_HEALING
:
318 if (u
.uhp
< u
.uhpmax
) {
333 pline("You feel somewhat dizzy.");
336 case POT_INVISIBILITY
:
337 pline("For an instant you couldn't see your right hand.");
340 pline("Something seems to be holding you.");
345 pline("Your knees seem more flexible now.");
349 pline("It suddenly gets dark.");
354 * case POT_GAIN_LEVEL:
355 * case POT_LEVITATION:
356 * case POT_FRUIT_JUICE:
357 * case POT_MONSTER_DETECTION:
358 * case POT_OBJECT_DETECTION:
362 /* note: no obfree() */
366 * -- rudimentary -- to do this correctly requires much more work
367 * -- all sharp weapons get one or more qualities derived from the potions
368 * -- texts on scrolls may be (partially) wiped out; do they become blank?
369 * -- or does their effect change, like under Confusion?
370 * -- all objects may be made invisible by POT_INVISIBILITY
371 * -- If the flask is small, can one dip a large object? Does it magically
372 * -- become a jug? Etc.
377 struct obj
*potion
, *obj
;
379 if (!(obj
= getobj("#", "dip")))
381 if (!(potion
= getobj("!", "dip into")))
383 pline("Interesting...");
384 if (obj
->otyp
== ARROW
|| obj
->otyp
== DART
||
385 obj
->otyp
== CROSSBOW_BOLT
)
386 if (potion
->otyp
== POT_SICKNESS
) {
388 if (obj
->spe
< 7) /* %% */
395 ghost_from_bottle(void)
399 if (!(mtmp
= makemon(PM_GHOST
, u
.ux
, u
.uy
))) {
400 pline("This bottle turns out to be empty.");
404 pline("As you open the bottle, an enormous ghost emerges!");
405 pline("You are frightened to death, and unable to move.");