Mercurial > hg > early-roguelike
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 | |