@@ -630,22 +630,31 @@ CaveBot.registerAction("goto", "#46e6a6", function(value, retries, prev)
630630 and type (WaypointNavigator .getLookaheadTarget ) == " function" then
631631 local lookahead = WaypointNavigator .getLookaheadTarget (playerPos )
632632 if lookahead and lookahead .z == playerPos .z then
633- -- Reject degenerate lookahead: at route wrap-around the navigator can return
634- -- the last WP on the route (e.g. the start of the loop) which is already
635- -- behind the player, causing walkTo to return "arrived" immediately and
636- -- the bot to spin forever without actually walking to destPos.
637633 local lhDist = math.max (
638634 math.abs (lookahead .x - playerPos .x ),
639635 math.abs (lookahead .y - playerPos .y )
640636 )
641- -- Reject floor-change tile as lookahead when the current WP is not a stair.
642- -- walkTo with allowFloorChange=false redirects away from stair tiles to an
643- -- adjacent tile, causing the bot to oscillate near the stair indefinitely
644- -- instead of advancing to the stair WP and using it properly.
645- local lookaheadIsStair = (FloorItems and FloorItems .isFloorChangeTile )
646- and FloorItems .isFloorChangeTile (lookahead )
647- if lhDist >= 3 and not lookaheadIsStair then
648- walkTarget = lookahead
637+ if lhDist >= 3 then
638+ -- Gate 1: reject floor-change tiles (walkTo redirects to adjacent tile
639+ -- with allowFloorChange=false, causing oscillation near the stair).
640+ local lookaheadIsStair = (FloorItems and FloorItems .isFloorChangeTile )
641+ and FloorItems .isFloorChangeTile (lookahead )
642+ -- Gate 2: reject unreachable targets behind walls. The lookahead is a
643+ -- geometric interpolation that ignores map topology; validate that A*
644+ -- can actually find a path before committing. Uses ignoreCreatures
645+ -- (creatures are transient) and precision=1 (don't need exact tile).
646+ local lookaheadReachable = true
647+ if not lookaheadIsStair then
648+ local lhPath = findPath (playerPos , lookahead , maxDist , {
649+ ignoreNonPathable = true ,
650+ ignoreCreatures = true ,
651+ precision = 1 ,
652+ })
653+ lookaheadReachable = lhPath and # lhPath > 0
654+ end
655+ if not lookaheadIsStair and lookaheadReachable then
656+ walkTarget = lookahead
657+ end
649658 end
650659 end
651660 end
0 commit comments