summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/externs.h6
-rw-r--r--crawl-ref/source/fight.cc34
-rw-r--r--crawl-ref/source/fight.h2
-rw-r--r--crawl-ref/source/mon-util.cc8
-rw-r--r--crawl-ref/source/ouch.cc15
-rw-r--r--crawl-ref/source/ouch.h2
-rw-r--r--crawl-ref/source/player.cc4
7 files changed, 32 insertions, 39 deletions
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index 85c1920513..52d570fec8 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -335,7 +335,7 @@ public:
virtual bool can_safely_mutate() const = 0;
virtual bool can_bleed() const = 0;
virtual bool mutate() = 0;
- virtual void drain_exp(actor *agent) = 0;
+ virtual bool drain_exp(actor *agent) = 0;
virtual void rot(actor *agent, int amount, int immediate = 0) = 0;
virtual int hurt(const actor *attacker, int amount,
beam_type flavour = BEAM_MISSILE,
@@ -1075,7 +1075,7 @@ public:
void slow_down(actor *, int str);
void confuse(actor *, int strength);
void heal(int amount, bool max_too = false);
- void drain_exp(actor *);
+ bool drain_exp(actor *);
void rot(actor *, int amount, int immediate = 0);
int hurt(const actor *attacker, int amount,
beam_type flavour = BEAM_MISSILE,
@@ -1507,7 +1507,7 @@ public:
void petrify(actor *, int str);
void slow_down(actor *, int str);
void confuse(actor *, int strength);
- void drain_exp(actor *);
+ bool drain_exp(actor *);
void rot(actor *, int amount, int immediate = 0);
int hurt(const actor *attacker, int amount,
beam_type flavour = BEAM_MISSILE,
diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc
index 289bf5e9f0..5847e8fd4e 100644
--- a/crawl-ref/source/fight.cc
+++ b/crawl-ref/source/fight.cc
@@ -2050,34 +2050,20 @@ int melee_attack::fire_res_apply_cerebov_downgrade(int res)
void melee_attack::drain_defender()
{
- // What to do, they're different...
- if (defender->atype() == ACT_PLAYER)
- {
- drain_player();
- obvious_effect = true;
- }
- else
- drain_monster();
-}
-
-void melee_attack::drain_player()
-{
- defender->drain_exp(attacker);
-
- special_damage = random2(damage_done) /
- (2 + defender->res_negative_energy()) + 1;
-}
-
-void melee_attack::drain_monster()
-{
- if (defender->res_negative_energy() > 0 || one_chance_in(3))
+ if (defender->atype() == ACT_MONSTER && one_chance_in(3))
return;
- defender->drain_exp(attacker);
+ const int rn = defender->res_negative_energy();
- special_damage = 1 + (random2(damage_done) / 2);
+ if (defender->drain_exp(attacker))
+ {
+ if (defender->atype() == ACT_PLAYER)
+ obvious_effect = true;
+
+ attacker->god_conduct(DID_NECROMANCY, 2);
+ }
- attacker->god_conduct(DID_NECROMANCY, 2);
+ special_damage = 1 + random2(damage_done) / (2 + rn);
}
bool melee_attack::distortion_affects_defender()
diff --git a/crawl-ref/source/fight.h b/crawl-ref/source/fight.h
index 8fb863ae74..7a28c08b1c 100644
--- a/crawl-ref/source/fight.h
+++ b/crawl-ref/source/fight.h
@@ -201,8 +201,6 @@ private:
const char *verb);
int fire_res_apply_cerebov_downgrade(int res);
void drain_defender();
- void drain_player();
- void drain_monster();
void check_defender_train_armour();
void check_defender_train_dodging();
void splash_defender_with_acid(int strength);
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index b7106a1a75..8a58871767 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -5895,10 +5895,10 @@ god_type monsters::deity() const
return (god);
}
-void monsters::drain_exp(actor *agent)
+bool monsters::drain_exp(actor *agent)
{
- if (res_negative_energy() > 0)
- return;
+ if (x_chance_in_y(res_negative_energy(), 3))
+ return (false);
if (mons_near(this) && player_monster_visible(this))
mprf("%s is drained!", name(DESC_CAP_THE).c_str());
@@ -5912,6 +5912,8 @@ void monsters::drain_exp(actor *agent)
max_hit_points -= 2 + random2(3);
hurt(agent, 2 + random2(3), BEAM_NEG);
+
+ return (true);
}
void monsters::rot(actor *agent, int amount, int immediate)
diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc
index 2faca91b49..ca82412f81 100644
--- a/crawl-ref/source/ouch.cc
+++ b/crawl-ref/source/ouch.cc
@@ -636,7 +636,7 @@ void lose_level()
xom_is_stimulated(255);
}
-void drain_exp(bool announce_full)
+bool drain_exp(bool announce_full)
{
const int protection = player_prot_life();
@@ -644,20 +644,23 @@ void drain_exp(bool announce_full)
{
if (announce_full)
canned_msg(MSG_YOU_RESIST);
- return;
+
+ return (false);
}
if (you.experience == 0)
{
ouch(INSTANT_DEATH, NON_MONSTER, KILLED_BY_DRAINING);
+
// Return in case death was escaped via wizard mode.
- return;
+ return (true);
}
if (you.experience_level == 1)
{
you.experience = 0;
- return;
+
+ return (true);
}
unsigned long total_exp = exp_needed(you.experience_level + 2)
@@ -708,7 +711,11 @@ void drain_exp(bool announce_full)
if (you.experience < exp_needed(you.experience_level + 1))
lose_level();
+
+ return (true);
}
+
+ return (false);
}
static void _xom_checks_damage(kill_method_type death_type,
diff --git a/crawl-ref/source/ouch.h b/crawl-ref/source/ouch.h
index 8c4d88bd60..29fb02de8d 100644
--- a/crawl-ref/source/ouch.h
+++ b/crawl-ref/source/ouch.h
@@ -71,7 +71,7 @@ void ouch(int dam, int death_source, kill_method_type death_type,
void lose_level(void);
-void drain_exp(bool announce_full = true);
+bool drain_exp(bool announce_full = true);
bool expose_items_to_element(beam_type flavour, const coord_def& where,
int strength = 0);
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index ebb8e10058..eebf92f4e6 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -7007,9 +7007,9 @@ void player::rot(actor *who, int amount, int immediate)
disease_player(50 + random2(100));
}
-void player::drain_exp(actor *who)
+bool player::drain_exp(actor *who)
{
- ::drain_exp();
+ return (::drain_exp());
}
void player::confuse(actor *who, int str)