Mercurial > hg > early-roguelike
diff arogue7/potions.c @ 125:adfa37e67084
Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Fri, 08 May 2015 15:24:40 -0400 |
parents | |
children | b786053d2f37 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/arogue7/potions.c Fri May 08 15:24:40 2015 -0400 @@ -0,0 +1,980 @@ +/* + * potions.c - Function(s) for dealing with potions + * + * Advanced Rogue + * Copyright (C) 1984, 1985, 1986 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. + */ + +/* + * Function(s) for dealing with potions + */ + +#include "curses.h" +#include "rogue.h" + + +/* + * add_abil is an array of functions used to change attributes. It must be + * ordered according to the attribute definitions in rogue.h. + */ + +void (*add_abil[NUMABILITIES])() = { + add_intelligence, add_strength, add_wisdom, add_dexterity, + add_constitution, add_charisma +}; + +/* + * res_abil is an array of functions used to change attributes. It must be + * ordered according to the attribute definitions in rogue.h. + */ + +void (*res_abil[NUMABILITIES])() = { + res_intelligence, res_strength, res_wisdom, res_dexterity, + res_constitution, res_charisma +}; + +/* + * Increase player's constitution + */ + +void +add_constitution(change) +int change; +{ + /* Do the potion */ + if (change < 0) { + msg("You feel less healthy now."); + pstats.s_const += change; + if (pstats.s_const <= 0) + death(D_CONSTITUTION); + } + else { + msg("You feel healthier now."); + pstats.s_const = min(pstats.s_const + change, 25); + } + + /* Adjust the maximum */ + if (max_stats.s_const < pstats.s_const) + max_stats.s_const = pstats.s_const; +} + +/* + * Increase player's charisma + */ + +void +add_charisma(change) +int change; +{ + /* Do the potion */ + if (change < 0) msg("You feel less attractive now."); + else msg("You feel more attractive now."); + + pstats.s_charisma += change; + if (pstats.s_charisma > 25) pstats.s_charisma = 25; + else if (pstats.s_charisma < 3) pstats.s_charisma = 3; + + /* Adjust the maximum */ + if (max_stats.s_charisma < pstats.s_charisma) + max_stats.s_charisma = pstats.s_charisma; +} + +/* + * Increase player's dexterity + */ + +void +add_dexterity(change) +int change; +{ + 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 (change < 0) msg("You feel less dextrous now."); + else msg("You feel more dextrous now. Watch those hands!"); + + pstats.s_dext += change; + if (pstats.s_dext > 25) pstats.s_dext = 25; + else if (pstats.s_dext < 3) pstats.s_dext = 3; + + /* 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 + */ + +add_haste(blessed) +bool blessed; +{ + int hasttime; + + if (player.t_ctype == C_MONK) { /* monks cannot be slowed or hasted */ + msg(nothing); + return; + } + + 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."); + player.t_no_move += movement(&player) * rnd(hasttime); + player.t_action = A_FREEZE; + lengthen(nohaste, roll(hasttime,hasttime)); + } + else { + msg("You feel yourself moving %sfaster.", blessed ? "much " : ""); + turn_on(player, ISHASTE); + fuse(nohaste, 0, roll(hasttime, hasttime), AFTER); + } +} + +/* + * Increase player's intelligence + */ +void +add_intelligence(change) +int change; +{ + 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 (change < 0) msg("You feel slightly less intelligent now."); + else msg("You feel more intelligent now. What a mind!"); + + pstats.s_intel += change; + if (pstats.s_intel > 25) pstats.s_intel = 25; + else if (pstats.s_intel < 3) pstats.s_intel = 3; + + /* 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 + */ +add_slow() +{ + /* monks cannot be slowed or hasted */ + if (player.t_ctype == C_MONK || ISWEARING(R_FREEDOM)) { + msg(nothing); + return; + } + + 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); + fuse(noslow, 0, roll(HASTETIME,HASTETIME), AFTER); + } + } +} + +/* + * Increase player's strength + */ + +void +add_strength(change) +int change; +{ + + if (change < 0) { + msg("You feel slightly weaker now."); + chg_str(change); + } + else { + msg("You feel stronger now. What bulging muscles!"); + chg_str(change); + } +} + +/* + * Increase player's wisdom + */ + +void +add_wisdom(change) +int change; +{ + 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 (change < 0) msg("You feel slightly less wise now."); + else msg("You feel wiser now. What a sage!"); + + pstats.s_wisdom += change; + if (pstats.s_wisdom > 25) pstats.s_wisdom = 25; + else if (pstats.s_wisdom < 3) pstats.s_wisdom = 3; + + /* 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; +} + +quaff(which, kind, flags, is_potion) +int which; +int kind; +int flags; +bool is_potion; +{ + register struct object *obj; + register struct linked_list *item, *titem; + register struct thing *th; + bool cursed, blessed; + + blessed = FALSE; + cursed = FALSE; + item = NULL; + + if (which < 0) { /* figure out which ourselves */ + /* This is a potion. */ + if (player.t_action != C_QUAFF) { + int units; + + item = get_item(pack, "quaff", QUAFFABLE, FALSE, FALSE); + + /* + * Make certain that it is somethings that we want to drink + */ + if (item == NULL) + return; + + /* How long does it take to quaff? */ + units = usage_time(item); + if (units < 0) return; + + player.t_using = item; /* Remember what it is */ + player.t_no_move = units * movement(&player); + if ((OBJPTR(item))->o_type == POTION) player.t_action = C_QUAFF; + else player.t_action = C_USE; + return; + } + + /* We have waited our time, let's quaff the potion */ + item = player.t_using; + player.t_using = NULL; + player.t_action = A_NIL; + + obj = OBJPTR(item); + /* remove it from the pack */ + inpack--; + detach(pack, item); + + flags = obj->o_flags; + which = obj->o_which; + kind = obj->o_kind; + } + cursed = flags & ISCURSED; + blessed = flags & ISBLESSED; + + switch(which) { + case P_CLEAR: + if (cursed) { + confus_player(); + } + 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) == 0) + 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) { + msg("You feel worse now."); + pstats.s_hpt -= roll(pstats.s_lvl, char_class[player.t_ctype].hit_pts); + if (pstats.s_hpt <= 0) + death(D_POISON); + } + else { + if (blessed) { + pstats.s_hpt += roll(pstats.s_lvl+1, char_class[player.t_ctype].hit_pts); + if (pstats.s_hpt > max_stats.s_hpt) + pstats.s_hpt = ++max_stats.s_hpt; + if (on(player, ISHUH)) { + extinguish(unconfuse); + unconfuse(); + } + } + else { + pstats.s_hpt += roll(pstats.s_lvl+1, char_class[player.t_ctype].hit_pts/2); + if (pstats.s_hpt > 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: + /* If it is cursed, we take a point away */ + if (cursed) { + if (ISWEARING(R_SUSABILITY)) { + msg(nothing); + break; + } + else add_abil[kind](-1); + } + + /* Otherwise we add points */ + else add_abil[kind](blessed ? 3 : 1); + + if (is_potion) p_know[P_ABIL] = TRUE; + when P_MFIND: + /* + * Potion of monster detection, if there are monters, detect them + */ + if (mlist != NULL) + { + register struct thing *tp; + register struct linked_list *item; + + msg("You begin to sense the presence of monsters."); + wclear(hw); + for (item=mlist; item!=NULL; item=next(item)) { + tp = THINGPTR(item); + if (on(*tp, NODETECT)) + continue; + if (off(*tp, ISRUN))/* turn off only on sleeping ones */ + turn_off(*tp, CANSURPRISE); + mvwaddch(hw, tp->t_pos.y, tp->t_pos.x, + monsters[tp->t_index].m_appear); + } + waddstr(msgw, morestr); + clearok(msgw, FALSE); + draw(msgw); + overlay(hw, cw); + draw(cw); + wait_for(' '); + 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 + */ + { + 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); + } + } + for (titem = mlist; titem != NULL; titem = next(titem)) { + register struct linked_list *pitem; + + th = THINGPTR(titem); + if (on(*th, NODETECT)) continue; + 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 (show) { + if (is_potion) p_know[P_TFIND] = TRUE; + msg("You sense the presence of magic on this level."); + waddstr(msgw, morestr); + clearok(msgw, FALSE); + draw(msgw); + overlay(hw,cw); + draw(cw); + wait_for(' '); + msg(""); + break; + } + else + 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) != 0) + lengthen(unsee, blessed ? SEEDURATION*3 : SEEDURATION); + sight(); + } + when P_PHASE: + if (cursed) { + msg("You can't move."); + player.t_no_move = movement(&player) * FREEZETIME; + player.t_action = A_FREEZE; + } + 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) { + if (is_potion) p_know[P_FLY] = TRUE; + 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(); + if (blessed) raise_level(); + } + when P_HASTE: + if (cursed) { /* Slow player down */ + add_slow(); + } + else { + add_haste(blessed); + if (is_potion) p_know[P_HASTE] = TRUE; + } + when P_RESTORE: { + register int i, howmuch, strength_tally; + + msg("Hey, this tastes great. It make you feel %swarm all over.", + blessed ? "really " : ""); + howmuch = blessed ? 2 : 1; + + for (i=0; i<NUMABILITIES; i++) { + if (i == A_STRENGTH) { + if (lost_str) { + if (lost_str > howmuch) { + lost_str -= howmuch; + + /* + * Save the lost strength. We have to set + * temporarilty set it to 0 so that res_strength + * will not restore it. + */ + strength_tally = lost_str; + lost_str = 0; + res_strength(howmuch); + lost_str = strength_tally; + } + else { + lost_str = 0; + extinguish(res_strength); + res_strength(howmuch); + } + } + else res_strength(howmuch); + } + else res_abil[i](howmuch); + } + } + when P_INVIS: + if (off(player, ISINVIS)) { + turn_on(player, ISINVIS); + msg("You have a tingling feeling all over your body"); + fuse(appear, 0, blessed ? GONETIME*3 : GONETIME, AFTER); + PLAYER = IPLAYER; + light(&hero); + } + else { + if (find_slot(appear)) { + msg("Your tingling feeling surges."); + lengthen(appear, blessed ? GONETIME*3 : GONETIME); + } + else msg("Nothing happens."); /* Using cloak */ + } + + when P_FFIND: + { + register struct linked_list *nitem; + register struct object *nobj; + bool show; + + show = FALSE; + wclear(hw); + for (nitem = lvl_obj; nitem != NULL; nitem = next(nitem)) { + nobj = OBJPTR(nitem); + if (nobj->o_type == FOOD) { + show = TRUE; + mvwaddch(hw, nobj->o_pos.y, nobj->o_pos.x, FOOD); + } + } + for (nitem = mlist; nitem != NULL; nitem = next(nitem)) { + register struct linked_list *pitem; + register struct thing *th; + + th = THINGPTR(nitem); + if (on(*th, NODETECT)) continue; + for(pitem = th->t_pack; pitem != NULL; pitem = next(pitem)){ + nobj = OBJPTR(pitem); + if (nobj->o_type == FOOD) { + show = TRUE; + mvwaddch(hw, th->t_pos.y, th->t_pos.x, FOOD); + } + } + } + if (show) { + if (is_potion) p_know[P_FFIND] = TRUE; + msg("Your nose tingles."); + msg("You sense the presence of food on this level."); + waddstr(msgw, morestr); + clearok(msgw, FALSE); + draw(msgw); + overlay(hw,cw); + draw(cw); + wait_for(' '); + msg(""); + } + else + msg("You have a strange feeling for a moment, then it passes."); + } + + when P_SKILL: + if (cursed) { + msg("You feel less skillful.");