summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/mon-behv.cc
diff options
context:
space:
mode:
authorMatthew Cline <zelgadis@sourceforge.net>2009-11-15 01:17:22 -0800
committerMatthew Cline <zelgadis@sourceforge.net>2009-11-15 01:20:33 -0800
commit3e4c55a7f265baf527c126a86dd80b9eca829919 (patch)
treefa8255c348dda08d83cb7d797e123c20e1bbf471 /crawl-ref/source/mon-behv.cc
parent421babd7402fc7f030768062ad66227d8bd220d0 (diff)
downloadcrawl-ref-3e4c55a7f265baf527c126a86dd80b9eca829919.tar.gz
crawl-ref-3e4c55a7f265baf527c126a86dd80b9eca829919.zip
handle_behaviour(): guess pos of invis foes
If a monster didn't know the position of an unseen but nearby foe, then casting a spell against the foe would cause an assert. So now the monster tries to guess the position of the foe: a random square within radius 3 of the foe, or radius 2 if the monster can sense invisible. This algorithm no doubt needs improvement.
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;