feat: grid hover sweep fallback when NPC body templates fail
Body templates went stale with the June 2026 patch (Malah, Cain, Tyrael, Larzuk, Qual-Kehk all undetectable), but name tags on hover score 0.9+ reliably. When the body-template hunt times out, sweep a coarse hover grid over the NPC ROI and click wherever the name tag appears. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -423,6 +423,42 @@ def open_npc_menu(npc_key: Npc) -> bool:
|
||||
else:
|
||||
Logger.warning(f"NPC {npc_key} - clicked but no action buttons found")
|
||||
wait(0.1) # Brief pause before next frame grab if no matches were valid
|
||||
# FINAL FALLBACK: body templates can go stale after a game patch (June 2026
|
||||
# patch changed several NPC appearances), but the name-tag-on-hover check is
|
||||
# rendering-stable — a real hover scores 0.9+. Sweep a coarse hover grid over
|
||||
# the NPC's ROI and click wherever the name tag appears.
|
||||
from screen import convert_screen_to_monitor
|
||||
Logger.debug(f"NPC {npc_key} - body-template hunt timed out, starting grid hover sweep")
|
||||
_close_open_panels()
|
||||
sweep_roi = npcs[npc_key]["roi"] if "roi" in npcs[npc_key] else roi_npc_search
|
||||
sx0, sy0, sw, sh = sweep_roi
|
||||
SWEEP_TAG_THRESHOLD = 0.4
|
||||
for sy in range(int(sy0 + 30), int(sy0 + sh - 15), 70):
|
||||
for sx in range(int(sx0 + 30), int(sx0 + sw - 15), 60):
|
||||
pos_m = convert_screen_to_monitor((sx, sy))
|
||||
mouse.move(*pos_m, randomize=2, delay_factor=[0.05, 0.1])
|
||||
wait(0.10, 0.14)
|
||||
hov = grab()
|
||||
tag_roi = [max(0, sx - 120), max(0, sy - 160), 240, 140]
|
||||
_, f_w = color_filter(hov, Config().colors["white"])
|
||||
res_w = template_finder.search(npcs[npc_key]["name_tag_white"], f_w, SWEEP_TAG_THRESHOLD, roi=tag_roi)
|
||||
if not res_w.valid:
|
||||
res_w = template_finder.search(npcs[npc_key]["name_tag_white"], hov, SWEEP_TAG_THRESHOLD, roi=tag_roi, use_grayscale=True)
|
||||
if res_w.valid:
|
||||
Logger.info(f"NPC {npc_key} - grid sweep found name tag at ({sx}, {sy}) (score {res_w.score:.3f}), clicking")
|
||||
mouse.click(button="left")
|
||||
wait(0.5, 0.7)
|
||||
if _wait_action_btns(npc_key, timeout=2.5):
|
||||
Logger.info(f"NPC {npc_key} - dialogue open via grid sweep")
|
||||
return True
|
||||
# one retry: first click sometimes just turns the NPC
|
||||
mouse.move(*pos_m, randomize=2, delay_factor=[0.1, 0.15])
|
||||
wait(0.15, 0.2)
|
||||
mouse.click(button="left")
|
||||
wait(0.5, 0.7)
|
||||
if _wait_action_btns(npc_key, timeout=2.5):
|
||||
Logger.info(f"NPC {npc_key} - dialogue open via grid sweep (retry)")
|
||||
return True
|
||||
Logger.error(f"open_npc_menu: timed out finding {npc_key} — saving screenshot")
|
||||
if Config().general["info_screenshots"]:
|
||||
safe_imwrite("./log/screenshots/info/info_npc_menu_timeout_" + time.strftime("%Y%m%d_%H%M%S") + ".png", grab())
|
||||
|
||||
Reference in New Issue
Block a user