summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/mon-behv.cc
diff options
context:
space:
mode:
authorMatthew Cline <zelgadis@sourceforge.net>2009-11-15 02:43:22 -0800
committerMatthew Cline <zelgadis@sourceforge.net>2009-11-15 02:43:47 -0800
commit45fa19fe2c8abb4a59c0d24d8e7b06c05c200f64 (patch)
tree30cc6335b2c4708979c4b14ff8bff24d455cc314 /crawl-ref/source/mon-behv.cc
parentdd7da972e69921748dd87120d6ebefab208cdf36 (diff)
downloadcrawl-ref-45fa19fe2c8abb4a59c0d24d8e7b06c05c200f64.tar.gz
crawl-ref-45fa19fe2c8abb4a59c0d24d8e7b06c05c200f64.zip
handle_behaviour(): fix infinite loop.
Diffstat (limited to 'crawl-ref/source/mon-behv.cc')
-rw-r--r--crawl-ref/source/mon-behv.cc27
1 files changed, 20 insertions, 7 deletions
diff --git a/crawl-ref/source/mon-behv.cc b/crawl-ref/source/mon-behv.cc
index f23620fb9f..c7a4e805b7 100644
--- a/crawl-ref/source/mon-behv.cc
+++ b/crawl-ref/source/mon-behv.cc
@@ -983,7 +983,7 @@ static void _set_random_slime_target(monsters* mon)
set_random_target(mon);
}
-static void _guess_invis_foe_pos(monsters *mon)
+static void _guess_invis_foe_pos(monsters *mon, bool strict = true)
{
const actor* foe = mon->get_foe();
const int guess_radius = mons_sense_invis(mon) ? 3 : 2;
@@ -992,10 +992,22 @@ static void _guess_invis_foe_pos(monsters *mon)
for (radius_iterator ri(mon->pos(), guess_radius); ri; ++ri)
{
- if (foe->is_habitable(*ri) && mon->mon_see_cell(*ri))
+ // NOTE: This depends on mon_see_cell() ignoring clouds,
+ // so that cells hidden by opaque clouds are included
+ // as a possibility for the foe's location.
+ if (!strict || foe->is_habitable(*ri) && mon->mon_see_cell(*ri))
possibilities.push_back(*ri);
}
+ // If being strict (monster must see possible cell, foe must be
+ // able to live there) gives no possibilites, then find *some*
+ // cell near the foe.
+ if (strict && possibilities.empty())
+ {
+ _guess_invis_foe_pos(mon, false);
+ return;
+ }
+
if (!possibilities.empty())
mon->target = possibilities[random2(possibilities.size())];
}
@@ -1229,11 +1241,12 @@ void handle_behaviour(monsters *mon)
// (0, 0) can lead to asserts, so lets try to
// avoid that.
_set_nearest_monster_foe(mon);
- if (mon->foe != MHITNOT)
- continue;
-
- new_beh = BEH_WANDER;
- break;
+ if (mon->foe == MHITNOT)
+ {
+ new_beh = BEH_WANDER;
+ break;
+ }
+ mon->target = mon->get_foe()->pos();
}
}