StarRailCopilot/tasks/rogue/blessing/bonus.py

106 lines
3.8 KiB
Python
Raw Permalink Normal View History

import re
import numpy as np
from module.base.timer import Timer
from module.logger import logger
from module.ocr.ocr import Ocr, OcrResultButton
from tasks.rogue.assets.assets_rogue_blessing import OCR_ROGUE_BUFF
from tasks.rogue.assets.assets_rogue_bonus import BONUS_BOTTOM_WHITE_BAR, BONUS_CONFIRM
2023-12-18 16:53:33 +00:00
from tasks.rogue.blessing.selector import RogueSelector
from tasks.rogue.blessing.utils import is_card_selected
2023-10-05 10:52:55 +00:00
from tasks.rogue.keywords import RogueBonus
class RogueBonusOcr(Ocr):
def after_process(self, result):
result = super().after_process(result)
if self.lang == 'cn':
replace_pattern_dict = {
"[宇宝][宙审]": "宇宙",
}
for pat, replace in replace_pattern_dict.items():
result = re.sub(pat, replace, result)
return result
class RogueBonusSelector(RogueSelector):
def _wait_bonus_page_loaded(self, timer=Timer(0.3, count=1), timeout=Timer(5, count=10)):
timer.reset()
timeout.reset()
while 1:
self.main.device.screenshot()
if timeout.reached():
logger.warning('Wait bonus page loaded timeout')
break
if self.main.appear(BONUS_BOTTOM_WHITE_BAR):
if timer.reached():
logger.info('Bonus page stabled')
break
else:
timer.reset()
def recognition(self):
self._wait_bonus_page_loaded()
ocr = RogueBonusOcr(OCR_ROGUE_BUFF)
results = ocr.matched_ocr(self.main.device.image, [RogueBonus])
expected_count = 3
if expected_count != len(results):
logger.warning(f"The OCR result does not match the bonus count. "
f"Expect {expected_count}, but recognized {len(results)} only.")
self.ocr_results = results
return results
def ui_select(self, target: OcrResultButton | None, skip_first_screenshot=True):
interval = Timer(1)
# start -> select
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.main.device.screenshot()
if is_card_selected(self.main, target, confirm_button=BONUS_CONFIRM):
break
if target is not None and interval.reached():
self.main.device.click(target)
interval.reset()
skip_first_screenshot = True
# Avoid double-clicking
interval = Timer(3, count=6)
# select -> confirm
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.main.device.screenshot()
if self.main.is_in_main():
logger.info("Main Page Checked")
break
if self.main.is_page_choose_curio():
logger.info("Choose curio page checked")
break
if self.main.is_page_choose_blessing():
logger.info("Choose blessing page checked")
break
if interval.reached():
self.main.device.click(BONUS_CONFIRM)
interval.reset()
def recognize_and_select(self):
self.recognition()
if not self.ocr_results:
self.ui_select(None)
options = {result.matched_keyword.en: result for result in self.ocr_results}
2023-10-18 15:36:31 +00:00
if self.main.config.RogueWorld_Bonus not in options.keys():
logger.warning(f"Can not find option: {self.main.config.RogueWorld_Bonus}, randomly choose one")
2023-12-27 06:29:13 +00:00
target = np.random.choice(list(options.values()))
else:
2023-10-18 15:36:31 +00:00
target = options[self.main.config.RogueWorld_Bonus]
logger.info(f"Choose bonus: {target}")
self.ui_select(target)