Annotation of early-roguelike/rogue5/potions.c, Revision 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