diff options
author | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-11-27 13:29:07 +0000 |
---|---|---|
committer | zelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573> | 2008-11-27 13:29:07 +0000 |
commit | 62ba7977a2d7085a7ee0232fa317293c878f9365 (patch) | |
tree | 172223027970cb8d574af7947e8b6eaa63c493da /crawl-ref/source/monstuff.cc | |
parent | 0566854703cbf6aef6623f44fde4bd5becb16854 (diff) | |
download | crawl-ref-62ba7977a2d7085a7ee0232fa317293c878f9365.tar.gz crawl-ref-62ba7977a2d7085a7ee0232fa317293c878f9365.zip |
Giant spores and lightning balls exploding is now handled immediately inside
of monster_die(), removing the need to ever check for "monster is dead
but still present because it's about to explode". It also lets you get
the credit (and blame) for any monsters the explosion hits if you attacking
it triggered the explosion. While I was at it I made the death-cause
display show if death from spore/ball explosion was due to an explosion
triggered by the player or one of the player's pets.
Also made it so that when similacrums and fire vortices are banished
or wizard-command-genocided that they don't leave behind a
freezing/burning cloud.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7653 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/monstuff.cc')
-rw-r--r-- | crawl-ref/source/monstuff.cc | 124 |
1 files changed, 89 insertions, 35 deletions
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); - } } //--------------------------------------------------------------- |