comparison urogue/potions.c @ 256:c495a4f288c6

Import UltraRogue from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 31 Jan 2017 19:56:04 -0500
parents
children 0250220d8cdd
comparison
equal deleted inserted replaced
253:d9badb9c0179 256:c495a4f288c6
1 /*
2 potions.c - Functions for dealing with potions
3
4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom
5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
10 All rights reserved.
11
12 Based on "Rogue: Exploring the Dungeons of Doom"
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
14 All rights reserved.
15
16 See the file LICENSE.TXT for full copyright and licensing information.
17 */
18
19 #include <string.h>
20 #include <stdlib.h>
21 #include "rogue.h"
22
23 /*
24 quaff - drink a potion (or effect a potion-like spell)
25
26 quaffer: who does it
27 which: which P_POTION (-1 means ask from pack)
28 flags: ISBLESSED, ISCURSED
29 */
30
31 void
32 quaff(struct thing *quaffer, int which, int flags)
33 {
34 struct object *obj;
35 struct thing *th;
36 struct stats *curp = &(quaffer->t_stats);
37 struct stats *maxp = &(quaffer->maxstats);
38 int blessed = flags & ISBLESSED;
39 int cursed = flags & ISCURSED;
40 int is_potion = (which < 0 ? TRUE : FALSE);
41
42 struct linked_list *item, *titem;
43 char buf[2 * LINELEN];
44
45 if (quaffer != &player)
46 {
47 monquaff(quaffer, which, flags);
48 return;
49 }
50
51 if (is_potion) /* A regular potion */
52 {
53 if ((item = get_item("quaff", POTION)) == NULL)
54 return;
55
56 obj = OBJPTR(item);
57
58 if (obj->o_type != POTION)
59 {
60 msg("You can't drink that!");
61 return;
62 }
63
64 /* Calculate its effect */
65
66 flags = obj->o_flags;
67 cursed = obj->o_flags & ISCURSED;
68 blessed = obj->o_flags & ISBLESSED;
69 which = obj->o_which;
70
71 /* remove it from the pack */
72
73 rem_pack(obj);
74 discard(item);
75 updpack();
76 }
77
78 switch(which)
79 {
80 case P_CLEAR:
81 if (cursed)
82 {
83 if (off(player, ISCLEAR))
84 {
85 msg("Wait, what's going on here. Huh? What? Who?");
86
87 if (on(player, ISHUH))
88 lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
89 else
90 light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER);
91
92 turn_on(player, ISHUH);
93 }
94 else
95 msg("You feel dizzy for a moment, but it passes.");
96 }
97 else
98 {
99 if (blessed) /* Make player immune for the whole game */
100 {
101 extinguish_fuse(FUSE_UNCLRHEAD); /* If we have a fuse, put it out */
102 msg("A strong blue aura surrounds your head.");
103 }
104 else /* Just light a fuse for how long player is safe */
105 {
106 if (off(player, ISCLEAR))
107 {
108 light_fuse(FUSE_UNCLRHEAD, 0, CLRDURATION, AFTER);
109 msg("A faint blue aura surrounds your head.");
110 }
111 else /* If have fuse lengthen, else permanently clear */
112 {
113 if (find_slot(FUSE_UNCLRHEAD,FUSE) == NULL)
114 msg("Your blue aura continues to glow strongly.");
115 else
116 {
117 lengthen_fuse(FUSE_UNCLRHEAD, CLRDURATION);
118 msg("Your blue aura brightens for a moment.");
119 }
120 }
121 }
122
123 turn_on(player, ISCLEAR);
124
125 /* If player is confused, unconfuse him */
126
127 if (on(player, ISHUH))
128 {
129 extinguish_fuse(FUSE_UNCONFUSE);
130 unconfuse(NULL);
131 }
132 }
133 break;
134
135 case P_HEALING:
136 if (cursed)
137 {
138 if (player.t_ctype != C_PALADIN
139 && !(player.t_ctype == C_NINJA
140 && curp->s_lvl > 12)
141 && !save(VS_POISON))
142 {
143 feel_message();
144 curp->s_hpt /= 2;
145 curp->s_power /= 2;
146
147 if ((curp->s_hpt -= 1) <= 0)
148 {
149 death(D_POISON);
150 return;
151 }
152 }
153 else
154 msg("You feel momentarily sick.");
155 }
156 else
157 {
158 int nsides = (blessed ? 8 : 4);
159 int hpt_gain = roll(curp->s_lvl, nsides);
160 int power_gain = roll(curp->s_lvl, nsides);
161
162 if (blessed && on(player, ISHUH))
163 {
164 extinguish_fuse(FUSE_UNCONFUSE);
165 unconfuse(NULL);
166 }
167
168 curp->s_hpt = min(curp->s_hpt + hpt_gain, maxp->s_hpt);
169
170 if (is_potion) /* Do not bump power or maximums if spell */
171 {
172 know_items[TYP_POTION][P_HEALING] = TRUE;
173 curp->s_power = min(curp->s_power + power_gain, maxp->s_power);
174
175 if (maxp->s_hpt == curp->s_hpt)
176 maxp->s_hpt = curp->s_hpt += roll(1, nsides);
177
178 if (maxp->s_power == curp->s_power)
179 maxp->s_power = curp->s_power += roll(1, nsides);
180 }
181
182 msg("You begin to feel %sbetter.", blessed ? "much " : "");
183
184 if (off(player, PERMBLIND))
185 sight(NULL);
186 }
187 break;
188
189 case P_GAINABIL:
190 {
191 int ctype;
192
193 if (!is_potion || pstats.s_arm <= 0)
194 feel_message();
195 else
196 {
197 if (blessed) /* add to all attributes */
198 {
199 add_intelligence(FALSE);
200 add_dexterity(FALSE);
201 add_strength(FALSE);
202 add_wisdom(FALSE);
203 add_const(FALSE);
204 }
205 else
206 {
207 if (rnd(100) < 70)
208 /* probably change own ability */
209 ctype = player.t_ctype;
210 else
211 switch(rnd(4))
212 {
213 case 0: ctype = C_FIGHTER; break;
214 case 1: ctype = C_MAGICIAN; break;
215 case 2: ctype = C_CLERIC; break;
216 case 3: ctype = C_THIEF; break;
217 }
218 switch (ctype)
219 {
220 case C_FIGHTER:add_strength(cursed); break;
221 case C_PALADIN:add_strength(cursed); break;
222 case C_RANGER:add_strength(cursed); break;
223 case C_MAGICIAN:add_intelligence(cursed); break;
224 case C_ILLUSION:add_intelligence(cursed); break;
225 case C_CLERIC:add_wisdom(cursed); break;
226 case C_DRUID:add_wisdom(cursed); break;
227 case C_THIEF:add_dexterity(cursed); break;
228 case C_ASSASIN:add_dexterity(cursed); break;
229 case C_NINJA:add_dexterity(cursed); break;
230 default: msg("You're a strange type!"); break;
231 }
232 }
233
234 if (rnd(100) < 10)
235 add_const(cursed);
236
237 if (rnd(100) < 60)
238 curp->s_arm += (cursed ? 1 : -1);
239
240 if (!cursed)
241 know_items[TYP_POTION][P_GAINABIL] = TRUE;
242 }
243 }
244 break;
245
246 case P_MONSTDET:
247
248 /*
249 * Potion of monster detection, if there are monsters,
250 * detect them
251 */
252
253 if (is_potion)
254 know_items[TYP_POTION][P_MONSTDET] = TRUE;
255
256 if (cursed)
257 {
258 int nm = roll(3, 6);
259 int i;
260 char ch;
261 struct room *rp;
262 coord pos;
263
264 msg("You begin to sense the presence of monsters.");
265 wclear(hw);
266
267 for (i = 1; i < nm; i++)
268 {
269 rp = &rooms[rnd_room()];
270 rnd_pos(rp, &pos);
271
272 if (rnd(2))
273 ch = 'a' + ucrnd(26);
274 else
275 ch = 'A' + ucrnd(26);
276
277 mvwaddch(hw, pos.y, pos.x, ch);
278 }
279 waddstr(cw, morestr);
280 overlay(hw, cw);
281 wrefresh(cw);
282 wait_for(' ');
283 msg("");
284 }
285 else if (mlist != NULL)
286 {
287 msg("You begin to sense the presence of monsters.");
288 waddstr(cw, morestr);
289 overlay(mw, cw);
290 wrefresh(cw);
291 wait_for(' ');
292 msg("");
293
294 if (blessed)
295 turn_on(player, BLESSMONS);
296 }
297 else
298 nothing_message(flags);
299 break;
300
301 case P_TREASDET:
302
303 /* Potion of magic detection. Show the potions and scrolls */
304
305 if (cursed)
306 {
307 int nm = roll(3, 3);
308 int i;
309 char ch;
310 struct room *rp;
311 coord pos;
312
313 msg("You sense the presence of magic on this level.");
314 wclear(hw);
315
316 for (i = 1; i < nm; i++)
317 {
318 rp = &rooms[rnd_room()];
319 rnd_pos(rp, &pos);
320
321 if (rnd(9) == 0)
322 ch = BMAGIC;
323 else if (rnd(9) == 0)
324 ch = CMAGIC;
325 else
326 ch = MAGIC;
327
328 mvwaddch(hw, pos.y, pos.x, ch);
329 }
330 waddstr(cw, morestr);
331
332 overlay(hw, cw);
333 wrefresh(cw);
334 wait_for(' ');
335 msg("");
336
337 if (is_potion)
338 know_items[TYP_POTION][P_TREASDET] = TRUE;
339
340 break;
341 }
342
343 if (blessed)
344 turn_on(player, BLESSMAGIC);
345
346 if (lvl_obj != NULL)
347 {
348 struct linked_list *mobj;
349 struct object *tp;
350 int showit;
351
352 showit = FALSE;
353 wclear(hw);
354
355 for (mobj = lvl_obj; mobj != NULL; mobj = next(mobj))
356 {
357 tp = OBJPTR(mobj);
358
359 if (is_magic(tp))
360 {
361 char mag_type = MAGIC;
362