summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/mon-behv.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/mon-behv.cc')
-rw-r--r--crawl-ref/source/mon-behv.cc35
1 files changed, 35 insertions, 0 deletions
diff --git a/crawl-ref/source/mon-behv.cc b/crawl-ref/source/mon-behv.cc
index 8b4956a8a9..f23620fb9f 100644
--- a/crawl-ref/source/mon-behv.cc
+++ b/crawl-ref/source/mon-behv.cc
@@ -983,6 +983,23 @@ static void _set_random_slime_target(monsters* mon)
set_random_target(mon);
}
+static void _guess_invis_foe_pos(monsters *mon)
+{
+ const actor* foe = mon->get_foe();
+ const int guess_radius = mons_sense_invis(mon) ? 3 : 2;
+
+ std::vector<coord_def> possibilities;
+
+ for (radius_iterator ri(mon->pos(), guess_radius); ri; ++ri)
+ {
+ if (foe->is_habitable(*ri) && mon->mon_see_cell(*ri))
+ possibilities.push_back(*ri);
+ }
+
+ if (!possibilities.empty())
+ mon->target = possibilities[random2(possibilities.size())];
+}
+
//---------------------------------------------------------------
//
// handle_behaviour
@@ -1202,6 +1219,24 @@ void handle_behaviour(monsters *mon)
// Foe gone out of LOS?
if (!proxFoe)
{
+ // Maybe the foe is just invisible.
+ if (mon->target.origin() && afoe && mon->near_foe())
+ {
+ _guess_invis_foe_pos(mon);
+ if (mon->target.origin())
+ {
+ // Having a seeking mon with a foe who's target is
+ // (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->travel_target == MTRAV_SIREN)
mon->travel_target = MTRAV_NONE;