mirror of
https://github.com/LmeSzinc/StarRailCopilot.git
synced 2024-11-22 00:35:34 +00:00
Upd: use combination instead of inheritance in RogueSelector
This commit is contained in:
parent
03caaa2855
commit
5a06402d43
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
25
tasks/rogue/assets/assets_rogue_bonus.py
Normal file
25
tasks/rogue/assets/assets_rogue_bonus.py
Normal file
@ -0,0 +1,25 @@
|
||||
from module.base.button import Button, ButtonWrapper
|
||||
|
||||
# This file was auto-generated, do not modify it manually. To generate:
|
||||
# ``` python -m dev_tools.button_extract ```
|
||||
|
||||
BONUS_BOTTOM_WHITE_BAR = ButtonWrapper(
|
||||
name='BONUS_BOTTOM_WHITE_BAR',
|
||||
share=Button(
|
||||
file='./assets/share/rogue/bonus/BONUS_BOTTOM_WHITE_BAR.png',
|
||||
area=(182, 568, 1098, 590),
|
||||
search=(162, 548, 1118, 610),
|
||||
color=(221, 221, 222),
|
||||
button=(182, 568, 1098, 590),
|
||||
),
|
||||
)
|
||||
BONUS_CONFIRM = ButtonWrapper(
|
||||
name='BONUS_CONFIRM',
|
||||
share=Button(
|
||||
file='./assets/share/rogue/bonus/BONUS_CONFIRM.png',
|
||||
area=(504, 629, 620, 677),
|
||||
search=(484, 609, 640, 697),
|
||||
color=(222, 224, 224),
|
||||
button=(504, 629, 620, 677),
|
||||
),
|
||||
)
|
@ -3,26 +3,6 @@ from module.base.button import Button, ButtonWrapper
|
||||
# This file was auto-generated, do not modify it manually. To generate:
|
||||
# ``` python -m dev_tools.button_extract ```
|
||||
|
||||
BONUS_BOTTOM_WHITE_BAR = ButtonWrapper(
|
||||
name='BONUS_BOTTOM_WHITE_BAR',
|
||||
share=Button(
|
||||
file='./assets/share/rogue/ui/BONUS_BOTTOM_WHITE_BAR.png',
|
||||
area=(182, 568, 1098, 590),
|
||||
search=(162, 548, 1118, 610),
|
||||
color=(221, 221, 222),
|
||||
button=(182, 568, 1098, 590),
|
||||
),
|
||||
)
|
||||
BONUS_CONFIRM = ButtonWrapper(
|
||||
name='BONUS_CONFIRM',
|
||||
share=Button(
|
||||
file='./assets/share/rogue/ui/BONUS_CONFIRM.png',
|
||||
area=(504, 629, 620, 677),
|
||||
search=(484, 609, 640, 697),
|
||||
color=(222, 224, 224),
|
||||
button=(504, 629, 620, 677),
|
||||
),
|
||||
)
|
||||
CHECK_BLESSING = ButtonWrapper(
|
||||
name='CHECK_BLESSING',
|
||||
share=Button(
|
||||
|
@ -12,7 +12,6 @@ from tasks.rogue.assets.assets_rogue_ui import CONFIRM
|
||||
from tasks.rogue.keywords import *
|
||||
from tasks.rogue.preset import *
|
||||
from tasks.rogue.selector import RogueSelector
|
||||
from tasks.rogue.ui import RogueUI
|
||||
from tasks.rogue.utils import get_regex_from_keyword_name, parse_name, is_card_selected
|
||||
|
||||
# normal blessing
|
||||
@ -78,7 +77,7 @@ class RogueBuffOcr(Ocr):
|
||||
return result
|
||||
|
||||
|
||||
class RogueBlessingSelector(RogueUI, RogueSelector):
|
||||
class RogueBlessingSelector(RogueSelector):
|
||||
"""
|
||||
Usage:
|
||||
self = RogueBlessingSelector('alas')
|
||||
@ -90,9 +89,9 @@ class RogueBlessingSelector(RogueUI, RogueSelector):
|
||||
"""
|
||||
Returns: The number of blessing
|
||||
"""
|
||||
if not self.image_color_count(BOTTOM_WHITE_BAR.area, color=(255, 255, 255), count=5000):
|
||||
if not self.main.image_color_count(BOTTOM_WHITE_BAR.area, color=(255, 255, 255), count=5000):
|
||||
return 0
|
||||
color = get_color(self.device.image, BOTTOM_WHITE_BAR.area)
|
||||
color = get_color(self.main.device.image, BOTTOM_WHITE_BAR.area)
|
||||
mean = np.mean(color)
|
||||
return int(mean // 60) # the magic number that maps blessing num with mean_color
|
||||
|
||||
@ -100,7 +99,7 @@ class RogueBlessingSelector(RogueUI, RogueSelector):
|
||||
self.ocr_results = []
|
||||
self._wait_until_blessing_loaded()
|
||||
ocr = RogueBuffOcr(OCR_ROGUE_BUFF)
|
||||
results = ocr.matched_ocr(self.device.image, [RogueBlessing, RogueResonance])
|
||||
results = ocr.matched_ocr(self.main.device.image, [RogueBlessing, RogueResonance])
|
||||
blessing_count = self.get_blessing_count()
|
||||
if blessing_count != len(results):
|
||||
logger.warning(f"The OCR result does not match the blessing count. "
|
||||
@ -121,8 +120,9 @@ class RogueBlessingSelector(RogueUI, RogueSelector):
|
||||
Case 2: choose curio
|
||||
Case 3: another choose blessings, but no blessing is selected when the new selection page loaded
|
||||
"""
|
||||
return (self.is_in_main() or self.is_page_choose_curio()
|
||||
or (self.is_page_choose_blessing() and not is_card_selected(self, target, confirm_button=CONFIRM)))
|
||||
return (self.main.is_in_main() or self.main.is_page_choose_curio()
|
||||
or (self.main.is_page_choose_blessing() and
|
||||
not is_card_selected(self.main, target, confirm_button=CONFIRM)))
|
||||
|
||||
interval = Timer(1)
|
||||
enforce = False
|
||||
@ -135,9 +135,9 @@ class RogueBlessingSelector(RogueUI, RogueSelector):
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
self.main.device.screenshot()
|
||||
|
||||
if is_card_selected(self, target, confirm_button=CONFIRM):
|
||||
if is_card_selected(self.main, target, confirm_button=CONFIRM):
|
||||
if enforce:
|
||||
logger.info("Buff selected (enforce)")
|
||||
else:
|
||||
@ -145,9 +145,9 @@ class RogueBlessingSelector(RogueUI, RogueSelector):
|
||||
break
|
||||
if interval.reached():
|
||||
if enforce:
|
||||
self.device.click(BLESSING_ENFORCE)
|
||||
self.main.device.click(BLESSING_ENFORCE)
|
||||
else:
|
||||
self.device.click(target)
|
||||
self.main.device.click(target)
|
||||
interval.reset()
|
||||
|
||||
skip_first_screenshot = True
|
||||
@ -156,16 +156,16 @@ class RogueBlessingSelector(RogueUI, RogueSelector):
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
self.main.device.screenshot()
|
||||
|
||||
if is_select_blessing_complete():
|
||||
break
|
||||
if interval.reached():
|
||||
self.device.click(CONFIRM)
|
||||
self.main.device.click(CONFIRM)
|
||||
interval.reset()
|
||||
|
||||
def _get_reset_count(self):
|
||||
current, _, _ = DigitCounter(OCR_RESET_COUNT).ocr_single_line(self.device.image)
|
||||
current, _, _ = DigitCounter(OCR_RESET_COUNT).ocr_single_line(self.main.device.image)
|
||||
return current
|
||||
|
||||
def _wait_until_blessing_loaded(self, timer=Timer(0.3, count=1), timeout=Timer(5, count=10)):
|
||||
@ -173,7 +173,7 @@ class RogueBlessingSelector(RogueUI, RogueSelector):
|
||||
timeout.reset()
|
||||
previous_count = self.get_blessing_count()
|
||||
while 1:
|
||||
self.device.screenshot()
|
||||
self.main.device.screenshot()
|
||||
blessing_count = self.get_blessing_count()
|
||||
|
||||
if timeout.reached():
|
||||
@ -189,7 +189,7 @@ class RogueBlessingSelector(RogueUI, RogueSelector):
|
||||
timer.reset()
|
||||
|
||||
def reset_blessing_list(self, skip_first_screenshot=True):
|
||||
if not self.is_page_choose_blessing():
|
||||
if not self.main.is_page_choose_blessing():
|
||||
return False
|
||||
|
||||
reset_count = self._get_reset_count()
|
||||
@ -197,8 +197,8 @@ class RogueBlessingSelector(RogueUI, RogueSelector):
|
||||
logger.info("Does not have enough reset count")
|
||||
return False
|
||||
|
||||
reset_cost = Digit(OCR_RESET_COST).ocr_single_line(self.device.image)
|
||||
if reset_cost > self.cosmic_fragment:
|
||||
reset_cost = Digit(OCR_RESET_COST).ocr_single_line(self.main.device.image)
|
||||
if reset_cost > self.main.cosmic_fragment:
|
||||
logger.info("Does not have enough cosmic fragment")
|
||||
return False
|
||||
|
||||
@ -207,7 +207,7 @@ class RogueBlessingSelector(RogueUI, RogueSelector):
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
self.main.device.screenshot()
|
||||
|
||||
new_count = self._get_reset_count()
|
||||
|
||||
@ -215,7 +215,7 @@ class RogueBlessingSelector(RogueUI, RogueSelector):
|
||||
logger.info("Reset once")
|
||||
break
|
||||
if interval.reached():
|
||||
self.device.click(BLESSING_RESET)
|
||||
self.main.device.click(BLESSING_RESET)
|
||||
interval.reset()
|
||||
return True
|
||||
|
||||
@ -224,16 +224,16 @@ class RogueBlessingSelector(RogueUI, RogueSelector):
|
||||
keyword = self.ocr_results[0].matched_keyword
|
||||
if isinstance(keyword, RogueBlessing):
|
||||
filter_ = BLESSING_FILTER
|
||||
if self.config.Rogue_PresetBlessingFilter == 'preset-1':
|
||||
if self.main.config.Rogue_PresetBlessingFilter == 'preset-1':
|
||||
filter_.load(parse_name(BLESSING_PRESET_1))
|
||||
if self.config.Rogue_PresetBlessingFilter == 'custom':
|
||||
filter_.load(parse_name(self.config.Rogue_CustomBlessingFilter))
|
||||
if self.main.config.Rogue_PresetBlessingFilter == 'custom':
|
||||
filter_.load(parse_name(self.main.config.Rogue_CustomBlessingFilter))
|
||||
if isinstance(keyword, RogueResonance):
|
||||
filter_ = RESONANCE_FILTER
|
||||
if self.config.Rogue_PresetResonanceFilter == 'preset-1':
|
||||
if self.main.config.Rogue_PresetResonanceFilter == 'preset-1':
|
||||
RESONANCE_FILTER.load(parse_name(RESONANCE_PRESET_1))
|
||||
if self.config.Rogue_PresetResonanceFilter == 'custom':
|
||||
RESONANCE_FILTER.load(parse_name(self.config.Rogue_CustomResonanceFilter))
|
||||
if self.main.config.Rogue_PresetResonanceFilter == 'custom':
|
||||
RESONANCE_FILTER.load(parse_name(self.main.config.Rogue_CustomResonanceFilter))
|
||||
self.filter_ = filter_
|
||||
|
||||
def try_select(self, option: OcrResultButton | str):
|
||||
|
83
tasks/rogue/bonus.py
Normal file
83
tasks/rogue/bonus.py
Normal file
@ -0,0 +1,83 @@
|
||||
import numpy as np
|
||||
|
||||
from module.base.timer import Timer
|
||||
from module.logger import logger
|
||||
from module.ocr.ocr import 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
|
||||
from tasks.rogue.keywords import RogueBonus
|
||||
from tasks.rogue.selector import RogueSelector
|
||||
from tasks.rogue.ui import RogueBonusOcr
|
||||
from tasks.rogue.utils import is_card_selected
|
||||
|
||||
|
||||
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 interval.reached():
|
||||
self.main.device.click(target)
|
||||
interval.reset()
|
||||
|
||||
skip_first_screenshot = True
|
||||
# select -> confirm
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.main.device.screenshot()
|
||||
|
||||
if self.main.is_in_main() or self.main.is_page_choose_curio() or self.main.is_page_choose_blessing():
|
||||
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}
|
||||
if self.main.config.Rogue_Bonus not in options.keys():
|
||||
logger.warning(f"Can not find option: {self.main.config.Rogue_Bonus}, randomly choose one")
|
||||
target = np.random.choice(options)
|
||||
else:
|
||||
target = options[self.main.config.Rogue_Bonus]
|
||||
logger.info(f"Choose bonus: {target}")
|
||||
self.ui_select(target)
|
@ -12,7 +12,6 @@ from tasks.rogue.assets.assets_rogue_ui import CONFIRM
|
||||
from tasks.rogue.keywords import RogueCurio
|
||||
from tasks.rogue.preset import CURIO_PRESET_1
|
||||
from tasks.rogue.selector import RogueSelector
|
||||
from tasks.rogue.ui import RogueUI
|
||||
from tasks.rogue.utils import get_regex_from_keyword_name, parse_name
|
||||
|
||||
CURIO_FILTER_ATTR = tuple()
|
||||
@ -36,11 +35,11 @@ class RogueCurioOcr(Ocr):
|
||||
return result
|
||||
|
||||
|
||||
class RogueCurioSelector(RogueUI, RogueSelector):
|
||||
class RogueCurioSelector(RogueSelector):
|
||||
def recognition(self):
|
||||
self.ocr_results = []
|
||||
ocr = RogueCurioOcr(OCR_ROGUE_CURIO)
|
||||
results = ocr.matched_ocr(self.device.image, RogueCurio)
|
||||
results = ocr.matched_ocr(self.main.device.image, RogueCurio)
|
||||
expect_num = 3
|
||||
if len(results) != expect_num:
|
||||
logger.warning(f"The OCR result does not match the curio count. "
|
||||
@ -50,13 +49,13 @@ class RogueCurioSelector(RogueUI, RogueSelector):
|
||||
|
||||
def ui_select(self, target: OcrResultButton | None, skip_first_screenshot=True):
|
||||
def is_curio_selected():
|
||||
return np.mean(get_color(self.device.image, tuple(target.area))) > 70 # shiny background
|
||||
return np.mean(get_color(self.main.device.image, tuple(target.area))) > 70 # shiny background
|
||||
|
||||
def is_select_curio_complete():
|
||||
"""
|
||||
Case 1: back to main page
|
||||
"""
|
||||
return self.is_in_main()
|
||||
return self.main.is_in_main()
|
||||
|
||||
enforce = False
|
||||
if not target:
|
||||
@ -67,7 +66,7 @@ class RogueCurioSelector(RogueUI, RogueSelector):
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
self.main.device.screenshot()
|
||||
|
||||
if is_curio_selected():
|
||||
if enforce:
|
||||
@ -77,9 +76,9 @@ class RogueCurioSelector(RogueUI, RogueSelector):
|
||||
break
|
||||
if interval.reached():
|
||||
if enforce:
|
||||
self.device.click(CURIO_ENFORCE)
|
||||
self.main.device.click(CURIO_ENFORCE)
|
||||
else:
|
||||
self.device.click(target)
|
||||
self.main.device.click(target)
|
||||
interval.reset()
|
||||
|
||||
skip_first_screenshot = True
|
||||
@ -88,12 +87,12 @@ class RogueCurioSelector(RogueUI, RogueSelector):
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
self.main.device.screenshot()
|
||||
|
||||
if is_select_curio_complete():
|
||||
break
|
||||
if interval.reached():
|
||||
self.device.click(CONFIRM)
|
||||
self.main.device.click(CONFIRM)
|
||||
interval.reset()
|
||||
|
||||
def try_select(self, option: OcrResultButton | str):
|
||||
@ -108,8 +107,8 @@ class RogueCurioSelector(RogueUI, RogueSelector):
|
||||
|
||||
def load_filter(self):
|
||||
filter_ = CURIO_FILTER
|
||||
if self.config.Rogue_PresetCurioFilter == 'preset-1':
|
||||
if self.main.config.Rogue_PresetCurioFilter == 'preset-1':
|
||||
filter_.load(parse_name(CURIO_PRESET_1))
|
||||
if self.config.Rogue_PresetCurioFilter == 'custom':
|
||||
filter_.load(parse_name(self.config.Rogue_CustomCurioFilter))
|
||||
if self.main.config.Rogue_PresetCurioFilter == 'custom':
|
||||
filter_.load(parse_name(self.main.config.Rogue_CustomCurioFilter))
|
||||
self.filter_ = filter_
|
||||
|
@ -4,12 +4,17 @@ from module.base.filter import MultiLangFilter
|
||||
from module.logger import logger
|
||||
from module.ocr.keyword import Keyword
|
||||
from module.ocr.ocr import OcrResultButton
|
||||
from tasks.rogue.ui import RogueUI
|
||||
|
||||
|
||||
class RogueSelector:
|
||||
"""
|
||||
An Interface used in blessing, curio, and other ui selection in rogue
|
||||
"""
|
||||
|
||||
def __init__(self, main: RogueUI):
|
||||
self.main = main
|
||||
|
||||
ocr_results: list[OcrResultButton]
|
||||
filter_: MultiLangFilter
|
||||
preset_methods: dict[str, callable]
|
||||
|
@ -1,15 +1,9 @@
|
||||
import re
|
||||
|
||||
import numpy as np
|
||||
|
||||
from module.base.timer import Timer
|
||||
from module.logger import logger
|
||||
from module.ocr.ocr import Digit, Ocr, OcrResultButton
|
||||
from module.ocr.ocr import Digit, Ocr
|
||||
from tasks.base.ui import UI
|
||||
from tasks.rogue.assets.assets_rogue_blessing import OCR_ROGUE_BUFF
|
||||
from tasks.rogue.assets.assets_rogue_ui import *
|
||||
from tasks.rogue.keywords import *
|
||||
from tasks.rogue.utils import is_card_selected
|
||||
|
||||
|
||||
class RogueBonusOcr(Ocr):
|
||||
@ -43,72 +37,3 @@ class RogueUI(UI):
|
||||
|
||||
def is_page_choose_bonus(self):
|
||||
return self.appear(PAGE_CHOOSE_BONUS)
|
||||
|
||||
def _wait_bonus_page_loaded(self, timer=Timer(0.3, count=1), timeout=Timer(5, count=10)):
|
||||
timer.reset()
|
||||
timeout.reset()
|
||||
while 1:
|
||||
self.device.screenshot()
|
||||
|
||||
if timeout.reached():
|
||||
logger.warning('Wait bonus page loaded timeout')
|
||||
break
|
||||
|
||||
if self.appear(BONUS_BOTTOM_WHITE_BAR):
|
||||
if timer.reached():
|
||||
logger.info('Bonus page stabled')
|
||||
break
|
||||
else:
|
||||
timer.reset()
|
||||
|
||||
def bonus_recognition(self):
|
||||
self._wait_bonus_page_loaded()
|
||||
ocr = RogueBonusOcr(OCR_ROGUE_BUFF)
|
||||
results = ocr.matched_ocr(self.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.")
|
||||
return results
|
||||
|
||||
def ui_choose_bonus(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.device.screenshot()
|
||||
|
||||
if is_card_selected(self, target, confirm_button=BONUS_CONFIRM):
|
||||
break
|
||||
if interval.reached():
|
||||
self.device.click(target)
|
||||
interval.reset()
|
||||
|
||||
skip_first_screenshot = True
|
||||
# select -> confirm
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if self.is_in_main() or self.is_page_choose_curio() or self.is_page_choose_blessing():
|
||||
break
|
||||
if interval.reached():
|
||||
self.device.click(BONUS_CONFIRM)
|
||||
interval.reset()
|
||||
|
||||
def recognize_and_select_bonus(self):
|
||||
results = self.bonus_recognition()
|
||||
if not results:
|
||||
self.ui_choose_bonus(None)
|
||||
options = {result.matched_keyword.en: result for result in results}
|
||||
if self.config.Rogue_Bonus not in options.keys():
|
||||
logger.warning(f"Can not find option: {self.config.Rogue_Bonus}, randomly choose one")
|
||||
target = np.random.choice(options)
|
||||
else:
|
||||
target = options[self.config.Rogue_Bonus]
|
||||
logger.info(f"Choose bonus: {target}")
|
||||
self.ui_choose_bonus(target)
|
||||
|
Loading…
Reference in New Issue
Block a user