summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/mon-util.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/mon-util.cc')
-rw-r--r--crawl-ref/source/mon-util.cc55
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;