/* * Function(s) for dealing with potions * * Advanced Rogue * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T * All rights reserved. * * Based on "Rogue: Exploring the Dungeons of Doom" * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman * All rights reserved. * * See the file LICENSE.TXT for full copyright and licensing information. */ #include "curses.h" #include "rogue.h" #include #include void res_intelligence(void); void res_wisdom(void); /* * Increase player's constitution */ void add_const(bool cursed) { /* Do the potion */ if (cursed) { msg("You feel less healthy now."); pstats.s_const--; if (pstats.s_const <= 0) death(D_CONSTITUTION); } else { msg("You feel healthier now."); pstats.s_const = min(pstats.s_const + 1, 25); } /* Adjust the maximum */ if (max_stats.s_const < pstats.s_const) max_stats.s_const = pstats.s_const; } /* * Increase player's dexterity */ void add_dexterity(bool cursed) { int ring_str; /* Value of ring strengths */ /* Undo any ring changes */ ring_str = ring_value(R_ADDHIT); pstats.s_dext -= ring_str; /* Now do the potion */ if (cursed) { msg("You feel less dextrous now."); pstats.s_dext--; } else { msg("You feel more dextrous now. Watch those hands!"); pstats.s_dext = min(pstats.s_dext + 1, 25); } /* Adjust the maximum */ if (max_stats.s_dext < pstats.s_dext) max_stats.s_dext = pstats.s_dext; /* Now put back the ring changes */ if (ring_str) pstats.s_dext += ring_str; } /* * add_haste: * add a haste to the player */ void add_haste(bool blessed) { int hasttime; if (blessed) hasttime = HASTETIME*2; else hasttime = HASTETIME; if (on(player, ISSLOW)) { /* Is person slow? */ extinguish(noslow); noslow(); if (blessed) hasttime = HASTETIME/2; else return; } if (on(player, ISHASTE)) { msg("You faint from exhaustion."); no_command += rnd(hasttime); lengthen(nohaste, roll(hasttime,hasttime)); } else { turn_on(player, ISHASTE); fuse(nohaste, 0, roll(hasttime, hasttime), AFTER); } } /* * Increase player's intelligence */ void add_intelligence(bool cursed) { int ring_str; /* Value of ring strengths */ /* Undo any ring changes */ ring_str = ring_value(R_ADDINTEL); pstats.s_intel -= ring_str; /* Now do the potion */ if (cursed) { msg("You feel slightly less intelligent now."); pstats.s_intel--; } else { msg("You feel more intelligent now. What a mind!"); pstats.s_intel = min(pstats.s_intel + 1, 25); } /* Adjust the maximum */ if (max_stats.s_intel < pstats.s_intel) max_stats.s_intel = pstats.s_intel; /* Now put back the ring changes */ if (ring_str) pstats.s_intel += ring_str; } /* * this routine makes the hero move slower */ void add_slow(void) { if (on(player, ISHASTE)) { /* Already sped up */ extinguish(nohaste); nohaste(); } else { msg("You feel yourself moving %sslower.", on(player, ISSLOW) ? "even " : ""); if (on(player, ISSLOW)) lengthen(noslow, roll(HASTETIME,HASTETIME)); else { turn_on(player, ISSLOW); player.t_turn = TRUE; fuse(noslow, 0, roll(HASTETIME,HASTETIME), AFTER); } } } /* * Increase player's strength */ void add_strength(bool cursed) { if (cursed) { msg("You feel slightly weaker now."); chg_str(-1); } else { msg("You feel stronger now. What bulging muscles!"); chg_str(1); } } /* * Increase player's wisdom */ void add_wisdom(bool cursed) { int ring_str; /* Value of ring strengths */ /* Undo any ring changes */ ring_str = ring_value(R_ADDWISDOM); pstats.s_wisdom -= ring_str; /* Now do the potion */ if (cursed) { msg("You feel slightly less wise now."); pstats.s_wisdom--; } else { msg("You feel wiser now. What a sage!"); pstats.s_wisdom = min(pstats.s_wisdom + 1, 25); } /* Adjust the maximum */ if (max_stats.s_wisdom < pstats.s_wisdom) max_stats.s_wisdom = pstats.s_wisdom; /* Now put back the ring changes */ if (ring_str) pstats.s_wisdom += ring_str; } /* * Lower a level of experience */ void lower_level(short who) { int fewer, nsides = 0; if (--pstats.s_lvl == 0) death(who); /* All levels gone */ msg("You suddenly feel less skillful."); pstats.s_exp /= 2; switch (player.t_ctype) { case C_FIGHTER: nsides = HIT_FIGHTER; when C_MAGICIAN:nsides = HIT_MAGICIAN; when C_CLERIC: nsides = HIT_CLERIC; when C_THIEF: nsides = HIT_THIEF; } fewer = max(1, roll(1,nsides) + const_bonus()); pstats.s_hpt -= fewer; max_stats.s_hpt -= fewer; if (pstats.s_hpt < 1) pstats.s_hpt = 1; if (max_stats.s_hpt < 1) death(who); } void quaff(int which, int flag, bool is_potion) { register struct object *obj = NULL; register struct linked_list *item, *titem; register struct thing *th; bool cursed, blessed; char buf[LINELEN]; blessed = FALSE; cursed = FALSE; item = NULL; if (which < 0) { /* figure out which ourselves */ item = get_item(pack, "quaff", POTION); /* * Make certain that it is somethings that we want to drink */ if (item == NULL) return; obj = OBJPTR(item); /* remove it from the pack */ inpack--; detach(pack, item); /* * Calculate the effect it has on the poor guy. */ cursed = (obj->o_flags & ISCURSED) != 0; blessed = (obj->o_flags & ISBLESSED) != 0; which = obj->o_which; } else { cursed = flag & ISCURSED; blessed = flag & ISBLESSED; } switch(which) { case P_CLEAR: if (cursed) { if (off(player, ISCLEAR)) { msg("Wait, what's going on here. Huh? What? Who?"); if (find_slot(unconfuse)) lengthen(unconfuse, rnd(8)+HUHDURATION); else fuse(unconfuse, 0, rnd(8)+HUHDURATION, AFTER); turn_on(player, ISHUH); } else msg("You feel dizzy for a moment, but it quickly passes."); } else { if (blessed) { /* Make player immune for the whole game */ extinguish(unclrhead); /* If we have a fuse, put it out */ msg("A strong blue aura surrounds your head."); } else { /* Just light a fuse for how long player is safe */ if (off(player, ISCLEAR)) { fuse(unclrhead, 0, CLRDURATION, AFTER); msg("A faint blue aura surrounds your head."); } else { /* If we have a fuse lengthen it, else we * are permanently clear. */ if (find_slot(unclrhead) == FALSE) msg("Your blue aura continues to glow strongly."); else { lengthen(unclrhead, CLRDURATION); msg("Your blue aura brightens for a moment."); } } } turn_on(player, ISCLEAR); /* If player is confused, unconfuse him */ if (on(player, ISHUH)) { extinguish(unconfuse); unconfuse(); } } when P_HEALING: if (cursed) { if (!save(VS_POISON, &player, 0)) { msg("You feel very sick now."); pstats.s_hpt /= 2; pstats.s_const--; if (pstats.s_const <= 0 || pstats.s_hpt <= 0) death(D_POISON); } else msg("You feel momentarily sick."); } else { if (blessed) { if ((pstats.s_hpt += roll(pstats.s_lvl, 8)) > max_stats.s_hpt) pstats.s_hpt = ++max_stats.s_hpt; if (on(player, ISHUH)) { extinguish(unconfuse); unconfuse(); } } else { if ((pstats.s_hpt += roll(pstats.s_lvl, 4)) > max_stats.s_hpt) pstats.s_hpt = ++max_stats.s_hpt; } msg("You begin to feel %sbetter.", blessed ? "much " : ""); sight(); if (is_potion) p_know[P_HEALING] = TRUE; } when P_ABIL: { int ctype; /* * if blessed then fix all attributes */ if (blessed) { add_intelligence(FALSE); add_dexterity(FALSE); add_strength(FALSE); add_wisdom(FALSE); add_const(FALSE); } /* probably will be own ability */ else { if (rnd(100) < 70) ctype = player.t_ctype; else do { ctype = rnd(4); } while (ctype == player.t_ctype); /* Small chance of doing constitution instead */ if (rnd(100) < 10) add_const(cursed); else switch (ctype) { case C_FIGHTER: add_strength(cursed); when C_MAGICIAN: add_intelligence(cursed); when C_CLERIC: add_wisdom(cursed); when C_THIEF: add_dexterity(cursed); otherwise: msg("You're a strange type!"); } } if (is_potion) p_know[P_ABIL] = TRUE; } when P_MFIND: /* * Potion of monster detection, if there are monters, detect them */ if (mlist != NULL) { overlay(mw, cw); draw(cw); msg("You begin to sense the presence of monsters.%s", morestr); draw(msgw); wait_for(cw,' '); msg(""); if (is_potion) p_know[P_MFIND] = TRUE; } else msg("You have a strange feeling for a moment, then it passes."); when P_TFIND: /* * Potion of magic detection. Show the potions and scrolls */ if (lvl_obj != NULL) { register struct linked_list *mobj; register struct object *tp; bool show; show = FALSE; wclear(hw); for (mobj = lvl_obj; mobj != NULL; mobj = next(mobj)) { tp = OBJPTR(mobj); if (is_magic(tp)) { char mag_type=MAGIC; /* Mark cursed items or bad weapons */ if ((tp->o_flags & ISCURSED) || (tp->o_type == WEAPON && (tp->o_hplus < 0 || tp->o_dplus < 0))) mag_type = CMAGIC; else if ((tp->o_flags & ISBLESSED) || (tp->o_type == WEAPON && (tp->o_hplus > 0 || tp->o_dplus > 0))) mag_type = BMAGIC; show = TRUE; mvwaddch(hw, tp->o_pos.y, tp->o_pos.x, mag_type); } if (is_potion) p_know[P_TFIND] = TRUE; } for (titem = mlist; titem != NULL; titem = next(titem)) { register struct linked_list *pitem; th = THINGPTR(titem); for(pitem = th->t_pack; pitem != NULL; pitem = next(pitem)){ tp = OBJPTR(pitem); if (is_magic(tp)) { char mag_type=MAGIC; /* Mark cursed items or bad weapons */ if ((tp->o_flags & ISCURSED) || (tp->o_type == WEAPON && (tp->o_hplus < 0 || tp->o_dplus < 0))) mag_type = CMAGIC; else if ((tp->o_flags & ISBLESSED) || (tp->o_type == WEAPON && (tp->o_hplus > 0 || tp->o_dplus > 0))) mag_type = BMAGIC; show = TRUE; mvwaddch(hw, th->t_pos.y, th->t_pos.x, mag_type); } if (is_potion) p_know[P_TFIND] = TRUE; } } if (show) { overlay(hw,cw); draw(cw); msg("You sense the presence of magic on this level.%s", morestr); draw(msgw); wait_for(cw,' '); msg(""); break; } } msg("You have a strange feeling for a moment, then it passes."); when P_SEEINVIS: if (cursed) { if (!find_slot(sight)) { msg("A cloak of darkness falls around you."); turn_on(player, ISBLIND); fuse(sight, 0, SEEDURATION, AFTER); light(&hero); } else lengthen(sight, SEEDURATION); } else { if (off(player, CANSEE)) { turn_on(player, CANSEE); msg("Your eyes begin to tingle."); fuse(unsee, 0, blessed ? SEEDURATION*3 :SEEDURATION, AFTER); light(&hero); } else if (find_slot(unsee) != FALSE) lengthen(unsee, blessed ? SEEDURATION*3 : SEEDURATION); sight(); } when P_PHASE: if (cursed) { msg("You can't move."); no_command = FREEZETIME; } else { int duration; if (blessed) duration = 3; else duration = 1; if (on(player, CANINWALL)) lengthen(unphase, duration*PHASEDURATION); else { fuse(unphase, 0, duration*PHASEDURATION, AFTER); turn_on(player, CANINWALL); } msg("You feel %slight-headed!", blessed ? "very " : ""); } when P_FLY: { int duration; bool say_message; say_message = TRUE; if (blessed) duration = 3; else duration = 1; if (on(player, ISFLY)) { if (find_slot(land)) lengthen(land, duration*FLYTIME); else { msg("Nothing happens."); /* Flying by cloak */ say_message = FALSE; } } else { fuse(land, 0, duration*FLYTIME, AFTER); turn_on(player, ISFLY); } if (say_message) msg("You feel %slighter than air!", blessed ? "much " : ""); } when P_RAISE: if (cursed) lower_level(D_POTION); else { msg("You suddenly feel %smore skillful", blessed ? "much " : ""); p_know[P_RAISE] = TRUE; raise_level(TRUE); if (blessed) raise_level(TRUE); } when P_HASTE: if (cursed) { /* Slow player down */ add_slow(); } else { if (off(player, ISSLOW)) msg("You feel yourself moving %sfaster.", blessed ? "much " : ""); add_haste(blessed); if (is_potion) p_know[P_HASTE] = TRUE; } when P_RESTORE: { register int i; msg("Hey, this tastes great. It make you feel warm all over."); if (lost_str) { extinguish(res_strength); lost_str = 0; } for (i=0; io_flags & ISKNOW) == 0 && (obj->o_flags & ISPOST) == 0 && p_guess[which] == NULL) { msg(terse ? "Call it: " : "What do you want to call it? "); if (get_str(buf, msgw) == NORM) { p_guess[which] = new((unsigned int) strlen(buf) + 1); strcpy(p_guess[which], buf); } } if (item != NULL) o_discard(item); updpack(TRUE); } /* * res_dexterity: * Restore player's dexterity * if called with zero the restore fully */ void res_dexterity(int howmuch) { short save_max; int ring_str; /* Discount the ring value */ ring_str = ring_value(R_ADDHIT); pstats.s_dext -= ring_str; if (pstats.s_dext < max_stats.s_dext ) { if (howmuch == 0) pstats.s_dext = max_stats.s_dext; else pstats.s_dext = min(pstats.s_dext+howmuch, max_stats.s_dext); } /* Redo the rings */ if (ring_str) { save_max = max_stats.s_dext; pstats.s_dext += ring_str; max_stats.s_dext = save_max; } } /* * res_intelligence: * Restore player's intelligence */ void res_intelligence(void) { short save_max; int ring_str; /* Discount the ring value */ ring_str = ring_value(R_ADDINTEL); pstats.s_intel -= ring_str; if (pstats.s_intel < max_stats.s_intel ) pstats.s_intel = max_stats.s_intel; /* Redo the rings */ if (ring_str) { save_max = max_stats.s_intel; pstats.s_intel += ring_str; max_stats.s_intel = save_max; } } /* * res_wisdom: * Restore player's wisdom */ void res_wisdom(void) { short save_max; int ring_str; /* Discount the ring value */ ring_str = ring_value(R_ADDWISDOM); pstats.s_wisdom -= ring_str; if (pstats.s_wisdom < max_stats.s_wisdom ) pstats.s_wisdom = max_stats.s_wisdom; /* Redo the rings */ if (ring_str) { save_max = max_stats.s_wisdom; pstats.s_wisdom += ring_str; max_stats.s_wisdom = save_max; } }