summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-29 10:32:57 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-29 10:32:57 +0000
commit2cc1fcd4c22999a035ce33eada216055a63b3cc7 (patch)
tree5790f233798631e161245745dc17aace4c3fe493 /crawl-ref/source
parent3744c360da8fefca3e74ec098b9478df017f6b3f (diff)
downloadcrawl-ref-2cc1fcd4c22999a035ce33eada216055a63b3cc7.tar.gz
crawl-ref-2cc1fcd4c22999a035ce33eada216055a63b3cc7.zip
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
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/debug.cc36
-rw-r--r--crawl-ref/source/dungeon.cc7
-rw-r--r--crawl-ref/source/mon-util.cc4
-rw-r--r--crawl-ref/source/monplace.cc2
-rw-r--r--crawl-ref/source/monstuff.cc46
5 files changed, 86 insertions, 9 deletions
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