mirror of
https://github.com/LmeSzinc/StarRailCopilot.git
synced 2024-11-22 00:35:34 +00:00
Fix: Echo of war navigation
This commit is contained in:
parent
f81b40963d
commit
706c5c1f7b
@ -4,9 +4,10 @@ import cv2
|
|||||||
from pponnxcr.predict_system import BoxedResult
|
from pponnxcr.predict_system import BoxedResult
|
||||||
|
|
||||||
from module.base.base import ModuleBase
|
from module.base.base import ModuleBase
|
||||||
|
from module.base.button import ClickButton
|
||||||
from module.base.decorator import run_once
|
from module.base.decorator import run_once
|
||||||
from module.base.timer import Timer
|
from module.base.timer import Timer
|
||||||
from module.base.utils import area_center, area_offset, crop, image_size
|
from module.base.utils import area_center, area_limit, area_offset, crop, image_size
|
||||||
from module.logger import logger
|
from module.logger import logger
|
||||||
from module.ocr.ocr import Ocr, OcrResultButton
|
from module.ocr.ocr import Ocr, OcrResultButton
|
||||||
from module.ocr.utils import split_and_pair_button_attr, split_and_pair_buttons
|
from module.ocr.utils import split_and_pair_button_attr, split_and_pair_buttons
|
||||||
@ -37,7 +38,8 @@ class OcrDungeonName(Ocr):
|
|||||||
result = re.sub(r'-[VⅤ][IⅠ]', '-Ⅵ', result)
|
result = re.sub(r'-[VⅤ][IⅠ]', '-Ⅵ', result)
|
||||||
|
|
||||||
# 苏乐达™热砂海选会场
|
# 苏乐达™热砂海选会场
|
||||||
result = re.sub(r'(苏乐达|蘇樂達|SoulGlad|スラーダ|FelizAlma)[rtT]*M', r'\1', result)
|
result = re.sub(r'(苏乐达|蘇樂達|SoulGlad|スラーダ|FelizAlma)[rtT]*M*', r'\1', result)
|
||||||
|
result = re.sub(r'["\']', '', result)
|
||||||
|
|
||||||
result = super().after_process(result)
|
result = super().after_process(result)
|
||||||
|
|
||||||
@ -64,10 +66,15 @@ class OcrDungeonList(OcrDungeonName):
|
|||||||
# Keep __init__ parameter unused
|
# Keep __init__ parameter unused
|
||||||
def __init__(self, button: ButtonWrapper = None, lang=None, name=None):
|
def __init__(self, button: ButtonWrapper = None, lang=None, name=None):
|
||||||
super().__init__(button=button, lang=lang, name='OcrDungeonList')
|
super().__init__(button=button, lang=lang, name='OcrDungeonList')
|
||||||
|
# target_dungeon: Dungeon attribute to use map planes to predict dungeons only.
|
||||||
|
self.target_dungeon = None
|
||||||
|
# limit_entrance: True to ensure the teleport button is insight
|
||||||
self.limit_entrance = False
|
self.limit_entrance = False
|
||||||
|
|
||||||
def detect_and_ocr(self, image, direct_ocr=False) -> list[BoxedResult]:
|
def detect_and_ocr(self, image, direct_ocr=False) -> list[BoxedResult]:
|
||||||
if self.button != OCR_DUNGEON_NAME:
|
if self.button != OCR_DUNGEON_NAME:
|
||||||
|
if self.limit_entrance:
|
||||||
|
self.button = ClickButton((*self.button.area[:3], self.button.area[3] - 70))
|
||||||
return super().detect_and_ocr(image, direct_ocr=direct_ocr)
|
return super().detect_and_ocr(image, direct_ocr=direct_ocr)
|
||||||
|
|
||||||
# Concat OCR_DUNGEON_NAME and OCR_DUNGEON_TELEPORT
|
# Concat OCR_DUNGEON_NAME and OCR_DUNGEON_TELEPORT
|
||||||
@ -99,37 +106,38 @@ class OcrDungeonList(OcrDungeonName):
|
|||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
class OcrDungeonListUsingPlane(OcrDungeonList):
|
|
||||||
def _match_result(self, *args, **kwargs):
|
def _match_result(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Convert MapPlane object to their corresponding DungeonList object
|
Convert MapPlane object to their corresponding DungeonList object
|
||||||
"""
|
"""
|
||||||
plane = super()._match_result(*args, **kwargs)
|
matched = super()._match_result(*args, **kwargs)
|
||||||
if plane is not None:
|
if self.target_dungeon is not None and matched is not None:
|
||||||
for dungeon in DungeonList.instances.values():
|
if self.target_dungeon.is_Calyx_Golden:
|
||||||
if dungeon.is_Calyx_Golden and dungeon.plane == plane:
|
# convert MapPlane and ignore DungeonList
|
||||||
return dungeon
|
if isinstance(matched, DungeonList):
|
||||||
return plane
|
return
|
||||||
|
for dungeon in DungeonList.instances.values():
|
||||||
|
if dungeon.is_Calyx_Golden and dungeon.plane == matched:
|
||||||
|
return dungeon
|
||||||
|
if self.target_dungeon.is_Calyx_Crimson:
|
||||||
|
if isinstance(matched, DungeonList):
|
||||||
|
return
|
||||||
|
for dungeon in DungeonList.instances.values():
|
||||||
|
if dungeon.is_Calyx_Crimson and dungeon.plane == matched:
|
||||||
|
return dungeon
|
||||||
|
else:
|
||||||
|
if isinstance(matched, MapPlane):
|
||||||
|
return
|
||||||
|
|
||||||
|
return matched
|
||||||
class OcrDungeonListLimitEntrance(OcrDungeonList):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.limit_entrance = True
|
|
||||||
|
|
||||||
|
|
||||||
class OcrDungeonListUsingPlaneLimitEntrance(OcrDungeonListUsingPlane, OcrDungeonListLimitEntrance):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class DraggableDungeonList(DraggableList):
|
class DraggableDungeonList(DraggableList):
|
||||||
teleports: list[OcrResultButton] = []
|
teleports: list[OcrResultButton] = []
|
||||||
navigates: list[OcrResultButton] = []
|
navigates: list[OcrResultButton] = []
|
||||||
|
|
||||||
# use_plane: True to use map planes to predict dungeons only.
|
# target_dungeon: Dungeon attribute to use map planes to predict dungeons only.
|
||||||
# Can only be True in Calyx Crimson
|
target_dungeon = None
|
||||||
use_plane = False
|
|
||||||
# limit_entrance: True to ensure the teleport button is insight
|
# limit_entrance: True to ensure the teleport button is insight
|
||||||
limit_entrance = False
|
limit_entrance = False
|
||||||
|
|
||||||
@ -139,19 +147,16 @@ class DraggableDungeonList(DraggableList):
|
|||||||
main:
|
main:
|
||||||
allow_early_access: True to allow dungeons that are in temporarily early access during events
|
allow_early_access: True to allow dungeons that are in temporarily early access during events
|
||||||
"""
|
"""
|
||||||
relative_area = (0, 0, 1280, 120)
|
relative_area = (0, -40, 1280, 120)
|
||||||
if self.use_plane:
|
|
||||||
self.keyword_class = [MapPlane, DungeonEntrance]
|
def create_ocr_class(*args, **kwargs):
|
||||||
if self.limit_entrance:
|
# Passing to OcrDungeonList
|
||||||
self.ocr_class = OcrDungeonListUsingPlaneLimitEntrance
|
obj = OcrDungeonList(*args, **kwargs)
|
||||||
else:
|
obj.target_dungeon = self.target_dungeon
|
||||||
self.ocr_class = OcrDungeonListUsingPlane
|
obj.limit_entrance = self.limit_entrance
|
||||||
else:
|
return obj
|
||||||
self.keyword_class = [DungeonList, DungeonEntrance]
|
|
||||||
if self.limit_entrance:
|
self.ocr_class = create_ocr_class
|
||||||
self.ocr_class = OcrDungeonListLimitEntrance
|
|
||||||
else:
|
|
||||||
self.ocr_class = OcrDungeonList
|
|
||||||
super().load_rows(main=main)
|
super().load_rows(main=main)
|
||||||
|
|
||||||
# Check early access dungeons
|
# Check early access dungeons
|
||||||
@ -238,7 +243,7 @@ class DungeonUIList(UI):
|
|||||||
else:
|
else:
|
||||||
DUNGEON_LIST.search_button = OCR_DUNGEON_NAME
|
DUNGEON_LIST.search_button = OCR_DUNGEON_NAME
|
||||||
# Predict dungeon by plane name in calyxes where dungeons share the same names
|
# Predict dungeon by plane name in calyxes where dungeons share the same names
|
||||||
DUNGEON_LIST.use_plane = bool(dungeon.is_Calyx)
|
DUNGEON_LIST.target_dungeon = dungeon
|
||||||
DUNGEON_LIST.check_row_order = True
|
DUNGEON_LIST.check_row_order = True
|
||||||
|
|
||||||
# Insight dungeon
|
# Insight dungeon
|
||||||
@ -281,7 +286,7 @@ class DungeonUIList(UI):
|
|||||||
logger.hr('Dungeon insight (sort)', level=2)
|
logger.hr('Dungeon insight (sort)', level=2)
|
||||||
logger.info(f'Dungeon insight: {dungeon}')
|
logger.info(f'Dungeon insight: {dungeon}')
|
||||||
DUNGEON_LIST.search_button = OCR_DUNGEON_NAME
|
DUNGEON_LIST.search_button = OCR_DUNGEON_NAME
|
||||||
DUNGEON_LIST.use_plane = bool(dungeon.is_Calyx_Golden)
|
DUNGEON_LIST.target_dungeon = dungeon
|
||||||
DUNGEON_LIST.check_row_order = False
|
DUNGEON_LIST.check_row_order = False
|
||||||
|
|
||||||
for _ in range(3):
|
for _ in range(3):
|
||||||
@ -342,7 +347,7 @@ class DungeonUIList(UI):
|
|||||||
out: COMBAT_PREPARE, FORGOTTEN_HALL_CHECK
|
out: COMBAT_PREPARE, FORGOTTEN_HALL_CHECK
|
||||||
"""
|
"""
|
||||||
logger.hr('Dungeon enter', level=2)
|
logger.hr('Dungeon enter', level=2)
|
||||||
DUNGEON_LIST.use_plane = bool(dungeon.is_Calyx_Crimson)
|
DUNGEON_LIST.target_dungeon = dungeon
|
||||||
skip_first_load = skip_first_screenshot
|
skip_first_load = skip_first_screenshot
|
||||||
|
|
||||||
@run_once
|
@run_once
|
||||||
@ -374,6 +379,8 @@ class DungeonUIList(UI):
|
|||||||
DUNGEON_LIST.load_rows(main=self)
|
DUNGEON_LIST.load_rows(main=self)
|
||||||
entrance = DUNGEON_LIST.keyword2button(dungeon)
|
entrance = DUNGEON_LIST.keyword2button(dungeon)
|
||||||
if entrance is not None:
|
if entrance is not None:
|
||||||
|
# Avoid clicking the soring button
|
||||||
|
entrance.button = area_limit(entrance.button, OCR_DUNGEON_TELEPORT.area)
|
||||||
self.device.click(entrance)
|
self.device.click(entrance)
|
||||||
screenshot_interval_set()
|
screenshot_interval_set()
|
||||||
self.interval_reset(page_guide.check_button)
|
self.interval_reset(page_guide.check_button)
|
||||||
@ -383,3 +390,9 @@ class DungeonUIList(UI):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
self.device.screenshot_interval_set()
|
self.device.screenshot_interval_set()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
self = DungeonUIList('src')
|
||||||
|
self.device.screenshot()
|
||||||
|
self.dungeon_insight(KEYWORDS_DUNGEON_LIST.Echo_of_War_Divine_Seed)
|
||||||
|
Loading…
Reference in New Issue
Block a user