summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/monstuff.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/monstuff.cc')
-rw-r--r--crawl-ref/source/monstuff.cc86
1 files changed, 61 insertions, 25 deletions
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 1d046afcf8..627f0d68ef 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -2609,11 +2609,11 @@ static void _handle_behaviour(monsters *mon)
if (mon->foe == MHITYOU && travelling
&& mon->travel_target == MTRAV_PLAYER)
{
+ // We've got a target, so we'll continue on our way.
#ifdef DEBUG_PATHFIND
mpr("Player out of LoS... start wandering.");
#endif
new_beh = BEH_WANDER;
- // We've got a target, so we'll continue on our way.
break;
}
@@ -2699,8 +2699,29 @@ static void _handle_behaviour(monsters *mon)
// Monster can see foe: continue 'tracking'
// by updating target x,y.
- if (mon->foe == MHITYOU && proxPlayer)
+ if (mon->foe == MHITYOU)
{
+ // Just because we can *see* the player, that doesn't mean
+ // we can actually get there. To find about that, we first
+ // check for transparent walls. If there are transparent
+ // walls in the way we'll need pathfinding, no matter what.
+ // (Though monsters with a los attack don't need to get any
+ // closer to hurt the player.)
+ // If no walls are detected, there could still be a river
+ // or a pool of lava in the way. So we check whether there
+ // is water or lava in LoS (boolean) and if so, try to find
+ // a way around it. It's possible that the player can see
+ // lava but it actually has no influence on the monster's
+ // movement (because it's lying in the opposite direction)
+ // but if so, we'll find that out during path finding.
+ // In another attempt of optimization, don't bother with
+ // path finding if the monster in question has no trouble
+ // travelling through water or flying across lava.
+ // Also, if no path is found (too far away, perhaps) set a
+ // flag, so we don't directly calculate the whole thing again
+ // next turn, and even extend that flag to neighbouring
+ // monsters of similar movement restrictions.
+
bool potentially_blocking = trans_wall_block;
// Smart monsters that can fire through walls won't use
@@ -2760,17 +2781,11 @@ static void _handle_behaviour(monsters *mon)
// If we're already on our way, do nothing.
if (travelling && mon->travel_target == MTRAV_PLAYER)
{
-#ifdef DEBUG_PATHFIND
- mpr("Already travelling...");
-#endif
int len = mon->travel_path.size();
coord_def targ = mon->travel_path[len - 1];
if (grid_see_grid(targ.x, targ.y, you.x_pos, you.y_pos,
can_move))
{
-#ifdef DEBUG_PATHFIND
- mpr("Target still valid?");
-#endif
// Current target still valid?
if (mon->x == mon->travel_path[0].x
&& mon->y == mon->travel_path[0].y)
@@ -2885,6 +2900,9 @@ static void _handle_behaviour(monsters *mon)
}
}
}
+ // Whew. If we arrived here, path finding didn't yield anything
+ // (or wasn't even attempted) and we need to set our target
+ // the traditional way.
// Sometimes, your friends will wander a bit.
if (isFriendly && one_chance_in(8))
@@ -2902,6 +2920,7 @@ static void _handle_behaviour(monsters *mon)
}
else
{
+ // We have a foe but it's not the player.
mon->target_x = menv[mon->foe].x;
mon->target_y = menv[mon->foe].y;
}
@@ -2984,6 +3003,9 @@ static void _handle_behaviour(monsters *mon)
// XXX: Note that this might still not be the best
// thing to do since another path might be even
// *closer* to our actual target now.
+ // Not by much, though, since the original path was
+ // optimal (A*) and the distance between the waypoints
+ // is rather small.
int erase = -1; // Erase how many waypoints?
for (unsigned int i = mon->travel_path.size() - 1;
@@ -3018,8 +3040,10 @@ static void _handle_behaviour(monsters *mon)
{
// We can't reach our old path from our current
// position, so calculate a new path instead.
-/*
+
monster_pathfind mp;
+ // The last coordinate in the path vector is our
+ // destination.
int len = mon->travel_path.size();
if (mp.start_pathfind(mon, mon->travel_path[len-1]))
{
@@ -3028,6 +3052,10 @@ static void _handle_behaviour(monsters *mon)
{
mon->target_x = mon->travel_path[0].x;
mon->target_y = mon->travel_path[0].y;
+#ifdef DEBUG_PATHFIND
+ mprf("Next waypoint: (%d, %d)",
+ mon->target_x, mon->target_y);
+#endif
}
else
{
@@ -3037,22 +3065,20 @@ static void _handle_behaviour(monsters *mon)
}
else
{
-*/
// Or just forget about the whole thing.
mon->travel_path.clear();
mon->travel_target = MTRAV_NONE;
need_target = true;
-// }
+ }
}
}
- else
- {
-#ifdef DEBUG_PATHFIND
- mpr("All clear. Continue travelling.");
-#endif
- }
+
+ // Else, we can see the next waypoint and are making good
+ // progress. Carry on, then!
}
+ // If we still need a target because we're not travelling
+ // (any more), check for patrol routes instead.
if (need_target && patrolling)
{
need_target = false;
@@ -3086,10 +3112,20 @@ static void _handle_behaviour(monsters *mon)
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.
+ // Other than for tracking the player, there's
+ // currently no distinction between smart and
+ // stupid monsters when it comes to travelling
+ // back to the patrol point. This is in part due
+ // to the flavourness of bees finding their way
+ // back to the Hive (patrolling should really be
+ // restricted to cases like this), and for the
+ // other part it's not that important because
+ // we calculate the path once and then follow it
+ // home, and the player won't ever see the
+ // orderly fashion the bees will trudge along.
+ // What he will see is them swarming back to the
+ // Hive entrance after some time, and that is what
+ // matters.
monster_pathfind mp;
if (mp.start_pathfind(mon, mon->patrol_point))
{
@@ -3102,6 +3138,9 @@ static void _handle_behaviour(monsters *mon)
}
else
{
+ // We're so close we don't even need
+ // a path. (Shouldn't happen as that
+ // should have been found above.)
mon->target_x = mon->patrol_point.x;
mon->target_y = mon->patrol_point.y;
}
@@ -3128,10 +3167,7 @@ static void _handle_behaviour(monsters *mon)
if (need_target)
{
-#ifdef DEBUG_PATHFIND
- if (!testbits( mon->flags, MF_BATTY ))
- mprf("Monster is wandering randomly.");
-#endif
+ // The monster is travelling randomly.
mon->target_x = 10 + random2(GXM - 10);
mon->target_y = 10 + random2(GYM - 10);
}