diff --git a/src/pather.py b/src/pather.py index 6975e3b..43dcfb0 100644 --- a/src/pather.py +++ b/src/pather.py @@ -674,12 +674,24 @@ class Pather: # we either want to tele charge but have no charges or don't wanna use the charge falling back to default pre_move handling char.pre_move() + # Auto-recovery sweep directions (absolute coords, char-centred). When a node + # template can't be found within `timeout`, the char is likely mis-positioned + # (e.g. returned from a boss to a town corner). Rather than fail immediately, + # walk this expanding pattern — each move brings new screen area into view so + # find_abs_node_pos can re-acquire the node. Only used for travel pathing + # (timeout > 3.1); boss approaches keep their fast fail so combat isn't stalled. + _recovery_sweep = [ + (-300, 0), (300, 0), (0, -250), (0, 250), + (-350, -250), (350, 250), (350, -250), (-350, 250), + (-200, 0), (0, -300), (200, 0), (0, 300), + ] last_direction = None for i, node_idx in enumerate(path): continue_to_next_node = False last_move = time.time() did_force_move = False teleport_count = 0 + recovery_idx = 0 while not continue_to_next_node: img = grab(force_new=True) # Handle timeout @@ -689,6 +701,19 @@ class Pather: Logger.debug("Opened wp, closing it again") keyboard.send("esc") last_move = time.time() + elif timeout > 3.1 and recovery_idx < len(_recovery_sweep): + # Auto-recover: actively explore to bring the node back on screen + # instead of giving up. Each step re-scans in the main loop below. + rec_abs = get_closest_non_hud_pixel(pos=_recovery_sweep[recovery_idx], pos_type="abs") + Logger.warning( + f"Pather: node {node_idx} lost — auto-recovery sweep " + f"{recovery_idx + 1}/{len(_recovery_sweep)} towards {rec_abs}" + ) + x_m, y_m = convert_abs_to_monitor(rec_abs) + char.move((x_m, y_m), force_move=True) + recovery_idx += 1 + did_force_move = True + last_move = time.time() else: # This is a bit hacky, but for moving into a boss location we set timeout usually quite low # because of all the spells and monsters it often can not determine the final template @@ -696,7 +721,7 @@ class Pather: if timeout > 3.1: if Config().general["info_screenshots"]: safe_imwrite("./log/screenshots/info/info_pather_got_stuck_" + time.strftime("%Y%m%d_%H%M%S") + ".png", img) - Logger.error("Got stuck exit pather") + Logger.error(f"Got stuck exit pather (node {node_idx}, recovery sweep exhausted)") return False # Sometimes we get stuck at rocks and stuff, after a few seconds force a move into the last known direction