Annotation of early-roguelike/rogue5/potions.c, Revision 1.1.1.1
1.1 rubenllo 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(turn_see_off, 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: * A wrapper for turn_see(TRUE), intended to be a fuse.
310: */
311: void
312: turn_see_off(void)
313: {
314: turn_see(TRUE);
315: }
316:
317: /*
318: * seen_stairs:
319: * Return TRUE if the player has seen the stairs
320: */
321: int
322: seen_stairs(void)
323: {
324: THING *tp;
325:
326: move(stairs.y, stairs.x);
327: if (CCHAR( inch() ) == STAIRS) /* it's on the map */
328: return TRUE;
329: if (ce(hero, stairs)) /* It's under him */
330: return TRUE;
331:
332: /*
333: * if a monster is on the stairs, this gets hairy
334: */
335: if ((tp = moat(stairs.y, stairs.x)) != NULL)
336: {
337: if (see_monst(tp) && on(*tp, ISRUN)) /* if it's visible and awake */
338: return TRUE; /* it must have moved there */
339:
340: if (on(player, SEEMONST) /* if she can detect monster */
341: && tp->t_oldch == STAIRS) /* and there once were stairs */
342: return TRUE; /* it must have moved there */
343: }
344: return FALSE;
345: }
346:
347: /*
348: * raise_level:
349: * The guy just magically went up a level.
350: */
351:
352: void
353: raise_level(void)
354: {
355: pstats.s_exp = e_levels[pstats.s_lvl-1] + 1L;
356: check_level();
357: }
358:
359: /*
360: * do_pot:
361: * Do a potion with standard setup. This means it uses a fuse and
362: * turns on a flag
363: */
364:
365: void
366: do_pot(int type, int knowit)
367: {
368: const PACT *pp;
369: int t;
370:
371: pp = &p_actions[type];
372: if (!pot_info[type].oi_know)
373: pot_info[type].oi_know = knowit;
374: t = spread(pp->pa_time);
375: if (!on(player, pp->pa_flags))
376: {
377: player.t_flags |= pp->pa_flags;
378: fuse(pp->pa_daemon, 0, t, AFTER);
379: look(FALSE);
380: }
381: else
382: lengthen(pp->pa_daemon, t);
383: msg(choose_str(pp->pa_high, pp->pa_straight));
384: }
CVSweb