diff options
Diffstat (limited to 'crawl-ref')
-rw-r--r-- | crawl-ref/source/externs.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/fight.cc | 13 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 22 | ||||
-rw-r--r-- | crawl-ref/source/player.cc | 9 | ||||
-rw-r--r-- | crawl-ref/source/spl-cast.cc | 44 |
5 files changed, 58 insertions, 33 deletions
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 6a65a845a9..747c733956 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -335,6 +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 void rot(actor *agent, int amount, int immediate = 0) = 0; virtual int hurt(const actor *attacker, int amount, beam_type flavour = BEAM_MISSILE, @@ -1073,6 +1074,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 *); void rot(actor *, int amount, int immediate = 0); int hurt(const actor *attacker, int amount, beam_type flavour = BEAM_MISSILE, @@ -1502,6 +1504,7 @@ public: void petrify(actor *, int str); void slow_down(actor *, int str); void confuse(actor *, int strength); + void 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 7fc91ca58a..6d3bd5f2a6 100644 --- a/crawl-ref/source/fight.cc +++ b/crawl-ref/source/fight.cc @@ -2062,7 +2062,8 @@ void melee_attack::drain_defender() void melee_attack::drain_player() { - drain_exp(); + defender->drain_exp(attacker); + special_damage = random2(damage_done) / (2 + defender->res_negative_energy()) + 1; @@ -2085,16 +2086,10 @@ void melee_attack::drain_monster() def_name(DESC_NOCAP_THE).c_str()); } - if (one_chance_in(5)) - { - defender_as_monster()->hit_dice--; - defender_as_monster()->experience = 0; - } - - defender_as_monster()->max_hit_points -= 2 + random2(3); - defender->hurt(attacker, 2 + random2(3), BEAM_NEG, false); + defender->drain_exp(attacker); special_damage = 1 + (random2(damage_done) / 2); + attacker->god_conduct(DID_NECROMANCY, 2); } diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index c5e4a2470c..193ee22c88 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -5874,6 +5874,22 @@ god_type monsters::deity() const return (god); } +void monsters::drain_exp(actor *agent) +{ + if (res_negative_energy()) + return; + + if (one_chance_in(5)) + { + hit_dice--; + experience = 0; + } + + max_hit_points -= 2 + random2(3); + + hurt(agent, 2 + random2(3), BEAM_NEG); +} + void monsters::rot(actor *agent, int amount, int immediate) { if (res_rotting() > 0 || amount <= 0) @@ -7138,7 +7154,7 @@ void monsters::apply_enchantment(const mon_enchant &me) { // We don't have a reasonable agent to give. // Don't clean up the monster in order to credit properly. - this->hurt(NULL, dam, BEAM_POISON, false); + hurt(NULL, dam, BEAM_POISON, false); #if DEBUG_DIAGNOSTICS // For debugging, we don't have this silent. @@ -7162,7 +7178,7 @@ void monsters::apply_enchantment(const mon_enchant &me) { if (hit_points > 1 && one_chance_in(3)) { - this->hurt(NULL, 1); // nonlethal so we don't care about agent + hurt(NULL, 1); // nonlethal so we don't care about agent if (hit_points < max_hit_points && coinflip()) --max_hit_points; } @@ -7182,7 +7198,7 @@ void monsters::apply_enchantment(const mon_enchant &me) simple_monster_message(this, " burns!"); // We don't have a reasonable agent to give. // Don't clean up the monster in order to credit properly. - this->hurt(NULL, dam, BEAM_NAPALM, false); + hurt(NULL, dam, BEAM_NAPALM, false); #if DEBUG_DIAGNOSTICS mprf( MSGCH_DIAGNOSTICS, "sticky flame damage: %d", dam ); diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 83f9acc7fa..cb1a22ace2 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -6963,7 +6963,7 @@ int player::hurt(const actor *agent, int amount, beam_type flavour, return (amount); } -void player::drain_stat(int stat, int amount, actor* attacker) +void player::drain_stat(int stat, int amount, actor *attacker) { if (attacker == NULL) lose_stat(stat, amount, false, ""); @@ -6987,6 +6987,11 @@ void player::rot(actor *who, int amount, int immediate) disease_player(50 + random2(100)); } +void player::drain_exp(actor *who) +{ + ::drain_exp(); +} + void player::confuse(actor *who, int str) { confuse_player(str); @@ -7025,7 +7030,7 @@ void player::petrify(actor *who, int str) void player::slow_down(actor *foe, int str) { - ::slow_player( str ); + ::slow_player(str); } int player::has_claws(bool allow_tran) const diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc index f1e6e81603..42d14d6b2f 100644 --- a/crawl-ref/source/spl-cast.cc +++ b/crawl-ref/source/spl-cast.cc @@ -3843,16 +3843,20 @@ void MiscastEffect::_necromancy(int severity) } case 1: - if (target->atype() == ACT_PLAYER && !player_prot_life() - && one_chance_in(3)) + you_msg = "You are engulfed in negative energy!"; + mon_msg_seen = "@The_monster@ is engulfed in negative energy!"; + + if (lethality_margin == 0 || you.experience > 0 + || !avoid_lethal(you.hp)) { - if (lethality_margin == 0 || you.experience > 0 - || !avoid_lethal(you.hp)) + if (!target->res_negative_energy() && one_chance_in(3)) { - drain_exp(); + target->drain_exp(act_source); + break; } - break; - } // otherwise it just flows through... + } + + // If draining failed, just flow through... case 2: // Monster messages needed. @@ -3872,8 +3876,8 @@ void MiscastEffect::_necromancy(int severity) break; case 3: // even nastier - // Don't use two last cases for monsters. - switch (random2(target->atype() == ACT_PLAYER ? 6 : 4)) + // Don't use last case for monsters. + switch (random2(target->atype() == ACT_PLAYER ? 6 : 5)) { case 0: if (target->holiness() == MH_UNDEAD) @@ -3911,24 +3915,26 @@ void MiscastEffect::_necromancy(int severity) break; case 4: - if (lethality_margin > 0 && you.experience == 0 - && avoid_lethal(you.hp)) + you_msg = "You are engulfed in negative energy!"; + mon_msg_seen = "@The_monster@ is engulfed in negative energy!"; + + if (lethality_margin == 0 || you.experience > 0 + || !avoid_lethal(you.hp)) { - return; + if (!target->res_negative_energy()) + { + target->drain_exp(act_source); + break; + } } - mpr("You are engulfed in negative energy!"); - - if (!player_prot_life()) - { - drain_exp(); + // If draining failed, just flow through if it's the player... + if (target->atype() == ACT_MONSTER) break; - } // otherwise it just flows through... case 5: _lose_stat(STAT_RANDOM, 1 + random2avg(7, 2)); break; - } break; } |