summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/monstuff.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/monstuff.cc')
-rw-r--r--crawl-ref/source/monstuff.cc125
1 files changed, 87 insertions, 38 deletions
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index f1aeaccf6e..2d4f98eae6 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -60,7 +60,7 @@
#include "player.h"
#include "randart.h"
#include "religion.h"
-#include "spl-cast.h"
+#include "spl-mis.h"
#include "spl-util.h"
#include "spells3.h"
#include "spells4.h"
@@ -696,12 +696,77 @@ static void _fire_monster_death_event(monsters *monster,
}
}
-void monster_die(monsters *monster, killer_type killer, int i, bool silent)
+static void _mummy_curse(monsters* monster, killer_type killer, int index)
+{
+ int pow;
+
+ switch(killer)
+ {
+ // Mummy killed by trap or something other than the player or
+ // another monster, so no curse.
+ case KILL_MISC:
+ // Mummy sent to the Abyss wasn't actually killed, so no curse.
+ case KILL_RESET:
+ case KILL_DISMISSED:
+ return;
+
+ default:
+ break;
+ }
+
+ switch(monster->type)
+ {
+ case MONS_MUMMY: pow = 1; break;
+ case MONS_GUARDIAN_MUMMY: pow = 3; break;
+ case MONS_MUMMY_PRIEST: pow = 8; break;
+ case MONS_GREATER_MUMMY: pow = 11; break;
+
+ default:
+ mpr("Unkown mummy type.", MSGCH_DIAGNOSTICS);
+ return;
+ }
+
+ // Killed by a Zot trap, a god, etc
+ if (index != NON_MONSTER && invalid_monster_index(killer))
+ return;
+
+ actor* target;
+ if (index == NON_MONSTER)
+ target = dynamic_cast<actor*>(&you);
+ else
+ {
+ // Mummies committing suicide don't cause a death curse.
+ if (index == (int) monster_index(monster))
+ return;
+ target = dynamic_cast<actor*>(&menv[index]);
+ }
+
+ // Mummy was killed by a giant spore or ball lightning?
+ if (!target->alive())
+ return;
+
+ if (monster->type == MONS_MUMMY && killer == NON_MONSTER)
+ curse_an_item(true);
+ else
+ {
+ if (index == NON_MONSTER)
+ mpr("You feel extremely nervous for a moment...",
+ MSGCH_MONSTER_SPELL);
+ else if (you.can_see(target))
+ mprf(MSGCH_MONSTER_SPELL, "A malignant arua surrounds %s.",
+ target->name(DESC_NOCAP_THE).c_str());
+ MiscastEffect(target, monster_index(monster), SPTYP_NECROMANCY,
+ pow, random2avg(88, 3), "a mummy death curse");
+ }
+}
+
+void monster_die(monsters *monster, killer_type killer,
+ int killer_index, bool silent)
{
if (monster->type == -1)
return;
- if (!silent && _monster_avoided_death(monster, killer, i))
+ if (!silent && _monster_avoided_death(monster, killer, killer_index))
return;
mons_clear_trapping_net(monster);
@@ -717,15 +782,14 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent)
bool drop_items = !hard_reset && !mons_is_holy(monster);
#ifdef DGL_MILESTONES
- _check_kill_milestone(monster, killer, i);
+ _check_kill_milestone(monster, killer, killer_index);
#endif
// Award experience for suicide if the suicide was caused by the
// player.
- if (MON_KILL(killer) && monster_killed == i)
+ if (MON_KILL(killer) && monster_killed == killer_index)
{
- const mon_enchant me = monster->get_ench(ENCH_CONFUSION);
- if (me.ench == ENCH_CONFUSION && me.who == KC_YOU)
+ if (monster->confused_by_you())
killer = KILL_YOU_CONF;
}
else if (MON_KILL(killer) && monster->has_ench(ENCH_CHARM))
@@ -781,7 +845,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent)
if (killer == KILL_YOU)
crawl_state.cancel_cmd_repeat();
- const bool pet_kill = _is_pet_kill(killer, i);
+ const bool pet_kill = _is_pet_kill(killer, killer_index);
if (monster->type == MONS_GIANT_SPORE
|| monster->type == MONS_BALL_LIGHTNING)
@@ -1020,10 +1084,11 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent)
&& pet_kill)
{
bool notice = false;
- const bool anon = (i == ANON_FRIENDLY_MONSTER);
+ const bool anon = (killer_index == ANON_FRIENDLY_MONSTER);
const mon_holy_type targ_holy = mons_holiness(monster),
- attacker_holy = anon ? MH_NATURAL : mons_holiness(&menv[i]);
+ attacker_holy = anon ? MH_NATURAL
+ : mons_holiness(&menv[killer_index]);
if (attacker_holy == MH_UNDEAD)
{
@@ -1034,7 +1099,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent)
// "slave", and I think it's okay that Yredelemnul
// ignores kills done by confused monsters as opposed
// to enslaved or friendly ones. (jpeg)
- if (mons_friendly(&menv[i]))
+ if (mons_friendly(&menv[killer_index]))
{
notice |=
did_god_conduct(DID_LIVING_KILLED_BY_UNDEAD_SLAVE,
@@ -1052,7 +1117,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent)
|| you.religion == GOD_VEHUMET
|| you.religion == GOD_MAKHLEB
|| you.religion == GOD_LUGONU
- || !anon && mons_is_god_gift(&menv[i]))
+ || !anon && mons_is_god_gift(&menv[killer_index]))
{
// Yes, we are splitting undead pets from the others
// as a way to focus Necromancy vs Summoning (ignoring
@@ -1114,9 +1179,9 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent)
&& mons_is_evil_or_unholy(monster)
&& !player_under_penance()
&& random2(you.piety) >= piety_breakpoint(0)
- && !invalid_monster_index(i))
+ && !invalid_monster_index(killer_index))
{
- monsters *mon = &menv[i];
+ monsters *mon = &menv[killer_index];
// Randomly bless the follower who killed.
if (!one_chance_in(3) && mon->alive()
@@ -1139,9 +1204,9 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent)
&& random2(you.piety) >= piety_breakpoint(2)
&& !player_under_penance()
&& !one_chance_in(3)
- && !invalid_monster_index(i))
+ && !invalid_monster_index(killer_index))
{
- bless_follower(&menv[i]);
+ bless_follower(&menv[killer_index]);
}
}
@@ -1221,25 +1286,9 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent)
}
else if (!mons_is_summoned(monster))
{
- if (monster->type == MONS_MUMMY)
+ if (mons_genus(monster->type) == MONS_MUMMY)
{
- if (YOU_KILL(killer) && killer != KILL_YOU_CONF)
- curse_an_item(true);
- }
- else if (monster->type == MONS_GUARDIAN_MUMMY
- || monster->type == MONS_GREATER_MUMMY
- || monster->type == MONS_MUMMY_PRIEST)
- {
- if (YOU_KILL(killer) && killer != KILL_YOU_CONF)
- {
- mpr("You feel extremely nervous for a moment...",
- MSGCH_MONSTER_SPELL);
-
- miscast_effect( SPTYP_NECROMANCY,
- 3 + (monster->type == MONS_GREATER_MUMMY) * 8
- + (monster->type == MONS_MUMMY_PRIEST) * 5,
- random2avg(88, 3), 100, "a mummy death curse" );
- }
+ _mummy_curse(monster, killer, killer_index);
}
}
@@ -1253,7 +1302,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent)
KC_OTHER;
unsigned int exp_gain = 0, avail_gain = 0;
- _give_adjusted_experience(monster, killer, pet_kill, i,
+ _give_adjusted_experience(monster, killer, pet_kill, killer_index,
&exp_gain, &avail_gain);
PlaceInfo& curr_PlaceInfo = you.get_place_info();
@@ -1288,7 +1337,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent)
}
}
- _fire_monster_death_event(monster, killer, i);
+ _fire_monster_death_event(monster, killer, killer_index);
const coord_def mwhere = monster->pos();
if (drop_items)
@@ -7504,7 +7553,7 @@ static void _mons_in_cloud(monsters *monster)
return;
beam.flavour = BEAM_CONFUSION;
- beam.thrower = cloud.beam_thrower();
+ beam.thrower = cloud.killer;
if (cloud.whose == KC_FRIENDLY)
beam.beam_source = ANON_FRIENDLY_MONSTER;
@@ -7608,7 +7657,7 @@ static void _mons_in_cloud(monsters *monster)
if (monster->hit_points < 1)
{
mon_enchant death_ench(ENCH_NONE, 0, cloud.whose);
- monster_die(monster, death_ench.killer(), death_ench.kill_agent());
+ monster_die(monster, cloud.killer, death_ench.kill_agent());
}
}
}