If the patrol point gets out of sight, zombies don't even attempt to get back. Instead they become confused (not literally, though) and reset their patrol point to 0 (if hostile, thus stop patrolling) or to their current position (to continue "waiting" if friendly). Also, while patrolling, if they reach their target there's a 50% chance of not moving this turn, and 50% the next turn, etc. Especially the latter needs testing. If it looks too stupid even for zombies I'll take it out again.
These changes should also help to make patrolling a bit more efficient because for stupid monsters we have:
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5335 c06c8d41-db1a-0410-9941-cceddc491573
22ORIULMB2NHLFZNJFK2AF275Q6XBKOBE4ZRMOADY64VK5FAUUSQC K2RBO245UPBDAGMUUMB5EPUNKBDMQ2FM4HLCTTF6Y7ILWW2XVSDQC UCEAWJ4I6AEFR64SSUFQSX6Q62JGLMJQ5BOO5MQSV3XIE7KAS6CQC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC W6IY6LF3MREPXC23AAKA2BJNUCJYCSOWY55DIWJWFLUEE2Y3LGNQC EOMCPVNQLX3IMLC46EAO67DPBH5KEG2FQTPBLGU62HIRWA3UQ7XQC P5TRGRH7XMQSPCZKM5IEEO34TY6WMLGHHX7BU6Y453JFRXLUR2VQC LTX72QGIPNUGWQN5ULPOMFCOPZTK7472DQY4AYX5WM3WHSUVXI5QC H7AOW4T4Q7AKOXREMK6ZXN3GK6A4I24ICE6VTROMJ5Y3LX47TSDAC PMCHUVWMCDXOWGXB4SWMBXFGHJYZG7KZ34SE33HFUGHPQYP3LYEAC BMHUBADDGIOZRVN4P3O5QKIDUYD4RFWBS7MP5X6LZWAYHUBRVD2QC G5WLU3B4MR3ZDJLGR6OHNIMLZXGQS2EWBJ5YYY5J2GWM6DTD44BAC 6TEISZD7HYSSL24EOKIBNURU66KGSQX7B7SNAHBP4DQSAOTGH2MQC void monster_los::set_monster(monsters *mon){mons = mon;if (gridx != mons->x)gridx = mons->x;if (gridy != mons->y)gridy = mons->y;}void monster_los::set_los_centre(int x, int y){if (!in_bounds(x, y))return;gridx = x;gridy = y;}void monster_los::set_los_range(int r){ASSERT (r >= 1 && r <= LOS_RADIUS);range = r;}
}void monster_los::set_monster(monsters *mon){mons = mon;if (gridx != mons->x)gridx = mons->x;if (gridy != mons->y)gridy = mons->y;}void monster_los::set_los_centre(int x, int y){if (!in_bounds(x, y))return;gridx = x;gridy = y;
int patrol_x = mon->patrol_point.x;int patrol_y = mon->patrol_point.y;
const int intel = mons_intel(mon->type);// Zombies will occasionally just stand around.// This does not mean that they don't move every second turn. Rather,// once they reach their chosen target, there's a 50% chance they'll// just remain there until next turn when this function is called// again.if (intel == I_PLANT && coinflip())return (true);const int patrol_x = mon->patrol_point.x;const int patrol_y = mon->patrol_point.y;// If there's no chance we'll find the patrol point, quit right away.if (grid_distance(mon->x, mon->y, patrol_x, patrol_y) > 2*LOS_RADIUS)return (false);const bool patrol_seen = mon->mon_see_grid(patrol_x, patrol_y,habitat2grid(mons_habitat(mon)));
monster_los lm;lm.set_monster(mon);lm.fill_los_field();bool patrol_seen = lm.in_sight(patrol_x, patrol_y);
if (intel == I_PLANT && !patrol_seen){// Really stupid monsters won't even try to get back into the// patrol zone.return (false);}// While the patrol point is in easy reach, monsters of insect/plant// intelligence will only use a range of 5 (distance from the patrol point).// Otherwise, try to get back using the full LOS.const int rad = (intel >= I_ANIMAL || !patrol_seen)? LOS_RADIUS : 5;const bool is_smart = (intel >= I_NORMAL);
// Note: This can take us into a position where the target// cannot be easily reached (e.g. blocked by a wall) and the// patrol point is out of sight, too. Such a case will be// handled below, though it might take a while until a monster// gets out of a deadlock.
// Only smart monsters will even attempt to move out of the// patrol area.// NOTE: Either of these can take us into a position where the// target cannot be easily reached (e.g. blocked by a wall)// and the patrol point is out of sight, too. Such a case// will be handled below, though it might take a while until// a monster gets out of a deadlock. (5% chance per turn.)
if (one_chance_in(++count_grids))
if (intel == I_PLANT && pos_x == patrol_x && pos_y == patrol_y){// Slightly greater chance to simply head for the centre.count_grids += 3;if (random2(count_grids) < 3)set_target = true;}else if (one_chance_in(++count_grids))set_target = true;if (set_target)
// it's time to head back.mon->target_x = mon->patrol_point.x;mon->target_y = mon->patrol_point.y;
// do one of the following:// * set current position as new patrol point// * forget about patrolling// * head back to patrol pointif (mons_intel(mon->type) == I_PLANT){// Really stupid monsters forget where they're// supposed to be.if (mons_friendly(mon)){// Your ally was told to wait, and wait it will!// (Though possibly not where you told it to.)mon->patrol_point = coord_def(mon->x, mon->y);}else{// Stop patrolling.mon->patrol_point = coord_def(0, 0);}}else{// It's time to head back!// Ideally, smart monsters should be able to use// pathfinding to find the way back, and animals// could decide to stop patrolling if the path// was too long.mon->target_x = mon->patrol_point.x;mon->target_y = mon->patrol_point.y;}