diff options
Diffstat (limited to 'src/cmd6.c')
-rw-r--r-- | src/cmd6.c | 7731 |
1 files changed, 0 insertions, 7731 deletions
diff --git a/src/cmd6.c b/src/cmd6.c deleted file mode 100644 index db89c465..00000000 --- a/src/cmd6.c +++ /dev/null @@ -1,7731 +0,0 @@ -/* File: cmd6.c */ - -/* Purpose: Object commands */ - -/* - * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke - * - * This software may be copied and distributed for educational, research, and - * not for profit purposes provided that this copyright and statement are - * included in all such copies. - */ - -#include "angband.h" - - -/* - * Forward declare - */ -static bool_ activate_spell(object_type * o_ptr, byte choice); - - -/* - * General function to find an item by its name - */ -cptr get_item_hook_find_obj_what; -bool_ get_item_hook_find_obj(int *item) -{ - int i; - char buf[80]; - char buf2[100]; - - strcpy(buf, ""); - if (!get_string(get_item_hook_find_obj_what, buf, 79)) - return FALSE; - - for (i = 0; i < INVEN_TOTAL; i++) - { - object_type *o_ptr = &p_ptr->inventory[i]; - - if (!item_tester_okay(o_ptr)) continue; - - object_desc(buf2, o_ptr, -1, 0); - if (!strcmp(buf, buf2)) - { - *item = i; - return TRUE; - } - } - return FALSE; -} - - -/* - * This file includes code for eating food, drinking potions, - * reading scrolls, aiming wands, using staffs, zapping rods, - * and activating artifacts. - * - * In all cases, if the player becomes "aware" of the item's use - * by testing it, mark it as "aware" and reward some experience - * based on the object's level, always rounding up. If the player - * remains "unaware", mark that object "kind" as "tried". - * - * This code now correctly handles the unstacking of wands, staffs, - * and rods. Note the overly paranoid warning about potential pack - * overflow, which allows the player to use and drop a stacked item. - * - * In all "unstacking" scenarios, the "used" object is "carried" as if - * the player had just picked it up. In particular, this means that if - * the use of an item induces pack overflow, that item will be dropped. - * - * For simplicity, these routines induce a full "pack reorganization" - * which not only combines similar items, but also reorganizes various - * items to obey the current "sorting" method. This may require about - * 400 item comparisons, but only occasionally. - * - * There may be a BIG problem with any "effect" that can cause "changes" - * to the p_ptr->inventory. For example, a "scroll of recharging" can cause - * a wand/staff to "disappear", moving the p_ptr->inventory up. Luckily, the - * scrolls all appear BEFORE the staffs/wands, so this is not a problem. - * But, for example, a "staff of recharging" could cause MAJOR problems. - * In such a case, it will be best to either (1) "postpone" the effect - * until the end of the function, or (2) "change" the effect, say, into - * giving a staff "negative" charges, or "turning a staff into a stick". - * It seems as though a "rod of recharging" might in fact cause problems. - * The basic problem is that the act of recharging (and destroying) an - * item causes the inducer of that action to "move", causing "o_ptr" to - * no longer point at the correct item, with horrifying results. - * - * Note that food/potions/scrolls no longer use bit-flags for effects, - * but instead use the "sval" (which is also used to sort the objects). - */ - - -/* - * Determine the effects of eating a corpse. A corpse can be - * eaten whole or cut into pieces for later. - */ -static void corpse_effect(object_type *o_ptr, bool_ cutting) -{ - monster_race *r_ptr = &r_info[o_ptr->pval2]; - - /* Assume no bad effects */ - bool_ harmful = FALSE; - - byte method, effect, d_dice, d_side; - - int i, dam, idam = 0, mdam, brpow, brdam = 0; - - - /* How much of the monster's breath attack remains */ - if (o_ptr->pval <= r_ptr->weight) - { - brpow = 0; - } - else - { - brpow = (o_ptr->pval - r_ptr->weight) / 5; - if (brpow > (r_ptr->weight / 5)) brpow = r_ptr->weight / 5; - } - - if (o_ptr->weight <= 0) o_ptr->weight = 1; - if (o_ptr->pval <= 0) o_ptr->pval = 1; - - /* - * The breath is only discharged by accident or by slicing off pieces - * of meat, and only by corpses. - */ - if ((o_ptr->sval != SV_CORPSE_CORPSE) || - (rand_int(o_ptr->weight / 5) && !cutting)) brpow = 0; - - /* Immediate effects - poison, acid, fire, etc. */ - if (!cutting) - { - for (i = 0; i < 4; i++) - { - /* skip empty blow slot */ - if (!r_ptr->blow[i].method) continue; - - method = r_ptr->blow[i].method; - effect = r_ptr->blow[i].effect; - d_dice = r_ptr->blow[i].d_dice; - d_side = r_ptr->blow[i].d_side; - dam = damroll(d_dice, d_side) * o_ptr->pval / o_ptr->weight / 2; - idam = damroll(d_dice, d_side) * - ((o_ptr->weight / o_ptr->pval > 2) ? - o_ptr->weight / o_ptr->pval : 2); - mdam = maxroll(d_dice, d_side) * 2; - - /* Analyse method */ - switch (method) - { - /* Methods that are meaningless after death */ - case RBM_BITE: - case RBM_STING: - case RBM_ENGULF: - case RBM_DROOL: - case RBM_SPIT: - case RBM_GAZE: - case RBM_WAIL: - case RBM_BEG: - case RBM_INSULT: - case RBM_MOAN: - { - continue; - } - } - - /* Analyse effect */ - switch (effect) - { - /* Effects that are meaningless after death */ - case RBE_HURT: - case RBE_UN_BONUS: - case RBE_UN_POWER: - case RBE_EAT_GOLD: - case RBE_EAT_ITEM: - case RBE_EAT_FOOD: - case RBE_EAT_LITE: - case RBE_ELEC: - case RBE_COLD: - case RBE_SHATTER: - { - break; - } - - case RBE_POISON: - { - if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) - { - set_poisoned(p_ptr->poisoned + dam + idam + 10); - harmful = TRUE; - } - - break; - } - - case RBE_ACID: - { - /* Total Immunity */ - if (!(p_ptr->immune_acid || (dam <= 0))) - { - /* Resist the damage */ - if (p_ptr->resist_acid) dam = (dam + 2) / 3; - if (p_ptr->oppose_acid) dam = (dam + 2) / 3; - - /* Take damage */ - take_hit(dam, "acidic food"); - harmful = TRUE; - } - else - { - set_oppose_acid(p_ptr->oppose_acid + idam); - } - - break; - } - - case RBE_FIRE: - { - /* Totally immune */ - if (p_ptr->immune_fire || (dam <= 0)) - { - /* Resist the damage */ - if (p_ptr->resist_fire) dam = (dam + 2) / 3; - if (p_ptr->oppose_fire) dam = (dam + 2) / 3; - - /* Take damage */ - take_hit(dam, "a fiery meal"); - harmful = TRUE; - } - else - { - set_oppose_fire(p_ptr->oppose_fire + idam); - } - - break; - } - - case RBE_BLIND: - { - if (!p_ptr->resist_blind) - { - set_blind(p_ptr->blind + dam * 2 + idam * 2 + 20); - } - - break; - } - - case RBE_CONFUSE: - { - if (!p_ptr->resist_conf) - { - set_confused(p_ptr->confused + dam + idam + 10); - } - if (!p_ptr->resist_chaos && rand_int(mdam - dam)) - { - set_image(p_ptr->image + dam * 10 + idam * 10 + 100); - } - - break; - } - - case RBE_HALLU: - { - if (!p_ptr->resist_chaos && rand_int(mdam - dam)) - { - set_image(p_ptr->image + dam * 10 + idam * 10 + 50); - } - - break; - } - - case RBE_TERRIFY: - { - if (!p_ptr->resist_fear) - { - set_afraid(p_ptr->afraid + dam + idam + 10); - } - - break; - } - - case RBE_PARALYZE: - { - if (!p_ptr->free_act) - { - set_paralyzed(p_ptr->paralyzed + dam + idam + 10); - } - - break; - } - - case RBE_LOSE_STR: - { - do_dec_stat(A_STR, STAT_DEC_NORMAL); - - break; - } - - case RBE_LOSE_INT: - { - do_dec_stat(A_INT, STAT_DEC_NORMAL); - - break; - } - - case RBE_LOSE_WIS: - { - do_dec_stat(A_WIS, STAT_DEC_NORMAL); - - break; - } - - case RBE_LOSE_DEX: - { - do_dec_stat(A_DEX, STAT_DEC_NORMAL); - - break; - } - - case RBE_LOSE_CON: - { - do_dec_stat(A_CON, STAT_DEC_NORMAL); - - break; - } - - case RBE_LOSE_CHR: - { - do_dec_stat(A_CHR, STAT_DEC_NORMAL); - - break; - } - - /* Don't eat Morgoth's corpse :) */ - case RBE_LOSE_ALL: - { - do_dec_stat(A_STR, STAT_DEC_NORMAL); - do_dec_stat(A_INT, STAT_DEC_NORMAL); - do_dec_stat(A_WIS, STAT_DEC_NORMAL); - do_dec_stat(A_DEX, STAT_DEC_NORMAL); - do_dec_stat(A_CON, STAT_DEC_NORMAL); - do_dec_stat(A_CHR, STAT_DEC_NORMAL); - o_ptr->pval = 1; - - break; - } - - case RBE_SANITY: - { - msg_print("You feel your sanity slipping away!"); - take_sanity_hit(dam, "eating an insane monster"); - - break; - } - - /* Unlife is bad to eat */ - case RBE_EXP_10: - { - msg_print("A black aura surrounds the corpse!"); - - if (p_ptr->hold_life && (rand_int(100) < 50)) - { - msg_print("You keep hold of your life force!"); - } - else - { - s32b d = damroll(10, 6) + - (p_ptr->exp / 100) * MON_DRAIN_LIFE; - - if (p_ptr->hold_life) - { - msg_print("You feel your life slipping away!"); - lose_exp(d / 10); - } - else - { - msg_print("You feel your life draining away!"); - lose_exp(d); - } - } - - o_ptr->pval = 1; - - break; - } - - case RBE_EXP_20: - { - msg_print("A black aura surrounds the corpse!"); - - if (p_ptr->hold_life && (rand_int(100) < 50)) - { - msg_print("You keep hold of your life force!"); - } - else - { - s32b d = damroll(20, 6) + - (p_ptr->exp / 100) * MON_DRAIN_LIFE; - - if (p_ptr->hold_life) - { - msg_print("You feel your life slipping away!"); - lose_exp(d / 10); - } - else - { - msg_print("You feel your life draining away!"); - lose_exp(d); - } - } - - o_ptr->pval = 1; - - break; - } - - case RBE_EXP_40: - { - msg_print("A black aura surrounds the corpse!"); - - if (p_ptr->hold_life && (rand_int(100) < 50)) - { - msg_print("You keep hold of your life force!"); - } - else - { - s32b d = damroll(40, 6) + - (p_ptr->exp / 100) * MON_DRAIN_LIFE; - - if (p_ptr->hold_life) - { - msg_print("You feel your life slipping away!"); - lose_exp(d / 10); - } - else - { - msg_print("You feel your life draining away!"); - lose_exp(d); - } - } - - o_ptr->pval = 1; - - break; - } - - case RBE_EXP_80: - { - msg_print("A black aura surrounds the corpse!"); - - if (p_ptr->hold_life && (rand_int(100) < 50)) - { - msg_print("You keep hold of your life force!"); - } - else - { - s32b d = damroll(80, 6) + - (p_ptr->exp / 100) * MON_DRAIN_LIFE; - - if (p_ptr->hold_life) - { - msg_print("You feel your life slipping away!"); - lose_exp(d / 10); - } - else - { - msg_print("You feel your life draining away!"); - lose_exp(d); - } - } - - o_ptr->pval = 1; - - break; - } - } - } - } /* if (!cutting) */ - - - /* - * The organ that supplies breath attacks is not - * immediately emptied upon death, although some types - * of breath have no effect. - * AMHD's make rather risky meals, and deadly snacks. - */ - - /* Acid */ - if (r_ptr->flags4 & RF4_BR_ACID && brpow > 0) - { - brdam = ((brpow / 3) > 1600 ? 1600 : (brpow / 3)); - - msg_print("You are hit by a gush of acid!"); - - /* Total Immunity */ - if (!(p_ptr->immune_acid || (brdam <= 0))) - { - /* Take damage */ - acid_dam(brdam, "a gush of acid"); - harmful = TRUE; - } - o_ptr->pval = 1; - } - else if (r_ptr->flags4 & RF4_BR_ACID) - { - set_oppose_acid(p_ptr->oppose_acid + rand_int(10) + 10); - } - - /* Electricity */ - if (r_ptr->flags4 & RF4_BR_ELEC && brpow > 0) - { - brdam = ((brpow / 3) > 1600 ? 1600 : (brpow / 3)); - - msg_print("You receive a heavy shock!"); - - /* Total Immunity */ - if (!(p_ptr->immune_elec || (brdam <= 0))) - { - /* Take damage */ - elec_dam(brdam, "an electric shock"); - harmful = TRUE; - } - o_ptr->weight = o_ptr->weight - brpow; - o_ptr->pval = o_ptr->weight; - } - else if (r_ptr->flags4 & RF4_BR_ELEC) - { - set_oppose_elec(p_ptr->oppose_elec + rand_int(10) + 10); - } - - /* Fire */ - if (r_ptr->flags4 & RF4_BR_FIRE && brpow > 0) - { - brdam = ((brpow / 3) > 1600 ? 1600 : (brpow / 3)); - - msg_print("Roaring flames engulf you!"); - - /* Total Immunity */ - if (!(p_ptr->immune_fire || (brdam <= 0))) - { - /* Take damage */ - fire_dam(brdam, "an explosion"); - harmful = TRUE; - } - o_ptr->pval = 1; - } - else if (r_ptr->flags4 & RF4_BR_FIRE) - { - set_oppose_fire(p_ptr->oppose_fire + rand_int(10) + 10); - } - - /* Cold */ - if (r_ptr->flags4 & RF4_BR_COLD && brpow > 0) - { - brdam = ((brpow / 3) > 1600 ? 1600 : (brpow / 3)); - - msg_print("You are caught in a freezing liquid!"); - - /* Total Immunity */ - if (!(p_ptr->immune_cold || (brdam <= 0))) - { - /* Take damage */ - cold_dam(brdam, "a chilling blast"); - harmful = TRUE; - } - o_ptr->weight = o_ptr->weight - brpow; - o_ptr->pval = o_ptr->weight; - } - else if (r_ptr->flags4 & RF4_BR_COLD) - { - set_oppose_cold(p_ptr->oppose_cold + rand_int(10) + 10); - } - - /* Poison */ - if (r_ptr->flags4 & RF4_BR_POIS && brpow > 0) - { - brdam = ((brpow / 3) > 800 ? 800 : (brpow / 3)); - - msg_print("You are surrounded by toxic gases!"); - - /* Resist the damage */ - if (p_ptr->resist_pois) brdam = (brdam + 2) / 3; - if (p_ptr->oppose_pois) brdam = (brdam + 2) / 3; - - if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) - { - (void)set_poisoned(p_ptr->poisoned + rand_int(brdam) + 10); - } - - /* Take damage */ - take_hit(brdam, "toxic gases"); - o_ptr->weight = o_ptr->weight - brpow; - o_ptr->pval = o_ptr->weight; - harmful = TRUE; - } - - /* Nether */ - if (r_ptr->flags4 & RF4_BR_NETH && brpow > 0) - { - brdam = ((brpow / 6) > 550 ? 550 : (brpow / 6)); - - msg_print("A black aura surrounds the corpse!"); - - if (p_ptr->resist_neth) - { - brdam *= 6; - brdam /= (randint(6) + 6); - } - else - { - if (p_ptr->hold_life && (rand_int(100) < 75)) - { - msg_print("You keep hold of your life force!"); - } - else if (p_ptr->hold_life) - { - msg_print("You feel your life slipping away!"); - lose_exp(200 + (p_ptr->exp / 1000) * MON_DRAIN_LIFE); - } - else - { - msg_print("You feel your life draining away!"); - lose_exp(200 + (p_ptr->exp / 100) * MON_DRAIN_LIFE); - } - } - - /* Take damage */ - take_hit(brdam, "an unholy blast"); - harmful = TRUE; - o_ptr->weight = o_ptr->weight - brpow; - o_ptr->pval = o_ptr->weight; - } - - /* Confusion */ - if (r_ptr->flags4 & RF4_BR_CONF && brpow > 0) - { - msg_print("A strange liquid splashes on you!"); - - if (!p_ptr->resist_conf) - { - set_confused(p_ptr->confused + brdam + idam + 10); - } - o_ptr->weight = o_ptr->weight - brpow; - o_ptr->pval = o_ptr->weight; - } - - /* Chaos */ - if (r_ptr->flags4 & RF4_BR_CHAO && brpow > 0) - { - brdam = ((brpow / 6) > 600 ? 600 : (brpow / 6)); - - msg_print("A swirling cloud surrounds you!"); - - if (p_ptr->resist_chaos) - { - brdam *= 6; - brdam /= (randint(6) + 6); - } - - if (!p_ptr->resist_conf) - { - (void)set_confused(p_ptr->confused + rand_int(20) + 10); - } - - if (!p_ptr->resist_chaos) - { - (void)set_image(p_ptr->image + randint(10)); - } - - if (!p_ptr->resist_neth && !p_ptr->resist_chaos) - { - if (p_ptr->hold_life && (rand_int(100) < 75)) - { - msg_print("You keep hold of your life force!"); - } - else if (p_ptr->hold_life) - { - msg_print("You feel your life slipping away!"); - lose_exp(500 + (p_ptr->exp / 1000) * MON_DRAIN_LIFE); - } - else - { - msg_print("You feel your life draining away!"); - lose_exp(5000 + (p_ptr->exp / 100) * MON_DRAIN_LIFE); - } - } - - /* Take damage */ - take_hit(brdam, "chaotic forces"); - o_ptr->pval = 1; - } - - /* Disenchantment */ - if (r_ptr->flags4 & RF4_BR_DISE && brpow > 0) - { - brdam = ((brpow / 6) > 500 ? 500 : (brpow / 6)); - - msg_print("You are blasted by raw mana!"); - - if (p_ptr->resist_disen) - { - brdam *= 6; - brdam /= (randint(6) + 6); - } - else - { - (void)apply_disenchant(0); - } - - /* Take damage */ - take_hit(brdam, "raw mana"); - o_ptr->pval = 1; - } - - /* Plasma */ - if (r_ptr->flags4 & RF4_BR_PLAS && brpow > 0) - { - brdam = ((brpow / 6) > 150 ? 150 : (brpow / 6)); - - msg_print("Searing flames engulf the corpse!"); - - /* Resist the damage */ - if (p_ptr->resist_fire || p_ptr->oppose_fire) brdam = (brdam + 2) / 3; - - if (!p_ptr->resist_sound) - { - int k = (randint((brdam > 40) ? 35 : (brdam * 3 / 4 + 5))); - (void)set_stun(p_ptr->stun + k); - } - - /* Take damage */ - take_hit(brdam, "an explosion"); - harmful = TRUE; - o_ptr->pval = 1; - } - - /* Hack -- Jellies are immune to acid only if they are already acidic */ - if (strchr("j", r_ptr->d_char) && (r_ptr->flags3 & RF3_IM_ACID)) - { - dam = damroll(8, 8); - - /* Total Immunity */ - if (!(p_ptr->immune_acid || (dam <= 0))) - { - /* Resist the damage */ - if (p_ptr->resist_acid) dam = (dam + 2) / 3; - if (p_ptr->oppose_acid) dam = (dam + 2) / 3; - - /* Take damage */ - take_hit(dam, "acidic food"); - } - harmful = TRUE; - } - - /* - * Hack -- Jellies, kobolds, spiders, icky things, molds, and mushrooms - * are immune to poison because their body already contains - * poisonous chemicals. - */ - if (strchr("ijkmS,", r_ptr->d_char) && (r_ptr->flags3 & RF3_IM_POIS)) - { - if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) - { - set_poisoned(p_ptr->poisoned + rand_int(15) + 10); - } - harmful = TRUE; - } - - /* - * Bad effects override good effects - * and hacked-up corpses lose intrinsics. - */ - if (!harmful && !cutting && (o_ptr->sval != SV_CORPSE_MEAT)) - { - if (r_ptr->flags3 & RF3_IM_ACID) - { - set_oppose_acid(p_ptr->oppose_acid + rand_int(10) + 10); - } - if (r_ptr->flags3 & RF3_IM_ELEC) - { - set_oppose_elec(p_ptr->oppose_elec + rand_int(10) + 10); - } - if (r_ptr->flags3 & RF3_IM_FIRE) - { - set_oppose_fire(p_ptr->oppose_fire + rand_int(10) + 10); - } - if (r_ptr->flags3 & RF3_IM_COLD) - { - set_oppose_cold(p_ptr->oppose_cold + rand_int(10) + 10); - } - if (r_ptr->flags3 & RF3_IM_POIS) - { - set_oppose_pois(p_ptr->oppose_pois + rand_int(10) + 10); - } - if (r_ptr->flags3 & RF3_RES_NETH) - { - set_protevil(p_ptr->protevil + rand_int(25) + 3 * r_ptr->level); - } - if (r_ptr->flags3 & RF3_RES_PLAS) - { - set_oppose_fire(p_ptr->oppose_fire + rand_int(20) + 20); - } - if (r_ptr->flags2 & RF2_SHAPECHANGER) - { - /* DGDGDG (void)set_mimic(20 , rand_int(MIMIC_VALAR)); */ - } - - if (r_ptr->flags3 & RF3_DEMON) - { - /* DGDGDG (void)set_mimic(30 , MIMIC_DEMON); */ - } - - if (r_ptr->flags3 & RF3_UNDEAD) - { - /* DGDGDG (void)set_mimic(30 , MIMIC_VAMPIRE); */ - } - - if (r_ptr->flags3 & RF3_NO_FEAR) - { - (void)set_afraid(0); - } - if (r_ptr->flags3 & RF3_NO_STUN) - { - (void)set_stun(0); - } - if (r_ptr->flags3 & RF3_NO_CONF) - { - (void)set_confused(0); - } - if (r_ptr->flags6 & RF6_S_THUNDERLORD) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_THUNDERLORD, FALSE); - } - if (r_ptr->flags6 & RF6_S_DEMON) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DEMON, FALSE); - } - if (r_ptr->flags6 & RF6_S_KIN) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_KIN, FALSE); - } - if (r_ptr->flags6 & RF6_S_HI_DEMON) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_DEMON, FALSE); - } - if (r_ptr->flags6 & RF6_S_MONSTER) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, 0, FALSE); - } - if (r_ptr->flags6 & RF6_S_MONSTERS) - { - int k; - for (k = 0; k < 8; k++) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, 0, FALSE); - } - } - if (r_ptr->flags6 & RF6_S_UNDEAD) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNDEAD, FALSE); - } - if (r_ptr->flags6 & RF6_S_DRAGON) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DRAGON, FALSE); - } - if (r_ptr->flags6 & RF6_S_ANT) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANT, FALSE); - } - if (r_ptr->flags6 & RF6_S_SPIDER) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_SPIDER, FALSE); - } - if (r_ptr->flags6 & RF6_S_HOUND) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HOUND, FALSE); - } - if (r_ptr->flags6 & RF6_S_HYDRA) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HYDRA, FALSE); - } - if (r_ptr->flags6 & RF6_S_ANGEL) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_ANGEL, FALSE); - } - if (r_ptr->flags6 & RF6_S_HI_DRAGON) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_DRAGON, FALSE); - } - if (r_ptr->flags6 & RF6_S_HI_UNDEAD) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_HI_UNDEAD, FALSE); - } - if (r_ptr->flags6 & RF6_S_WRAITH) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_WRAITH, FALSE); - } - if (r_ptr->flags6 & RF6_S_UNIQUE) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNIQUE, FALSE); - } - } -} - - -/* - * Hook to determine if an object is eatable - */ -static bool_ item_tester_hook_eatable(object_type *o_ptr) -{ - /* Foods and, well, corpses are edible */ - if ((o_ptr->tval == TV_FOOD) || (o_ptr->tval == TV_CORPSE)) return (TRUE); - - /* Assume not */ - return (FALSE); -} - - -/* - * Eat some food (from the pack or floor) - */ -void do_cmd_eat_food(void) -{ - int item, ident, lev, fval = 0; - - object_type *o_ptr; - object_type *q_ptr, forge; - - monster_race *r_ptr; - - cptr q, s; - - bool_ destroy = TRUE; - - - /* Restrict choices to food */ - item_tester_hook = item_tester_hook_eatable; - - /* Set up the extra finder */ - get_item_hook_find_obj_what = "Food full name? "; - get_item_extra_hook = get_item_hook_find_obj; - - /* Get an item */ - q = "Eat which item? "; - s = "You have nothing to eat."; - if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return; - - /* Get the item */ - o_ptr = get_object(item); - - /* Sound */ - sound(SOUND_EAT); - - - /* Take a turn */ - energy_use = 100; - - /* Identity not known yet */ - ident = FALSE; - - /* Object level */ - lev = k_info[o_ptr->k_idx].level; - - /* Scripted foods */ - if (process_hooks_ret(HOOK_EAT, "d", "(O)", o_ptr)) - { - ident = process_hooks_return[0].num; - } - /* (not quite) Normal foods */ - else if (o_ptr->tval == TV_FOOD) - { - /* Analyze the food */ - switch (o_ptr->sval) - { - case SV_FOOD_GREAT_HEALTH: - { - p_ptr->hp_mod += 70; - msg_print("As you eat it you begin to feel your life flow getting stronger."); - ident = TRUE; - p_ptr->update |= (PU_HP); - - break; - } - - case SV_FOOD_POISON: - { - if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) - { - if (set_poisoned(p_ptr->poisoned + rand_int(10) + 10)) - { - ident = TRUE; - } - } - - break; - } - - case SV_FOOD_BLINDNESS: - { - if (!p_ptr->resist_blind) - { - if (set_blind(p_ptr->blind + rand_int(200) + 200)) - { - ident = TRUE; - } - } - - break; - } - - case SV_FOOD_PARANOIA: - { - if (!p_ptr->resist_fear) - { - if (set_afraid(p_ptr->afraid + rand_int(10) + 10)) - { - ident = TRUE; - } - } - - break; - } - - case SV_FOOD_CONFUSION: - { - if (!p_ptr->resist_conf) - { - if (set_confused(p_ptr->confused + rand_int(10) + 10)) - { - ident = TRUE; - } - } - - break; - } - - case SV_FOOD_HALLUCINATION: - { - if (!p_ptr->resist_chaos) - { - if (set_image(p_ptr->image + rand_int(250) + 250)) - { - ident = TRUE; - } - } - - break; - } - - case SV_FOOD_PARALYSIS: - { - if (!p_ptr->free_act) - { - if (set_paralyzed(p_ptr->paralyzed + rand_int(10) + 10)) - { - ident = TRUE; - } - } - - break; - } - - case SV_FOOD_WEAKNESS: - { - take_hit(damroll(6, 6), "poisonous food"); - (void)do_dec_stat(A_STR, STAT_DEC_NORMAL); - - ident = TRUE; - - break; - } - - case SV_FOOD_SICKNESS: - { - take_hit(damroll(6, 6), "poisonous food"); - (void)do_dec_stat(A_CON, STAT_DEC_NORMAL); - - ident = TRUE; - - break; - } - - case SV_FOOD_STUPIDITY: - { - take_hit(damroll(8, 8), "poisonous food"); - (void)do_dec_stat(A_INT, STAT_DEC_NORMAL); - - ident = TRUE; - - break; - } - - case SV_FOOD_NAIVETY: - { - take_hit(damroll(8, 8), "poisonous food"); - (void)do_dec_stat(A_WIS, STAT_DEC_NORMAL); - - ident = TRUE; - - break; - } - - case SV_FOOD_UNHEALTH: - { - take_hit(damroll(10, 10), "poisonous food"); - (void)do_dec_stat(A_CON, STAT_DEC_NORMAL); - - ident = TRUE; - - break; - } - - case SV_FOOD_DISEASE: - { - take_hit(damroll(10, 10), "poisonous food"); - (void)do_dec_stat(A_STR, STAT_DEC_NORMAL); - - ident = TRUE; - - break; - } - - case SV_FOOD_CURE_POISON: - { - if (set_poisoned(0)) ident = TRUE; - - break; - } - - case SV_FOOD_CURE_BLINDNESS: - { - if (set_blind(0)) ident = TRUE; - - break; - } - - case SV_FOOD_CURE_PARANOIA: - { - if (set_afraid(0)) ident = TRUE; - - break; - } - - case SV_FOOD_CURE_CONFUSION: - { - if (set_confused(0)) ident = TRUE; - - break; - } - - case SV_FOOD_CURE_SERIOUS: - { - if (hp_player(damroll(4, 8))) ident = TRUE; - - break; - } - - case SV_FOOD_RESTORE_STR: - { - if (do_res_stat(A_STR, TRUE)) ident = TRUE; - - break; - } - - case SV_FOOD_RESTORE_CON: - { - if (do_res_stat(A_CON, TRUE)) ident = TRUE; - - break; - } - - case SV_FOOD_RESTORING: - { - if (do_res_stat(A_STR, TRUE)) ident = TRUE; - if (do_res_stat(A_INT, TRUE)) ident = TRUE; - if (do_res_stat(A_WIS, TRUE)) ident = TRUE; - if (do_res_stat(A_DEX, TRUE)) ident = TRUE; - if (do_res_stat(A_CON, TRUE)) ident = TRUE; - if (do_res_stat(A_CHR, TRUE)) ident = TRUE; - - break; - } - - case SV_FOOD_FORTUNE_COOKIE: - { - char rumour[80]; - - msg_print("That tastes good."); - msg_print("There is message in the cookie. It says:"); - msg_print(NULL); - - switch (randint(20)) - { - case 1: - { - get_rnd_line("chainswd.txt", rumour); - break; - } - - case 2: - { - get_rnd_line("error.txt", rumour); - break; - } - - case 3: - case 4: - case 5: - { - get_rnd_line("death.txt", rumour); - break; - } - - default: - { - get_rnd_line("rumors.txt", rumour); - break; - } - } - - msg_format("%s", rumour); - msg_print(NULL); - - ident = TRUE; - - break; - } - - - case SV_FOOD_RATION: - case SV_FOOD_BISCUIT: - case SV_FOOD_JERKY: - { - msg_print("That tastes good."); - - ident = TRUE; - - break; - } - - case SV_FOOD_SLIME_MOLD: - { - msg_print("That tastes good."); - - /* 2% chance of getting the mold power */ - if (magik(2)) - { - ADD_POWER(p_ptr->powers_mod, PWR_GROW_MOLD); - p_ptr->update |= PU_POWERS; - } - - ident = TRUE; - - break; - } - - case SV_FOOD_WAYBREAD: - { - msg_print("That tastes very good."); - (void)set_poisoned(0); - (void)hp_player(damroll(4, 8)); - set_food(PY_FOOD_MAX - 1); - - ident = TRUE; - - break; - } - - case SV_FOOD_PINT_OF_ALE: - case SV_FOOD_PINT_OF_WINE: - { - msg_print("That tastes good."); - - ident = TRUE; - - q_ptr = &forge; - object_prep(q_ptr, lookup_kind(TV_BOTTLE, 1)); - q_ptr->number = 1; - object_aware(q_ptr); - object_known(q_ptr); - q_ptr->ident |= IDENT_STOREB; - (void)inven_carry(q_ptr, FALSE); - - break; - } - - case SV_FOOD_ATHELAS: - { - msg_print("A fresh, clean essence rises, driving away wounds and poison."); - - (void)set_poisoned(0); - (void)set_stun(0); - (void)set_cut(0); - if (p_ptr->black_breath) - { - msg_print("The hold of the Black Breath on you is broken!"); - p_ptr->black_breath = FALSE; - } - - ident = TRUE; - - break; - } - } - } - - /* Corpses... */ - else - { - r_ptr = &r_info[o_ptr->pval2]; - - /* Analyse the corpse */ - switch (o_ptr->sval) - { - case SV_CORPSE_CORPSE: - { - bool_ no_meat = FALSE; - - /* Not all is edible. Apologies if messy. */ - - /* Check weight -- they have to have some meat left */ - if (r_ptr->flags9 & RF9_DROP_SKELETON) - { - if (o_ptr->weight <= (r_ptr->weight * 3) / 5) - { - no_meat = TRUE; - } - } - - /* Non-skeletons are naturally have more allowances */ - else - { - if (o_ptr->weight <= (r_ptr->weight * 7) / 20) - { - no_meat = TRUE; - } - } - - /* Nothing left to eat */ - if (no_meat) - { - msg_print("There is not enough meat."); - return; - } - - - /* Check freshness */ - if (!o_ptr->timeout) msg_print("Ugh! Raw meat!"); - else msg_print("That tastes good."); - - - /* A pound of raw meat */ - o_ptr->pval -= 10; - o_ptr->weight -= 10; - - /* Corpses still have meat on them */ - destroy = FALSE; - - ident = TRUE; - - break; - } - - case SV_CORPSE_HEAD: - { - msg_print("You feel rather sick."); - - /* A pound of raw meat */ - o_ptr->pval -= 10; - o_ptr->weight -= 10; - - /* Corpses still have meat on them */ - destroy = FALSE; - - ident = TRUE; - - break; - } - - case SV_CORPSE_MEAT: - { - /* Just meat */ - if (!o_ptr->timeout) msg_print("You quickly swallow the meat."); - else msg_print("That tastes good."); - - ident = TRUE; - - /* Those darn microorganisms */ - if (!o_ptr->timeout && (o_ptr->weight > o_ptr->pval) && - !(p_ptr->resist_pois || p_ptr->oppose_pois)) - { - set_poisoned(p_ptr->poisoned + rand_int(o_ptr->weight - o_ptr->pval) + - (o_ptr->weight - o_ptr->pval)); - } - - break; - } - } - - corpse_effect(o_ptr, FALSE); - - /* Less nutritious than food rations, but much more of it. */ - fval = (o_ptr->timeout) ? 2000 : 2500; - - /* Those darn microorganisms */ - if (!o_ptr->timeout && (o_ptr->weight - o_ptr->pval > 10) && - !(p_ptr->resist_pois || p_ptr->oppose_pois)) - { - set_poisoned(p_ptr->poisoned + rand_int(o_ptr->weight - o_ptr->pval) + - (o_ptr->weight - o_ptr->pval)); - } - - /* Partially cured */ - if (o_ptr->weight > o_ptr->timeout) - { - /* Adjust the "timeout" without overflowing */ - o_ptr->timeout = (o_ptr->timeout * ((100 * o_ptr->timeout) / o_ptr->weight)) / 100; - } - } - - - /* Combine / Reorder the pack (later) */ - p_ptr->notice |= (PN_COMBINE | PN_REORDER); - - /* We have tried it */ - object_tried(o_ptr); - - /* The player is now aware of the object */ - if (ident && !object_aware_p(o_ptr)) - { - object_aware(o_ptr); - gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev); - } - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER); - - if (!fval) fval = o_ptr->pval; - - /* Food can feed the player, in a different ways */ - - /* Vampires */ - if ((PRACE_FLAG(PR1_VAMPIRE)) || (p_ptr->mimic_form == resolve_mimic_name("Vampire"))) - { - /* Reduced nutritional benefit */ - /* (void)set_food(p_ptr->food + (fval / 10)); -- No more */ - msg_print("Mere victuals hold scant sustenance for a being such as yourself."); - - /* Hungry */ - if (p_ptr->food < PY_FOOD_ALERT) - { - msg_print("Your hunger can only be satisfied with fresh blood!"); - } - } - - else if (PRACE_FLAG(PR1_NO_FOOD)) - { - if (PRACE_FLAG(PR1_UNDEAD)) - { - msg_print("The food of mortals is poor sustenance for you."); - } - else - { - msg_print("Food is poor sustenance for you."); - } - set_food(p_ptr->food + ((fval) / 40)); - } - - /* Those living in fresh */ - else - { - (void)set_food(p_ptr->food + fval); - } - - - /* Destroy food? */ - if (destroy) - { - inc_stack_size(item, -1); - } -} - - -/* - * Cut a corpse up for convenient storage - */ -void do_cmd_cut_corpse(void) -{ - int item, meat = 0, not_meat = 0; - - object_type *o_ptr; - - object_type *i_ptr; - - object_type object_type_body; - - monster_race *r_ptr; - - cptr q, s; - - - /* Restrict choices to corpses */ - item_tester_tval = TV_CORPSE; - - /* Get an item */ - q = "Hack up which corpse? "; - s = "You have no corpses."; - if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return; - - /* Get the item */ - o_ptr = get_object(item); - - r_ptr = &r_info[o_ptr->pval2]; - - if ((o_ptr->sval != SV_CORPSE_CORPSE) && (o_ptr->sval != SV_CORPSE_HEAD)) - { - msg_print ("You cannot split that."); - return; - } - - switch (o_ptr->sval) - { - case SV_CORPSE_CORPSE: - { - if (r_ptr->flags9 & RF9_DROP_SKELETON) - { - not_meat = (r_ptr->weight * 3) / 5; - } - else - { - not_meat = (r_ptr->weight * 7) / 20; - } - meat = r_ptr->weight + r_ptr->weight / 10 - not_meat; - - break; - } - - case SV_CORPSE_HEAD: - { - not_meat = r_ptr->weight / 150; - meat = r_ptr->weight / 30 + r_ptr->weight / 300 - not_meat; - - break; - } - } - - if ((o_ptr->weight <= not_meat) || (meat < 10)) - { - msg_print("There is not enough meat."); - return; - } - - /* Hacking 10 pounds off */ - if (meat > 100) meat = 100; - - /* Take a turn */ - energy_use = 100; - - o_ptr->pval -= meat; - o_ptr->weight -= meat; - - msg_print("You hack some meat off the corpse."); - - corpse_effect(o_ptr, TRUE); - - /* Get local object */ - i_ptr = &object_type_body; - - /* Make some meat */ - object_prep(i_ptr, lookup_kind(TV_CORPSE, SV_CORPSE_MEAT)); - - i_ptr->number = meat / 10; - i_ptr->pval2 = o_ptr->pval2; - - /* Length of time before decay */ - i_ptr->pval = 1000 + rand_int(1000); - - if (inven_carry_okay(i_ptr)) - { - inven_carry(i_ptr, TRUE); - } - else - { - drop_near(i_ptr, 0, p_ptr->py, p_ptr->px); - } -} - - -/* - * Use a potion to cure some meat - * - * Salt water works well. - */ -void do_cmd_cure_meat(void) -{ - int item, num, cure; - - object_type *o_ptr; - - object_type *i_ptr; - - cptr q, s; - - - /* Restrict choices to corpses */ - item_tester_tval = TV_CORPSE; - item_tester_hook = item_tester_hook_eatable; - - /* Get some meat */ - q = "Cure which meat? "; - s = "You have no meat to cure."; - if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return; - - /* Get the item */ - o_ptr = get_object(item); - - /* Restrict choices to potions */ - item_tester_tval = TV_POTION; - - /* Get a potion */ - q = "Use which potion? "; - s = "You have no potions to use."; - if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return; - - /* Get the item */ - i_ptr = get_object(item); - - if (i_ptr->number > 1) - { - /* Get a number */ - get_count(1, i_ptr->number); - - /* Save it */ - num = command_arg; - } - else - { - num = 1; - } - - if (num == 0) return; - - /* Take a turn */ - energy_use = 100; - - q = "You soak the meat."; - s = "You soak the meat."; - - switch (i_ptr->sval) - { - case SV_POTION_SALT_WATER: - { - q = "You salt the meat."; - cure = 200 * num; - - break; - } - - case SV_POTION_POISON: - { - q = "You poison the meat."; - cure = 0; - o_ptr->pval /= 2; - if (o_ptr->pval > o_ptr->weight) o_ptr->pval = o_ptr->weight; - - break; - } - - case SV_POTION_CONFUSION: - { - cure = 80 * num; - - break; - } - - case SV_POTION_SLOW_POISON: - { - cure = 20 * num; - - break; - } - - case SV_POTION_CURE_POISON: - { - cure = 45 * num; - - break; - } - - case SV_POTION_DEATH: - { - q = "You ruin the meat."; - cure = 0; - o_ptr->pval /= 10; - if (o_ptr->pval > o_ptr->weight) o_ptr->pval = o_ptr->weight / 2; - - break; - } - - default: - { - cure = 0; - - break; - } - } - - /* Message */ - if (object_known_p(i_ptr)) msg_print(q); - else msg_print(s); - - /* The meat is already spoiling */ - if (((o_ptr->sval == SV_CORPSE_MEAT) && (o_ptr->weight > o_ptr->pval)) || - (o_ptr->weight - o_ptr->pval > 10)) - { - cure = (cure * o_ptr->pval) / (o_ptr->weight * 20); - } - - /* Cure the meat */ - o_ptr->timeout += cure / o_ptr->number; - - if (o_ptr->timeout > o_ptr->pval) o_ptr->timeout = o_ptr->pval; - - /* Use up the potions */ - inc_stack_size(item, -num); -} - - -/* - * Hook to determine if an object is quaffable - */ -static bool_ item_tester_hook_quaffable(object_type *o_ptr) -{ - if ((o_ptr->tval == TV_POTION) || (o_ptr->tval == TV_POTION2)) return (TRUE); - - /* Assume not */ - return (FALSE); -} - - -static bool_ quaff_potion(int tval, int sval, int pval, int pval2) -{ - int ident = FALSE; - - - /* "Traditional" potions */ - if (tval == TV_POTION) - { - switch (sval) - { - case SV_POTION_WATER: - case SV_POTION_APPLE_JUICE: - case SV_POTION_SLIME_MOLD: - { - msg_print("You feel less thirsty."); - ident = TRUE; - - break; - } - - case SV_POTION_SLOWNESS: - { - if (set_slow(p_ptr->slow + randint(25) + 15)) ident = TRUE; - - break; - } - - case SV_POTION_SALT_WATER: - { - msg_print("The potion makes you vomit!"); - (void)set_food(PY_FOOD_STARVE - 1); - (void)set_poisoned(0); - (void)set_paralyzed(p_ptr->paralyzed + 4); - ident = TRUE; - - break; - } - - case SV_POTION_POISON: - { - if (!(p_ptr->resist_pois || p_ptr->oppose_pois)) - { - if (set_poisoned(p_ptr->poisoned + rand_int(15) + 10)) - { - ident = TRUE; - } - } - - break; - } - - case SV_POTION_BLINDNESS: - { - if (!p_ptr->resist_blind) - { - if (set_blind(p_ptr->blind + rand_int(100) + 100)) - { - ident = TRUE; - } - } - - break; - } - - /* Booze */ - case SV_POTION_CONFUSION: - { - if (!((p_ptr->resist_conf) || (p_ptr->resist_chaos))) - { - if (set_confused(p_ptr->confused + rand_int(20) + 15)) - { - ident = TRUE; - } - if (randint(2) == 1) - { - if (set_image(p_ptr->image + rand_int(150) + 150)) - { - ident = TRUE; - } - } - if (randint(13) == 1) - { - ident = TRUE; - if (randint(3) == 1) lose_all_info(); - else wiz_dark(); - teleport_player(100); - wiz_dark(); - msg_print("You wake up elsewhere with a sore head..."); - msg_print("You can't remember a thing, or how you got here!"); - } - } - - break; - } - - case SV_POTION_SLEEP: - { - if (!p_ptr->free_act) - { - if (set_paralyzed(p_ptr->paralyzed + rand_int(4) + 4)) - { - ident = TRUE; - } - } - - break; - } - - case SV_POTION_LOSE_MEMORIES: - { - if (!p_ptr->hold_life && (p_ptr->exp > 0)) - { - msg_print("You feel your memories fade."); - lose_exp(p_ptr->exp / 4); - ident = TRUE; - } - - break; - } - - case SV_POTION_RUINATION: - { - msg_print("Your nerves and muscles feel weak and lifeless!"); - take_hit(damroll(10, 10), "a potion of Ruination"); - (void)dec_stat(A_DEX, 25, TRUE); - (void)dec_stat(A_WIS, 25, TRUE); - (void)dec_stat(A_CON, 25, TRUE); - (void)dec_stat(A_STR, 25, TRUE); - (void)dec_stat(A_CHR, 25, TRUE); - (void)dec_stat(A_INT, 25, TRUE); - ident = TRUE; - - break; - } - - case SV_POTION_DEC_STR: - { - if (do_dec_stat(A_STR, STAT_DEC_NORMAL)) ident = TRUE; - - break; - } - - case SV_POTION_DEC_INT: - { - if (do_dec_stat(A_INT, STAT_DEC_NORMAL)) ident = TRUE; - - break; - } - - case SV_POTION_DEC_WIS: - { - if (do_dec_stat(A_WIS, STAT_DEC_NORMAL)) ident = TRUE; - - break; - } - - case SV_POTION_DEC_DEX: - { - if (do_dec_stat(A_DEX, STAT_DEC_NORMAL)) ident = TRUE; - - break; - } - - case SV_POTION_DEC_CON: - { - if (do_dec_stat(A_CON, STAT_DEC_NORMAL)) ident = TRUE; - - break; - } - - case SV_POTION_DEC_CHR: - { - if (do_dec_stat(A_CHR, STAT_DEC_NORMAL)) ident = TRUE; - - break; - } - - case SV_POTION_DETONATIONS: - { - msg_print("Massive explosions rupture your body!"); - take_hit(damroll(50, 20), "a potion of Detonation"); - (void)set_stun(p_ptr->stun + 75); - (void)set_cut(p_ptr->cut + 5000); - ident = TRUE; - - break; - } - - case SV_POTION_DEATH: - { - msg_print("A feeling of Death flows through your body."); - take_hit(5000, "a potion of Death"); - ident = TRUE; - - break; - } - - case SV_POTION_INFRAVISION: - { - if (set_tim_infra(p_ptr->tim_infra + 100 + randint(100))) - { - ident = TRUE; - } - - break; - } - - case SV_POTION_DETECT_INVIS: - { - if (set_tim_invis(p_ptr->tim_invis + 12 + randint(12))) - { - ident = TRUE; - } - - break; - } - - case SV_POTION_SLOW_POISON: - { - if (set_poisoned(p_ptr->poisoned / 2)) ident = TRUE; - - break; - } - - case SV_POTION_CURE_POISON: - { - if (set_poisoned(0)) ident = TRUE; - - break; - } - - case SV_POTION_BOLDNESS: - { - if (set_afraid(0)) ident = TRUE; - - break; - } - - case SV_POTION_SPEED: - { - if (!p_ptr->fast) - { - if (set_fast(randint(25) + 15, 10)) ident = TRUE; - } - else - { - (void)set_fast(p_ptr->fast + 5, 10); - } - - break; - } - - case SV_POTION_RESIST_HEAT: - { - if (set_oppose_fire(p_ptr->oppose_fire + randint(10) + 10)) - { - ident = TRUE; - } - - break; - } - - case SV_POTION_RESIST_COLD: - { - if (set_oppose_cold(p_ptr->oppose_cold + randint(10) + 10)) - { - ident = TRUE; - } - - break; - } - - case SV_POTION_HEROISM: - { - if (set_afraid(0)) ident = TRUE; - if (set_hero(p_ptr->hero + randint(25) + 25)) ident = TRUE; - if (hp_player(10)) ident = TRUE; - - break; - } - - case SV_POTION_BESERK_STRENGTH: - { - if (set_afraid(0)) ident = TRUE; - if (set_shero(p_ptr->shero + randint(25) + 25)) ident = TRUE; - if (hp_player(30)) ident = TRUE; - - break; - } - - case SV_POTION_CURE_LIGHT: - { - if (hp_player(damroll(2, 8))) ident = TRUE; - if (set_blind(0)) ident = TRUE; - if (set_cut(p_ptr->cut - 10)) ident = TRUE; - - break; - } - - case SV_POTION_CURE_SERIOUS: - { - if (hp_player(damroll(4, 8))) ident = TRUE; - if (set_blind(0)) ident = TRUE; - if (set_confused(0)) ident = TRUE; - if (set_cut((p_ptr->cut / 2) - 50)) ident = TRUE; - - break; - } - - case SV_POTION_CURE_CRITICAL: - { - if (hp_player(damroll(6, 8))) ident = TRUE; - if (set_blind(0)) ident = TRUE; - if (set_confused(0)) ident = TRUE; - if (set_poisoned(0)) ident = TRUE; - if (set_stun(0)) ident = TRUE; - if (set_cut(0)) ident = TRUE; - - break; - } - - case SV_POTION_HEALING: - { - if (hp_player(300)) ident = TRUE; - if (set_blind(0)) ident = TRUE; - if (set_confused(0)) ident = TRUE; - if (set_poisoned(0)) ident = TRUE; - if (set_stun(0)) ident = TRUE; - if (set_cut(0)) ident = TRUE; - - break; - } - - case SV_POTION_STAR_HEALING: - { - if (hp_player(1200)) ident = TRUE; - if (set_blind(0)) ident = TRUE; - if (set_confused(0)) ident = TRUE; - if (set_poisoned(0)) ident = TRUE; - if (set_stun(0)) ident = TRUE; - if (set_cut(0)) ident = TRUE; - - break; - } - - case SV_POTION_LIFE: - { - msg_print("You feel life flow through your body!"); - restore_level(); - hp_player(5000); - (void)set_poisoned(0); - (void)set_blind(0); - (void)set_confused(0); - (void)set_image(0); - (void)set_stun(0); - (void)set_cut(0); - (void)do_res_stat(A_STR, TRUE); - (void)do_res_stat(A_CON, TRUE); - (void)do_res_stat(A_DEX, TRUE); - (void)do_res_stat(A_WIS, TRUE); - (void)do_res_stat(A_INT, TRUE); - (void)do_res_stat(A_CHR, TRUE); - if (p_ptr->black_breath) - { - msg_print("The hold of the Black Breath on you is broken!"); - } - p_ptr->black_breath = FALSE; - ident = TRUE; - - break; - } - - case SV_POTION_RESTORE_MANA: - { - if (p_ptr->csp < p_ptr->msp) - { - p_ptr->csp = p_ptr->msp; - p_ptr->csp_frac = 0; - msg_print("Your feel your head clear."); - p_ptr->redraw |= (PR_MANA); - p_ptr->window |= (PW_PLAYER); - ident = TRUE; - } - - break; - } - - case SV_POTION_RESTORE_EXP: - { - if (restore_level()) ident = TRUE; - - break; - } - - case SV_POTION_RES_STR: - { - if (do_res_stat(A_STR, TRUE)) ident = TRUE; - - break; - } - - case SV_POTION_RES_INT: - { - if (do_res_stat(A_INT, TRUE)) ident = TRUE; - - break; - } - - case SV_POTION_RES_WIS: - { - if (do_res_stat(A_WIS, TRUE)) ident = TRUE; - - break; - } - - case SV_POTION_RES_DEX: - { - if (do_res_stat(A_DEX, TRUE)) ident = TRUE; - - break; - } - - case SV_POTION_RES_CON: - { - if (do_res_stat(A_CON, TRUE)) ident = TRUE; - - break; - } - - case SV_POTION_RES_CHR: - { - if (do_res_stat(A_CHR, TRUE)) ident = TRUE; - - break; - } - - case SV_POTION_INC_STR: - { - if (do_inc_stat(A_STR)) ident = TRUE; - - break; - } - - case SV_POTION_INC_INT: - { - if (do_inc_stat(A_INT)) ident = TRUE; - - break; - } - - case SV_POTION_INC_WIS: - { - if (do_inc_stat(A_WIS)) ident = TRUE; - - break; - } - - case SV_POTION_INC_DEX: - { - if (do_inc_stat(A_DEX)) ident = TRUE; - - break; - } - - case SV_POTION_INC_CON: - { - if (do_inc_stat(A_CON)) ident = TRUE; - - break; - } - - case SV_POTION_INC_CHR: - { - if (do_inc_stat(A_CHR)) ident = TRUE; - - break; - } - - case SV_POTION_AUGMENTATION: - { - if (do_inc_stat(A_STR)) ident = TRUE; - if (do_inc_stat(A_INT)) ident = TRUE; - if (do_inc_stat(A_WIS)) ident = TRUE; - if (do_inc_stat(A_DEX)) ident = TRUE; - if (do_inc_stat(A_CON)) ident = TRUE; - if (do_inc_stat(A_CHR)) ident = TRUE; - - break; - } - - case SV_POTION_ENLIGHTENMENT: - { - msg_print("An image of your surroundings forms in your mind..."); - wiz_lite(); - ident = TRUE; - - break; - } - - case SV_POTION_STAR_ENLIGHTENMENT: - { - msg_print("You begin to feel more enlightened..."); - msg_print(NULL); - wiz_lite_extra(); - (void)do_inc_stat(A_INT); - (void)do_inc_stat(A_WIS); - (void)detect_traps(DEFAULT_RADIUS); - (void)detect_doors(DEFAULT_RADIUS); - (void)detect_stairs(DEFAULT_RADIUS); - (void)detect_treasure(DEFAULT_RADIUS); - (void)detect_objects_gold(DEFAULT_RADIUS); - (void)detect_objects_normal(DEFAULT_RADIUS); - identify_pack(); - self_knowledge(NULL); - ident = TRUE; - - break; - } - - case SV_POTION_SELF_KNOWLEDGE: - { - msg_print("You begin to know yourself a little better..."); - msg_print(NULL); - self_knowledge(NULL); - ident = TRUE; - - break; - } - - case SV_POTION_EXPERIENCE: - { - if (p_ptr->exp < PY_MAX_EXP) - { - s32b ee = (p_ptr->exp / 2) + 10; - if (ee > 100000L) ee = 100000L; - msg_print("You feel more experienced."); - gain_exp(ee); - ident = TRUE; - } - - break; - } - - case SV_POTION_RESISTANCE: - { - (void)set_oppose_acid(p_ptr->oppose_acid + randint(20) + 20); - (void)set_oppose_elec(p_ptr->oppose_elec + randint(20) + 20); - (void)set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20); - (void)set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20); - (void)set_oppose_pois(p_ptr->oppose_pois + randint(20) + 20); - ident = TRUE; - - break; - } - - case SV_POTION_CURING: - { - if (hp_player(50)) ident = TRUE; - if (set_blind(0)) ident = TRUE; - if (set_poisoned(0)) ident = TRUE; - if (set_confused(0)) ident = TRUE; - if (set_stun(0)) ident = TRUE; - if (set_cut(0)) ident = TRUE; - if (set_image(0)) ident = TRUE; - if (heal_insanity(50)) ident = TRUE; - - break; - } - - case SV_POTION_INVULNERABILITY: - { - (void)set_invuln(p_ptr->invuln + randint(7) + 7); - ident = TRUE; - - break; - } - - case SV_POTION_NEW_LIFE: - { - do_cmd_rerate(); - ident = TRUE; - - break; - } - - case SV_POTION_BLOOD: - { - msg_print("You feel the blood of life running through your veins!"); - ident = TRUE; - p_ptr->allow_one_death++; - - break; - } - - case SV_POTION_MUTATION: - { - msg_print("You feel the dark corruptions of Morgoth coming over you!"); - gain_random_corruption(0); - ident = TRUE; - break; - } - - case SV_POTION_INVIS: - { - int t = 30 + randint(30); - - if (set_invis(p_ptr->tim_invis + t, 35)) - { - ident = TRUE; - } - set_tim_invis(p_ptr->tim_invis + t); - - break; - } - - case SV_POTION_LEARNING: - { - p_ptr->skill_points += rand_range(4, 10 + luck( -4, 4)); - cmsg_format(TERM_L_GREEN, "You can increase %d more skills.", p_ptr->skill_points); - - break; - } - - default: - { - break; - } - } - } - - /* "Duplicate" potions */ - else - { - switch (sval) - { - case SV_POTION2_MIMIC: - { - if (!p_ptr->mimic_form) - { - s32b time; - - call_lua("get_mimic_rand_dur", "(d)", "d", pval2, &time); - - set_mimic(time, pval2, (p_ptr->lev * 2) / 3); - - /* Redraw title */ - p_ptr->redraw |= (PR_TITLE); - - /* Recalculate bonuses */ - p_ptr->update |= (PU_BONUS); - - ident = TRUE; - } - - break; - } - - case SV_POTION2_CURE_LIGHT_SANITY: - { - if (heal_insanity(damroll(4, 8))) ident = TRUE; - - break; - } - - case SV_POTION2_CURE_SERIOUS_SANITY: - { - if (heal_insanity(damroll(8, 8))) ident = TRUE; - - break; - } - - case SV_POTION2_CURE_CRITICAL_SANITY: - { - if (heal_insanity(damroll(12, 8))) ident = TRUE; - - break; - } - - case SV_POTION2_CURE_SANITY: - { - if (heal_insanity(damroll(10, 100))) ident = TRUE; - - break; - } - - default: - { - break; - } - } - } - - return (ident); -} - - -/* - * Quaff a potion (from the pack or the floor) - */ -void do_cmd_quaff_potion(void) -{ - int item, ident, lev; - - object_type *o_ptr; - - object_type *q_ptr, forge; - - cptr q, s; - - - /* Restrict choices to potions */ - item_tester_hook = item_tester_hook_quaffable; - - /* Set up the extra finder */ - get_item_hook_find_obj_what = "Potion full name? "; - get_item_extra_hook = get_item_hook_find_obj; - - /* Get an item */ - q = "Quaff which potion? "; - s = "You have no potions to quaff."; - if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return; - - /* Get the item */ - o_ptr = get_object(item); - - - /* Sound */ - sound(SOUND_QUAFF); - - - /* Take a turn */ - energy_use = 100; - - /* Not identified yet */ - ident = FALSE; - - /* Object level */ - lev = k_info[o_ptr->k_idx].level; - - /* Analyze the potion */ - if (process_hooks_ret(HOOK_QUAFF, "d", "(O)", o_ptr)) - { - ident = process_hooks_return[0].num; - } - else - { - ident = quaff_potion(o_ptr->tval, o_ptr->sval, o_ptr->pval, o_ptr->pval2); - } - - /* Combine / Reorder the pack (later) */ - p_ptr->notice |= (PN_COMBINE | PN_REORDER); - - /* The item has been tried */ - object_tried(o_ptr); - - /* An identification was made */ - if (ident && !object_aware_p(o_ptr)) - { - object_aware(o_ptr); - gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev); - } - - if (get_skill(SKILL_ALCHEMY)) - { - if (item >= 0) - { - q_ptr = &forge; - object_prep(q_ptr, lookup_kind(TV_BOTTLE, 1)); - q_ptr->number = 1; - object_aware(q_ptr); - object_known(q_ptr); - - q_ptr->ident |= IDENT_STOREB; - - (void)inven_carry(q_ptr, FALSE); - } - } - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER); - - - /* Potions can feed the player */ - (void)set_food(p_ptr->food + o_ptr->pval); - - - /* Destroy potion */ - inc_stack_size(item, -1); -} - - -/* - * Drink from a fountain - */ -void do_cmd_drink_fountain(void) -{ - cave_type *c_ptr = &cave[p_ptr->py][p_ptr->px]; - - bool_ ident; - - int tval, sval, pval = 0; - - int i; - - char ch; - - - /* Is the fountain empty? */ - if (c_ptr->special2 <= 0) - { - msg_print("The fountain is dried out."); - return; - } - - /* We quaff or we fill ? */ - if (!get_com("Do you want to [Q]uaff or [F]ill from the fountain? ", &ch)) - { - return; - } - - if ((ch == 'F') || (ch == 'f')) - { - do_cmd_fill_bottle(); - - return; - } - - else if ((ch == 'Q') || (ch == 'q')) - { - if (c_ptr->special <= SV_POTION_LAST) - { - tval = TV_POTION; - sval = c_ptr->special; - } - else - { - tval = TV_POTION2; - sval = c_ptr->special - SV_POTION_LAST; - } - - for (i = 0; i < max_k_idx; i++) - { - object_kind *k_ptr = &k_info[i]; - - if (k_ptr->tval != tval) continue; - if (k_ptr->sval != sval) continue; - - pval = k_ptr->pval; - - break; - } - - ident = quaff_potion(tval, sval, pval, 0); - - c_ptr->special2--; - - if (c_ptr->special2 <= 0) - { - cave_set_feat(p_ptr->py, p_ptr->px, FEAT_EMPTY_FOUNTAIN); - } - - if (ident) c_ptr->info |= CAVE_IDNT; - } -} - - -/* - * Fill an empty bottle - */ -void do_cmd_fill_bottle(void) -{ - cave_type *c_ptr = &cave[p_ptr->py][p_ptr->px]; - - int tval, sval, item, amt = 1; - - object_type *q_ptr, *o_ptr, forge; - - cptr q, s; - - /* Is the fountain empty? */ - /* - * This check is redundant as it is done in do_cmd_drink_fountain() - * but I keep this because someone might want to call this directly. - * -- Kusunose - */ - if (c_ptr->special2 <= 0) - { - msg_print("The fountain has dried up."); - return; - } - - /* Determine the tval/sval of the potion */ - if (c_ptr->special <= SV_POTION_LAST) - { - tval = TV_POTION; - sval = c_ptr->special; - } - else - { - tval = TV_POTION2; - sval = c_ptr->special - SV_POTION_LAST; - } - - /* Restrict choices to bottles */ - item_tester_tval = TV_BOTTLE; - - /* Get an item */ - q = "Fill which bottle? "; - s = "You have no bottles to fill."; - if (!get_item(&item, q, s, (USE_INVEN))) return; - o_ptr = &p_ptr->inventory[item]; - - /* Find out how many the player wants */ - if (o_ptr->number > 1) - { - /* Get a quantity */ - amt = get_quantity(NULL, o_ptr->number); - - /* Allow user abort */ - if (amt <= 0) return; - } - - if (amt > c_ptr->special2) amt = c_ptr->special2; - - /* Destroy bottles */ - inc_stack_size(item, -amt); - - /* Create the potion */ - q_ptr = &forge; - object_prep(q_ptr, lookup_kind(tval, sval)); - q_ptr->number = amt; - - if (c_ptr->info & CAVE_IDNT) - { - object_aware(q_ptr); - object_known(q_ptr); - } - - inven_carry(q_ptr, TRUE); - - c_ptr->special2 -= amt; - - if (c_ptr->special2 <= 0) - { - cave_set_feat(p_ptr->py, p_ptr->px, FEAT_EMPTY_FOUNTAIN); - } - - return; -} - - -/* - * Curse the players armor - */ -bool_ curse_armor(void) -{ - object_type *o_ptr; - - char o_name[80]; - - - /* Curse the body armor */ - o_ptr = &p_ptr->inventory[INVEN_BODY]; - - /* Nothing to curse */ - if (!o_ptr->k_idx) return (FALSE); - - - /* Describe */ - object_desc(o_name, o_ptr, FALSE, 3); - - /* Attempt a saving throw for artifacts */ - if (((o_ptr->art_name) || artifact_p(o_ptr)) && (rand_int(100) < 50)) - { - /* Cool */ - msg_format("A terrible black aura tries to surround your armour, " - "but your %s resists the effects!", o_name); - } - - /* not artifact or failed save... */ - else - { - /* Oops */ - msg_format("A terrible black aura blasts your %s!", o_name); - - /* Blast the armor */ - o_ptr->name1 = 0; - o_ptr->name2 = EGO_BLASTED; - o_ptr->to_a = 0 - randint(5) - randint(5); - o_ptr->to_h = 0; - o_ptr->to_d = 0; - o_ptr->ac = 0; - o_ptr->dd = 0; - o_ptr->ds = 0; - o_ptr->art_flags1 = 0; - o_ptr->art_flags2 = 0; - o_ptr->art_flags3 = 0; - o_ptr->art_flags4 = 0; - - /* Curse it */ - o_ptr->ident |= (IDENT_CURSED); - - /* Recalculate bonuses */ - p_ptr->update |= (PU_BONUS); - - /* Recalculate mana */ - p_ptr->update |= (PU_MANA); - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER); - } - - return (TRUE); -} - - -/* - * Curse the players weapon - */ -bool_ curse_weapon(void) -{ - object_type *o_ptr; - - char o_name[80]; - - - /* Curse the weapon */ - o_ptr = &p_ptr->inventory[INVEN_WIELD]; - - /* Nothing to curse */ - if (!o_ptr->k_idx) return (FALSE); - - - /* Describe */ - object_desc(o_name, o_ptr, FALSE, 3); - - /* Attempt a saving throw */ - if ((artifact_p(o_ptr) || o_ptr->art_name) && (rand_int(100) < 50)) - { - /* Cool */ - msg_format("A terrible black aura tries to surround your weapon, " - "but your %s resists the effects!", o_name); - } - - /* not artifact or failed save... */ - else - { - /* Oops */ - msg_format("A terrible black aura blasts your %s!", o_name); - - /* Shatter the weapon */ - o_ptr->name1 = 0; - o_ptr->name2 = EGO_SHATTERED; - o_ptr->to_h = 0 - randint(5) - randint(5); - o_ptr->to_d = 0 - randint(5) - randint(5); - o_ptr->to_a = 0; - o_ptr->ac = 0; - o_ptr->dd = 0; - o_ptr->ds = 0; - o_ptr->art_flags1 = 0; - o_ptr->art_flags2 = 0; - o_ptr->art_flags3 = 0; - o_ptr->art_flags4 = 0; - - - /* Curse it */ - o_ptr->ident |= (IDENT_CURSED); - - /* Recalculate bonuses */ - p_ptr->update |= (PU_BONUS); - - /* Recalculate mana */ - p_ptr->update |= (PU_MANA); - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER); - } - - /* Notice */ - return (TRUE); -} - - -/* - * Hook to determine if an object is readable - */ -static bool_ item_tester_hook_readable(object_type *o_ptr) -{ - if ((o_ptr->tval == TV_SCROLL) || (o_ptr->tval == TV_PARCHMENT)) return (TRUE); - - /* Assume not */ - return (FALSE); -} - - -/* - * Read a scroll (from the pack or floor). - * - * Certain scrolls can be "aborted" without losing the scroll. These - * include scrolls with no effects but recharge or identify, which are - * cancelled before use. XXX Reading them still takes a turn, though. - */ -void do_cmd_read_scroll(void) -{ - int item, k, used_up, ident, lev; - - object_type *o_ptr; - - object_type *q_ptr, forge; - - cptr q, s; - - - /* Check some conditions */ - if (p_ptr->blind) - { - msg_print("You can't see anything."); - return; - } - - if (no_lite()) - { - msg_print("You have no light by which to read."); - return; - } - - if (p_ptr->confused) - { - msg_print("You are too confused!"); - return; - } - - - /* Restrict choices to scrolls */ - item_tester_hook = item_tester_hook_readable; - - /* Set up the extra finder */ - get_item_hook_find_obj_what = "Scroll full name? "; - get_item_extra_hook = get_item_hook_find_obj; - - /* Get an item */ - q = "Read which scroll? "; - s = "You have no scrolls to read."; - if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return; - - /* Get the item */ - o_ptr = get_object(item); - - /* Take a turn */ - energy_use = 100; - - /* Not identified yet */ - ident = FALSE; - - /* Object level */ - lev = k_info[o_ptr->k_idx].level; - - /* Assume the scroll will get used up */ - used_up = TRUE; - - /* New scripts, can override the ingame code */ - if (process_hooks_ret(HOOK_READ, "dd", "(O)", o_ptr)) - { - used_up = process_hooks_return[0].num; - ident = process_hooks_return[1].num; - } - /* Traditional scrolls */ - else if (o_ptr->tval == TV_SCROLL) - { - /* Analyze the scroll */ - switch (o_ptr->sval) - { - case SV_SCROLL_MASS_RESURECTION: - { - int k; - - ident = TRUE; - msg_print("You feel the souls of the dead coming back " - "from the Halls of Mandos."); - - for (k = 0; k < max_r_idx; k++) - { - monster_race *r_ptr = &r_info[k]; - - if (r_ptr->flags1 & RF1_UNIQUE && - !(r_ptr->flags9 & RF9_SPECIAL_GENE)) - { - r_ptr->max_num = 1; - } - } - - break; - } - - case SV_SCROLL_DEINCARNATION: - { - if (!get_check("Do you really want to leave your body? " - "(beware, it'll be destroyed!) ")) - { - used_up = FALSE; - break; - } - - do_cmd_leave_body(FALSE); - - ident = TRUE; - used_up = TRUE; - - break; - } - - /* original didn't set used_up flag ??? -- pelpel */ - case SV_SCROLL_RESET_RECALL: - { - if (!reset_recall(TRUE)) - { - used_up = FALSE; - break; - } - - msg_format("Recall reset to %s at level %d.", - d_info[p_ptr->recall_dungeon].name + d_name, - max_dlv[p_ptr->recall_dungeon]); - - ident = TRUE; - used_up = TRUE; - - break; - } - - case SV_SCROLL_DIVINATION: - { - int i, count = 0; - char buf[120]; - - while (count < 1000) - { - count++; - i = rand_int(MAX_FATES); - if (!fates[i].fate) continue; - if (fates[i].know) continue; - - msg_print("A message appears on the scroll. It says:"); - msg_print(NULL); - - fate_desc(buf, i); - msg_format("%s", buf); - - msg_print(NULL); - msg_print("The scroll disappears in a puff of smoke!"); - - fates[i].know = TRUE; - ident = TRUE; - - break; - } - - break; - } - - case SV_SCROLL_DARKNESS: - { - if (!(p_ptr->resist_blind) && !(p_ptr->resist_dark)) - { - (void)set_blind(p_ptr->blind + 3 + randint(5)); - } - if (unlite_area(10, 3)) ident = TRUE; - - break; - } - - case SV_SCROLL_AGGRAVATE_MONSTER: - { - msg_print("There is a high-pitched humming noise."); - aggravate_monsters(1); - - ident = TRUE; - - break; - } - - case SV_SCROLL_CURSE_ARMOR: - { - if (curse_armor()) ident = TRUE; - - break; - } - - case SV_SCROLL_CURSE_WEAPON: - { - if (curse_weapon()) ident = TRUE; - - break; - } - - case SV_SCROLL_SUMMON_MONSTER: - { - for (k = 0; k < randint(3); k++) - { - if (summon_specific(p_ptr->py, p_ptr->px, dun_level, 0)) - { - ident = TRUE; - } - } - - break; - } - - case SV_SCROLL_SUMMON_MINE: - { - if (summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_MINE, FALSE)) - { - ident = TRUE; - } - - break; - } - - case SV_SCROLL_SUMMON_UNDEAD: - { - for (k = 0; k < randint(3); k++) - { - if (summon_specific(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNDEAD)) - { - ident = TRUE; - } - } - - break; - } - - case SV_SCROLL_TRAP_CREATION: - { - if (trap_creation()) ident = TRUE; - - break; - } - - case SV_SCROLL_PHASE_DOOR: - { - teleport_player(10); - - ident = TRUE; - - break; - } - - case SV_SCROLL_TELEPORT: - { - teleport_player(100); - - ident = TRUE; - - break; - } - - case SV_SCROLL_TELEPORT_LEVEL: - { - (void)teleport_player_level(); - - ident = TRUE; - - break; - } - - case SV_SCROLL_WORD_OF_RECALL: - { - if ((dungeon_flags2 & DF2_ASK_LEAVE) && !get_check("Leave this unique level forever? ")) - { - used_up = FALSE; - } - else - { - recall_player(21, 15); - - ident = TRUE; - } - - break; - } - - case SV_SCROLL_IDENTIFY: - { - ident = TRUE; - - if (!ident_spell()) used_up = FALSE; - - break; - } - - case SV_SCROLL_STAR_IDENTIFY: - { - ident = TRUE; - - if (!identify_fully()) used_up = FALSE; - - break; - } - - case SV_SCROLL_REMOVE_CURSE: - { - if (remove_curse()) - { - msg_print("You feel as if someone is watching over you."); - ident = TRUE; - } - - break; - } - - case SV_SCROLL_STAR_REMOVE_CURSE: - { - remove_all_curse(); - - ident = TRUE; - - break; - } - - case SV_SCROLL_ENCHANT_ARMOR: - { - ident = TRUE; - - if (!enchant_spell(0, 0, 1, 0)) used_up = FALSE; - - break; - } - - case SV_SCROLL_ENCHANT_WEAPON_TO_HIT: - { - if (!enchant_spell(1, 0, 0, 0)) used_up = FALSE; - - ident = TRUE; - - break; - } - - case SV_SCROLL_ENCHANT_WEAPON_TO_DAM: - { - if (!enchant_spell(0, 1, 0, 0)) used_up = FALSE; - - ident = TRUE; - - break; - } - - case SV_SCROLL_ENCHANT_WEAPON_PVAL: - { - if (!enchant_spell(0, 0, 0, 1)) used_up = FALSE; - - ident = TRUE; - - break; - } - - case SV_SCROLL_STAR_ENCHANT_ARMOR: - { - if (!enchant_spell(0, 0, randint(3) + 2, 0)) used_up = FALSE; - - ident = TRUE; - - break; - } - - case SV_SCROLL_STAR_ENCHANT_WEAPON: - { - if (!enchant_spell(randint(3), randint(3), 0, 0)) used_up = FALSE; - - ident = TRUE; - - break; - } - - case SV_SCROLL_RECHARGING: - { - if (!recharge(60)) used_up = FALSE; - - ident = TRUE; - - break; - } - - case SV_SCROLL_LIGHT: - { - if (lite_area(damroll(2, 8), 2)) ident = TRUE; - - break; - } - - case SV_SCROLL_MAPPING: - { - map_area(); - - ident = TRUE; - - break; - } - - case SV_SCROLL_DETECT_GOLD: - { - if (detect_treasure(DEFAULT_RADIUS)) ident = TRUE; - if (detect_objects_gold(DEFAULT_RADIUS)) ident = TRUE; - - break; - } - - case SV_SCROLL_DETECT_ITEM: - { - if (detect_objects_normal(DEFAULT_RADIUS)) ident = TRUE; - - break; - } - - case SV_SCROLL_DETECT_TRAP: - { - if (detect_traps(DEFAULT_RADIUS)) ident = TRUE; - - break; - } - - case SV_SCROLL_DETECT_DOOR: - { - if (detect_doors(DEFAULT_RADIUS)) ident = TRUE; - if (detect_stairs(DEFAULT_RADIUS)) ident = TRUE; - - break; - } - - case SV_SCROLL_DETECT_INVIS: - { - if (detect_monsters_invis(DEFAULT_RADIUS)) ident = TRUE; - - break; - } - - case SV_SCROLL_SATISFY_HUNGER: - { - if (set_food(PY_FOOD_MAX - 1)) ident = TRUE; - - break; - } - - case SV_SCROLL_BLESSING: - { - if (set_blessed(p_ptr->blessed + randint(12) + 6)) ident = TRUE; - - break; - } - - case SV_SCROLL_HOLY_CHANT: - { - if (set_blessed(p_ptr->blessed + randint(24) + 12)) ident = TRUE; - - break; - } - - case SV_SCROLL_HOLY_PRAYER: - { - if (set_blessed(p_ptr->blessed + randint(48) + 24)) ident = TRUE; - - break; - } - - case SV_SCROLL_MONSTER_CONFUSION: - { - if (p_ptr->confusing == 0) - { - msg_print("Your hands begin to glow."); - p_ptr->confusing = TRUE; - ident = TRUE; - } - - break; - } - - case SV_SCROLL_PROTECTION_FROM_EVIL: - { - k = 3 * p_ptr->lev; - if (set_protevil(p_ptr->protevil + randint(25) + k)) ident = TRUE; - - break; - } - - case SV_SCROLL_RUNE_OF_PROTECTION: - { - warding_glyph(); - - ident = TRUE; - - break; - } - - case SV_SCROLL_TRAP_DOOR_DESTRUCTION: - { - if (destroy_doors_touch()) ident = TRUE; - - break; - } - - case SV_SCROLL_STAR_DESTRUCTION: - { - /* Prevent destruction of quest levels and town */ - if (!is_quest(dun_level) && dun_level) - { - destroy_area(p_ptr->py, p_ptr->px, 15, TRUE, FALSE); - } - else - { - msg_print("The dungeon trembles..."); - } - - ident = TRUE; - - break; - } - - case SV_SCROLL_DISPEL_UNDEAD: - { - if (dispel_undead(60)) ident = TRUE; - - break; - } - - case SV_SCROLL_GENOCIDE: - { - (void)genocide(TRUE); - - ident = TRUE; - - break; - } - - case SV_SCROLL_MASS_GENOCIDE: - { - (void)mass_genocide(TRUE); - - ident = TRUE; - - break; - } - - case SV_SCROLL_ACQUIREMENT: - { - acquirement(p_ptr->py, p_ptr->px, 1, TRUE, FALSE); - - ident = TRUE; - - break; - } - - case SV_SCROLL_STAR_ACQUIREMENT: - { - acquirement(p_ptr->py, p_ptr->px, randint(2) + 1, TRUE, FALSE); - - ident = TRUE; - - break; - } - - /* ZAngband scrolls */ - case SV_SCROLL_FIRE: - { - fire_ball(GF_FIRE, 0, 150, 4); - - /* - * Note: "Double" damage since it is centered on - * the player ... - */ - if (!p_ptr->oppose_fire && !p_ptr->resist_fire && - !p_ptr->immune_fire) - { - take_hit(50 + randint(50) + (p_ptr->sensible_fire) ? 20 : 0, - "a Scroll of Fire"); - } - - ident = TRUE; - - break; - } - - - case SV_SCROLL_ICE: - { - fire_ball(GF_ICE, 0, 175, 4); - - if (!p_ptr->oppose_cold && !p_ptr->resist_cold && - !p_ptr->immune_cold) - { - take_hit(100 + randint(100), "a Scroll of Ice"); - } - - ident = TRUE; - - break; - } - - case SV_SCROLL_CHAOS: - { - fire_ball(GF_CHAOS, 0, 222, 4); - - if (!p_ptr->resist_chaos) - { - take_hit(111 + randint(111), "a Scroll of Chaos"); - } - - ident = TRUE; - - break; - } - - case SV_SCROLL_RUMOR: - { - char rumour[80]; - - msg_print("There is message on the scroll. It says:"); - msg_print(NULL); - - /* Pick random text */ - switch (randint(20)) - { - case 1: - { - get_rnd_line("chainswd.txt", rumour); - - break; - } - - case 2: - { - get_rnd_line("error.txt", rumour); - - break; - } - - case 3: - case 4: - case 5: - { - get_rnd_line("death.txt", rumour); - - break; - } - - default: - { - get_rnd_line("rumors.txt", rumour); - - break; - } - } - - msg_format("%s", rumour); - msg_print(NULL); - - msg_print("The scroll disappears in a puff of smoke!"); - - ident = TRUE; - - break; - } - - case SV_SCROLL_ARTIFACT: - { - ident = TRUE; - - if (!artifact_scroll()) used_up = FALSE; - - break; - } - - default: - { - break; - } - } - } - - /* Other readable items */ - else - { - /* Maps */ - if (o_ptr->sval >= 200) - { - int i, n; - char buf[80], fil[20]; - - strnfmt(fil, 20, "book-%d.txt", o_ptr->sval); - - n = atoi(get_line(fil, ANGBAND_DIR_FILE, buf, -1)); - - /* Parse all the fields */ - for (i = 0; i < n; i += 4) - { - /* Grab the fields */ - int x = atoi(get_line(fil, ANGBAND_DIR_FILE, buf, i + 0)); - int y = atoi(get_line(fil, ANGBAND_DIR_FILE, buf, i + 1)); - int w = atoi(get_line(fil, ANGBAND_DIR_FILE, buf, i + 2)); - int h = atoi(get_line(fil, ANGBAND_DIR_FILE, buf, i + 3)); - - reveal_wilderness_around_player(y, x, h, w); - } - } - - /* Normal parchements */ - else - { - /* Save screen */ - screen_save(); - - /* Get the filename */ - q = format("book-%d.txt", o_ptr->sval); - - /* Peruse the help file */ - (void)show_file(q, NULL, 0, 0); - - /* Load screen */ - screen_load(); - - if (o_ptr->sval >= 100) - { - inscription_info[o_ptr->sval - 100].know = TRUE; - } - - used_up = FALSE; - } - } - - - /* Combine / Reorder the pack (later) */ - p_ptr->notice |= (PN_COMBINE | PN_REORDER); - - /* The item was tried */ - object_tried(o_ptr); - - /* An identification was made */ - if (ident && !object_aware_p(o_ptr)) - { - object_aware(o_ptr); - gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev); - } - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER); - - - /* Hack -- allow certain scrolls to be "preserved" */ - if (!used_up) return; - - sound(SOUND_SCROLL); - - /* Destroy scroll */ - inc_stack_size(item, -1); - - if (get_skill(SKILL_ALCHEMY)) - { - if (item >= 0) - { - q_ptr = &forge; - object_prep(q_ptr, lookup_kind(TV_SCROLL, SV_SCROLL_NOTHING)); - object_aware(q_ptr); - object_known(q_ptr); - - q_ptr->ident |= IDENT_STOREB; - - (void)inven_carry(q_ptr, FALSE); - } - } -} - - - -/* Set the 'stick mode' on */ -void set_stick_mode(object_type *o_ptr) -{ - s32b bonus = o_ptr->pval3 & 0xFFFF; - s32b max = o_ptr->pval3 >> 16; - - exec_lua(format("get_level_use_stick = %d; get_level_max_stick = %d", bonus, max)); -} -/* Remove 'stick mode' */ -void unset_stick_mode() -{ - exec_lua("get_level_use_stick = -1; get_level_max_stick = -1"); -} - - -/* - * Use a staff. -RAK- - * - * One charge of one staff disappears. - * - * Hack -- staffs of identify can be "cancelled". - */ -void do_cmd_use_staff(void) -{ - int item, ident, chance; - - s32b obvious, use_charge; - - object_type *o_ptr; - - u32b f1, f2, f3, f4, f5, esp; - - cptr q, s; - - /* No magic */ - if (p_ptr->antimagic) - { - msg_print("Your anti-magic field disrupts any magic attempts."); - return; - } - - /* Restrict choices to wands */ - item_tester_tval = TV_STAFF; - - /* Set up the extra finder */ - get_item_hook_find_obj_what = "Staff full name? "; - get_item_extra_hook = get_item_hook_find_obj; - - /* Get an item */ - q = "Use which staff? "; - s = "You have no staff to use."; - if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return; - - /* Get the item */ - o_ptr = get_object(item); - - /* Mega-Hack -- refuse to use a pile from the ground */ - if ((item < 0) && (o_ptr->number > 1)) - { - msg_print("You must first pick up the staffs."); - return; - } - - /* Enter device mode */ - set_stick_mode(o_ptr); - - /* Take a turn */ - energy_use = 100; - - /* Not identified yet */ - ident = FALSE; - - /* get the chance */ - chance = exec_lua(format("return spell_chance(%d)", o_ptr->pval2)); - - /* Extract object flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - /* Is it simple to use ? */ - if (f4 & TR4_EASY_USE) - { - chance /= 3; - } - - /* Give everyone a (slight) chance */ - if ((chance < USE_DEVICE) && (rand_int(USE_DEVICE - chance + 1) == 0)) - { - chance = USE_DEVICE; - } - - /* Roll for usage */ - if (magik(chance)) - { - if (flush_failure) flush(); - msg_print("You failed to use the staff properly."); - sound(SOUND_FAIL); - - /* Leave device mode */ - unset_stick_mode(); - return; - } - - /* Notice empty staffs */ - if (o_ptr->pval <= 0) - { - if (flush_failure) flush(); - msg_print("The staff has no charges left."); - o_ptr->ident |= (IDENT_EMPTY); - - /* Leave device mode */ - unset_stick_mode(); - return; - } - - - /* Sound */ - sound(SOUND_ZAP); - - - /* Analyze the staff */ - call_lua("activate_stick", "(d)", "dd", o_ptr->pval2, &obvious, &use_charge); - - /* Combine / Reorder the pack (later) */ - p_ptr->notice |= (PN_COMBINE | PN_REORDER); - - /* Tried the item */ - object_tried(o_ptr); - - /* An identification was made */ - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER); - - - /* Hack -- some uses are "free" */ - if (!use_charge) - { - /* Leave device mode */ - unset_stick_mode(); - - return; - } - - /* An identification was made */ - if (obvious) - { - object_aware(o_ptr); - } - - /* Use a single charge */ - o_ptr->pval--; - - /* XXX Hack -- unstack if necessary */ - if ((item >= 0) && (o_ptr->number > 1)) - { - object_type forge; - object_type *q_ptr; - - /* Get local object */ - q_ptr = &forge; - - /* Obtain a local object */ - object_copy(q_ptr, o_ptr); - - /* Modify quantity */ - q_ptr->number = 1; - - /* Restore the charges */ - o_ptr->pval++; - - /* Unstack the used item */ - o_ptr->number--; - item = inven_carry(q_ptr, FALSE); - - /* Message */ - msg_print("You unstack your staff."); - } - - /* Describe charges in the pack */ - if (item >= 0) - { - inven_item_charges(item); - } - - /* Describe charges on the floor */ - else - { - floor_item_charges(0 - item); - } - - /* Leave device mode */ - unset_stick_mode(); -} - - -/* - * Aim a wand (from the pack or floor). - * - * Use a single charge from a single item. - * Handle "unstacking" in a logical manner. - * - * For simplicity, you cannot use a stack of items from the - * ground. This would require too much nasty code. - * - * There are no wands which can "destroy" themselves, in the p_ptr->inventory - * or on the ground, so we can ignore this possibility. Note that this - * required giving "wand of wonder" the ability to ignore destruction - * by electric balls. - * - * All wands can be "cancelled" at the "Direction?" prompt for free. - * - * Note that the basic "bolt" wands do slightly less damage than the - * basic "bolt" rods, but the basic "ball" wands do the same damage - * as the basic "ball" rods. - */ -void do_cmd_aim_wand(void) -{ - s32b obvious, use_charge; - - int item, ident, chance, sval; - - object_type *o_ptr; - - cptr q, s; - - u32b f1, f2, f3, f4, f5, esp; - - - /* No magic */ - if (p_ptr->antimagic) - { - msg_print("Your anti-magic field disrupts any magic attempts."); - return; - } - - /* Restrict choices to wands */ - item_tester_tval = TV_WAND; - - /* Set up the extra finder */ - get_item_hook_find_obj_what = "Wand full name? "; - get_item_extra_hook = get_item_hook_find_obj; - - /* Get an item */ - q = "Aim which wand? "; - s = "You have no wand to aim."; - if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return; - - /* Get the item */ - o_ptr = get_object(item); - - - /* Mega-Hack -- refuse to aim a pile from the ground */ - if ((item < 0) && (o_ptr->number > 1)) - { - msg_print("You must first pick up the wands."); - return; - } - - /* Take a turn */ - energy_use = 100; - - /* Not identified yet */ - ident = FALSE; - - /* Enter device mode */ - set_stick_mode(o_ptr); - - /* get the chance */ - chance = exec_lua(format("return spell_chance(%d)", o_ptr->pval2)); - - /* Extract object flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - /* Is it simple to use ? */ - if (f4 & TR4_EASY_USE) - { - chance /= 3; - } - - /* Roll for usage */ - if (magik(chance)) - { - if (flush_failure) flush(); - msg_print("You failed to use the wand properly."); - sound(SOUND_FAIL); - - /* Leave device mode */ - unset_stick_mode(); - return; - } - - /* The wand is already empty! */ - if (o_ptr->pval <= 0) - { - if (flush_failure) flush(); - msg_print("The wand has no charges left."); - o_ptr->ident |= (IDENT_EMPTY); - - /* Leave device mode */ - unset_stick_mode(); - return; - } - - - /* Sound */ - sound(SOUND_ZAP); - - - /* XXX Hack -- Extract the "sval" effect */ - sval = o_ptr->sval; - - /* Analyze the wand */ - call_lua("activate_stick", "(d)", "dd", o_ptr->pval2, &obvious, &use_charge); - - /* Combine / Reorder the pack (later) */ - p_ptr->notice |= (PN_COMBINE | PN_REORDER); - - /* Mark it as tried */ - object_tried(o_ptr); - - /* Hack -- some uses are "free" */ - if (!use_charge) - { - /* Leave device mode */ - unset_stick_mode(); - - return; - } - - /* An identification was made */ - if (obvious) - { - object_aware(o_ptr); - } - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER); - - - /* Use a single charge */ - o_ptr->pval--; - - /* Describe the charges in the pack */ - if (item >= 0) - { - inven_item_charges(item); - } - - /* Describe the charges on the floor */ - else - { - floor_item_charges(0 - item); - } - - /* Leave device mode */ - unset_stick_mode(); -} - - - - - - -/* - * Activate (zap) a Rod - * - * Unstack fully charged rods as needed. - * - * Hack -- rods of perception/genocide can be "cancelled" - * All rods can be cancelled at the "Direction?" prompt - */ - - -/* - * Hook to determine if an object is zapable - */ -static bool_ item_tester_hook_zapable(object_type *o_ptr) -{ - if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_ROD_MAIN)) return (TRUE); - - /* Assume not */ - return (FALSE); -} - - -/* - * Hook to determine if an object is attachable - */ -static bool_ item_tester_hook_attachable(object_type *o_ptr) -{ - if ((o_ptr->tval == TV_ROD_MAIN) && - (o_ptr->pval == SV_ROD_NOTHING)) return (TRUE); - - /* Assume not */ - return (FALSE); -} - - -/* - * Combine a rod and a rod tip - */ -void zap_combine_rod_tip(object_type *q_ptr, int tip_item) -{ - int item; - - object_type *o_ptr; - - cptr q, s; - - u32b f1, f2, f3, f4, f5, esp; - s32b cost; - - - /* No magic */ - if (p_ptr->antimagic) - { - msg_print("Your anti-magic field disrupts any magic attempts."); - return; - } - - /* Restrict choices to rods */ - item_tester_hook = item_tester_hook_attachable; - - /* Get an item */ - q = "Attach the rod tip with which rod? "; - s = "You have no rod to attach to."; - if (!get_item(&item, q, s, (USE_INVEN))) return; - - /* Get the item */ - o_ptr = get_object(item); - - /* Examine the rod */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - /* Calculate rod tip's mana cost */ - cost = q_ptr->pval; - - if (f4 & TR4_CHEAPNESS) - { - cost /= 2; - } - - /* - * The rod must have at least the same mana capacity as the - * rod tip spell needs - */ - if (o_ptr->pval2 < cost) - { - msg_print("This rod doesn't have enough mana for the rod tip."); - return; - } - - /* Attach the tip to the rod */ - o_ptr->pval = q_ptr->sval; - - /* Destroy rod tip */ - inc_stack_size(tip_item, -1); -} - - -/* - * Zap a rod, or attack a rod tip to a rod - */ -void do_cmd_zap_rod(void) -{ - int item, ident, chance, dir, lev; - - int cost; - - bool_ require_dir; - - object_type *o_ptr; - - object_kind *tip_ptr; - - u32b f1, f2, f3, f4, f5, esp; - - cptr q, s; - - /* Hack -- let perception get aborted */ - bool_ use_charge = TRUE; - - - /* No magic */ - if (p_ptr->antimagic) - { - msg_print("Your anti-magic field disrupts any magic attempts."); - return; - } - - - /* Restrict choices to rods */ - item_tester_hook = item_tester_hook_zapable; - - /* Set up the extra finder */ - get_item_hook_find_obj_what = "Rod full name? "; - get_item_extra_hook = get_item_hook_find_obj; - - /* Get an item */ - q = "Zap which rod? "; - s = "You have no rod to zap."; - if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EXTRA))) return; - - /* Get the item */ - o_ptr = get_object(item); - - - /* "Zapping" a Rod Tip on rod of nothing will attach it */ - if (o_ptr->tval == TV_ROD) - { - if (item >= 0) - { - zap_combine_rod_tip(o_ptr, item); - return; - } - else - { - msg_print("You can't zap a rod tip that's on the floor."); - return; - } - } - - - /* Non-directed rods */ - if (o_ptr->pval < SV_ROD_MIN_DIRECTION) - { - require_dir = FALSE; - } - - /* Some rods always require direction */ - else - { - switch (o_ptr->pval) - { - case SV_ROD_DETECT_TRAP: - case SV_ROD_HAVOC: - case SV_ROD_HOME: - { - require_dir = FALSE; - break; - } - - default: - { - require_dir = TRUE; - break; - } - } - } - - /* Get a direction (unless KNOWN not to need it) */ - if (!object_aware_p(o_ptr) || require_dir) - { - /* Get a direction, allow cancel */ - if (!get_aim_dir(&dir)) return; - } - - /* Take a turn */ - energy_use = 100; - - /* Examine the rod */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - if (f4 & TR4_FAST_CAST) energy_use /= 2; - - /* Not identified yet */ - ident = FALSE; - - /* Extract the item level */ - tip_ptr = &k_info[lookup_kind(TV_ROD, o_ptr->pval)]; - lev = k_info[lookup_kind(TV_ROD, o_ptr->pval)].level; - - /* Base chance of success */ - chance = p_ptr->skill_dev; - - /* Confusion hurts skill */ - if (p_ptr->confused) chance = chance / 2; - - /* High level objects are harder */ - chance = chance - ((lev > 50) ? 50 : lev); - - if (chance <= 0) - { - chance = 1; - } - - /* Is it simple to use ? */ - if (f4 & TR4_EASY_USE) - { - chance *= 10; - } - - /* Give everyone a (slight) chance */ - if ((chance < USE_DEVICE) && (rand_int(USE_DEVICE - chance + 1) == 0)) - { - chance = USE_DEVICE; - } - - /* Roll for usage */ - if ((chance < USE_DEVICE) || (randint(chance) < USE_DEVICE)) - { - /* Flush input if necessary */ - if (flush_failure) flush(); - - /* Message */ - msg_print("You failed to use the rod properly."); - - sound(SOUND_FAIL); - - return; - } - - /* Extract mana cost */ - cost = tip_ptr->pval; - - /* "Cheapness" ego halven the cost */ - if (f4 & TR4_CHEAPNESS) cost = cost / 2; - - /* A single rod is still charging */ - if (o_ptr->timeout < cost) - { - /* Flush input if necessary */ - if (flush_failure) flush(); - - /* Message */ - msg_print("The rod does not have enough mana yet."); - - return; - } - - /* Increase the timeout by the rod kind's pval. */ - o_ptr->timeout -= cost; - - /* Sound */ - sound(SOUND_ZAP); - - /* Analyze the rod */ - switch (o_ptr->pval) - { - case SV_ROD_HOME: - { - ident = TRUE; - - do_cmd_home_trump(); - - break; - } - - case SV_ROD_DETECT_TRAP: - { - if (detect_traps(DEFAULT_RADIUS)) ident = TRUE; - - break; - } - - case SV_ROD_DETECT_DOOR: - { - if (detect_doors(DEFAULT_RADIUS)) ident = TRUE; - if (detect_stairs(DEFAULT_RADIUS)) ident = TRUE; - - break; - } - - case SV_ROD_IDENTIFY: - { - ident = TRUE; - - if (!ident_spell()) use_charge = FALSE; - - break; - } - - case SV_ROD_RECALL: - { - if ((dungeon_flags2 & DF2_ASK_LEAVE) && !get_check("Leave this unique level forever? ")) - { - use_charge = FALSE; - } - else - { - recall_player(21, 15); - - ident = TRUE; - } - - break; - } - - case SV_ROD_ILLUMINATION: - { - if (lite_area(damroll(2, 8), 2)) ident = TRUE; - - break; - } - - case SV_ROD_MAPPING: - { - map_area(); - - ident = TRUE; - - break; - } - - case SV_ROD_DETECTION: - { - detect_all(DEFAULT_RADIUS); - - ident = TRUE; - - break; - } - - case SV_ROD_PROBING: - { - probing(); - - ident = TRUE; - - break; - } - - case SV_ROD_CURING: - { - if (set_blind(0)) ident = TRUE; - if (set_poisoned(0)) ident = TRUE; - if (set_confused(0)) ident = TRUE; - if (set_stun(0)) ident = TRUE; - if (set_cut(0)) ident = TRUE; - if (set_image(0)) ident = TRUE; - - break; - } - - case SV_ROD_HEALING: - { - if (hp_player(500)) ident = TRUE; - if (set_stun(0)) ident = TRUE; - if (set_cut(0)) ident = TRUE; - - break; - } - - case SV_ROD_RESTORATION: - { - if (restore_level()) ident = TRUE; - if (do_res_stat(A_STR, TRUE)) ident = TRUE; - if (do_res_stat(A_INT, TRUE)) ident = TRUE; - if (do_res_stat(A_WIS, TRUE)) ident = TRUE; - if (do_res_stat(A_DEX, TRUE)) ident = TRUE; - if (do_res_stat(A_CON, TRUE)) ident = TRUE; - if (do_res_stat(A_CHR, TRUE)) ident = TRUE; - - break; - } - - case SV_ROD_SPEED: - { - if (!p_ptr->fast) - { - if (set_fast(randint(30) + 15, 10)) ident = TRUE; - } - else - { - (void)set_fast(p_ptr->fast + 5, 10); - } - - break; - } - - case SV_ROD_TELEPORT_AWAY: - { - if (teleport_monster(dir)) ident = TRUE; - - break; - } - - case SV_ROD_DISARMING: - { - if (disarm_trap(dir)) ident = TRUE; - - break; - } - - case SV_ROD_LITE: - { - msg_print("A line of blue shimmering light appears."); - lite_line(dir); - - ident = TRUE; - - break; - } - - case SV_ROD_SLEEP_MONSTER: - { - if (sleep_monster(dir)) ident = TRUE; - - break; - } - - case SV_ROD_SLOW_MONSTER: - { - if (slow_monster(dir)) ident = TRUE; - - break; - } - - case SV_ROD_DRAIN_LIFE: - { - if (drain_life(dir, 75)) ident = TRUE; - - break; - } - - case SV_ROD_POLYMORPH: - { - if (poly_monster(dir)) ident = TRUE; - - break; - } - - case SV_ROD_ACID_BOLT: - { - fire_bolt_or_beam(10, GF_ACID, dir, damroll(6, 8)); - - ident = TRUE; - - break; - } - - case SV_ROD_ELEC_BOLT: - { - fire_bolt_or_beam(10, GF_ELEC, dir, damroll(3, 8)); - - ident = TRUE; - - break; - } - - case SV_ROD_FIRE_BOLT: - { - fire_bolt_or_beam(10, GF_FIRE, dir, damroll(8, 8)); - - ident = TRUE; - - break; - } - - case SV_ROD_COLD_BOLT: - { - fire_bolt_or_beam(10, GF_COLD, dir, damroll(5, 8)); - - ident = TRUE; - - break; - } - - case SV_ROD_ACID_BALL: - { - fire_ball(GF_ACID, dir, 60, 2); - - ident = TRUE; - - break; - } - - case SV_ROD_ELEC_BALL: - { - fire_ball(GF_ELEC, dir, 32, 2); - - ident = TRUE; - - break; - } - - case SV_ROD_FIRE_BALL: - { - fire_ball(GF_FIRE, dir, 72, 2); - - ident = TRUE; - - break; - } - - case SV_ROD_COLD_BALL: - { - fire_ball(GF_COLD, dir, 48, 2); - - ident = TRUE; - - break; - } - - case SV_ROD_HAVOC: - { - call_chaos(); - - ident = TRUE; - - break; - } - - default: - { - process_hooks(HOOK_ZAP, "(d,d)", o_ptr->tval, o_ptr->sval); - - break; - } - } - - - /* Combine / Reorder the pack (later) */ - p_ptr->notice |= (PN_COMBINE | PN_REORDER); - - /* Tried the object */ - object_tried(o_ptr); - - /* Successfully determined the object function */ - if (ident && !object_aware_p(o_ptr)) - { - object_aware(o_ptr); - gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev); - } - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER); - - /* Hack -- deal with cancelled zap */ - if (!use_charge) - { - o_ptr->timeout += cost; - - return; - } -} - - - - -/* - * Hook to determine if an object is activable - */ -static bool_ item_tester_hook_activate(object_type *o_ptr) -{ - u32b f1, f2, f3, f4, f5, esp; - - - /* Not known */ - if (!object_known_p(o_ptr)) return (FALSE); - - /* Extract the flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - /* Check activation flag */ - if (f3 & (TR3_ACTIVATE)) return (TRUE); - - /* Assume not */ - return (FALSE); -} - - - -/* - * Hack -- activate the ring of power - */ -int ring_of_power() -{ - char ch = 0, p = 0; - - int plev = p_ptr->lev; - - int timeout = 0; - - - /* Select power to use */ - while (TRUE) - { - if (!get_com("[S]ummon a wraith, [R]ule the world or " - "[C]ast a powerful attack? ", &ch)) - { - return (0); - } - - if (ch == 'S' || ch == 's') - { - p = 1; - break; - } - if (ch == 'R' || ch == 'r') - { - p = 2; - break; - } - if (ch == 'C' || ch == 'c') - { - p = 3; - break; - } - } - - /* Summon a Wraith */ - if (p == 1) - { - /* Rewrite this -- pelpel */ - if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2), - (plev > 47 ? SUMMON_HI_UNDEAD_NO_UNIQUES : SUMMON_UNDEAD), - (bool_)(((plev > 24) && (randint(3) == 1)) ? TRUE : FALSE))) - { - msg_print("Cold winds begin to blow around you, " - "carrying with them the stench of decay..."); - msg_print("Ancient, long-dead forms arise from the ground " - "to serve you!"); - } - timeout = 200 + rand_int(200); - } - - /* Rule the World -- only if we can really do so */ - else if (p == 2) - { - msg_print("The power of the ring destroys the world!"); - msg_print("The world changes!"); - - autosave_checkpoint(); - - /* Leaving */ - p_ptr->leaving = TRUE; - timeout = 250 + rand_int(250); - } - - /* Cast a powerful spell */ - else if (p == 3) - { - int dir; - - if (!get_aim_dir(&dir)) return (0); - - if (rand_int(3) == 0) - { - msg_print("You call the fire of Mount Doom!"); - fire_ball(GF_METEOR, dir, 600, 4); - } - else - { - msg_print("Your ring tries to take possession of your enemy's mind!"); - fire_bolt(GF_CHARM, dir, 600); - } - timeout = 300 + rand_int(300); - } - - return (timeout); -} - - - - -/* - * Enchant some bolts - */ -bool_ brand_bolts(void) -{ - int i; - - - /* Use the first acceptable bolts */ - for (i = 0; i < INVEN_PACK; i++) - { - object_type *o_ptr = &p_ptr->inventory[i]; - - /* Skip non-bolts */ - if (o_ptr->tval != TV_BOLT) continue; - - /* Skip artifacts and ego-items */ - if (o_ptr->art_name || artifact_p(o_ptr) || ego_item_p(o_ptr)) continue; - - /* Skip cursed/broken items */ - if (cursed_p(o_ptr)) continue; - - /* Randomize */ - if (rand_int(100) < 75) continue; - - /* Message */ - msg_print("Your bolts are covered in a fiery aura!"); - - /* Ego-item */ - o_ptr->name2 = EGO_FLAME; - - /* Apply the ego */ - apply_magic(o_ptr, dun_level, FALSE, FALSE, FALSE); - - /* Enchant */ - enchant(o_ptr, rand_int(3) + 4, ENCH_TOHIT | ENCH_TODAM); - - /* Notice */ - return (TRUE); - } - - /* Flush */ - if (flush_failure) flush(); - - /* Fail */ - msg_print("The fiery enchantment failed."); - - /* Notice */ - return (TRUE); -} - - -/* - * Objects in the p_ptr->inventory can now be activated, and - * SOME of those may be able to stack (ego wands or something) - * in any case, we can't know that it's impossible. *BUT* we'll - * ignore it for now, and the timeout will be set on the entire stack - * of objects. Reduces their utility, but oh well. - * - * Note that it always takes a turn to activate an object, even if - * the user hits "escape" at the "direction" prompt. - */ -void do_cmd_activate(void) -{ - int item, lev, chance; - - char ch, spell_choice; - - object_type *o_ptr; - - u32b f1, f2, f3, f4, f5, esp; - - cptr q, s; - - - /* Prepare the hook */ - item_tester_hook = item_tester_hook_activate; - - /* Get an item */ - command_wrk = USE_EQUIP; - q = "Activate which item? "; - s = "You have nothing to activate."; - if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN))) return; - - /* Get the item */ - o_ptr = get_object(item); - - /* Extract object flags */ - object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp); - - /* Wearable items have to be worn */ - if (!(f5 & TR5_ACTIVATE_NO_WIELD)) - { - if (item < INVEN_WIELD) - { - msg_print("You must wear it to activate it."); - return; - } - } - - /* Take a turn */ - energy_use = 100; - - /* Extract the item level */ - lev = k_info[o_ptr->k_idx].level; - - /* Hack -- Use artifact level instead */ - if (artifact_p(o_ptr)) - { - if (o_ptr->tval == TV_RANDART) - { - lev = random_artifacts[o_ptr->sval].level; - } - else - { - lev = a_info[o_ptr->name1].level; - } - } - - /* Base chance of success */ - chance = p_ptr->skill_dev; - - /* Confusion hurts skill */ - if (p_ptr->confused) chance = chance / 2; - - /* Hight level objects are harder */ - chance = chance - ((lev > 50) ? 50 : lev); - - if (chance <= 0) - { - chance = 1; - } - - /* Is it simple to use ? */ - if (f4 & TR4_EASY_USE) - { - chance *= 10; - } - - /* Give everyone a (slight) chance */ - if ((chance < USE_DEVICE) && (rand_int(USE_DEVICE - chance + 1) == 0)) - { - chance = USE_DEVICE; - } - - /* Roll for usage */ - if ((chance < USE_DEVICE) || (randint(chance) < USE_DEVICE)) - { - if (flush_failure) flush(); - msg_print("You failed to activate it properly."); - sound(SOUND_FAIL); - return; - } - - /* Check the recharge */ - if (o_ptr->timeout) - { - /* Mage Staff of Spells -- Have another timeout in xtra2 */ - if (is_ego_p(o_ptr, EGO_MSTAFF_SPELL) && o_ptr->xtra2) - { - msg_print("It whines, glows and fades..."); - return; - } - - /* Monster eggs */ - else if (o_ptr->tval == TV_EGG) - { - msg_print("You resume the development of the egg."); - o_ptr->timeout = 0; - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP); - - /* Success */ - return; - } - - /* Normal activatable items */ - else - { - msg_print("It whines, glows and fades..."); - return; - } - } - - - /* Activate the item */ - msg_print("You activate it..."); - - /* Sound */ - sound(SOUND_ZAP); - - /* Lua hook ? -- go first to allow lua to override */ - if (process_hooks(HOOK_ACTIVATE, "(d)", item)) - { - return; - } - - /* New mostly unified activation code - This has to be early to allow artifacts to override normal items -- neil */ - - if ( activation_aux(o_ptr, TRUE, item) == NULL ) - { - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP); - - /* Success */ - return; - } - - /* Mage Staff of Spells */ - if (is_ego_p(o_ptr, EGO_MSTAFF_SPELL)) - { - while (TRUE) - { - if (!get_com("Use Spell [1] or [2]?", &ch)) - { - return; - } - - if (ch == '1') - { - spell_choice = 1; - break; - } - - if (ch == '2') - { - spell_choice = 2; - break; - } - } - - if (spell_choice == 1) - { - /* Still need to check timeouts because there is another counter */ - if (o_ptr->timeout) - { - msg_print("The first spell is still charging!"); - return; - } - - /* Cast spell 1 */ - activate_spell(o_ptr, spell_choice); - } - else if (spell_choice == 2) - { - /* Still need to check timeouts because there is another counter */ - if (o_ptr->xtra2) - { - msg_print("The second spell is still charging!"); - return; - } - - /* Cast spell 2 */ - activate_spell(o_ptr, spell_choice); - } - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP); - - /* Success */ - return; - } - - /* Monster eggs */ - if (o_ptr->tval == TV_EGG) - { - msg_print("You stop the development of the egg."); - o_ptr->timeout = -1; - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP); - - /* Success */ - return; - } - - /* Musical instruments */ - if (o_ptr->tval == TV_INSTRUMENT) - { - /* Horns */ - if (o_ptr->sval == SV_HORN) - { - msg_format("Your instrument emits a loud sound!"); - - aggravate_monsters(1); - - o_ptr->timeout = 100; - } - - /* Success */ - return; - } - - /* Mistake */ - msg_print("Oops. That object cannot be activated."); -} - - - -const char *activation_aux(object_type * o_ptr, bool_ doit, int item) -{ - int plev = get_skill(SKILL_DEVICE); - - int i = 0, ii = 0, ij = 0, k, dir, dummy = 0; - int chance; - bool_ is_junkart = (o_ptr->tval == TV_RANDART); - - int spell = 0; - - /* Junkarts */ - if (is_junkart) - spell = activation_info[o_ptr->pval2].spell; - - /* True Actifacts */ - if (!spell && o_ptr->name1) - spell = a_info[o_ptr->name1].activate; - - /* Random and Alchemist Artifacts */ - if (!spell && o_ptr->art_name) - spell = o_ptr->xtra2; - - /* Ego Items */ - if (!spell && o_ptr->name2) - spell = e_info[o_ptr->name2].activate; - - /* Dual egos with the second ego having the activation */ - if (!spell && o_ptr->name2b) - spell = e_info[o_ptr->name2b].activate; - - /* Intrinsic to item type (rings of Ice, etc) */ - if (!spell) - spell = k_info[o_ptr->k_idx].activate; - - /* Complain about mis-configured .txt files? */ - if (!spell) - return "Unknown!"; - - /* Negative means a unified spell index */ - if (spell < 0) - { - if (doit) - { - call_lua("activate_activation", "(d,d)", "", -spell, item); - o_ptr->timeout = exec_lua(format("return get_activation_timeout(%d)", -spell)); - } - else - { - return string_exec_lua(format("return get_activation_desc(%d)", -spell)); - } - } - else - { - /* Activate for attack */ - switch (spell) - { - case ACT_GILGALAD: - { - if (!doit) return "starlight (75) every 75+d75 turns"; - for (k = 1; k < 10; k++) - { - if (k - 5) fire_beam(GF_LITE, k, 75); - } - - o_ptr->timeout = rand_int(75) + 75; - - break; - } - - case ACT_CELEBRIMBOR: - { - if (!doit) return "temporary ESP (dur 20+d20) every 20+d50 turns"; - set_tim_esp(p_ptr->tim_esp + randint(20) + 20); - - o_ptr->timeout = rand_int(50) + 20; - - break; - } - - case ACT_SKULLCLEAVER: - { - if (!doit) return "destruction every 200+d200 turns"; - destroy_area(p_ptr->py, p_ptr->px, 15, TRUE, FALSE); - - o_ptr->timeout = rand_int(200) + 200; - - break; - } - - case ACT_HARADRIM: - { - if (!doit) return "berserk strength every 50+d50 turns"; - set_afraid(0); - set_shero(p_ptr->shero + randint(25) + 25); - hp_player(30); - - o_ptr->timeout = rand_int(50) + 50; - - break; - } - - case ACT_FUNDIN: - { - if (!doit) return "dispel evil (x4) every 100+d100 turns"; - dispel_evil(p_ptr->lev * 4); - - o_ptr->timeout = rand_int(100) + 100; - - break; - } - - case ACT_EOL: - { - if (!doit) return "mana bolt (9d8) 7+d7 turns"; - if (!get_aim_dir(&dir)) break; - fire_bolt(GF_MANA, dir, damroll(9, 8)); - - o_ptr->timeout = rand_int(7) + 7; - - break; - } - - case ACT_UMBAR: - { - if (!doit) return "magic arrow (10d10) every 20+d20 turns"; - if (!get_aim_dir(&dir)) break; - fire_bolt(GF_MISSILE, dir, damroll(10, 10)); - - o_ptr->timeout = rand_int(20) + 20; - - break; - } - - case ACT_NUMENOR: - { - /* Give full knowledge */ - /* Hack -- Maximal info */ - monster_race *r_ptr; - cave_type *c_ptr; - int x, y, m; - - if (!doit) return "analyze monster every 500+d200 turns"; - - if (!tgt_pt(&x, &y)) break; - - c_ptr = &cave[y][x]; - if (!c_ptr->m_idx) break; - - r_ptr = &r_info[c_ptr->m_idx]; - - /* Observe "maximal" attacks */ - for (m = 0; m < 4; m++) - { - /* Examine "actual" blows */ - if (r_ptr->blow[m].effect || r_ptr->blow[m].method) - { - /* Hack -- maximal observations */ - r_ptr->r_blows[m] = MAX_UCHAR; - } - } - - /* Hack -- maximal drops */ - r_ptr->r_drop_gold = r_ptr->r_drop_item = - (((r_ptr->flags1 & (RF1_DROP_4D2)) ? 8 : 0) + - ((r_ptr->flags1 & (RF1_DROP_3D2)) ? 6 : 0) + - ((r_ptr->flags1 & (RF1_DROP_2D2)) ? 4 : 0) + - ((r_ptr->flags1 & (RF1_DROP_1D2)) ? 2 : 0) + - ((r_ptr->flags1 & (RF1_DROP_90)) ? 1 : 0) + - ((r_ptr->flags1 & (RF1_DROP_60)) ? 1 : 0)); - - /* Hack -- but only "valid" drops */ - if (r_ptr->flags1 & (RF1_ONLY_GOLD)) r_ptr->r_drop_item = 0; - if (r_ptr->flags1 & (RF1_ONLY_ITEM)) r_ptr->r_drop_gold = 0; - - /* Hack -- observe many spells */ - r_ptr->r_cast_inate = MAX_UCHAR; - r_ptr->r_cast_spell = MAX_UCHAR; - - /* Hack -- know all the flags */ - r_ptr->r_flags1 = r_ptr->flags1; - r_ptr->r_flags2 = r_ptr->flags2; - r_ptr->r_flags3 = r_ptr->flags3; - r_ptr->r_flags4 = r_ptr->flags4; - r_ptr->r_flags5 = r_ptr->flags5; - r_ptr->r_flags6 = r_ptr->flags6; - r_ptr->r_flags7 = r_ptr->flags7; - r_ptr->r_flags8 = r_ptr->flags8; - r_ptr->r_flags9 = r_ptr->flags9; - - o_ptr->timeout = rand_int(200) + 500; - - break; - } - - case ACT_KNOWLEDGE: - { - if (!doit) return "whispers from beyond(sanity drain) 100+d200 turns"; - identify_fully(); - take_sanity_hit(damroll(10, 7), "the sounds of the dead"); - - o_ptr->timeout = rand_int(200) + 100; - - break; - } - - case ACT_UNDEATH: - { - if (!doit) return "ruination every 10+d10 turns"; - msg_print("The phial wells with dark light..."); - unlite_area(damroll(2, 15), 3); - take_hit(damroll(10, 10), "activating The Phial of Undeath"); - (void)dec_stat(A_DEX, 25, STAT_DEC_PERMANENT); - (void)dec_stat(A_WIS, 25, STAT_DEC_PERMANENT); - (void)dec_stat(A_CON, 25, STAT_DEC_PERMANENT); - (void)dec_stat(A_STR, 25, STAT_DEC_PERMANENT); - (void)dec_stat(A_CHR, 25, STAT_DEC_PERMANENT); - (void)dec_stat(A_INT, 25, STAT_DEC_PERMANENT); - - o_ptr->timeout = rand_int(10) + 10; - - break; - } - - case ACT_THRAIN: - { - if (!doit) return "detection every 30+d30 turns"; - msg_print("The stone glows a deep green..."); - detect_all(DEFAULT_RADIUS); - - o_ptr->timeout = rand_int(30) + 30; - - break; - } - - case ACT_BARAHIR: - { - if (!doit) return "dispel small life every 55+d55 turns"; - msg_print("You exterminate small life."); - (void)dispel_monsters(4); - - o_ptr->timeout = rand_int(55) + 55; - - break; - } - - case ACT_TULKAS: - { - if (!doit) return "haste self (75+d75 turns) every 150+d150 turns"; - msg_print("The ring glows brightly..."); - if (!p_ptr->fast) - { - (void)set_fast(randint(75) + 75, 10); - } - else - { - (void)set_fast(p_ptr->fast + 5, 10); - } - - o_ptr->timeout = rand_int(150) + 150; - - break; - } - - case ACT_NARYA: - { - if (!doit) return "healing (500) every 200+d100 turns"; - msg_print("The ring glows deep red..."); - hp_player(500); - set_blind(0); - set_confused(0); - set_poisoned(0); - set_stun(0); - set_cut(0); - - o_ptr->timeout = rand_int(100) + 200; - - break; - } - - case ACT_NENYA: - { - if (!doit) return "healing (800) every 100+d200 turns"; - msg_print("The ring glows bright white..."); - hp_player(800); - set_blind(0); - set_confused(0); - set_poisoned(0); - set_stun(0); - set_cut(0); - - o_ptr->timeout = rand_int(200) + 100; - - break; - } - - case ACT_VILYA: - { - if (!doit) return "greater healing (900) every 200+d200 turns"; - msg_print("The ring glows deep blue..."); - hp_player(900); - set_blind(0); - set_confused(0); - set_poisoned(0); - set_stun(0); - set_cut(0); - if (p_ptr->black_breath) - { - p_ptr->black_breath = FALSE; - msg_print("The hold of the Black Breath on you is broken!"); - } - - o_ptr->timeout = rand_int(200) + 200; - - break; - } - - case ACT_POWER: - { - if (!doit) return "powerful things"; - msg_print("The ring glows intensely black..."); - - o_ptr->timeout = ring_of_power(); - - break; - } - - - /* The Stone of Lore is perilous, for the sake of game balance. */ - case ACT_STONE_LORE: - { - if (!doit) return "perilous identify every turn"; - msg_print("The stone reveals hidden mysteries..."); - if (!ident_spell()) break; - - if (has_ability(AB_PERFECT_CASTING)) - { - /* Sufficient mana */ - if (20 <= p_ptr->csp) - { - /* Use some mana */ - p_ptr->csp -= 20; - } - - /* Over-exert the player */ - else - { - int oops = 20 - p_ptr->csp; - - /* No mana left */ - p_ptr->csp = 0; - p_ptr->csp_frac = 0; - - /* Message */ - msg_print("You are too weak to control the stone!"); - - /* Hack -- Bypass free action */ - (void)set_paralyzed(p_ptr->paralyzed + - randint(5 * oops + 1)); - - /* Confusing. */ - (void)set_confused(p_ptr->confused + - randint(5 * oops + 1)); - } - - /* Redraw mana */ - p_ptr->redraw |= (PR_MANA); - } - - take_hit(damroll(1, 12), "perilous secrets"); - - /* Confusing. */ - if (rand_int(5) == 0) - { - (void)set_confused(p_ptr->confused + randint(10)); - } - - /* Exercise a little care... */ - if (rand_int(20) == 0) - { - take_hit(damroll(4, 10), "perilous secrets"); - } - - o_ptr->timeout = 1; - - break; - } - - case ACT_RAZORBACK: - { - if (!doit) return "star ball (150) every 1000 turns"; - msg_print("Your armor is surrounded by lightning..."); - for (i = 0; i < 8; i++) fire_ball(GF_ELEC, ddd[i], 150, 3); - - o_ptr->timeout = 1000; - - break; - } - - case ACT_BLADETURNER: - { - if (!doit) return "invulnerability (4+d8) every 800 turns"; - set_invuln(p_ptr->invuln + randint(8) + 4); - - o_ptr->timeout = 800; - - break; - } - - case ACT_MEDIATOR: - { - if (!doit) return "breathe elements (300), berserk rage, bless, and resistance every 400 turns"; - if (!get_aim_dir(&dir)) break; - msg_print("You breathe the elements."); - fire_ball(GF_MISSILE, dir, 300, 4); - msg_print("Your armor glows many colours..."); - (void)set_afraid(0); - (void)set_shero(p_ptr->shero + randint(50) + 50); - (void)hp_player(30); - (void)set_blessed(p_ptr->blessed + randint(50) + 50); - (void)set_oppose_acid(p_ptr->oppose_acid + randint(50) + 50); - (void)set_oppose_elec(p_ptr->oppose_elec + randint(50) + 50); - (void)set_oppose_fire(p_ptr->oppose_fire + randint(50) + 50); - (void)set_oppose_cold(p_ptr->oppose_cold + randint(50) + 50); - (void)set_oppose_pois(p_ptr->oppose_pois + randint(50) + 50); - - o_ptr->timeout = 400; - - break; - } - - case ACT_BELEGENNON: - { - if (!doit) return ("heal (777), curing and heroism every 300 turns"); - msg_print("A heavenly choir sings..."); - (void)set_poisoned(0); - (void)set_cut(0); - (void)set_stun(0); - (void)set_confused(0); - (void)set_blind(0); - (void)set_hero(p_ptr->hero + randint(25) + 25); - (void)hp_player(777); - - o_ptr->timeout = 300; - - break; - } - - case ACT_GORLIM: - { - if (!doit) return "rays of fear in every direction"; - turn_monsters(40 + p_ptr->lev); - - o_ptr->timeout = 3 * (p_ptr->lev + 10); - - break; - } - - case ACT_COLLUIN: - { - if (!doit) return "resistance (20+d20 turns) every 111 turns"; - msg_print("Your cloak glows many colours..."); - (void)set_oppose_acid(p_ptr->oppose_acid + randint(20) + 20); - (void)set_oppose_elec(p_ptr->oppose_elec + randint(20) + 20); - (void)set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20); - (void)set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20); - (void)set_oppose_pois(p_ptr->oppose_pois + randint(20) + 20); - - o_ptr->timeout = 111; - - break; - } - - - case ACT_BELANGIL: - { - if (!doit) return "frost ball (48) every 5+d5 turns"; - msg_print("Your dagger is covered in frost..."); - if (!get_aim_dir(&dir)) break; - fire_ball(GF_COLD, dir, 48, 2); - - o_ptr->timeout = rand_int(5) + 5; - - break; - } - - case ACT_ANGUIREL: - { - if (!doit) return "a getaway every 35 turns"; - switch (randint(13)) - { - case 1: - case 2: - case 3: - case 4: - case 5: - { - teleport_player(10); - - break; - } - - case 6: - case 7: - case 8: - case 9: - case 10: - { - teleport_player(222); - - break; - } - - case 11: - case 12: - { - (void)stair_creation(); - - break; - } - - default: - { - if (get_check("Leave this level? ")) - { - autosave_checkpoint(); - - /* Leaving */ - p_ptr->leaving = TRUE; - } - - break; - } - } - - o_ptr->timeout = 35; - - break; - } - - case ACT_ERU: - { - if (!doit) return "healing(7000), curing every 500 turns"; - msg_print("Your sword glows an intense white..."); - hp_player(7000); - heal_insanity(50); - set_blind(0); - set_poisoned(0); - set_confused(0); - set_stun(0); - set_cut(0); - set_image(0); - - o_ptr->timeout = 500; - - break; - } - - case ACT_DAWN: - { - if (!doit) return "summon the Legion of the Dawn every 500+d500 turns"; - msg_print("You summon the Legion of the Dawn."); - (void)summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DAWN, TRUE); - - o_ptr->timeout = 500 + randint(500); - - break; - } - - case ACT_FIRESTAR: - { - if (!doit) return "large fire ball (72) every 100 turns"; - msg_print("Your morning star rages in fire..."); - if (!get_aim_dir(&dir)) break; - fire_ball(GF_FIRE, dir, 72, 3); - - o_ptr->timeout = 100; - - break; - } - - case ACT_TURMIL: - { - if (!doit) return "drain life (90) every 70 turns"; - msg_print("Your hammer glows white..."); - if (!get_aim_dir(&dir)) break; - drain_life(dir, 90); - - o_ptr->timeout = 70; - - break; - } - - case ACT_CUBRAGOL: - { - if (!doit) return "fire branding of bolts every 999 turns"; - msg_print("Your crossbow glows deep red..."); - (void)brand_bolts(); - - o_ptr->timeout = 999; - - break; - } - - case ACT_ELESSAR: - { - if (!doit) return "heal and cure black breath every 200 turns"; - if (p_ptr->black_breath) - { - msg_print("The hold of the Black Breath on you is broken!"); - } - p_ptr->black_breath = FALSE; - hp_player(100); - - o_ptr->timeout = 200; - - break; - } - - case ACT_GANDALF: - { - if (!doit) return "restore mana every 666 turns"; - msg_print("Your mage staff glows deep blue..."); - if (p_ptr->csp < p_ptr->msp) - { - p_ptr->csp = p_ptr->msp; - p_ptr->csp_frac = 0; - msg_print("Your feel your head clear."); - p_ptr->redraw |= (PR_MANA); - p_ptr->window |= (PW_PLAYER); - } - - o_ptr->timeout = 666; - - break; - } - - case ACT_MARDA: - { - if (!doit) return "summon a thunderlord every 1000 turns"; - if (randint(3) == 1) - { - if (summon_specific(p_ptr->py, p_ptr->px, ((plev * 3) / 2), SUMMON_THUNDERLORD)) - { - msg_print("A Thunderlord comes from thin air!"); - msg_print("'I will burn you!'"); - } - } - else - { - if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2), - SUMMON_THUNDERLORD, (bool_)(plev == 50 ? TRUE : FALSE))) - { - msg_print("A Thunderlord comes from thin air!"); - msg_print("'I will help you in your difficult task.'"); - } - } - - o_ptr->timeout = 1000; - - break; - } - - case ACT_PALANTIR: - { - if (!doit) return "clairvoyance every 100+d100 turns"; - msg_print("The stone glows a deep green..."); - wiz_lite_extra(); - (void)detect_traps(DEFAULT_RADIUS); - (void)detect_doors(DEFAULT_RADIUS); - (void)detect_stairs(DEFAULT_RADIUS); - - o_ptr->timeout = rand_int(100) + 100; - - break; - } - - case ACT_EREBOR: - { - if (!doit) return "open a secret passage every 75 turns"; - msg_print("Your pick twists in your hands."); - - if (!get_aim_dir(&dir)) break; - if (passwall(dir, TRUE)) - { - msg_print("A passage opens, and you step through."); - } - else - { - msg_print("There is no wall there!"); - } - - o_ptr->timeout = 75; - - break; - } - - case ACT_DRUEDAIN: - { - if (!doit) return "detection every 99 turns"; - msg_print("Your drum shows you the world."); - detect_all(DEFAULT_RADIUS); - - o_ptr->timeout = 99; - - break; - } - - case ACT_ROHAN: - { - if (!doit) return "heroism, berserker, and haste every 250 turns"; - msg_print("Your horn glows deep red."); - set_afraid(0); - set_shero(p_ptr->shero + damroll(5, 10) + 30); - set_afraid(0); - set_hero(p_ptr->hero + damroll(5, 10) + 30); - set_fast(p_ptr->fast + damroll(5, 10) + 30, 10); - hp_player(30); - - o_ptr->timeout = 250; - - break; - } - - case ACT_HELM: - { - if (!doit) return "sound ball (300) every 300 turns"; - msg_print("Your horn emits a loud sound."); - if (!get_aim_dir(&dir)) break; - fire_ball(GF_SOUND, dir, 300, 6); - - o_ptr->timeout = 300; - - break; - } - - case ACT_BOROMIR: - { - if (!doit) return "mass human summoning every 1000 turns"; - msg_print("Your horn calls for help."); - for (i = 0; i < 15; i++) - { - summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2), SUMMON_HUMAN, TRUE); - } - - o_ptr->timeout = 1000; - - break; - } - - case ACT_HURIN: - { - if (!doit) return "berserker and +10 to speed (50) every 100+d200 turns"; - if (!p_ptr->fast) - { - (void)set_fast(randint(50) + 50, 10); - } - else - { - (void)set_fast(p_ptr->fast + 5, 10); - } - hp_player(30); - set_afraid(0); - set_shero(p_ptr->shero + randint(50) + 50); - - o_ptr->timeout = rand_int(200) + 100; - - break; - } - - case ACT_AXE_GOTHMOG: - { - if (!doit) return "fire ball (300) every 200+d200 turns"; - msg_print("Your lochaber axe erupts in fire..."); - if (!get_aim_dir(&dir)) break; - fire_ball(GF_FIRE, dir, 300, 4); - - o_ptr->timeout = 200 + rand_int(200); - - break; - } - - case ACT_MELKOR: - { - if (!doit) return "darkness ball (150) every 100 turns"; - msg_print("Your spear is covered of darkness..."); - if (!get_aim_dir(&dir)) break; - fire_ball(GF_DARK, dir, 150, 3); - - o_ptr->timeout = 100; - - break; - } - - case ACT_GROND: - { - if (!doit) return "alter reality every 100 turns"; - msg_print("Your hammer hits the floor..."); - alter_reality(); - - o_ptr->timeout = 100; - - break; - } - - case ACT_NATUREBANE: - { - if (!doit) return "dispel monsters (300) every 200+d200 turns"; - msg_print("Your axe glows blood red..."); - dispel_monsters(300); - - o_ptr->timeout = 200 + randint(200); - - break; - } - - case ACT_NIGHT: - { - if (!doit) return "vampiric drain (3*100) every 250 turns"; - msg_print("Your axe emits a black aura..."); - if (!get_aim_dir(&dir)) break; - for (i = 0; i < 3; i++) - { - if (drain_life(dir, 100)) hp_player(100); - } - - o_ptr->timeout = 250; - - break; - } - - case ACT_ORCHAST: - { - if (!doit) return "detect orcs every 10 turns"; - msg_print("Your weapon glows brightly..."); - (void)detect_monsters_xxx(RF3_ORC, DEFAULT_RADIUS); - - o_ptr->timeout = 10; - - break; - } - case ACT_SUNLIGHT: - { - if (!doit) return "beam of sunlight every 10 turns"; - - if (!get_aim_dir(&dir)) break; - msg_print("A line of sunlight appears."); - lite_line(dir); - - o_ptr->timeout = 10; - - break; - } - - case ACT_BO_MISS_1: - { - if (!doit) return "magic missile (2d6) every 2 turns"; - msg_print("It glows extremely brightly..."); - if (!get_aim_dir(&dir)) break; - fire_bolt(GF_MISSILE, dir, damroll(2, 6)); - - o_ptr->timeout = 2; - - break; - } - - case ACT_BA_POIS_1: - { - if (!doit) return "stinking cloud (12), rad. 3, every 4+d4 turns"; - msg_print("It throbs deep green..."); - if (!get_aim_dir(&dir)) break; - fire_ball(GF_POIS, dir, 12, 3); - - o_ptr->timeout = rand_int(4) + 4; - - break; - } - - case ACT_BO_ELEC_1: - { - if (!doit) return "lightning bolt (4d8) every 6+d6 turns"; - msg_print("It is covered in sparks..."); - if (!get_aim_dir(&dir)) break; - fire_bolt(GF_ELEC, dir, damroll(4, 8)); - - o_ptr->timeout = rand_int(6) + 6; - - break; - } - - case ACT_BO_ACID_1: - { - if (!doit) return "acid bolt (5d8) every 5+d5 turns"; - msg_print("It is covered in acid..."); - if (!get_aim_dir(&dir)) break; - fire_bolt(GF_ACID, dir, damroll(5, 8)); - - o_ptr->timeout = rand_int(5) + 5; - - break; - } - - case ACT_BO_COLD_1: - { - if (!doit) return "frost bolt (6d8) every 7+d7 turns"; - msg_print("It is covered in frost..."); - if (!get_aim_dir(&dir)) break; - fire_bolt(GF_COLD, dir, damroll(6, 8)); - - o_ptr->timeout = rand_int(7) + 7; - - break; - } - - case ACT_BO_FIRE_1: - { - if (!doit) return "fire bolt (9d8) every 8+d8 turns"; - msg_print("It is covered in fire..."); - if (!get_aim_dir(&dir)) break; - fire_bolt(GF_FIRE, dir, damroll(9, 8)); - - o_ptr->timeout = rand_int(8) + 8; - - break; - } - - case ACT_BA_COLD_1: - { - if (!doit) return "ball of cold (48) every 400 turns"; - msg_print("It is covered in frost..."); - if (!get_aim_dir(&dir)) break; - fire_ball(GF_COLD, dir, 48, 2); - - o_ptr->timeout = 400; - - break; - } - - case ACT_BA_FIRE_1: - { - if (!doit) return "ball of fire (72) every 400 turns"; - msg_print("It glows an intense red..."); - if (!get_aim_dir(&dir)) break; - fire_ball(GF_FIRE, dir, 72, 2); - - o_ptr->timeout = 400; - - break; - } - - case ACT_DRAIN_1: - { - if (!doit) return "drain life (100) every 100+d100 turns"; - msg_print("It glows black..."); - if (!get_aim_dir(&dir)) break; - if (drain_life(dir, 100)) - - o_ptr->timeout = rand_int(100) + 100; - - break; - } - - case ACT_BA_COLD_2: - { - if (!doit) return "ball of cold (100) every 300 turns"; - msg_print("It glows an intense blue..."); - if (!get_aim_dir(&dir)) break; - fire_ball(GF_COLD, dir, 100, 2); - - o_ptr->timeout = 300; - - break; - } - - case ACT_BA_ELEC_2: - { - if (!doit) return "ball of lightning (100) every 500 turns"; - msg_print("It crackles with electricity..."); - if (!get_aim_dir(&dir)) break; - fire_ball(GF_ELEC, dir, 100, 3); - - o_ptr->timeout = 500; - - break; - } - - case ACT_DRAIN_2: - { - if (!doit) return "drain life (120) every 400 turns"; - msg_print("It glows black..."); - if (!get_aim_dir(&dir)) break; - drain_life(dir, 120); - - o_ptr->timeout = 400; - - break; - } - - case ACT_VAMPIRE_1: - { - if (!doit) return "vampiric drain (3*50) every 400 turns"; - if (!get_aim_dir(&dir)) break; - for (dummy = 0; dummy < 3; dummy++) - { - if (drain_life(dir, 50)) - hp_player(50); - } - - o_ptr->timeout = 400; - - break; - } - - case ACT_BO_MISS_2: - { - if (!doit) return "arrows (150) every 90+d90 turns"; - msg_print("It grows magical spikes..."); - if (!get_aim_dir(&dir)) break; - fire_bolt(GF_ARROW, dir, 150); - - o_ptr->timeout = rand_int(90) + 90; - - break; - } - - case ACT_BA_FIRE_2: - { - if (!doit) return "fire ball (120) every 225+d225 turns"; - msg_print("It glows deep red..."); - if (!get_aim_dir(&dir)) break; - fire_ball(GF_FIRE, dir, 120, 3); - - o_ptr->timeout = rand_int(225) + 225; - - break; - } - - case ACT_BA_COLD_3: - { - if (!doit) return "ball of cold (200) every 325+d325 turns"; - msg_print("It glows bright white..."); - if (!get_aim_dir(&dir)) break; - fire_ball(GF_COLD, dir, 200, 3); - - o_ptr->timeout = rand_int(325) + 325; - - break; - } - - case ACT_BA_ELEC_3: - { - if (!doit) return "Lightning Ball (250) every 425+d425 turns"; - msg_print("It glows deep blue..."); - if (!get_aim_dir(&dir)) break; - fire_ball(GF_ELEC, dir, 250, 3); - - o_ptr->timeout = rand_int(425) + 425; - - break; - } - - case ACT_WHIRLWIND: - { - int y = 0, x = 0; - cave_type *c_ptr; - monster_type *m_ptr; - if (!doit) return "whirlwind attack every 250 turns"; - - for (dir = 0; dir <= 9; dir++) - { - y = p_ptr->py + ddy[dir]; - x = p_ptr->px + ddx[dir]; - c_ptr = &cave[y][x]; - - /* Get the monster */ - m_ptr = &m_list[c_ptr->m_idx]; - - /* Hack -- attack monsters */ - if (c_ptr->m_idx && (m_ptr->ml || cave_floor_bold(y, x))) - { - py_attack(y, x, -1); - } - } - - o_ptr->timeout = 250; - - break; - } - - case ACT_VAMPIRE_2: - { - if (!doit) return "vampiric drain (3*100) every 400 turns"; - if (!get_aim_dir(&dir)) break; - for (dummy = 0; dummy < 3; dummy++) - { - if (drain_life(dir, 100)) - hp_player(100); - } - - o_ptr->timeout = 400; - - break; - } - - - case ACT_CALL_CHAOS: - { - if (!doit) return "call chaos every 350 turns"; - msg_print("It glows in scintillating colours..."); - call_chaos(); - - o_ptr->timeout = 350; - - break; - } - - case ACT_ROCKET: - { - if (!doit) return "launch rocket (120+level) every 400 turns"; - if (!get_aim_dir(&dir)) break; - msg_print("You launch a rocket!"); - fire_ball(GF_ROCKET, dir, 120 + (plev), 2); - - o_ptr->timeout = 400; - - break; - } - - case ACT_DISP_EVIL: - { - if (!doit) return "dispel evil (level*5) every 300+d300 turns"; - msg_print("It floods the area with goodness..."); - dispel_evil(p_ptr->lev * 5); - - o_ptr->timeout = rand_int(300) + 300; - - break; - } - - case ACT_DISP_GOOD: - { - if (!doit) return "dispel good (level*5) every 300+d300 turns"; - msg_print("It floods the area with evil..."); - dispel_good(p_ptr->lev * 5); - - o_ptr->timeout = rand_int(300) + 300; - - break; - } - - case ACT_BA_MISS_3: - { - if (!doit) return "elemental breath (300) every 500 turns"; - if (!get_aim_dir(&dir)) break; - msg_print("You breathe the elements."); - fire_ball(GF_MISSILE, dir, 300, 4); - - o_ptr->timeout = 500; - - break; - } - - /* Activate for other offensive action */ - - case ACT_CONFUSE: - { - if (!doit) return "confuse monster every 15 turns"; - msg_print("It glows in scintillating colours..."); - if (!get_aim_dir(&dir)) break; - confuse_monster(dir, 20); - - o_ptr->timeout = 15; - - break; - } - - case ACT_SLEEP: - { - if (!doit) return "sleep nearby monsters every 55 turns"; - msg_print("It glows deep blue..."); - sleep_monsters_touch(); - - o_ptr->timeout = 55; - - break; - } - - case ACT_QUAKE: - { - if (!doit) return "earthquake (rad 10) every 50 turns"; - /* Prevent destruction of quest levels and town */ - if (!is_quest(dun_level) && dun_level) - { - earthquake(p_ptr->py, p_ptr->px, 10); - o_ptr->timeout = 50; - } - - break; - } - - case ACT_TERROR: - { - if (!doit) return "terror every 3 * (level+10) turns"; - turn_monsters(40 + p_ptr->lev); - - o_ptr->timeout = 3 * (p_ptr->lev + 10); - - break; - } - - case ACT_TELE_AWAY: - { - if (!doit) return "teleport away every 200 turns"; - if (!get_aim_dir(&dir)) break; - (void)fire_beam(GF_AWAY_ALL, dir, plev); - - o_ptr->timeout = 200; - - break; - } - - case ACT_BANISH_EVIL: - { - if (!doit) return "banish evil every 250+d250 turns"; - if (banish_evil(100)) - { - msg_print("The power of the artifact banishes evil!"); - } - - o_ptr->timeout = 250 + randint(250); - - break; - } - - case ACT_GENOCIDE: - { - if (!doit) return "genocide every 500 turns"; - msg_print("It glows deep blue..."); - (void)genocide(TRUE); - - o_ptr->timeout = 500; - - break; - } - - case ACT_MASS_GENO: - { - if (!doit) return "mass genocide every 1000 turns"; - msg_print("It lets out a long, shrill note..."); - (void)mass_genocide(TRUE); - - o_ptr->timeout = 1000; - - break; - } - - /* Activate for summoning / charming */ - - case ACT_CHARM_ANIMAL: - { - if (!doit) return "charm animal every 300 turns"; - if (!get_aim_dir(&dir)) break; - (void) charm_animal(dir, plev); - - o_ptr->timeout = 300; - - break; - } - - case ACT_CHARM_UNDEAD: - { - if (!doit) return "enslave undead every 333 turns"; - if (!get_aim_dir(&dir)) break; - (void)control_one_undead(dir, plev); - - o_ptr->timeout = 333; - - break; - } - - case ACT_CHARM_OTHER: - { - if (!doit) return "charm monster every 400 turns"; - if (!get_aim_dir(&dir)) break; - (void) charm_monster(dir, plev); - - o_ptr->timeout = 400; - - break; - } - - case ACT_CHARM_ANIMALS: - { - if (!doit) return "animal friendship every 500 turns"; - (void) charm_animals(plev * 2); - - o_ptr->timeout = 500; - - break; - } - - case ACT_CHARM_OTHERS: - { - if (!doit) return "mass charm every 750 turns"; - charm_monsters(plev * 2); - - o_ptr->timeout = 750; - - break; - } - - case ACT_SUMMON_ANIMAL: - { - if (!doit) return "summon animal every 200+d300 turns"; - (void)summon_specific_friendly(p_ptr->py, p_ptr->px, plev, SUMMON_ANIMAL_RANGER, TRUE); - - o_ptr->timeout = 200 + randint(300); - - break; - } - - case ACT_SUMMON_PHANTOM: - { - if (!doit) return "summon phantasmal servant every 200+d200 turns"; - msg_print("You summon a phantasmal servant."); - (void)summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_PHANTOM, TRUE); - - o_ptr->timeout = 200 + randint(200); - - break; - } - - case ACT_SUMMON_ELEMENTAL: - { - if (!doit) return "summon elemental every 750 turns"; - if (randint(3) == 1) - { - if (summon_specific(p_ptr->py, p_ptr->px, ((plev * 3) / 2), SUMMON_ELEMENTAL)) - { - msg_print("An elemental materialises..."); - msg_print("You fail to control it!"); - } - } - else - { - if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2), - SUMMON_ELEMENTAL, (bool_)(plev == 50 ? TRUE : FALSE))) - { - msg_print("An elemental materialises..."); - msg_print("It seems obedient to you."); - } - } - - o_ptr->timeout = 750; - - break; - } - - case ACT_SUMMON_DEMON: - { - if (!doit) return "summon demon every 666+d333 turns"; - if (randint(3) == 1) - { - if (summon_specific(p_ptr->py, p_ptr->px, ((plev * 3) / 2), SUMMON_DEMON)) - { - msg_print("The area fills with a stench of sulphur and brimstone."); - msg_print("'NON SERVIAM! Wretch! I shall feast on thy mortal soul!'"); - } - } - else - { - if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2), - SUMMON_DEMON, (bool_)(plev == 50 ? TRUE : FALSE))) - { - msg_print("The area fills with a stench of sulphur and brimstone."); - msg_print("'What is thy bidding... Master?'"); - } - } - - o_ptr->timeout = 666 + randint(333); - - break; - } - - case ACT_SUMMON_UNDEAD: - { - if (!doit) return "summon undead every 666+d333 turns"; - if (randint(3) == 1) - { - if (summon_specific(p_ptr->py, p_ptr->px, ((plev * 3) / 2), - (plev > 47 ? SUMMON_HI_UNDEAD : SUMMON_UNDEAD))) - { - msg_print("Cold winds begin to blow around you, carrying with them the stench of decay..."); - msg_print("'The dead arise... to punish you for disturbing them!'"); - } - } - else - { - if (summon_specific_friendly(p_ptr->py, p_ptr->px, ((plev * 3) / 2), - (plev > 47 ? SUMMON_HI_UNDEAD_NO_UNIQUES : SUMMON_UNDEAD), - (bool_)(((plev > 24) && (randint(3) == 1)) ? TRUE : FALSE))) - { - msg_print("Cold winds begin to blow around you, carrying with them the stench of decay..."); - msg_print("Ancient, long-dead forms arise from the ground to serve you!"); - } - } - - o_ptr->timeout = 666 + randint(333); - - break; - } - - /* Activate for healing */ - - case ACT_CURE_LW: - { - if (!doit) return format("cure light wounds every %d turns", (is_junkart ? 50 : 10)); - (void)set_afraid(0); - (void)hp_player(30); - - o_ptr->timeout = 10; - - break; - } - - case ACT_CURE_MW: - { - if (!doit) return format("cure serious wounds every %s turns", (is_junkart? "75" : "3+d3")); - msg_print("It radiates deep purple..."); - hp_player(damroll(4, 8)); - (void)set_cut((p_ptr->cut / 2) - 50); - - o_ptr->timeout = rand_int(3) + 3; - - break; - } - - case ACT_CURE_POISON: - { - if (!doit) return "remove fear and cure poison every 5 turns"; - msg_print("It glows deep blue..."); - (void)set_afraid(0); - (void)set_poisoned(0); - - o_ptr->timeout = 5; - - break; - } - - case ACT_REST_LIFE: - { - if (!doit) return "restore life levels every 450 turns"; - msg_print("It glows a deep red..."); - restore_level(); - - o_ptr->timeout = 450; - - break; - } - - case ACT_REST_ALL: - { - if (!doit) return format("restore stats and life levels every %d turns", (is_junkart ? 200 : 750)); - msg_print("It glows a deep green..."); - (void)do_res_stat(A_STR, TRUE); - (void)do_res_stat(A_INT, TRUE); - (void)do_res_stat(A_WIS, TRUE); - (void)do_res_stat(A_DEX, TRUE); - (void)do_res_stat(A_CON, TRUE); - (void)do_res_stat(A_CHR, TRUE); - (void)restore_level(); - - o_ptr->timeout = 750; - - break; - } - - case ACT_CURE_700: - { - if (!doit) return format("heal 700 hit points every %d turns", (is_junkart ? 100 : 250)); - msg_print("It glows deep blue..."); - msg_print("You feel a warm tingling inside..."); - (void)hp_player(700); - (void)set_cut(0); - - o_ptr->timeout = 250; - - break; - } - - case ACT_CURE_1000: - { - if (!doit) return "heal 1000 hit points every 888 turns"; - msg_print("It glows a bright white..."); - msg_print("You feel much better..."); - (void)hp_player(1000); - (void)set_cut(0); - - o_ptr->timeout = 888; - - break; - } - - case ACT_ESP: - { - if (!doit) return "temporary ESP (dur 25+d30) every 200 turns"; - (void)set_tim_esp(p_ptr->tim_esp + randint(30) + 25); - - o_ptr->timeout = 200; - - break; - } - - case ACT_BERSERK: - { - if (!doit) return "heroism and berserk (dur 50+d50) every 100+d100 turns"; - (void)set_shero(p_ptr->shero + randint(50) + 50); - (void)set_blessed(p_ptr->blessed + randint(50) + 50); - - o_ptr->timeout = 100 + randint(100); - - break; - } - - case ACT_PROT_EVIL: - { - if (!doit) return "protection from evil (dur level*3 + d25) every 225+d225 turns"; - msg_print("It lets out a shrill wail..."); - k = 3 * p_ptr->lev; - (void)set_protevil(p_ptr->protevil + randint(25) + k); - - o_ptr->timeout = rand_int(225) + 225; - - break; - } - - case ACT_RESIST_ALL: - { - if (!doit) return "resist elements (dur 40+d40) every 200 turns"; - msg_print("It glows many colours..."); - (void)set_oppose_acid(p_ptr->oppose_acid + randint(40) + 40); - (void)set_oppose_elec(p_ptr->oppose_elec + randint(40) + 40); - (void)set_oppose_fire(p_ptr->oppose_fire + randint(40) + 40); - (void)set_oppose_cold(p_ptr->oppose_cold + randint(40) + 40); - (void)set_oppose_pois(p_ptr->oppose_pois + randint(40) + 40); - - o_ptr->timeout = 200; - - break; - } - - case ACT_SPEED: - { - if (!doit) return "speed (dur 20+d20) every 250 turns"; - msg_print("It glows bright green..."); - if (!p_ptr->fast) - { - (void)set_fast(randint(20) + 20, 10); - } - else - { - (void)set_fast(p_ptr->fast + 5, 10); - } - - o_ptr->timeout = 250; - - break; - } - - case ACT_XTRA_SPEED: - { - if (!doit) return "speed (dur 75+d75) every 200+d200 turns"; - msg_print("It glows brightly..."); - if (!p_ptr->fast) - { - (void)set_fast(randint(75) + 75, 10); - } - else - { - (void)set_fast(p_ptr->fast + 5, 10); - } - - o_ptr->timeout = rand_int(200) + 200; - - break; - } - - case ACT_WRAITH: - { - if (!doit) return "wraith form (level/2 + d(level/2)) every 1000 turns"; - set_shadow(p_ptr->tim_wraith + randint(plev / 2) + (plev / 2)); - - o_ptr->timeout = 1000; - - break; - } - - case ACT_INVULN: - { - if (!doit) return "invulnerability (dur 8+d8) every 1000 turns"; - (void)set_invuln(p_ptr->invuln + randint(8) + 8); - - o_ptr->timeout = 1000; - - break; - } - - /* Activate for general purpose effect (detection etc.) */ - - case ACT_LIGHT: - { - if (!doit) return format("light area (dam 2d15) every %s turns", (is_junkart ? "100" : "10+d10")); - msg_print("It wells with clear light..."); - lite_area(damroll(2, 15), 3); - - o_ptr->timeout = rand_int(10) + 10; - - break; - } - - case ACT_MAP_LIGHT: - { - if (!doit) return "light (dam 2d15) & map area every 50+d50 turns"; - msg_print("It shines brightly..."); - map_area(); - lite_area(damroll(2, 15), 3); - - o_ptr->timeout = rand_int(50) + 50; - - break; - } - - case ACT_DETECT_ALL: - { - if (!doit) return "detection every 55+d55 turns"; - msg_print("It glows bright white..."); - msg_print("An image forms in your mind..."); - detect_all(DEFAULT_RADIUS); - - o_ptr->timeout = rand_int(55) + 55; - - break; - } - - case ACT_DETECT_XTRA: - { - if (!doit) return "detection, probing and identify true every 1000 turns"; - msg_print("It glows brightly..."); - detect_all(DEFAULT_RADIUS); - probing(); - identify_fully(); - - o_ptr->timeout = 1000; - - break; - } - - case ACT_ID_FULL: - { - if (!doit) return "identify true every 750 turns"; - msg_print("It glows yellow..."); - identify_fully(); - - o_ptr->timeout = 750; - - break; - } - - case ACT_ID_PLAIN: - { - if (!doit) return "identify spell every 10 turns"; - if (!ident_spell()) break; - - o_ptr->timeout = 10; - - break; - } - - case ACT_RUNE_EXPLO: - { - if (!doit) return "explosive rune every 200 turns"; - msg_print("It glows bright red..."); - explosive_rune(); - - o_ptr->timeout = 200; - - break; - } - - case ACT_RUNE_PROT: - { - if (!doit) return "rune of protection every 400 turns"; - msg_print("It glows light blue..."); - warding_glyph(); - - o_ptr->timeout = 400; - - break; - } - - case ACT_SATIATE: - { - if (!doit) return "satisfy hunger every 200 turns"; - (void)set_food(PY_FOOD_MAX - 1); - - o_ptr->timeout = 200; - - break; - } - - case ACT_DEST_DOOR: - { - if (!doit) return "destroy doors and traps every 10 turns"; - msg_print("It glows bright red..."); - destroy_doors_touch(); - - o_ptr->timeout = 10; - - break; - } - - case ACT_STONE_MUD: - { - if (!doit) return "stone to mud every 5 turns"; - msg_print("It pulsates..."); - if (!get_aim_dir(&dir)) break; - wall_to_mud(dir); - - o_ptr->timeout = 5; - - break; - } - - case ACT_RECHARGE: - { - if (!doit) return "recharging every 70 turns"; - recharge(60); - - o_ptr->timeout = 70; - - break; - } - - case ACT_ALCHEMY: - { - if (!doit) return "alchemy every 500 turns"; - msg_print("It glows bright yellow..."); - (void) alchemy(); - - o_ptr->timeout = 500; - - break; - } - - case ACT_DIM_DOOR: - { - if (!doit) return "dimension door every 100 turns"; - if (dungeon_flags2 & DF2_NO_TELEPORT) - { - msg_print("Not on special levels!"); - break; - } - - msg_print("You open a Void Jumpgate. Choose a destination."); - if (!tgt_pt(&ii, &ij)) break; - - p_ptr->energy -= 60 - plev; - - if (!cave_empty_bold(ij, ii) || (cave[ij][ii].info & CAVE_ICKY) || - (distance(ij, ii, p_ptr->py, p_ptr->px) > plev + 2) || - (!rand_int(plev * plev / 2))) - { - msg_print("You fail to exit the void correctly!"); - p_ptr->energy -= 100; - get_pos_player(10, &ij, &ii); - } - - cave_set_feat(p_ptr->py, p_ptr->px, FEAT_BETWEEN); - cave_set_feat(ij, ii, FEAT_BETWEEN); - cave[p_ptr->py][p_ptr->px].special = ii + (ij << 8); - cave[ij][ii].special = p_ptr->px + (p_ptr->py << 8); - - o_ptr->timeout = 100; - - break; - } - - case ACT_TELEPORT: - { - if (!doit) return format("teleport (range 100) every %d turns", (is_junkart? 100 : 45)); - msg_print("It twists space around you..."); - teleport_player(100); - - o_ptr->timeout = 45; - - break; - } - - case ACT_RECALL: - { - if (!(dungeon_flags2 & DF2_ASK_LEAVE) || ((dungeon_flags2 & DF2_ASK_LEAVE) && !get_check("Leave this unique level forever? "))) - { - if (!doit) return "word of recall every 200 turns"; - msg_print("It glows soft white..."); - recall_player(20,15); - - o_ptr->timeout = 200; - } - - break; - } - - case ACT_DEATH: - { - if (!doit) return "death"; - take_hit(5000, "activating a death spell"); - - /* Timeout is set before return */ - - break; - } - - case ACT_RUINATION: - { - if (!doit) return "Ruination"; - msg_print("Your nerves and muscles feel weak and lifeless!"); - - take_hit(damroll(10, 10), "activating Ruination"); - (void)dec_stat(A_DEX, 25, TRUE); - (void)dec_stat(A_WIS, 25, TRUE); - (void)dec_stat(A_CON, 25, TRUE); - (void)dec_stat(A_STR, 25, TRUE); - (void)dec_stat(A_CHR, 25, TRUE); - (void)dec_stat(A_INT, 25, TRUE); - - /* Timeout is set before return */ - - break; - } - - case ACT_DESTRUC: - { - if (!doit) return "Destruction every 100 turns"; - earthquake(p_ptr->py, p_ptr->px, 12); - - /* Timeout is set before return */ - - break; - } - - case ACT_UNINT: - { - if (!doit) return "decreasing Intelligence"; - (void)dec_stat(A_INT, 25, FALSE); - - /* Timeout is set before return */ - - break; - } - - case ACT_UNSTR: - { - if (!doit) return "decreasing Strength"; - (void)dec_stat(A_STR, 25, FALSE); - - /* Timeout is set before return */ - - break; - } - - case ACT_UNCON: - { - if (!doit) return "decreasing Constitution"; - (void)dec_stat(A_CON, 25, FALSE); - - /* Timeout is set before return */ - - break; - } - - case ACT_UNCHR: - { - if (!doit) return "decreasing Charisma"; - (void)dec_stat(A_CHR, 25, FALSE); - - /* Timeout is set before return */ - - break; - } - - case ACT_UNDEX: - { - if (!doit) return "decreasing Dexterity"; - (void)dec_stat(A_DEX, 25, FALSE); - - /* Timeout is set before return */ - - break; - } - - case ACT_UNWIS: - { - if (!doit) return "decreasing Wisdom"; - (void)dec_stat(A_WIS, 25, FALSE); - - /* Timeout is set before return */ - - break; - } - - case ACT_STATLOSS: - { - if (!doit) return "stat loss"; - (void)dec_stat(A_STR, 15, FALSE); - (void)dec_stat(A_INT, 15, FALSE); - (void)dec_stat(A_WIS, 15, FALSE); - (void)dec_stat(A_DEX, 15, FALSE); - (void)dec_stat(A_CON, 15, FALSE); - (void)dec_stat(A_CHR, 15, FALSE); - - /* Timeout is set before return */ - - break; - } - - case ACT_HISTATLOSS: - { - if (!doit) return "high stat loss"; - (void)dec_stat(A_STR, 25, FALSE); - (void)dec_stat(A_INT, 25, FALSE); - (void)dec_stat(A_WIS, 25, FALSE); - (void)dec_stat(A_DEX, 25, FALSE); - (void)dec_stat(A_CON, 25, FALSE); - (void)dec_stat(A_CHR, 25, FALSE); - - /* Timeout is set before return */ - - break; - } - - case ACT_EXPLOSS: - { - if (!doit) return "experience loss"; - lose_exp(p_ptr->exp / 20); - - /* Timeout is set before return */ - - break; - } - - case ACT_HIEXPLOSS: - { - if (!doit) return "high experience loss"; - lose_exp(p_ptr->exp / 10); - - /* Timeout is set before return */ - - break; - } - - case ACT_SUMMON_MONST: - { - if (!doit) return "summon monster"; - summon_specific(p_ptr->py, p_ptr->px, max_dlv[dungeon_type], 0); - - /* Timeout is set before return */ - - break; - } - - case ACT_PARALYZE: - { - if (!doit) return "paralyze"; - set_paralyzed(p_ptr->paralyzed + 20 + randint(10)); - - /* Timeout is set before return */ - - break; - } - - case ACT_HALLU: - { - if (!doit) return "hallucination every 10 turns"; - set_image(p_ptr->image + 20 + randint(10)); - - /* Timeout is set before return */ - - break; - } - - case ACT_POISON: - { - if (!doit) return "poison"; - set_poisoned(p_ptr->poisoned + 20 + randint(10)); - - /* Timeout is set before return */ - - break; - } - - case ACT_HUNGER: - { - if (!doit) return "create hunger"; - (void)set_food(PY_FOOD_WEAK); - - /* Timeout is set before return */ - - break; - } - - case ACT_STUN: - { - if (!doit) return "stun"; - set_stun(p_ptr->stun + 20 + randint(10)); - - /* Timeout is set before return */ - - break; - } - - case ACT_CUTS: - { - if (!doit) return "cuts"; - set_cut(p_ptr->cut + 20 + randint(10)); - - /* Timeout is set before return */ - - break; - } - - case ACT_PARANO: - { - if (!doit) return "confusion"; - set_confused(p_ptr->confused + 30 + randint(10)); - - /* Timeout is set before return */ - - break; - } - - case ACT_CONFUSION: - { - if (!doit) return "confusion"; - set_confused(p_ptr->confused + 20 + randint(10)); - - /* Timeout is set before return */ - - break; - } - - case ACT_BLIND: - { - if (!doit) return "blindness"; - set_blind(p_ptr->blind + 20 + randint(10)); - - /* Timeout is set before return */ - - break; - } - - case ACT_PET_SUMMON: - { - if (!doit) return "summon pet every 101 turns"; - summon_specific_friendly(p_ptr->py, p_ptr->px, max_dlv[dungeon_type], 0, FALSE); - - /* Timeout is set before return */ - /*FINDME*/ - - break; - } - - case ACT_CURE_PARA: - { - if (!doit) return "cure confusion every 500 turns"; - set_confused(0); - - /* Timeout is set before return */ - - break; - } - - case ACT_CURE_HALLU: - { - if (!doit) return "cure hallucination every 100 turns"; - set_image(0); - - /* Timeout is set before return */ - - break; - } - - case ACT_CURE_POIS: - { - if (!doit) return "cure poison every 100 turns"; - set_poisoned(0); - - /* Timeout is set before return */ - - break; - } - - case ACT_CURE_HUNGER: - { - if (!doit) return "satisfy hunger every 100 turns"; - (void)set_food(PY_FOOD_MAX - 1); - - /* Timeout is set before return */ - - break; - } - - case ACT_CURE_STUN: - { - if (!doit) return "cure stun every 100 turns"; - set_stun(0); - - /* Timeout is set before return */ - - break; - } - - case ACT_CURE_CUTS: - { - if (!doit) return "cure cuts every 100 turns"; - set_cut(0); - - /* Timeout is set before return */ - - break; - } - - case ACT_CURE_FEAR: - { - if (!doit) return "cure fear every 100 turns"; - set_afraid(0); - - /* Timeout is set before return */ - - break; - } - - case ACT_CURE_CONF: - { - if (!doit) return "cure confusion every 100 turns"; - set_confused(0); - - /* Timeout is set before return */ - - break; - } - - case ACT_CURE_BLIND: - { - if (!doit) return "cure blindness every 100 turns"; - set_blind(0); - - /* Timeout is set before return */ - - break; - } - - case ACT_CURING: - { - if (!doit) return "curing every 110 turns"; - set_blind(0); - set_poisoned(0); - set_confused(0); - set_stun(0); - set_cut(0); - set_image(0); - - /* Timeout is set before return */ - - break; - } - - case ACT_DARKNESS: - { - if (!doit) return "darkness"; - unlite_area(damroll(2, 10), 10); - - /* Timeout is set before return */ - - break; - } - - case ACT_LEV_TELE: - { - if (!doit) return "teleport level every 50 turns"; - teleport_player_level(); - - /* Timeout is set before return */ - - break; - } - - case ACT_ACQUIREMENT: - { - if (!doit) return "acquirement every 3000 turns"; - acquirement(p_ptr->py, p_ptr->px, 1, FALSE, FALSE); - - /* Timeout is set before return */ - - break; - } - - case ACT_WEIRD: - { - if (!doit) return "something weird every 5 turns"; - /* It doesn't do anything */ - - /* Timeout is set before return */ - - break; - } - - case ACT_AGGRAVATE: - { - if (!doit) return "aggravate"; - aggravate_monsters(1); - - /* Timeout is set before return */ - - break; - } - - case ACT_MUT: - { - if (!doit) return "gain corruption every 10 turns"; - gain_random_corruption(0); - /* Timeout is set before return */ - - break; - } - - case ACT_CURE_INSANITY: - { - if (!doit) return "cure insanity every 200 turns"; - heal_insanity(damroll(10, 10)); - - /* Timeout is set before return */ - - break; - } - - case ACT_CURE_MUT: - { - msg_print("Ahah, you wish."); - /* Timeout is set before return */ - - break; - } - - case ACT_LIGHT_ABSORBTION: - { - int y, x, light = 0, dir; - cave_type *c_ptr; - - if (!doit) return "light absorption every 80 turns"; - - for (y = p_ptr->py - 6; y <= p_ptr->py + 6; y++) - { - for (x = p_ptr->px - 6; x <= p_ptr->px + 6; x++) - { - if (!in_bounds(y, x)) continue; - - c_ptr = &cave[y][x]; - - if (distance(y, x, p_ptr->py, p_ptr->px) > 6) continue; - - if (c_ptr->info & CAVE_GLOW) - { - light++; - - /* No longer in the array */ - c_ptr->info &= ~(CAVE_TEMP); - - /* Darken the grid */ - c_ptr->info &= ~(CAVE_GLOW); - - /* Hack -- Forget "boring" grids */ - if (cave_plain_floor_grid(c_ptr) && - !(c_ptr->info & (CAVE_TRDT))) - { - /* Forget the grid */ - c_ptr->info &= ~(CAVE_MARK); - - /* Notice */ - note_spot(y, x); - } - - /* Process affected monsters */ - if (c_ptr->m_idx) - { - /* Update the monster */ - update_mon(c_ptr->m_idx, FALSE); - } - - /* Redraw */ - lite_spot(y, x); - } - } - } - - if (!get_aim_dir(&dir)) return (FALSE); - - msg_print("The light around you is absorbed... " - "and released in a powerful bolt!"); - fire_bolt(GF_LITE, dir, damroll(light, p_ptr->lev)); - - /* Timeout is set before return */ - - break; - } - /* Horns of DragonKind (Note that these are new egos)*/ - case ACT_BA_FIRE_H: - { - if (!doit) return "large fire ball (300) every 100 turns"; - fire_ball(GF_FIRE, 5, 300, 7); - - o_ptr->timeout = 100; - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP); - - break; - } - case ACT_BA_COLD_H: - { - if (!doit) return "large cold ball (300) every 100 turns"; - fire_ball(GF_COLD, 5, 300, 7); - - o_ptr->timeout = 100; - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP); - - break; - } - case ACT_BA_ELEC_H: - { - if (!doit) return "large lightning ball (300) every 100 turns"; - fire_ball(GF_ELEC, 5, 300, 7); - - o_ptr->timeout = 100; - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP); - - break; - } - case ACT_BA_ACID_H: - { - if (!doit) return "large acid ball (300) every 100 turns"; - fire_ball(GF_ACID, 5, 300, 7); - - o_ptr->timeout = 100; - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP); - - break; - } - - case ACT_SPIN: - { - if (!doit) return "spinning around every 50+d25 turns"; - do_spin(); - - o_ptr->timeout = 50 + randint(25); - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP); - - /* Done */ - break; - } - case ACT_NOLDOR: - { - if (!doit) return "detect treasure every 10+d20 turns"; - detect_treasure(DEFAULT_RADIUS); - - o_ptr->timeout = 10 + randint(20); - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP); - - /* Done */ - break; - } - case ACT_SPECTRAL: - { - if (!doit) return "wraith-form every 50+d50 turns"; - if (!p_ptr->wraith_form) - { - set_shadow(20 + randint(20)); - } - else - { - set_shadow(p_ptr->tim_wraith + randint(20)); - } - - o_ptr->timeout = 50 + randint(50); - - /* Window stuff */ - p_ptr->window |= PW_INVEN | PW_EQUIP; - - /* Done */ - break; - } - case ACT_JUMP: - { - if (!doit) return "phasing every 10+d10 turns"; - teleport_player(10); - o_ptr->timeout = 10 + randint(10); - - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP); - - /* Done */ - break; - } - - case ACT_DEST_TELE: - { - if (!doit) return "teleportation and destruction of the ring"; - if (!item) - { - msg_print("You can't activate this when it's there!"); - } - if (get_check("This will destroy the ring. Do you wish to continue? ")) - { - msg_print("The ring explodes into a space distortion."); - teleport_player(200); - - /* It explodes, doesn't it ? */ - take_hit(damroll(2, 10), "an exploding ring"); - - inc_stack_size_ex(item, -255, OPTIMIZE, NO_DESCRIBE); - } - - break; - } - /*amulet of serpents dam 100, rad 2 timeout 40+d60 */ - case ACT_BA_POIS_4: - { - if (!doit) return "venom breathing every 40+d60 turns"; - /* Get a direction for breathing (or abort) */ - if (!get_aim_dir(&dir)) break; - - msg_print("You breathe venom..."); - fire_ball(GF_POIS, dir, 100, 2); - - o_ptr->timeout = rand_int(60) + 40; - - /* Window stuff */ - p_ptr->window |= PW_INVEN | PW_EQUIP; - - /* Done */ - break; - } - /*rings of X 50,50+d50 dur 20+d20 */ - case ACT_BA_COLD_4: - { - if (!doit) return "ball of cold and resist cold every 50+d50 turns"; - /* Get a direction for breathing (or abort) */ - if (!get_aim_dir(&dir)) break; - - fire_ball(GF_COLD, dir, 50, 2); - (void)set_oppose_cold(p_ptr->oppose_cold + randint(20) + 20); - - o_ptr->timeout = rand_int(50) + 50; - - break; - } - - case ACT_BA_FIRE_4: - { - if (!doit) return "ball of fire and resist fire every 50+d50 turns"; - /* Get a direction for breathing (or abort) */ - if (!get_aim_dir(&dir)) break; - - fire_ball(GF_FIRE, dir, 50, 2); - (void)set_oppose_fire(p_ptr->oppose_fire + randint(20) + 20); - - o_ptr->timeout = rand_int(50) + 50; - - break; - } - case ACT_BA_ACID_4: - { - if (!doit) return "ball of acid and resist acid every 50+d50 turns"; - /* Get a direction for breathing (or abort) */ - if (!get_aim_dir(&dir)) break; - - fire_ball(GF_ACID, dir, 50, 2); - (void)set_oppose_acid(p_ptr->oppose_acid + randint(20) + 20); - - o_ptr->timeout = rand_int(50) + 50; - - break; - } - - case ACT_BA_ELEC_4: - { - if (!doit) return "ball of lightning and resist lightning every 50+d50 turns"; - /* Get a direction for breathing (or abort) */ - if (!get_aim_dir(&dir)) break; - - fire_ball(GF_ELEC, dir, 50, 2); - (void)set_oppose_elec(p_ptr->oppose_elec + randint(20) + 20); - - o_ptr->timeout = rand_int(50) + 50; - - break; - } - - case ACT_BR_ELEC: - { - if (!doit) return "breathe lightning (100) every 90+d90 turns"; - if (!get_aim_dir(&dir)) break; - msg_print("You breathe lightning."); - fire_ball(GF_ELEC, dir, 100, 2); - - o_ptr->timeout = rand_int(90) + 90; - - break; - } - - case ACT_BR_COLD: - { - if (!doit) return "breathe frost (110) every 90+d90 turns"; - if (!get_aim_dir(&dir)) break; - msg_print("You breathe frost."); - fire_ball(GF_COLD, dir, 110, 2); - - o_ptr->timeout = rand_int(90) + 90; - - break; - } - - case ACT_BR_FIRE: - { - if (!doit) return "breathe fire (200) every 90+d90 turns"; - if (!get_aim_dir(&dir)) break; - msg_print("You breathe fire."); - fire_ball(GF_FIRE, dir, 200, 2); - - o_ptr->timeout = rand_int(90) + 90; - - break; - } - - case ACT_BR_ACID: - { - if (!doit) return "breathe acid (130) every 90+d90 turns"; - if (!get_aim_dir(&dir)) break; - msg_print("You breathe acid."); - fire_ball(GF_ACID, dir, 130, 2); - - o_ptr->timeout = rand_int(90) + 90; - - break; - } - - case ACT_BR_POIS: - { - if (!doit) return "breathe poison gas (150) every 90+d90 turns"; - if (!get_aim_dir(&dir)) break; - msg_print("You breathe poison gas."); - fire_ball(GF_POIS, dir, 150, 2); - - o_ptr->timeout = rand_int(90) + 90; - - break; - } - - case ACT_BR_MANY: - { - if (!doit) return "breathe multi-hued (250) every 60+d60 turns"; - if (!get_aim_dir(&dir)) break; - chance = rand_int(5); - msg_format("You breathe %s.", - ((chance == 1) ? "lightning" : - ((chance == 2) ? "frost" : - ((chance == 3) ? "acid" : - ((chance == 4) ? "poison gas" : "fire"))))); - fire_ball(((chance == 1) ? GF_ELEC : - ((chance == 2) ? GF_COLD : - ((chance == 3) ? GF_ACID : - ((chance == 4) ? GF_POIS : GF_FIRE)))), - dir, 250, 2); - - o_ptr->timeout = rand_int(60) + 60; - - break; - } - - case ACT_BR_CONF: - { - if (!doit) return "breathe confusion (120) every 90+d90 turns"; - if (!get_aim_dir(&dir)) break; - msg_print("You breathe confusion."); - fire_ball(GF_CONFUSION, dir, 120, 2); - - o_ptr->timeout = rand_int(90) + 90; - - break; - } - - case ACT_BR_SOUND: - { - if (!doit) return "breathe sound (130) every 90+d90 turns"; - if (!get_aim_dir(&dir)) break; - msg_print("You breathe sound."); - fire_ball(GF_SOUND, dir, 130, 2); - - o_ptr->timeout = rand_int(90) + 90; - - break; - } - - case ACT_BR_CHAOS: - { - if (!doit) return "breathe chaos/disenchant (220) every 60+d90 turns"; - if (!get_aim_dir(&dir)) break; - chance = rand_int(2); - msg_format("You breathe %s.", - ((chance == 1 ? "chaos" : "disenchantment"))); - fire_ball((chance == 1 ? GF_CHAOS : GF_DISENCHANT), - dir, 220, 2); - - o_ptr->timeout = rand_int(90) + 60; - - break; - } - - case ACT_BR_SHARD: - { - if (!doit) return "breathe sound/shards (230) every 60+d90 turns"; - if (!get_aim_dir(&dir)) break; - chance = rand_int(2); - msg_format("You breathe %s.", - ((chance == 1 ? "sound" : "shards"))); - fire_ball((chance == 1 ? GF_SOUND : GF_SHARDS), - dir, 230, 2); - - o_ptr->timeout = rand_int(90) + 60; - - break; - } - - case ACT_BR_BALANCE: - { - if (!doit) return "breathe balance (250) every 60+d90 turns"; - if (!get_aim_dir(&dir)) break; - chance = rand_int(4); - msg_format("You breathe %s.", - ((chance == 1) ? "chaos" : - ((chance == 2) ? "disenchantment" : - ((chance == 3) ? "sound" : "shards")))); - fire_ball(((chance == 1) ? GF_CHAOS : - ((chance == 2) ? GF_DISENCHANT : - ((chance == 3) ? GF_SOUND : GF_SHARDS))), - dir, 250, 2); - - o_ptr->timeout = rand_int(90) + 60; - - break; - } - - case ACT_BR_LIGHT: - { - if (!doit) return "breathe light/darkness (200) every 60+d90 turns"; - if (!get_aim_dir(&dir)) break; - chance = rand_int(2); - msg_format("You breathe %s.", - ((chance == 0 ? "light" : "darkness"))); - fire_ball((chance == 0 ? GF_LITE : GF_DARK), dir, 200, 2); - - o_ptr->timeout = rand_int(90) + 60; - - break; - } - case ACT_BR_POWER: - { - if (!doit) return "breathe the elements (300) every 60+d90 turns"; - if (!get_aim_dir(&dir)) break; - msg_print("You breathe the elements."); - fire_ball(GF_MISSILE, dir, 300, 3); - - o_ptr->timeout = rand_int(90) + 60; - - break; - } - case ACT_GROW_MOLD: - { - if (!doit) return "grow mushrooms every 50+d50 turns"; - msg_print("You twirl and spores fly everywhere!"); - for (i = 0; i < 8; i++) - summon_specific_friendly(p_ptr->py, p_ptr->px, p_ptr->lev, SUMMON_BIZARRE1, FALSE); - - o_ptr->timeout = randint(50) + 50; - - break; - } - case ACT_MUSIC: - /* - fall through to unknown, as music should be - handled by calling procedure. - */ - - default: - { - msg_format("Unknown activation effect: %d.", spell); - if ( !doit ) return "Unknown Activation"; - return NULL; - } - } - } - - /* Set timeout for junkarts - * Note that I still need to set the timeouts for other - * (non-random) artifacts above - */ - if (is_junkart && doit) - o_ptr->timeout = activation_info[o_ptr->pval2].cost / 10; - - return NULL; -} - - -static bool_ activate_spell(object_type * o_ptr, byte choice) -{ - int mana = 0, gf = 0, mod = 0; - - rune_spell s_ptr; - - - if (choice == 1) - { - gf = o_ptr->pval & 0xFFFF; - mod = o_ptr->pval3 & 0xFFFF; - mana = o_ptr->pval2 & 0xFF; - } - else if (choice == 2) - { - gf = o_ptr->pval >> 16; - mod = o_ptr->pval3 >> 16; - mana = o_ptr->pval2 >> 8; - } - - s_ptr.type = gf; - s_ptr.rune2 = 1 << mod; - s_ptr.mana = mana; - - /* Execute */ - rune_exec(&s_ptr, 0); - - if (choice == 1) o_ptr->timeout = mana * 5; - if (choice == 2) o_ptr->xtra2 = mana * 5; - - return (TRUE); -} |