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.3 2005/05/22 03:37:05 y0netan1 Exp $ */
7 extern int float_down();
8 extern struct monst youmonst;
9 extern struct monst *makemon();
12 struct obj *otmp,*objs;
14 int unkn = 0, nothing = 0;
16 otmp = getobj("!", "drink");
18 if(!strcmp(objects[otmp->otyp].oc_descr, "smoky") && !rn2(13)) {
23 case POT_RESTORE_STRENGTH:
25 pline("Wow! This makes you feel great!");
26 if(u.ustr < u.ustrmax) {
33 pline("Ooph! This tastes like liquid fire!");
35 /* the whiskey makes us feel better */
36 if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey");
38 pline("You pass out.");
40 nomovemsg = "You awake with a headache.";
43 case POT_INVISIBILITY:
44 if(Invis || See_invisible)
48 pline("Gee! All of a sudden, you can't see yourself.");
50 pline("You feel rather airy."), unkn++;
56 pline("This tastes like fruit juice.");
60 pline("You begin to feel better.");
65 if(Blind) Blind = 1; /* see on next move */
70 pline("You are motionlessly suspended.");
72 pline("Your feet are frozen to the floor!");
75 case POT_MONSTER_DETECTION:
77 strange_feeling(otmp, "You feel threatened.");
81 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
83 at(mtmp->mx,mtmp->my,mtmp->data->mlet);
85 pline("You sense the presence of monsters.");
90 case POT_OBJECT_DETECTION:
92 strange_feeling(otmp, "You feel a pull downward.");
95 for(objs = fobj; objs; objs = objs->nobj)
96 if(objs->ox != u.ux || objs->oy != u.uy)
98 pline("You sense the presence of objects close nearby.");
102 for(objs = fobj; objs; objs = objs->nobj)
103 at(objs->ox,objs->oy,objs->olet);
105 pline("You sense the presence of objects.");
111 pline("Yech! This stuff tastes like poison.");
112 if(Poison_resistance)
113 pline("(But in fact it was biologically contaminated orange juice.)");
115 losehp(rnd(10), "contaminated potion");
119 pline("Huh, What? Where am I?");
122 Confusion += rn1(7,16);
124 case POT_GAIN_STRENGTH:
125 pline("Wow do you feel strong!");
126 if(u.ustr >= 118) break; /* > 118 is impossible */
127 if(u.ustr > 17) u.ustr += rnd(118-u.ustr);
129 if(u.ustr > u.ustrmax) u.ustrmax = u.ustr;
138 if(!(Fast & ~INTRINSIC))
139 pline("You are suddenly moving much faster.");
141 pline("Your legs get new energy."), unkn++;
146 pline("A cloud of darkness falls upon you.");
149 Blind += rn1(100,250);
155 case POT_EXTRA_HEALING:
156 pline("You feel much better.");
160 u.uhp = (u.uhpmax += 2);
169 Levitation += rnd(100);
170 u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down;
173 impossible("What a funny potion! (%u)", otmp->otyp);
178 pline("You have a peculiar feeling for a moment, then it passes.");
180 if(otmp->dknown && !objects[otmp->otyp].oc_name_known) {
182 objects[otmp->otyp].oc_name_known = 1;
183 more_experienced(0,10);
184 } else if(!objects[otmp->otyp].oc_uname)
196 pline("You feel more experienced.");
201 extern long newuexp();
203 u.uexp = newuexp()+1;
204 pline("Welcome to experience level %u.", ++u.ulevel);
209 strange_feeling(obj,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"
230 extern char *xname();
231 const char *botlnam = bottlenames[rn2(SIZE(bottlenames))];
232 boolean uclose, isyou = (mon == &youmonst);
236 pline("The %s crashes on your head and breaks into shivers.",
238 losehp(rnd(2), "thrown potion");
240 uclose = (dist(mon->mx,mon->my) < 3);
241 /* perhaps 'E' and 'a' have no head? */
242 pline("The %s crashes on %s's head and breaks into shivers.",
243 botlnam, monnam(mon));
244 if(rn2(5) && mon->mhp > 1)
247 pline("The %s evaporates.", xname(obj));
249 if(!isyou && !rn2(3)) switch(obj->otyp) {
251 case POT_RESTORE_STRENGTH:
252 case POT_GAIN_STRENGTH:
254 case POT_EXTRA_HEALING:
255 if(mon->mhp < mon->mhpmax) {
256 mon->mhp = mon->mhpmax;
257 pline("%s looks sound and hale again!", Monnam(mon));
270 case POT_INVISIBILITY:
282 mon->mblinded |= 64 + rn2(64);
287 case POT_FRUIT_JUICE:
288 case POT_MONSTER_DETECTION:
289 case POT_OBJECT_DETECTION:
295 obfree(obj, Null(obj));
302 case POT_RESTORE_STRENGTH:
303 case POT_GAIN_STRENGTH:
304 if(u.ustr < u.ustrmax) u.ustr++, flags.botl = 1;
307 case POT_EXTRA_HEALING:
308 if(u.uhp < u.uhpmax) u.uhp++, flags.botl = 1;
311 if(u.uhp <= 5) u.uhp = 1; else u.uhp -= 5;
317 pline("You feel somewhat dizzy.");
320 case POT_INVISIBILITY:
321 pline("For an instant you couldn't see your right hand.");
324 pline("Something seems to be holding you.");
329 pline("Your knees seem more flexible now.");
332 if(!Blind) pline("It suddenly gets dark.");
339 case POT_FRUIT_JUICE:
340 case POT_MONSTER_DETECTION:
341 case POT_OBJECT_DETECTION:
345 /* note: no obfree() */
349 * -- rudimentary -- to do this correctly requires much more work
350 * -- all sharp weapons get one or more qualities derived from the potions
351 * -- texts on scrolls may be (partially) wiped out; do they become blank?
352 * -- or does their effect change, like under Confusion?
353 * -- all objects may be made invisible by POT_INVISIBILITY
354 * -- If the flask is small, can one dip a large object? Does it magically
355 * -- 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 extern struct permonst pm_ghost;
379 if(!(mtmp = makemon(PM_GHOST,u.ux,u.uy))){
380 pline("This bottle turns out to be empty.");
384 pline("As you open the bottle, an enormous ghost emerges!");
385 pline("You are frightened to death, and unable to move.");