diff options
-rw-r--r-- | crawl-ref/source/beam.cc | 24 | ||||
-rw-r--r-- | crawl-ref/source/hiscores.cc | 37 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 124 | ||||
-rw-r--r-- | crawl-ref/source/mstuff2.cc | 63 | ||||
-rw-r--r-- | crawl-ref/source/mstuff2.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/spl-cast.cc | 5 |
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; |