Fix template and OCR dynamic scaling to use Unity Canvas Scaler height and refine MAIN_MENU detection

This commit is contained in:
VolandSZ
2026-09-08 22:52:19 +03:00
parent 9b71e20e8f
commit 58c62a405d
2 changed files with 18 additions and 6 deletions

View File

@ -101,9 +101,16 @@ class DirtyLeagueBot:
self.scaled_templates[name_without_ext] = img
logging.info(f"Loaded {len(self.base_templates)} base template(s) from '{self.assets_dir}'")
def get_frame_scale(self, frame: np.ndarray) -> float:
"""
Calculates UI scaling factor relative to base design height.
Unity Canvas Scaler in DirtyLeague scales UI proportionally to screen height.
"""
return frame.shape[0] / float(self.BASE_DESIGN_HEIGHT)
def get_scaled_template(self, template_name: str, scale: float) -> Optional[np.ndarray]:
"""
Retrieves template scaled for the given resolution scale factor (fw / BASE_DESIGN_WIDTH).
Retrieves template scaled for the given resolution scale factor (fh / BASE_DESIGN_HEIGHT).
Caches scaled results so resizing only happens on window resolution changes.
"""
if template_name not in self.base_templates:
@ -137,7 +144,7 @@ class DirtyLeagueBot:
Returns client center coordinates (center_x, center_y) if matched, else None.
"""
fh, fw = frame.shape[:2]
scale = fw / float(self.BASE_DESIGN_WIDTH)
scale = self.get_frame_scale(frame)
tpl = self.get_scaled_template(template_name, scale)
if tpl is None:
return None
@ -177,7 +184,7 @@ class DirtyLeagueBot:
x2 = max(0, min(fw, int(rx2 * fw)))
y2 = max(0, min(fh, int(ry2 * fh)))
scale = fw / float(self.BASE_DESIGN_WIDTH)
scale = self.get_frame_scale(frame)
tpl = self.get_scaled_template(template_name, scale)
if tpl is None:
return None
@ -284,7 +291,7 @@ class DirtyLeagueBot:
return GameState.CHEST_OPEN_SCREEN
if self.find_template(frame, "btn_fight") or self.find_template(frame, "btn_play"):
return GameState.TOWER_LOBBY
if self.find_template(frame, "anchor_main_menu") or self.find_template(frame, "btn_mode_tower"):
if self.find_template(frame, "btn_mode_tower"):
return GameState.MAIN_MENU
return GameState.UNKNOWN
@ -301,7 +308,7 @@ class DirtyLeagueBot:
rel_w = 0.0547
rel_h = 0.0341
scale = fw / float(self.BASE_DESIGN_WIDTH)
scale = self.get_frame_scale(frame)
tpl_open = self.get_scaled_template("status_open", scale)
tpl_vacant = self.get_scaled_template("status_vacant", scale)
@ -327,6 +334,11 @@ class DirtyLeagueBot:
if max_v_vacant >= 0.75:
status = "VACANT"
if status != "OPEN" and status != "VACANT":
txt = ocr_reader.read_text(status_crop).lower()
if "vacan" in txt:
status = "VACANT"
click_cx = sx + sw // 2
click_cy = sy - int(0.035 * fh)
results[slot_id] = {

View File

@ -96,7 +96,7 @@ class OcrReader:
if fh < 300 or fw < 500:
return None
scale = fw / 3840.0
scale = fh / 2050.0
# Relative ROI for crown digit badge
y1, y2 = int(fh * 0.6780), int(fh * 0.7146)