diff options
Diffstat (limited to 'crawl-ref/source/monstuff.cc')
-rw-r--r-- | crawl-ref/source/monstuff.cc | 114 |
1 files changed, 19 insertions, 95 deletions
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 30d9c10001..4f233d86fc 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -4301,7 +4301,6 @@ static bool _handle_special_ability(monsters *monster, bolt & beem) //--------------------------------------------------------------- static bool _handle_potion(monsters *monster, bolt & beem) { - // Yes, there is a logic to this ordering {dlb}: if (mons_is_sleeping(monster) || monster->inv[MSLOT_POTION] == NON_ITEM || !one_chance_in(3)) @@ -4309,108 +4308,33 @@ static bool _handle_potion(monsters *monster, bolt & beem) return (false); } - bool imbibed = false; - item_type_id_state_type ident = ID_UNKNOWN_TYPE; - bool was_visible = (mons_near(monster) && player_monster_visible(monster)); + bool rc = false; - const int potion_type = mitm[monster->inv[MSLOT_POTION]].sub_type; - switch (potion_type) - { - case POT_HEALING: - case POT_HEAL_WOUNDS: - if (monster->hit_points <= monster->max_hit_points / 2 - && mons_holiness(monster) != MH_UNDEAD - && mons_holiness(monster) != MH_NONLIVING - && mons_holiness(monster) != MH_PLANT) - { - simple_monster_message(monster, " drinks a potion."); + const int potion_idx = monster->inv[MSLOT_POTION]; + item_def& potion = mitm[potion_idx]; + const potion_type ptype = static_cast<potion_type>(potion.sub_type); - if (heal_monster(monster, 5 + random2(7), false)) - { - simple_monster_message(monster, " is healed!"); - ident = ID_MON_TRIED_TYPE; - } - - if (mitm[monster->inv[MSLOT_POTION]].sub_type == POT_HEAL_WOUNDS) - { - heal_monster(monster, 10 + random2avg(28, 3), false); - } - - if (potion_type == POT_HEALING) - { - monster->del_ench(ENCH_POISON); - monster->del_ench(ENCH_SICK); - if (monster->del_ench(ENCH_CONFUSION)) - ident = ID_KNOWN_TYPE; - if (monster->del_ench(ENCH_ROT)) - ident = ID_KNOWN_TYPE; - } - - imbibed = true; - } - break; - - case POT_BLOOD: - case POT_BLOOD_COAGULATED: - if (mons_species(monster->type) == MONS_VAMPIRE - && monster->hit_points <= monster->max_hit_points / 2) - { - simple_monster_message(monster, " drinks a potion."); - - if (heal_monster(monster, 10 + random2avg(28, 3), false)) - { - simple_monster_message(monster, " is healed!"); - ident = ID_MON_TRIED_TYPE; - } - - imbibed = true; - } - break; - - case POT_SPEED: - // Notice that these are the same odd colours used in - // mons_ench_f2() {dlb} - if (monster->has_ench(ENCH_HASTE)) - break; - - beem.flavour = BEAM_HASTE; - // intentional fall through - case POT_INVISIBILITY: - if (mitm[monster->inv[MSLOT_POTION]].sub_type == POT_INVISIBILITY) - { - if (monster->has_ench(ENCH_INVIS)) - break; - - beem.flavour = BEAM_INVISIBILITY; - // Friendly monsters won't go invisible if the player can't - // see invisible. We're being nice. - if (mons_friendly(monster) && !player_see_invis(false)) - break; - } + if (monster->can_drink_potion(ptype) && monster->should_drink_potion(ptype)) + { + const bool was_visible = you.can_see(monster); - // Allow monsters to drink these when player in sight. (jpeg) - simple_monster_message(monster, " drinks a potion."); - mons_ench_f2(monster, beem); - imbibed = true; - if (beem.obvious_effect) - ident = ID_KNOWN_TYPE; - break; - } + // Drink the potion. + const item_type_id_state_type id = monster->drink_potion_effect(ptype); - if (imbibed) - { - if (dec_mitm_item_quantity( monster->inv[MSLOT_POTION], 1 )) + // Give ID if necessary. + if (was_visible && id != ID_UNKNOWN_TYPE) + set_ident_type(OBJ_POTIONS, ptype, id); + + // Remove it from inventory. + if (dec_mitm_item_quantity(potion_idx, 1)) monster->inv[MSLOT_POTION] = NON_ITEM; - else if (is_blood_potion(mitm[monster->inv[MSLOT_POTION]])) - remove_oldest_blood_potion(mitm[monster->inv[MSLOT_POTION]]); - - if (ident != ID_UNKNOWN_TYPE && was_visible) - set_ident_type(OBJ_POTIONS, potion_type, ident); + else if (is_blood_potion(potion)) + remove_oldest_blood_potion(potion); monster->lose_energy(EUT_ITEM); + rc = true; } - - return (imbibed); + return rc; } static bool _handle_reaching(monsters *monster) |