]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - games/hack/hack.potion.c
This commit was generated by cvs2svn to compensate for changes in r43007,
[FreeBSD/FreeBSD.git] / games / hack / hack.potion.c
1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.potion.c - version 1.0.3 */
3
4 #include "hack.h"
5 extern int float_down();
6 extern char *nomovemsg;
7 extern struct monst youmonst;
8 extern struct monst *makemon();
9
10 dodrink() {
11         register struct obj *otmp,*objs;
12         register struct monst *mtmp;
13         register int unkn = 0, nothing = 0;
14
15         otmp = getobj("!", "drink");
16         if(!otmp) return(0);
17         if(!strcmp(objects[otmp->otyp].oc_descr, "smoky") && !rn2(13)) {
18                 ghost_from_bottle();
19                 goto use_it;
20         }
21         switch(otmp->otyp){
22         case POT_RESTORE_STRENGTH:
23                 unkn++;
24                 pline("Wow!  This makes you feel great!");
25                 if(u.ustr < u.ustrmax) {
26                         u.ustr = u.ustrmax;
27                         flags.botl = 1;
28                 }
29                 break;
30         case POT_BOOZE:
31                 unkn++;
32                 pline("Ooph!  This tastes like liquid fire!");
33                 Confusion += d(3,8);
34                 /* the whiskey makes us feel better */
35                 if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey");
36                 if(!rn2(4)) {
37                         pline("You pass out.");
38                         multi = -rnd(15);
39                         nomovemsg = "You awake with a headache.";
40                 }
41                 break;
42         case POT_INVISIBILITY:
43                 if(Invis || See_invisible)
44                   nothing++;
45                 else {
46                   if(!Blind)
47                     pline("Gee!  All of a sudden, you can't see yourself.");
48                   else
49                     pline("You feel rather airy."), unkn++;
50                   newsym(u.ux,u.uy);
51                 }
52                 Invis += rn1(15,31);
53                 break;
54         case POT_FRUIT_JUICE:
55                 pline("This tastes like fruit juice.");
56                 lesshungry(20);
57                 break;
58         case POT_HEALING:
59                 pline("You begin to feel better.");
60                 flags.botl = 1;
61                 u.uhp += rnd(10);
62                 if(u.uhp > u.uhpmax)
63                         u.uhp = ++u.uhpmax;
64                 if(Blind) Blind = 1;    /* see on next move */
65                 if(Sick) Sick = 0;
66                 break;
67         case POT_PARALYSIS:
68                 if(Levitation)
69                         pline("You are motionlessly suspended.");
70                 else
71                         pline("Your feet are frozen to the floor!");
72                 nomul(-(rn1(10,25)));
73                 break;
74         case POT_MONSTER_DETECTION:
75                 if(!fmon) {
76                         strange_feeling(otmp, "You feel threatened.");
77                         return(1);
78                 } else {
79                         cls();
80                         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
81                                 if(mtmp->mx > 0)
82                                 at(mtmp->mx,mtmp->my,mtmp->data->mlet);
83                         prme();
84                         pline("You sense the presence of monsters.");
85                         more();
86                         docrt();
87                 }
88                 break;
89         case POT_OBJECT_DETECTION:
90                 if(!fobj) {
91                         strange_feeling(otmp, "You feel a pull downward.");
92                         return(1);
93                 } else {
94                     for(objs = fobj; objs; objs = objs->nobj)
95                         if(objs->ox != u.ux || objs->oy != u.uy)
96                                 goto outobjmap;
97                     pline("You sense the presence of objects close nearby.");
98                     break;
99                 outobjmap:
100                         cls();
101                         for(objs = fobj; objs; objs = objs->nobj)
102                                 at(objs->ox,objs->oy,objs->olet);
103                         prme();
104                         pline("You sense the presence of objects.");
105                         more();
106                         docrt();
107                 }
108                 break;
109         case POT_SICKNESS:
110                 pline("Yech! This stuff tastes like poison.");
111                 if(Poison_resistance)
112     pline("(But in fact it was biologically contaminated orange juice.)");
113                 losestr(rn1(4,3));
114                 losehp(rnd(10), "contaminated potion");
115                 break;
116         case POT_CONFUSION:
117                 if(!Confusion)
118                         pline("Huh, What?  Where am I?");
119                 else
120                         nothing++;
121                 Confusion += rn1(7,16);
122                 break;
123         case POT_GAIN_STRENGTH:
124                 pline("Wow do you feel strong!");
125                 if(u.ustr >= 118) break;        /* > 118 is impossible */
126                 if(u.ustr > 17) u.ustr += rnd(118-u.ustr);
127                 else u.ustr++;
128                 if(u.ustr > u.ustrmax) u.ustrmax = u.ustr;
129                 flags.botl = 1;
130                 break;
131         case POT_SPEED:
132                 if(Wounded_legs) {
133                         heal_legs();
134                         unkn++;
135                         break;
136                 }
137                 if(!(Fast & ~INTRINSIC))
138                         pline("You are suddenly moving much faster.");
139                 else
140                         pline("Your legs get new energy."), unkn++;
141                 Fast += rn1(10,100);
142                 break;
143         case POT_BLINDNESS:
144                 if(!Blind)
145                         pline("A cloud of darkness falls upon you.");
146                 else
147                         nothing++;
148                 Blind += rn1(100,250);
149                 seeoff(0);
150                 break;
151         case POT_GAIN_LEVEL:
152                 pluslvl();
153                 break;
154         case POT_EXTRA_HEALING:
155                 pline("You feel much better.");
156                 flags.botl = 1;
157                 u.uhp += d(2,20)+1;
158                 if(u.uhp > u.uhpmax)
159                         u.uhp = (u.uhpmax += 2);
160                 if(Blind) Blind = 1;
161                 if(Sick) Sick = 0;
162                 break;
163         case POT_LEVITATION:
164                 if(!Levitation)
165                         float_up();
166                 else
167                         nothing++;
168                 Levitation += rnd(100);
169                 u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down;
170                 break;
171         default:
172                 impossible("What a funny potion! (%u)", otmp->otyp);
173                 return(0);
174         }
175         if(nothing) {
176             unkn++;
177             pline("You have a peculiar feeling for a moment, then it passes.");
178         }
179         if(otmp->dknown && !objects[otmp->otyp].oc_name_known) {
180                 if(!unkn) {
181                         objects[otmp->otyp].oc_name_known = 1;
182                         more_experienced(0,10);
183                 } else if(!objects[otmp->otyp].oc_uname)
184                         docall(otmp);
185         }
186 use_it:
187         useup(otmp);
188         return(1);
189 }
190
191 pluslvl()
192 {
193         register num;
194
195         pline("You feel more experienced.");
196         num = rnd(10);
197         u.uhpmax += num;
198         u.uhp += num;
199         if(u.ulevel < 14) {
200                 extern long newuexp();
201
202                 u.uexp = newuexp()+1;
203                 pline("Welcome to experience level %u.", ++u.ulevel);
204         }
205         flags.botl = 1;
206 }
207
208 strange_feeling(obj,txt)
209 register struct obj *obj;
210 register char *txt;
211 {
212         if(flags.beginner)
213             pline("You have a strange feeling for a moment, then it passes.");
214         else
215             pline(txt);
216         if(!objects[obj->otyp].oc_name_known && !objects[obj->otyp].oc_uname)
217                 docall(obj);
218         useup(obj);
219 }
220
221 char *bottlenames[] = {
222         "bottle", "phial", "flagon", "carafe", "flask", "jar", "vial"
223 };
224
225 potionhit(mon, obj)
226 register struct monst *mon;
227 register struct obj *obj;
228 {
229         extern char *xname();
230         register char *botlnam = bottlenames[rn2(SIZE(bottlenames))];
231         boolean uclose, isyou = (mon == &youmonst);
232
233         if(isyou) {
234                 uclose = TRUE;
235                 pline("The %s crashes on your head and breaks into shivers.",
236                         botlnam);
237                 losehp(rnd(2), "thrown potion");
238         } else {
239                 uclose = (dist(mon->mx,mon->my) < 3);
240                 /* perhaps 'E' and 'a' have no head? */
241                 pline("The %s crashes on %s's head and breaks into shivers.",
242                         botlnam, monnam(mon));
243                 if(rn2(5) && mon->mhp > 1)
244                         mon->mhp--;
245         }
246         pline("The %s evaporates.", xname(obj));
247
248         if(!isyou && !rn2(3)) switch(obj->otyp) {
249
250         case POT_RESTORE_STRENGTH:
251         case POT_GAIN_STRENGTH:
252         case POT_HEALING:
253         case POT_EXTRA_HEALING:
254                 if(mon->mhp < mon->mhpmax) {
255                         mon->mhp = mon->mhpmax;
256                         pline("%s looks sound and hale again!", Monnam(mon));
257                 }
258                 break;
259         case POT_SICKNESS:
260                 if(mon->mhpmax > 3)
261                         mon->mhpmax /= 2;
262                 if(mon->mhp > 2)
263                         mon->mhp /= 2;
264                 break;
265         case POT_CONFUSION:
266         case POT_BOOZE:
267                 mon->mconf = 1;
268                 break;
269         case POT_INVISIBILITY:
270                 unpmon(mon);
271                 mon->minvis = 1;
272                 pmon(mon);
273                 break;
274         case POT_PARALYSIS:
275                 mon->mfroz = 1;
276                 break;
277         case POT_SPEED:
278                 mon->mspeed = MFAST;
279                 break;
280         case POT_BLINDNESS:
281                 mon->mblinded |= 64 + rn2(64);
282                 break;
283 /*
284         case POT_GAIN_LEVEL:
285         case POT_LEVITATION:
286         case POT_FRUIT_JUICE:
287         case POT_MONSTER_DETECTION:
288         case POT_OBJECT_DETECTION:
289                 break;
290 */
291         }
292         if(uclose && rn2(5))
293                 potionbreathe(obj);
294         obfree(obj, Null(obj));
295 }
296
297 potionbreathe(obj)
298 register struct obj *obj;
299 {
300         switch(obj->otyp) {
301         case POT_RESTORE_STRENGTH:
302         case POT_GAIN_STRENGTH:
303                 if(u.ustr < u.ustrmax) u.ustr++, flags.botl = 1;
304                 break;
305         case POT_HEALING:
306         case POT_EXTRA_HEALING:
307                 if(u.uhp < u.uhpmax) u.uhp++, flags.botl = 1;
308                 break;
309         case POT_SICKNESS:
310                 if(u.uhp <= 5) u.uhp = 1; else u.uhp -= 5;
311                 flags.botl = 1;
312                 break;
313         case POT_CONFUSION:
314         case POT_BOOZE:
315                 if(!Confusion)
316                         pline("You feel somewhat dizzy.");
317                 Confusion += rnd(5);
318                 break;
319         case POT_INVISIBILITY:
320                 pline("For an instant you couldn't see your right hand.");
321                 break;
322         case POT_PARALYSIS:
323                 pline("Something seems to be holding you.");
324                 nomul(-rnd(5));
325                 break;
326         case POT_SPEED:
327                 Fast += rnd(5);
328                 pline("Your knees seem more flexible now.");
329                 break;
330         case POT_BLINDNESS:
331                 if(!Blind) pline("It suddenly gets dark.");
332                 Blind += rnd(5);
333                 seeoff(0);
334                 break;
335 /*
336         case POT_GAIN_LEVEL:
337         case POT_LEVITATION:
338         case POT_FRUIT_JUICE:
339         case POT_MONSTER_DETECTION:
340         case POT_OBJECT_DETECTION:
341                 break;
342 */
343         }
344         /* note: no obfree() */
345 }
346
347 /*
348  * -- rudimentary -- to do this correctly requires much more work
349  * -- all sharp weapons get one or more qualities derived from the potions
350  * -- texts on scrolls may be (partially) wiped out; do they become blank?
351  * --   or does their effect change, like under Confusion?
352  * -- all objects may be made invisible by POT_INVISIBILITY
353  * -- If the flask is small, can one dip a large object? Does it magically
354  * --   become a jug? Etc.
355  */
356 dodip(){
357         register struct obj *potion, *obj;
358
359         if(!(obj = getobj("#", "dip")))
360                 return(0);
361         if(!(potion = getobj("!", "dip into")))
362                 return(0);
363         pline("Interesting...");
364         if(obj->otyp == ARROW || obj->otyp == DART ||
365            obj->otyp == CROSSBOW_BOLT) {
366                 if(potion->otyp == POT_SICKNESS) {
367                         useup(potion);
368                         if(obj->spe < 7) obj->spe++;    /* %% */
369                 }
370         }
371         return(1);
372 }
373
374 ghost_from_bottle(){
375         extern struct permonst pm_ghost;
376         register struct monst *mtmp;
377
378         if(!(mtmp = makemon(PM_GHOST,u.ux,u.uy))){
379                 pline("This bottle turns out to be empty.");
380                 return;
381         }
382         mnexto(mtmp);
383         pline("As you open the bottle, an enormous ghost emerges!");
384         pline("You are frightened to death, and unable to move.");
385         nomul(-3);
386 }