diff options
Diffstat (limited to 'crawl-ref/source/mon-util.cc')
-rw-r--r-- | crawl-ref/source/mon-util.cc | 55 |
1 files changed, 51 insertions, 4 deletions
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index bb5e894e17..3b3415b31f 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -700,7 +700,7 @@ int mons_resist_magic( const monsters *mon ) // negative values get multiplied with mhd if (u < 0) - u = mon->hit_dice * -u; + u = mon->hit_dice * -u * 4 / 3; u += scan_mon_inv_randarts( mon, RAP_MAGIC ); @@ -796,11 +796,17 @@ bool mons_res_asphyx( const monsters *mon ) || mons_resist(mon, MR_RES_ASPHYX)); } +int mons_res_acid( const monsters *mon ) +{ + const unsigned long f = get_mons_resists(mon); + return ((f & MR_RES_ACID) != 0); +} + int mons_res_poison( const monsters *mon ) { int mc = mon->type; - int u = 0, f = get_mons_resists(mon); + unsigned long u = 0, f = get_mons_resists(mon); if (f & MR_RES_POISON) u++; @@ -2415,7 +2421,8 @@ monsters::monsters(const monsters &mon) monsters &monsters::operator = (const monsters &mon) { - init_with(mon); + if (this != &mon) + init_with(mon); return (*this); } @@ -2471,6 +2478,11 @@ bool monsters::floundering() const && !mons_flies(this)); } +bool monsters::can_drown() const +{ + return (!mons_res_asphyx(this)); +} + size_type monsters::body_size(int /* psize */, bool /* base */) const { const monsterentry *e = seekmonster(type); @@ -3275,6 +3287,7 @@ void monsters::timeout_enchantments(int levels) case ENCH_STICKY_FLAME: case ENCH_ABJ: case ENCH_SHORT_LIVED: case ENCH_SLOW: case ENCH_HASTE: case ENCH_FEAR: case ENCH_INVIS: case ENCH_CHARM: case ENCH_SLEEP_WARY: + case ENCH_SICK: case ENCH_SLEEPY: lose_ench_levels(*cur, levels); break; @@ -3289,6 +3302,9 @@ void monsters::timeout_enchantments(int levels) default: break; } + + if (!alive()) + break; } } @@ -3340,6 +3356,14 @@ void monsters::apply_enchantment(mon_enchant me, int spd) } break; + case ENCH_SICK: + { + const int lost = !spd? 1 : div_rand_round(10, spd); + if (lost > 0) + lose_ench_levels(me, lost); + break; + } + case ENCH_SUBMERGED: { // not even air elementals unsubmerge into clouds @@ -3561,6 +3585,10 @@ void monsters::apply_enchantment(mon_enchant me, int spd) del_ench(ENCH_SLEEP_WARY); break; + case ENCH_SLEEPY: + del_ench(ENCH_SLEEPY); + break; + default: break; } @@ -3585,6 +3613,21 @@ kill_category monsters::kill_alignment() const return (attitude == ATT_FRIENDLY? KC_FRIENDLY : KC_OTHER); } +void monsters::sicken(int amount) +{ + if (holiness() != MH_NATURAL || (amount /= 2) < 1) + return; + + if (!has_ench(ENCH_SICK) + && mons_near(this) && player_monster_visible(this)) + { + // Yes, could be confused with poisoning. + mprf("%s looks sick.", name(DESC_CAP_THE).c_str()); + } + + add_ench(mon_enchant(ENCH_SICK, amount)); +} + ///////////////////////////////////////////////////////////////////////// // mon_enchant @@ -3593,7 +3636,7 @@ static const char *enchant_names[] = "none", "slow", "haste", "fear", "conf", "inv", "pois", "bers", "rot", "summon", "abj", "backlit", "charm", "fire", "gloshifter", "shifter", "tp", "wary", "submerged", - "short lived", "paralysis", "bug" + "short lived", "paralysis", "sick", "sleep", "bug" }; const char *mons_enchantment_name(enchant_type ench) @@ -3628,6 +3671,10 @@ void mon_enchant::merge_killer(kill_category k) void mon_enchant::cap_degree() { + // Sickness is not capped. + if (ench == ENCH_SICK) + return; + // Hard cap to simulate old enum behaviour, we should really throw this // out entirely. const int max = ench == ENCH_ABJ? 6 : 4; |