Bug 31 fixed the keypress that opened CHRONICLE but explicitly left the real
gap open: the panel guard matches only LeftPanel / RightPanel, and a centred
panel matches neither. Nothing closed it, and a centred panel blanks EVERY
later template search.
Recurred 2026-08-28 with the merc key never pressed at all
(resurrect_merc | skip | merc alive), so something else opened it and it simply
stayed. The error screenshot shows Chronicle filling the screen while the bot
hunted A5_RED_PORTAL for 66s:
Traverse from a5_larzuk to a5_nihlathak_portal
Wanted to select A5_RED_PORTAL, but could not find it
random guess towards (96, -115)
Wanted to select A5_RED_PORTAL, but could not find it
Why the existing guard missed it, measured on that frame: the Chronicle's close
button scores 1.000 against CLOSE_PANEL_2 at (952, 56). That x IS inside
right_panel_header (830,0,455,56) — but the ROI is 56px tall and the button's
centre sits exactly at y=56, so the match falls outside. Both header ROIs
scored 0.409 and 0.373.
Adds a center_panel_header ROI (400,0,620,92) and a CenterPanel ScreenObject,
and escapes it WITHOUT counting toward a chicken — a centred panel is
self-inflicted UI state like the waypoint panel, and chickening on it throws
away a healthy game. Bounded by the same _MAX_WP_PANEL_ESCAPES so one that
genuinely will not close still falls through.
Verified on the failure frame: CenterPanel True, LeftPanel False, RightPanel
False.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
47 lines
1.9 KiB
Python
47 lines
1.9 KiB
Python
"""A centred panel must be detected and closed.
|
|
|
|
Bug 31 fixed the merc-panel keypress that opened CHRONICLE, but noted the real
|
|
gap was never closed: the health manager's guard matches only LeftPanel /
|
|
RightPanel, and a centred panel matches neither. Nothing closes it, and a
|
|
centred panel blanks EVERY later template search.
|
|
|
|
Measured 2026-08-28: Chronicle open, A5_RED_PORTAL unfindable, 66s
|
|
click_red_portal failure. The Chronicle's close button scores 1.000 against
|
|
CLOSE_PANEL_2 at (952, 56) — inside right_panel_header's x-range but exactly at
|
|
its 56px height boundary, so the match centre falls outside the ROI.
|
|
"""
|
|
import inspect
|
|
|
|
|
|
def test_center_panel_screenobject_exists():
|
|
from ui_manager import ScreenObjects
|
|
|
|
assert hasattr(ScreenObjects, "CenterPanel"), "no detection for a centred panel"
|
|
|
|
|
|
def test_center_panel_roi_covers_the_chronicle_close_button():
|
|
from config import Config
|
|
|
|
x, y, w, h = Config().ui_roi["center_panel_header"]
|
|
cx, cy = 952, 56 # measured Chronicle X position
|
|
assert x <= cx <= x + w, "ROI does not span the Chronicle close button in x"
|
|
assert y <= cy <= y + h, (
|
|
"ROI does not span it in y — this is exactly how right_panel_header "
|
|
"missed it, its 56px height ending at the button's centre"
|
|
)
|
|
|
|
|
|
def test_guard_checks_center_panel_before_chickening():
|
|
"""It must be escaped, not counted as a threat.
|
|
|
|
A centred panel is self-inflicted UI state, like the waypoint panel.
|
|
Chickening on it throws away a healthy game.
|
|
"""
|
|
from health_manager import HealthManager
|
|
|
|
src = inspect.getsource(HealthManager)
|
|
assert "ScreenObjects.CenterPanel" in src, "guard never checks for a centred panel"
|
|
center_at = src.index("ScreenObjects.CenterPanel")
|
|
chicken_at = src.index("Chickening to be safe")
|
|
assert center_at < chicken_at, "centred-panel escape must come before the chicken path"
|