also applied !oH healing, make monsters drink !oH when helpful, disallow potions for some monsters (currently only liches and mummies, more can be added.) Fixes 2035734, 2048006.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@6944 c06c8d41-db1a-0410-9941-cceddc491573
Q6WLX2VTRJ3LGDPWBH5WKQM7CIIJ5H6AEIKMXPF2PJA5JX5ZLUZQC ZO2PZE57FZOUNGR2MEA3ZRRC7DEC7R3NMXLHZMGWROSIYKH2FAWAC JLAGD2FAV3CWVO7PLXTHLT7MBI23TUSYLSNHFAWP5IB5UO77VKJAC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC 542UIZKI65UDRNEMGFFDBWYD5XC7AYLTZ3JZQRR2GHYJALD3YY6QC L254F6ZIU2HWGLFFGPIORTN4C3TDQ3E5JZ7Z7GQA5AEDIKL6PKDAC 3RNRFLMD2X4RUFTDVITLXAP377YB6F6YMQLL3DAXSUZDZBTWSLRQC 3GSAVTNKEG45AT2U734R5STSRP22WJZL3H6KUFRUWCIA6A4CZE5QC KBNY5FWKTEAKABFCLPC3QFKFSVZKAGXINPCIFV6WDSWFO4VCKNTAC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC BW2JVFBXXFVN5PWDH2KZY5NP4AVH7W755SH5SMRQSAR7F2WFZWNAC OSGS3PH2L5CBTDVZCZS6OCFQNA4A7RMEXBYJQB7DDZBYYJW7QSSAC TVC7W7C2XKBQSD2IJFMWFVGXZAOD4EUOW43NAQTOF5KFMAUOJABQC GPEJOT73KMACP33IPAKFR5ROGHCOIP22VXZMQNYTGLEA2OSZUM2AC JD3FMKAAAUQZSNPGFLVX7F5H5SWGUSYOFZU4X5W4XYNV6HUKDBKAC RBAGQ2PB7V5YAM5KSHSZR2E3MLKDSRVM5XYGI2TIXP5QMVBOQHDQC X5WLJCJVW55SXZVP7IKP7ADCJIGNKN4PKAXFECVR6TNK7XSMZR7QC 4ORX7M2SWZX3WEZWQ7JSFKKT64PTVWEJD4BP5A5UW67HB3PIXRGQC BSAKBTGIAD3JFZPNLMEI6SOJ2XPT4EJNETZYBW2555ASJTZ2GEGQC 22MF6OUN62WDBJR5QFNJTKU7Q5TIQ76XWCEIRBFWAZDMZUSKJGCAC SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC M2HMYLYYXSP5XGX6MCI77IT6UW5K4YSEUJWHPQPYXVSW5L36BJ2AC 5XSXMOBGXFLTIQE6WDXWWFVDOTUPZSIQ2FWT3YI5QMVU6D76IUYQC Y2NYY7HWFZ2LQDK3ACSLGS37F2J2IJ5LRGCIMZYXLEOSVPD3A4DAC bool imbibed = false;item_type_id_state_type ident = ID_UNKNOWN_TYPE;bool was_visible = (mons_near(monster) && player_monster_visible(monster));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.");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;
bool rc = false;
beem.flavour = BEAM_HASTE;// intentional fall throughcase POT_INVISIBILITY:if (mitm[monster->inv[MSLOT_POTION]].sub_type == POT_INVISIBILITY){if (monster->has_ench(ENCH_INVIS))break;
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);
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);
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);
}bool monsters::can_drink_potion(potion_type ptype) const{bool rc = true;switch (mons_species()){case MONS_LICH:case MONS_MUMMY:rc = false;break;default:break;}switch (ptype){case POT_HEALING:case POT_HEAL_WOUNDS:if (holiness() == MH_UNDEAD|| holiness() == MH_NONLIVING|| holiness() == MH_PLANT){rc = false;}break;case POT_BLOOD:case POT_BLOOD_COAGULATED:rc = (mons_species() == MONS_VAMPIRE);break;default:break;}return rc;
bool monsters::should_drink_potion(potion_type ptype) const{bool rc = false;switch (ptype){case POT_HEALING:rc = (hit_points <= max_hit_points / 2)|| has_ench(ENCH_POISON)|| has_ench(ENCH_SICK)|| has_ench(ENCH_CONFUSION)|| has_ench(ENCH_ROT);break;case POT_HEAL_WOUNDS:rc = (hit_points <= max_hit_points / 2);break;case POT_BLOOD:case POT_BLOOD_COAGULATED:rc = (hit_points <= max_hit_points / 2);break;case POT_SPEED:rc = !has_ench(ENCH_HASTE);break;case POT_INVISIBILITY:// We're being nice: friendlies won't go invisible// if the player won't be able to see them.rc = !has_ench(ENCH_INVIS)&& (player_see_invis(false) || !mons_friendly(this));break;default:break;}return rc;}// Return the ID status gained.item_type_id_state_type monsters::drink_potion_effect(potion_type ptype){simple_monster_message(this, " drinks a potion.");item_type_id_state_type ident = ID_MON_TRIED_TYPE;switch (ptype){case POT_HEALING:{heal(5 + random2(7));simple_monster_message(this, " is healed!");const enchant_type cured_enchants[] = {ENCH_POISON, ENCH_SICK, ENCH_CONFUSION, ENCH_ROT};// We can differentiate healing and heal wounds (and blood,// for vampires) by seeing if any status ailments are cured.for (unsigned int i = 0; i < ARRAYSZ(cured_enchants); ++i)if (del_ench(cured_enchants[i]))ident = ID_KNOWN_TYPE;}break;case POT_HEAL_WOUNDS:heal(10 + random2avg(28, 3));simple_monster_message(this, " is healed!");break;case POT_BLOOD:case POT_BLOOD_COAGULATED:if (mons_species() == MONS_VAMPIRE){heal(10 + random2avg(28, 3));simple_monster_message(this, " is healed!");}break;case POT_SPEED:{// XXX FIXME Extract haste() function from mons_ench_f2().bolt beem;beem.target = pos();beem.flavour = BEAM_HASTE;mons_ench_f2(this, beem);if (beem.obvious_effect)ident = ID_KNOWN_TYPE;break;}case POT_INVISIBILITY:{// XXX FIXME Extract go_invis() function from mons_ench_f2().bolt beem;beem.target = pos();beem.flavour = BEAM_INVISIBILITY;mons_ench_f2(this, beem);if (beem.obvious_effect)ident = ID_KNOWN_TYPE;break;}default:break;}return ident;}
enum potion_type{POT_HEALING, // 0POT_HEAL_WOUNDS,POT_SPEED,POT_MIGHT,POT_GAIN_STRENGTH,POT_GAIN_DEXTERITY, // 5POT_GAIN_INTELLIGENCE,POT_LEVITATION,POT_POISON,POT_SLOWING,POT_PARALYSIS, // 10POT_CONFUSION,POT_INVISIBILITY,POT_PORRIDGE,POT_DEGENERATION,POT_DECAY, // 15POT_WATER,POT_EXPERIENCE,POT_MAGIC,POT_RESTORE_ABILITIES,POT_STRONG_POISON, // 20POT_BERSERK_RAGE,POT_CURE_MUTATION,POT_MUTATION,POT_RESISTANCE,POT_BLOOD, // 25POT_BLOOD_COAGULATED,NUM_POTIONS // 27};
};enum potion_type{POT_HEALING, // 0POT_HEAL_WOUNDS,POT_SPEED,POT_MIGHT,POT_GAIN_STRENGTH,POT_GAIN_DEXTERITY, // 5POT_GAIN_INTELLIGENCE,POT_LEVITATION,POT_POISON,POT_SLOWING,POT_PARALYSIS, // 10POT_CONFUSION,POT_INVISIBILITY,POT_PORRIDGE,POT_DEGENERATION,POT_DECAY, // 15POT_WATER,POT_EXPERIENCE,POT_MAGIC,POT_RESTORE_ABILITIES,POT_STRONG_POISON, // 20POT_BERSERK_RAGE,POT_CURE_MUTATION,POT_MUTATION,POT_RESISTANCE,POT_BLOOD, // 25POT_BLOOD_COAGULATED,NUM_POTIONS // 27