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 $ */
4 /* $DragonFly: src/games/hack/hack.potion.c,v 1.4 2006/08/21 19:45:32 pavalos Exp $ */
7 extern struct monst youmonst;
9 static void ghost_from_bottle(void);
14 struct obj *otmp,*objs;
16 int unkn = 0, nothing = 0;
18 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 */
38 if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey");
40 pline("You pass out.");
42 nomovemsg = "You awake with a headache.";
45 case POT_INVISIBILITY:
46 if(Invis || See_invisible)
50 pline("Gee! All of a sudden, you can't see yourself.");
52 pline("You feel rather airy."), unkn++;
58 pline("This tastes like fruit juice.");
62 pline("You begin to feel better.");
67 if(Blind) Blind = 1; /* see on next move */
72 pline("You are motionlessly suspended.");
74 pline("Your feet are frozen to the floor!");
77 case POT_MONSTER_DETECTION:
79 strange_feeling(otmp, "You feel threatened.");
83 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
85 at(mtmp->mx,mtmp->my,mtmp->data->mlet);
87 pline("You sense the presence of monsters.");
92 case POT_OBJECT_DETECTION:
94 strange_feeling(otmp, "You feel a pull downward.");
97 for(objs = fobj; objs; objs = objs->nobj)
98 if(objs->ox != u.ux || objs->oy != u.uy)
100 pline("You sense the presence of objects close nearby.");
104 for(objs = fobj; objs; objs = objs->nobj)
105 at(objs->ox,objs->oy,objs->olet);
107 pline("You sense the presence of objects.");
113 pline("Yech! This stuff tastes like poison.");
114 if(Poison_resistance)
115 pline("(But in fact it was biologically contaminated orange juice.)");
117 losehp(rnd(10), "contaminated potion");
121 pline("Huh, What? Where am I?");
124 Confusion += rn1(7,16);
126 case POT_GAIN_STRENGTH:
127 pline("Wow do you feel strong!");
128 if(u.ustr >= 118) break; /* > 118 is impossible */
129 if(u.ustr > 17) u.ustr += rnd(118-u.ustr);
131 if(u.ustr > u.ustrmax) u.ustrmax = u.ustr;
140 if(!(Fast & ~INTRINSIC))
141 pline("You are suddenly moving much faster.");
143 pline("Your legs get new energy."), unkn++;
148 pline("A cloud of darkness falls upon you.");
151 Blind += rn1(100,250);
157 case POT_EXTRA_HEALING:
158 pline("You feel much better.");
162 u.uhp = (u.uhpmax += 2);
171 Levitation += rnd(100);
172 u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down;
175 impossible("What a funny potion! (%u)", otmp->otyp);
180 pline("You have a peculiar feeling for a moment, then it passes.");
182 if(otmp->dknown && !objects[otmp->otyp].oc_name_known) {
184 objects[otmp->otyp].oc_name_known = 1;
185 more_experienced(0,10);
186 } else if(!objects[otmp->otyp].oc_uname)
199 pline("You feel more experienced.");
204 u.uexp = newuexp()+1;
205 pline("Welcome to experience level %u.", ++u.ulevel);
211 strange_feeling(struct obj *obj, const char *txt)
214 pline("You have a strange feeling for a moment, then it passes.");
217 if(!objects[obj->otyp].oc_name_known && !objects[obj->otyp].oc_uname)
222 static const char *bottlenames[] = {
223 "bottle", "phial", "flagon", "carafe", "flask", "jar", "vial"
227 potionhit(struct monst *mon, struct obj *obj)
229 const char *botlnam = bottlenames[rn2(SIZE(bottlenames))];
230 boolean uclose, isyou = (mon == &youmonst);
234 pline("The %s crashes on your head and breaks into shivers.",
236 losehp(rnd(2), "thrown potion");
238 uclose = (dist(mon->mx,mon->my) < 3);
239 /* perhaps 'E' and 'a' have no head? */
240 pline("The %s crashes on %s's head and breaks into shivers.",
241 botlnam, monnam(mon));
242 if(rn2(5) && mon->mhp > 1)
245 pline("The %s evaporates.", xname(obj));
247 if(!isyou && !rn2(3)) switch(obj->otyp) {
249 case POT_RESTORE_STRENGTH:
250 case POT_GAIN_STRENGTH:
252 case POT_EXTRA_HEALING:
253 if(mon->mhp < mon->mhpmax) {
254 mon->mhp = mon->mhpmax;
255 pline("%s looks sound and hale again!", Monnam(mon));
268 case POT_INVISIBILITY:
280 mon->mblinded |= 64 + rn2(64);
285 case POT_FRUIT_JUICE:
286 case POT_MONSTER_DETECTION:
287 case POT_OBJECT_DETECTION:
293 obfree(obj, Null(obj));
297 potionbreathe(struct obj *obj)
300 case POT_RESTORE_STRENGTH:
301 case POT_GAIN_STRENGTH:
302 if(u.ustr < u.ustrmax) u.ustr++, flags.botl = 1;
305 case POT_EXTRA_HEALING:
306 if(u.uhp < u.uhpmax) u.uhp++, flags.botl = 1;
309 if(u.uhp <= 5) u.uhp = 1; else u.uhp -= 5;
315 pline("You feel somewhat dizzy.");
318 case POT_INVISIBILITY:
319 pline("For an instant you couldn't see your right hand.");
322 pline("Something seems to be holding you.");
327 pline("Your knees seem more flexible now.");
330 if(!Blind) pline("It suddenly gets dark.");
337 case POT_FRUIT_JUICE:
338 case POT_MONSTER_DETECTION:
339 case POT_OBJECT_DETECTION:
343 /* note: no obfree() */
347 * -- rudimentary -- to do this correctly requires much more work
348 * -- all sharp weapons get one or more qualities derived from the potions
349 * -- texts on scrolls may be (partially) wiped out; do they become blank?
350 * -- or does their effect change, like under Confusion?
351 * -- all objects may be made invisible by POT_INVISIBILITY
352 * -- If the flask is small, can one dip a large object? Does it magically
353 * -- become a jug? Etc.
358 struct obj *potion, *obj;
360 if(!(obj = getobj("#", "dip")))
362 if(!(potion = getobj("!", "dip into")))
364 pline("Interesting...");
365 if(obj->otyp == ARROW || obj->otyp == DART ||
366 obj->otyp == CROSSBOW_BOLT) {
367 if(potion->otyp == POT_SICKNESS) {
369 if(obj->spe < 7) obj->spe++; /* %% */
376 ghost_from_bottle(void)
380 if(!(mtmp = makemon(PM_GHOST,u.ux,u.uy))){
381 pline("This bottle turns out to be empty.");
385 pline("As you open the bottle, an enormous ghost emerges!");
386 pline("You are frightened to death, and unable to move.");