Mercurial > hg > early-roguelike
comparison rogue5/potions.c @ 33:f502bf60e6e4
Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
author | elwin |
---|---|
date | Mon, 24 May 2010 20:10:59 +0000 |
parents | |
children | 696277507a2e |
comparison
equal
deleted
inserted
replaced
32:2dcd75e6a736 | 33:f502bf60e6e4 |
---|---|
1 /* | |
2 * Function(s) for dealing with potions | |
3 * | |
4 * @(#)potions.c 4.46 (Berkeley) 06/07/83 | |
5 * | |
6 * Rogue: Exploring the Dungeons of Doom | |
7 * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman | |
8 * All rights reserved. | |
9 * | |
10 * See the file LICENSE.TXT for full copyright and licensing information. | |
11 */ | |
12 | |
13 #include <curses.h> | |
14 #include <ctype.h> | |
15 #include "rogue.h" | |
16 | |
17 typedef struct PACT | |
18 { | |
19 const int pa_flags; | |
20 void (*pa_daemon)(); | |
21 const int pa_time; | |
22 const char *pa_high, *pa_straight; | |
23 } PACT; | |
24 | |
25 static const PACT p_actions[] = | |
26 { | |
27 { ISHUH, unconfuse, HUHDURATION, /* P_CONFUSE */ | |
28 "what a tripy feeling!", | |
29 "wait, what's going on here. Huh? What? Who?" }, | |
30 { ISHALU, come_down, SEEDURATION, /* P_LSD */ | |
31 "Oh, wow! Everything seems so cosmic!", | |
32 "Oh, wow! Everything seems so cosmic!" }, | |
33 { 0, NULL, 0 }, /* P_POISON */ | |
34 { 0, NULL, 0 }, /* P_STRENGTH */ | |
35 { CANSEE, unsee, SEEDURATION, /* P_SEEINVIS */ | |
36 prbuf, | |
37 prbuf }, | |
38 { 0, NULL, 0 }, /* P_HEALING */ | |
39 { 0, NULL, 0 }, /* P_MFIND */ | |
40 { 0, NULL, 0 }, /* P_TFIND */ | |
41 { 0, NULL, 0 }, /* P_RAISE */ | |
42 { 0, NULL, 0 }, /* P_XHEAL */ | |
43 { 0, NULL, 0 }, /* P_HASTE */ | |
44 { 0, NULL, 0 }, /* P_RESTORE */ | |
45 { ISBLIND, sight, SEEDURATION, /* P_BLIND */ | |
46 "oh, bummer! Everything is dark! Help!", | |
47 "a cloak of darkness falls around you" }, | |
48 { ISLEVIT, land, HEALTIME, /* P_LEVIT */ | |
49 "oh, wow! You're floating in the air!", | |
50 "you start to float in the air" } | |
51 }; | |
52 | |
53 /* | |
54 * quaff: | |
55 * Quaff a potion from the pack | |
56 */ | |
57 | |
58 void | |
59 quaff(void) | |
60 { | |
61 THING *obj, *tp, *mp; | |
62 int discardit = FALSE; | |
63 int show, trip; | |
64 | |
65 obj = get_item("quaff", POTION); | |
66 /* | |
67 * Make certain that it is somethings that we want to drink | |
68 */ | |
69 if (obj == NULL) | |
70 return; | |
71 if (obj->o_type != POTION) | |
72 { | |
73 if (!terse) | |
74 msg("yuk! Why would you want to drink that?"); | |
75 else | |
76 msg("that's undrinkable"); | |
77 return; | |
78 } | |
79 if (obj == cur_weapon) | |
80 cur_weapon = NULL; | |
81 | |
82 /* | |
83 * Calculate the effect it has on the poor guy. | |
84 */ | |
85 trip = on(player, ISHALU); | |
86 discardit = (obj->o_count == 1); | |
87 leave_pack(obj, FALSE, FALSE); | |
88 switch (obj->o_which) | |
89 { | |
90 case P_CONFUSE: | |
91 do_pot(P_CONFUSE, !trip); | |
92 when P_POISON: | |
93 pot_info[P_POISON].oi_know = TRUE; | |
94 if (ISWEARING(R_SUSTSTR)) | |
95 msg("you feel momentarily sick"); | |
96 else | |
97 { | |
98 chg_str(-(rnd(3) + 1)); | |
99 msg("you feel very sick now"); | |
100 come_down(); | |
101 } | |
102 when P_HEALING: | |
103 pot_info[P_HEALING].oi_know = TRUE; | |
104 if ((pstats.s_hpt += roll(pstats.s_lvl, 4)) > max_hp) | |
105 pstats.s_hpt = ++max_hp; | |
106 sight(); | |
107 msg("you begin to feel better"); | |
108 when P_STRENGTH: | |
109 pot_info[P_STRENGTH].oi_know = TRUE; | |
110 chg_str(1); | |
111 msg("you feel stronger, now. What bulging muscles!"); | |
112 when P_MFIND: | |
113 player.t_flags |= SEEMONST; | |
114 fuse((void(*)())turn_see, TRUE, HUHDURATION, AFTER); | |
115 if (!turn_see(FALSE)) | |
116 msg("you have a %s feeling for a moment, then it passes", | |
117 choose_str("normal", "strange")); | |
118 when P_TFIND: | |
119 /* | |
120 * Potion of magic detection. Show the potions and scrolls | |
121 */ | |
122 show = FALSE; | |
123 if (lvl_obj != NULL) | |
124 { | |
125 wclear(hw); | |
126 for (tp = lvl_obj; tp != NULL; tp = next(tp)) | |
127 { | |
128 if (is_magic(tp)) | |
129 { | |
130 show = TRUE; | |
131 wmove(hw, tp->o_pos.y, tp->o_pos.x); | |
132 waddch(hw, MAGIC); | |
133 pot_info[P_TFIND].oi_know = TRUE; | |
134 } | |
135 } | |
136 for (mp = mlist; mp != NULL; mp = next(mp)) | |
137 { | |
138 for (tp = mp->t_pack; tp != NULL; tp = next(tp)) | |
139 { | |
140 if (is_magic(tp)) | |
141 { | |
142 show = TRUE; | |
143 wmove(hw, mp->t_pos.y, mp->t_pos.x); | |
144 waddch(hw, MAGIC); | |
145 } | |
146 } | |
147 } | |
148 } | |
149 if (show) | |
150 { | |
151 pot_info[P_TFIND].oi_know = TRUE; | |
152 show_win("You sense the presence of magic on this level.--More--"); | |
153 } | |
154 else | |
155 msg("you have a %s feeling for a moment, then it passes", | |
156 choose_str("normal", "strange")); | |
157 when P_LSD: | |
158 if (!trip) | |
159 { | |
160 if (on(player, SEEMONST)) | |
161 turn_see(FALSE); | |
162 start_daemon(visuals, 0, BEFORE); | |
163 seenstairs = seen_stairs(); | |
164 } | |
165 do_pot(P_LSD, TRUE); | |
166 when P_SEEINVIS: | |
167 sprintf(prbuf, "this potion tastes like %s juice", fruit); | |
168 show = on(player, CANSEE); | |
169 do_pot(P_SEEINVIS, FALSE); | |
170 if (!show) | |
171 invis_on(); | |
172 sight(); | |
173 when P_RAISE: | |
174 pot_info[P_RAISE].oi_know = TRUE; | |
175 msg("you suddenly feel much more skillful"); | |
176 raise_level(); | |
177 when P_XHEAL: | |
178 pot_info[P_XHEAL].oi_know = TRUE; | |
179 if ((pstats.s_hpt += roll(pstats.s_lvl, 8)) > max_hp) | |
180 { | |
181 if (pstats.s_hpt > max_hp + pstats.s_lvl + 1) | |
182 ++max_hp; | |
183 pstats.s_hpt = ++max_hp; | |
184 } | |
185 sight(); | |
186 come_down(); | |
187 msg("you begin to feel much better"); | |
188 when P_HASTE: | |
189 pot_info[P_HASTE].oi_know = TRUE; | |
190 after = FALSE; | |
191 if (add_haste(TRUE)) | |
192 msg("you feel yourself moving much faster"); | |
193 when P_RESTORE: | |
194 if (ISRING(LEFT, R_ADDSTR)) | |
195 add_str(&pstats.s_str, -cur_ring[LEFT]->o_arm); | |
196 if (ISRING(RIGHT, R_ADDSTR)) | |
197 add_str(&pstats.s_str, -cur_ring[RIGHT]->o_arm); | |
198 if (pstats.s_str < max_stats.s_str) | |
199 pstats.s_str = max_stats.s_str; | |
200 if (ISRING(LEFT, R_ADDSTR)) | |
201 add_str(&pstats.s_str, cur_ring[LEFT]->o_arm); | |
202 if (ISRING(RIGHT, R_ADDSTR)) | |
203 add_str(&pstats.s_str, cur_ring[RIGHT]->o_arm); | |
204 msg("hey, this tastes great. It make you feel warm all over"); | |
205 when P_BLIND: | |
206 do_pot(P_BLIND, TRUE); | |
207 when P_LEVIT: | |
208 do_pot(P_LEVIT, TRUE); | |
209 #ifdef MASTER | |
210 otherwise: | |
211 msg("what an odd tasting potion!"); | |
212 return; | |
213 #endif | |
214 } | |
215 status(); | |
216 /* | |
217 * Throw the item away | |
218 */ | |
219 | |
220 call_it(&pot_info[obj->o_which]); | |
221 | |
222 if (discardit) | |
223 discard(obj); | |
224 return; | |
225 } | |
226 | |
227 /* | |
228 * is_magic: | |
229 * Returns true if an object radiates magic | |
230 */ | |
231 int | |
232 is_magic(const THING *obj) | |
233 { | |
234 switch (obj->o_type) | |
235 { | |
236 case ARMOR: | |
237 return ((obj->o_flags&ISPROT) || obj->o_arm != a_class[obj->o_which]); | |
238 case WEAPON: | |
239 return (obj->o_hplus != 0 || obj->o_dplus != 0); | |
240 case POTION: | |
241 case SCROLL: | |
242 case STICK: | |
243 case RING: | |
244 case AMULET: | |
245 return TRUE; | |
246 } | |
247 return FALSE; | |
248 } | |
249 | |
250 /* | |
251 * invis_on: | |
252 * Turn on the ability to see invisible | |
253 */ | |
254 | |
255 void | |
256 invis_on(void) | |
257 { | |
258 THING *mp; | |
259 | |
260 player.t_flags |= CANSEE; | |
261 for (mp = mlist; mp != NULL; mp = next(mp)) | |
262 if (on(*mp, ISINVIS) && see_monst(mp) && !on(player, ISHALU)) | |
263 mvaddch(mp->t_pos.y, mp->t_pos.x, mp->t_disguise); | |
264 } | |
265 | |
266 /* | |
267 * turn_see: | |
268 * Put on or off seeing monsters on this level | |
269 */ | |
270 int | |
271 turn_see(int turn_off) | |
272 { | |
273 THING *mp; | |
274 int can_see, add_new; | |
275 | |
276 add_new = FALSE; | |
277 for (mp = mlist; mp != NULL; mp = next(mp)) | |
278 { | |
279 move(mp->t_pos.y, mp->t_pos.x); | |
280 can_see = see_monst(mp); | |
281 if (turn_off) | |
282 { | |
283 if (!can_see) | |
284 addch(mp->t_oldch); | |
285 } | |
286 else | |
287 { | |
288 if (!can_see) | |
289 standout(); | |
290 if (!on(player, ISHALU)) | |
291 addch(mp->t_type); | |
292 else | |
293 addch(rnd(26) + 'A'); | |
294 if (!can_see) | |
295 { | |
296 standend(); | |
297 add_new++; | |
298 } | |
299 } | |
300 } | |
301 if (turn_off) | |
302 player.t_flags &= ~SEEMONST; | |
303 else | |
304 player.t_flags |= SEEMONST; | |
305 return add_new; | |
306 } | |
307 | |
308 /* | |
309 * seen_stairs: | |
310 * Return TRUE if the player has seen the stairs | |
311 */ | |
312 int | |
313 seen_stairs(void) | |
314 { | |
315 THING *tp; | |
316 | |
317 move(stairs.y, stairs.x); | |
318 if (CCHAR( inch() ) == STAIRS) /* it's on the map */ | |
319 return TRUE; | |
320 if (ce(hero, stairs)) /* It's under him */ | |
321 return TRUE; | |
322 | |
323 /* | |
324 * if a monster is on the stairs, this gets hairy | |
325 */ | |
326 if ((tp = moat(stairs.y, stairs.x)) != NULL) | |
327 { | |
328 if (see_monst(tp) && on(*tp, ISRUN)) /* if it's visible and awake */ | |
329 return TRUE; /* it must have moved there */ | |
330 | |
331 if (on(player, SEEMONST) /* if she can detect monster */ | |
332 && tp->t_oldch == STAIRS) /* and there once were stairs */ | |
333 return TRUE; /* it must have moved there */ | |
334 } | |
335 return FALSE; | |
336 } | |
337 | |
338 /* | |
339 * raise_level: | |
340 * The guy just magically went up a level. | |
341 */ | |
342 | |
343 void | |
344 raise_level(void) | |
345 { | |
346 pstats.s_exp = e_levels[pstats.s_lvl-1] + 1L; | |
347 check_level(); | |
348 } | |
349 | |
350 /* | |
351 * do_pot: | |
352 * Do a potion with standard setup. This means it uses a fuse and | |
353 * turns on a flag | |
354 */ | |
355 | |
356 void | |
357 do_pot(int type, int knowit) | |
358 { | |
359 const PACT *pp; | |
360 int t; | |
361 | |
362 pp = &p_actions[type]; | |
363 if (!pot_info[type].oi_know) | |
364 pot_info[type].oi_know = knowit; | |
365 t = spread(pp->pa_time); | |
366 if (!on(player, pp->pa_flags)) | |
367 { | |
368 player.t_flags |= pp->pa_flags; | |
369 fuse(pp->pa_daemon, 0, t, AFTER); | |
370 look(FALSE); | |
371 } | |
372 else | |
373 lengthen(pp->pa_daemon, t); | |
374 msg(choose_str(pp->pa_high, pp->pa_straight)); | |
375 } |