From 45fa19fe2c8abb4a59c0d24d8e7b06c05c200f64 Mon Sep 17 00:00:00 2001 From: Matthew Cline Date: Sun, 15 Nov 2009 02:43:22 -0800 Subject: handle_behaviour(): fix infinite loop. --- crawl-ref/source/mon-behv.cc | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'crawl-ref/source/mon-behv.cc') 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(); } } -- cgit v1.2.3-54-g00ecf