summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/beam.cc24
-rw-r--r--crawl-ref/source/hiscores.cc37
-rw-r--r--crawl-ref/source/monstuff.cc124
-rw-r--r--crawl-ref/source/mstuff2.cc63
-rw-r--r--crawl-ref/source/mstuff2.h1
-rw-r--r--crawl-ref/source/spl-cast.cc5
6 files changed, 138 insertions, 116 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 04720fe360..cd600a3ba6 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -3219,18 +3219,26 @@ static void _affect_place_explosion_clouds(bolt &beam, const coord_def& p)
// A little helper function to handle the calling of ouch()...
static void _beam_ouch(int dam, bolt &beam)
{
+ monsters *monst = NULL;
+ if (!invalid_monster_index(beam.beam_source)
+ && menv[beam.beam_source].type != -1)
+ {
+ monst = &menv[beam.beam_source];
+ }
+
// The order of this is important.
- if (YOU_KILL(beam.thrower) && beam.aux_source.empty())
+ if (monst && (monst->type == MONS_GIANT_SPORE
+ || monst->type == MONS_BALL_LIGHTNING))
+ {
+ ouch(dam, beam.beam_source, KILLED_BY_SPORE,
+ beam.aux_source.c_str());
+ }
+ else if (YOU_KILL(beam.thrower) && beam.aux_source.empty())
ouch(dam, NON_MONSTER, KILLED_BY_TARGETTING);
else if (MON_KILL(beam.thrower))
{
- if (beam.flavour == BEAM_SPORE)
- ouch(dam, beam.beam_source, KILLED_BY_SPORE);
- else
- {
- ouch(dam, beam.beam_source, KILLED_BY_BEAM,
- beam.aux_source.c_str());
- }
+ ouch(dam, beam.beam_source, KILLED_BY_BEAM,
+ beam.aux_source.c_str());
}
else // KILL_MISC || (YOU_KILL && aux_source)
{
diff --git a/crawl-ref/source/hiscores.cc b/crawl-ref/source/hiscores.cc
index d3d194d554..548e9c1532 100644
--- a/crawl-ref/source/hiscores.cc
+++ b/crawl-ref/source/hiscores.cc
@@ -762,8 +762,10 @@ void scorefile_entry::init_death_cause(int dam, int dsrc,
auxkilldata = aux;
// for death by monster
- if ((death_type == KILLED_BY_MONSTER || death_type == KILLED_BY_BEAM)
- && !invalid_monster_index(death_source))
+ if ((death_type == KILLED_BY_MONSTER || death_type == KILLED_BY_BEAM
+ || death_type == KILLED_BY_SPORE)
+ && !invalid_monster_index(death_source)
+ && menv[death_source].type != -1)
{
const monsters *monster = &menv[death_source];
@@ -806,10 +808,13 @@ void scorefile_entry::init_death_cause(int dam, int dsrc,
const bool death = you.hp <= 0;
- death_source_name = monster->name(DESC_NOCAP_A, death);
+ const description_level_type desc =
+ death_type == KILLED_BY_SPORE ? DESC_PLAIN : DESC_NOCAP_A;
+
+ death_source_name = monster->name(desc, death);
if (monster->has_base_name())
death_source_name +=
- ", " + monster->base_name(DESC_NOCAP_A, death);
+ ", " + monster->base_name(desc, death);
if (monster->has_ench(ENCH_SHAPESHIFTER))
death_source_name += " (shapeshifter)";
@@ -1636,7 +1641,21 @@ std::string scorefile_entry::death_description(death_desc_verbosity verbosity)
break;
case KILLED_BY_SPORE:
- desc += terse? "spore" : "Killed by an exploding spore";
+ if (terse)
+ {
+ if (death_source_name.empty())
+ desc += "spore";
+ else
+ desc += get_monster_data(death_source)->name;
+ }
+ else
+ {
+ desc += "Killed by an exploding ";
+ if (death_source_name.empty())
+ desc += "spore";
+ else
+ desc += death_source_name;
+ }
needs_damage = true;
break;
@@ -1851,6 +1870,14 @@ std::string scorefile_entry::death_description(death_desc_verbosity verbosity)
}
}
+ if (death_type == KILLED_BY_SPORE && !terse && !auxkilldata.empty())
+ {
+ desc += "... ";
+ desc += auxkilldata;
+ desc += "\n";
+ desc += " ";
+ }
+
if (terse)
{
trim_string(desc);
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 7810c20034..010e5ee080 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -784,6 +784,86 @@ static void _mummy_curse(monsters* monster, killer_type killer, int index)
}
}
+static void _spore_goes_pop(monsters *monster, killer_type killer,
+ int killer_index, bool pet_kill, bool wizard)
+{
+ if (monster->hit_points > 0 || monster->hit_points <= -15 || wizard
+ || killer == KILL_RESET || killer == KILL_DISMISSED)
+ {
+ return;
+ }
+
+ if (killer == KILL_MISC)
+ killer = KILL_MON;
+
+ bolt beam;
+ const int type = monster->type;
+
+ beam.is_tracer = false;
+ beam.is_explosion = true;
+ beam.beam_source = monster_index(monster);
+ beam.type = dchar_glyph(DCHAR_FIRED_BURST);
+ beam.pos = monster->pos();
+ beam.source = monster->pos();
+ beam.target = monster->pos();
+ beam.thrower = killer;
+ beam.aux_source.clear();
+
+ if (YOU_KILL(killer))
+ beam.aux_source = "set off by themselves";
+ else if (pet_kill)
+ beam.aux_source = "set off by their pet";
+
+ const char* msg = NULL;
+ const char* sanct_msg = NULL;
+ if (type == MONS_GIANT_SPORE)
+ {
+ beam.flavour = BEAM_SPORE;
+ beam.name = "explosion of spores";
+ beam.colour = LIGHTGREY;
+ beam.damage = dice_def( 3, 15 );
+ beam.ex_size = 2;
+ msg = "The giant spore explodes!";
+ sanct_msg = "By Zin's power, the giant spore's explosion is contained.";
+ }
+ else if (type == MONS_BALL_LIGHTNING)
+ {
+ beam.flavour = BEAM_ELECTRICITY;
+ beam.name = "blast of lightning";
+ beam.colour = LIGHTCYAN;
+ beam.damage = dice_def( 3, 20 );
+ beam.ex_size = coinflip() ? 3 : 2;
+ msg = "The ball lightning explodes!";
+ sanct_msg = "By Zin's power, the ball lightning's explosion "
+ "is contained.";
+ }
+ else
+ {
+ msg::streams(MSGCH_DIAGNOSTICS) << "Unknown spore type: "
+ << static_cast<int>(type)
+ << std::endl;
+ return;
+ }
+
+ if (you.can_see(monster))
+ {
+ viewwindow(true, false);
+ if (is_sanctuary(monster->pos()))
+ mpr(sanct_msg, MSGCH_GOD);
+ else
+ mpr(msg);
+ }
+
+ if (is_sanctuary(monster->pos()))
+ return;
+
+ // Detach monster from the grid first, so it doesn't get hit by
+ // its own explosion. (GDL)
+ mgrd(monster->pos()) = NON_MONSTER;
+ explosion(beam, false, false, true, true, mons_near(monster));
+ mgrd(monster->pos()) = monster_index(monster);
+}
+
void monster_die(monsters *monster, killer_type killer,
int killer_index, bool silent, bool wizard)
{
@@ -879,20 +959,20 @@ void monster_die(monsters *monster, killer_type killer,
if (monster->type == MONS_GIANT_SPORE
|| monster->type == MONS_BALL_LIGHTNING)
{
- if (monster->hit_points < 1 && monster->hit_points > -15)
- return;
+ _spore_goes_pop(monster, killer, killer_index, pet_kill, wizard);
}
else if (monster->type == MONS_FIRE_VORTEX
|| monster->type == MONS_SPATIAL_VORTEX)
{
- if (!silent)
+ if (!silent && killer != KILL_RESET)
{
simple_monster_message( monster, " dissipates!",
MSGCH_MONSTER_DAMAGE, MDAM_DEAD );
silent = true;
}
- if (monster->type == MONS_FIRE_VORTEX)
+ if (monster->type == MONS_FIRE_VORTEX && !wizard
+ && killer != KILL_RESET)
{
place_cloud(CLOUD_FIRE, monster->pos(), 2 + random2(4),
monster->kill_alignment());
@@ -904,15 +984,16 @@ void monster_die(monsters *monster, killer_type killer,
else if (monster->type == MONS_SIMULACRUM_SMALL
|| monster->type == MONS_SIMULACRUM_LARGE)
{
- if (!silent)
+ if (!silent && killer != KILL_RESET)
{
simple_monster_message( monster, " vapourises!",
MSGCH_MONSTER_DAMAGE, MDAM_DEAD );
silent = true;
}
- place_cloud(CLOUD_COLD, monster->pos(), 2 + random2(4),
- monster->kill_alignment());
+ if (!wizard && killer != KILL_RESET)
+ place_cloud(CLOUD_COLD, monster->pos(), 2 + random2(4),
+ monster->kill_alignment());
if (killer == KILL_RESET)
killer = KILL_DISMISSED;
@@ -5860,7 +5941,7 @@ static void _swim_or_move_energy(monsters *mon)
#if DEBUG
# define DEBUG_ENERGY_USE(problem) \
- if (monster->speed_increment == old_energy) \
+ if (monster->speed_increment == old_energy && monster->alive()) \
mprf(MSGCH_DIAGNOSTICS, \
problem " for monster '%s' consumed no energy", \
monster->name(DESC_PLAIN).c_str(), true);
@@ -6282,19 +6363,6 @@ static void _handle_monster_move(int i, monsters *monster)
DEBUG_ENERGY_USE("monster_attack()");
}
- if ((monster->type == MONS_GIANT_SPORE
- || monster->type == MONS_BALL_LIGHTNING)
- && monster->hit_points < 1)
- {
- // Detach monster from the grid first, so it
- // doesn't get hit by its own explosion. (GDL)
- mgrd(monster->pos()) = NON_MONSTER;
-
- spore_goes_pop(monster);
- monster_cleanup(monster);
- continue;
- }
-
if (attacked)
{
mmov.reset();
@@ -6324,21 +6392,7 @@ static void _handle_monster_move(int i, monsters *monster)
}
if (monster->type != -1 && monster->hit_points < 1)
- {
- if (monster->type == MONS_GIANT_SPORE
- || monster->type == MONS_BALL_LIGHTNING)
- {
- // Detach monster from the grid first, so it
- // doesn't get hit by its own explosion. (GDL)
- mgrd(monster->pos()) = NON_MONSTER;
-
- spore_goes_pop(monster);
- monster_cleanup(monster);
- return;
- }
- else
monster_die(monster, KILL_MISC, NON_MONSTER);
- }
}
//---------------------------------------------------------------
diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc
index 640c2d24e0..18da736352 100644
--- a/crawl-ref/source/mstuff2.cc
+++ b/crawl-ref/source/mstuff2.cc
@@ -1237,69 +1237,6 @@ bool mons_thrown_object_destroyed( item_def *item, const coord_def& where,
return destroyed;
}
-// XXX: Should really do something about mons_hit, but can't be bothered.
-void spore_goes_pop(monsters *monster)
-{
- bolt beam;
- const int type = monster->type;
-
- if (monster == NULL)
- return;
-
- beam.is_tracer = false;
- beam.is_explosion = true;
- beam.beam_source = monster_index(monster);
- beam.type = dchar_glyph(DCHAR_FIRED_BURST);
- beam.target = monster->pos();
- beam.thrower = KILL_MON; // someone else's explosion
- beam.aux_source.clear();
-
- const char* msg = NULL;
- const char* sanct_msg = NULL;
- if (type == MONS_GIANT_SPORE)
- {
- beam.flavour = BEAM_SPORE;
- beam.name = "explosion of spores";
- beam.colour = LIGHTGREY;
- beam.damage = dice_def( 3, 15 );
- beam.ex_size = 2;
- msg = "The giant spore explodes!";
- sanct_msg = "By Zin's power, the giant spore's explosion is contained.";
- }
- else if (type == MONS_BALL_LIGHTNING)
- {
- beam.flavour = BEAM_ELECTRICITY;
- beam.name = "blast of lightning";
- beam.colour = LIGHTCYAN;
- beam.damage = dice_def( 3, 20 );
- beam.ex_size = coinflip() ? 3 : 2;
- msg = "The ball lightning explodes!";
- sanct_msg = "By Zin's power, the ball lightning's explosion "
- "is contained.";
- }
- else
- {
- msg::streams(MSGCH_DIAGNOSTICS) << "Unknown spore type: "
- << static_cast<int>(type)
- << std::endl;
- return;
- }
-
- if (you.can_see(monster))
- {
- viewwindow(true, false);
- if (is_sanctuary(monster->pos()))
- mpr(sanct_msg, MSGCH_GOD);
- else
- mpr(msg);
- }
-
- if (is_sanctuary(monster->pos()))
- return;
-
- explosion(beam, false, false, true, true, mons_near(monster));
-}
-
bolt mons_spells( monsters *mons, spell_type spell_cast, int power )
{
ASSERT(power > 0);
diff --git a/crawl-ref/source/mstuff2.h b/crawl-ref/source/mstuff2.h
index 1a3b722953..d0f9a32744 100644
--- a/crawl-ref/source/mstuff2.h
+++ b/crawl-ref/source/mstuff2.h
@@ -30,7 +30,6 @@ bool monster_random_space(const monsters *monster, coord_def& target,
bool monster_random_space(monster_type mon, coord_def& target,
bool forbid_sanctuary = false);
void monster_teleport(monsters *monster, bool instan, bool silent = false);
-void spore_goes_pop(monsters *monster);
bool orc_battle_cry(monsters *chief);
bool orange_statue_effects(monsters *mons);
bool silver_statue_effects(monsters *mons);
diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc
index 11556d5570..b16e8b3cd1 100644
--- a/crawl-ref/source/spl-cast.cc
+++ b/crawl-ref/source/spl-cast.cc
@@ -2234,10 +2234,7 @@ void MiscastEffect::init()
|| pow == -1 && fail == -1 && level >= 0 && level <= 3);
ASSERT(target != NULL);
- // A dead but not-yet-exploded giant spore or ball lightning *might*
- // be the target of a miscast effect.
- ASSERT(target->alive() || target->id() == MONS_GIANT_SPORE
- || target->id() == MONS_BALL_LIGHTNING);
+ ASSERT(target->alive());
source_known = target_known = false;