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