diff options
-rw-r--r-- | crawl-ref/source/externs.h | 6 | ||||
-rw-r--r-- | crawl-ref/source/fight.cc | 34 | ||||
-rw-r--r-- | crawl-ref/source/fight.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 8 | ||||
-rw-r--r-- | crawl-ref/source/ouch.cc | 15 | ||||
-rw-r--r-- | crawl-ref/source/ouch.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/player.cc | 4 |
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) |