From 2cc1fcd4c22999a035ce33eada216055a63b3cc7 Mon Sep 17 00:00:00 2001 From: zelgadis Date: Mon, 29 Dec 2008 10:32:57 +0000 Subject: Some more attempts to prevent/catch/diagnose floating monster problems. Among other things: * If level generation leaves some monsters detached then this will be specifically noted. * If applying _handle_monster_move() to a monster causes that monster to become detached it will be noted (those it won't catch *other* monster being detached by that monster moving). git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8009 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/debug.cc | 36 +++++++++++++++++++++++++++++----- crawl-ref/source/dungeon.cc | 7 +++++++ crawl-ref/source/mon-util.cc | 4 ++++ crawl-ref/source/monplace.cc | 2 ++ crawl-ref/source/monstuff.cc | 46 ++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 86 insertions(+), 9 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index 34baa50826..79664df68b 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -2253,6 +2253,15 @@ void debug_item_scan( void ) #endif #if DEBUG_MONS_SCAN +static void _announce_level_prob(bool warned) +{ + if (!warned && Generating_Level) + { + mpr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", MSGCH_ERROR); + mpr("mgrd problem occurred during level generation", MSGCH_ERROR); + } +} + void debug_mons_scan() { bool warned = false; @@ -2260,15 +2269,27 @@ void debug_mons_scan() for (int x = 0; x < GXM; ++x) { const int mons = mgrd[x][y]; - if (mons != NON_MONSTER && - menv[mons].pos() != coord_def(x, y)) + if (mons == NON_MONSTER) + continue; + const monsters *m = &menv[mons]; + if (m->pos() != coord_def(x, y)) { - const monsters *m = &menv[mons]; + _announce_level_prob(warned); mprf(MSGCH_WARN, - "Bogosity: mgrd at %d,%d points at %s, " - "but monster is at %d,%d", + "Bogosity: mgrd at (%d,%d) points at %s, " + "but monster is at (%d,%d)", x, y, m->name(DESC_PLAIN, true).c_str(), m->pos().x, m->pos().y); + if (!m->alive()) + mpr("Additionally, it isn't alive.", MSGCH_WARN); + warned = true; + } + else if (!m->alive()) + { + _announce_level_prob(warned); + mprf(MSGCH_WARN, + "mgrd at (%d,%d) points at dead monster %s", + x, y, m->name(DESC_PLAIN, true).c_str()); warned = true; } } @@ -2280,6 +2301,7 @@ void debug_mons_scan() continue; if (mgrd(m->pos()) != i) { + _announce_level_prob(warned); mprf(MSGCH_WARN, "Floating monster: %s at (%d,%d)", m->name(DESC_PLAIN, true).c_str(), m->pos().x, m->pos().y); warned = true; @@ -2308,6 +2330,10 @@ void debug_mons_scan() } } } + + if (warned && Generating_Level) + mpr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", MSGCH_ERROR); + // If there are warnings, force the dev to notice. :P if (warned) more(); diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 71dd75dd8a..aef1bd79dd 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -313,6 +313,13 @@ bool builder(int level_number, int level_type) Level_Unique_Maps.clear(); Level_Unique_Tags.clear(); _dgn_map_colour_fixup(); + +#if DEBUG_MONS_SCAN + // If debug_mons_scan() find a problem while Generating_Level is + // still true then it will announce that a problem was caused + // during level generation. + debug_mons_scan(); +#endif return (true); } diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 79f0361fb0..91ec861bd9 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -4916,6 +4916,9 @@ bool monsters::has_base_name() const std::string monsters::name(description_level_type desc, bool force_vis) const { + if (type == -1) + return ("INVALID MONSTER"); + const bool possessive = (desc == DESC_NOCAP_YOUR || desc == DESC_NOCAP_ITS); @@ -5280,6 +5283,7 @@ int monsters::get_experience_level() const void monsters::moveto( const coord_def& c ) { + ASSERT(mgrd(c) == NON_MONSTER || c == pos()); position = c; } diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index 4141730bc7..84a128e5e1 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -975,6 +975,8 @@ static int _place_monster_aux( const mgen_data &mg, return (-1); } + ASSERT(mgrd(fpos) == NON_MONSTER); + // Now, actually create the monster. (Wheeee!) menv[id].type = mg.cls; menv[id].base_monster = mg.base_type; diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index da64131419..83da543cf5 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -1972,11 +1972,9 @@ bool monster_blink(monsters *monster) mons_clear_trapping_net(monster); - mgrd(monster->pos()) = NON_MONSTER; const coord_def oldplace = monster->pos(); - - monster->moveto(near); - mgrd(near) = monster_index(monster); + if (!monster->move_to_pos(near)) + return (false); if (player_monster_visible(monster) && mons_near(monster)) seen_monster(monster); @@ -2124,6 +2122,12 @@ bool swap_places(monsters *monster, const coord_def &loc) ASSERT(map_bounds(loc)); ASSERT(_habitat_okay(monster, grd(loc))); + if (mgrd(loc) != NON_MONSTER) + { + mpr("Something prevents you from swapping places."); + return (false); + } + mpr("You swap places."); mgrd(monster->pos()) = NON_MONSTER; @@ -4681,6 +4685,14 @@ static bool _siren_movement_effect(const monsters *monster) if (swapping) { + if (mgrd(oldpos) != NON_MONSTER) + { + mprf("Something prevents you from swapping places " + "with %s.", + mon->name(DESC_NOCAP_THE).c_str()); + return (do_resist); + } + int swap_mon = mgrd(newpos); // Pick the monster up. mgrd(newpos) = NON_MONSTER; @@ -6386,12 +6398,38 @@ static void _handle_monster_move(int i, monsters *monster) int non_move_energy = std::min(entry->energy_usage.move, entry->energy_usage.swim); +#if DEBUG_MONS_SCAN + bool monster_was_floating = mgrd(monster->pos()) != monster->mindex(); +#endif + while (monster->has_action_energy()) { // The continues & breaks are WRT this. if (!monster->alive()) break; +#if DEBUG_MONS_SCAN + if (!monster_was_floating + && mgrd(monster->pos()) != monster->mindex()) + { + mprf(MSGCH_ERROR, "Monster %s became detached from mgrd " + "in _handle_monster_move() loop", + monster->name(DESC_PLAIN, true).c_str()); + mpr("[[[[[[[[[[[[[[[[[[", MSGCH_WARN); + debug_mons_scan(); + mpr("]]]]]]]]]]]]]]]]]]", MSGCH_WARN); + monster_was_floating = true; + } + else if (monster_was_floating + && mgrd(monster->pos()) == monster->mindex()) + { + mprf(MSGCH_DIAGNOSTICS, "Monster %s re-attached itself to mgrd " + "in _handle_monster_move() loop", + monster->name(DESC_PLAIN, true).c_str()); + monster_was_floating = false; + } +#endif + if (monster->speed_increment >= old_energy) { #if DEBUG -- cgit v1.2.3-54-g00ecf