mirror of
https://github.com/LmeSzinc/StarRailCopilot.git
synced 2024-11-16 06:25:24 +00:00
Merge pull request #198 from Yinhaoran1128/dev
Upd: Use DraggableList to rewrite choose rogue path and add propagation in rogue
This commit is contained in:
commit
986a90c18a
BIN
assets/cn/rogue/path/PAGE_ROGUE_PATH.png
Normal file
BIN
assets/cn/rogue/path/PAGE_ROGUE_PATH.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
BIN
assets/en/rogue/path/PAGE_ROGUE_PATH.png
Normal file
BIN
assets/en/rogue/path/PAGE_ROGUE_PATH.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.3 KiB |
BIN
assets/share/rogue/path/CHECK_PROPAGATION.png
Normal file
BIN
assets/share/rogue/path/CHECK_PROPAGATION.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.8 KiB |
BIN
assets/share/rogue/path/CHOOSE_LEFT.png
Normal file
BIN
assets/share/rogue/path/CHOOSE_LEFT.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
assets/share/rogue/path/CHOOSE_RIGHT.png
Normal file
BIN
assets/share/rogue/path/CHOOSE_RIGHT.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
@ -1208,7 +1208,8 @@
|
|||||||
"Abundance",
|
"Abundance",
|
||||||
"The_Hunt",
|
"The_Hunt",
|
||||||
"Destruction",
|
"Destruction",
|
||||||
"Elation"
|
"Elation",
|
||||||
|
"Propagation"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"Bonus": {
|
"Bonus": {
|
||||||
|
@ -212,7 +212,7 @@ RogueWorld:
|
|||||||
]
|
]
|
||||||
Path:
|
Path:
|
||||||
value: The_Hunt
|
value: The_Hunt
|
||||||
option: [ Preservation, Remembrance, Nihility, Abundance, The_Hunt, Destruction, Elation ]
|
option: [ Preservation, Remembrance, Nihility, Abundance, The_Hunt, Destruction, Elation, Propagation ]
|
||||||
Bonus:
|
Bonus:
|
||||||
value: Blessing Cosmos
|
value: Blessing Cosmos
|
||||||
option: [ Blessing Cosmos, Miracle Cosmos, Fragmented Cosmos ]
|
option: [ Blessing Cosmos, Miracle Cosmos, Fragmented Cosmos ]
|
||||||
|
@ -119,7 +119,7 @@ class GeneratedConfig:
|
|||||||
|
|
||||||
# Group `RogueWorld`
|
# Group `RogueWorld`
|
||||||
RogueWorld_World = 'Simulated_Universe_World_7' # Simulated_Universe_World_3, Simulated_Universe_World_4, Simulated_Universe_World_5, Simulated_Universe_World_6, Simulated_Universe_World_7, Simulated_Universe_World_8
|
RogueWorld_World = 'Simulated_Universe_World_7' # Simulated_Universe_World_3, Simulated_Universe_World_4, Simulated_Universe_World_5, Simulated_Universe_World_6, Simulated_Universe_World_7, Simulated_Universe_World_8
|
||||||
RogueWorld_Path = 'The_Hunt' # Preservation, Remembrance, Nihility, Abundance, The_Hunt, Destruction, Elation
|
RogueWorld_Path = 'The_Hunt' # Preservation, Remembrance, Nihility, Abundance, The_Hunt, Destruction, Elation, Propagation
|
||||||
RogueWorld_Bonus = 'Blessing Cosmos' # Blessing Cosmos, Miracle Cosmos, Fragmented Cosmos
|
RogueWorld_Bonus = 'Blessing Cosmos' # Blessing Cosmos, Miracle Cosmos, Fragmented Cosmos
|
||||||
RogueWorld_DomainStrategy = 'combat' # combat, occurrence
|
RogueWorld_DomainStrategy = 'combat' # combat, occurrence
|
||||||
RogueWorld_UseImmersifier = True
|
RogueWorld_UseImmersifier = True
|
||||||
|
@ -806,7 +806,8 @@
|
|||||||
"Abundance": "Abundance",
|
"Abundance": "Abundance",
|
||||||
"The_Hunt": "The Hunt",
|
"The_Hunt": "The Hunt",
|
||||||
"Destruction": "Destruction",
|
"Destruction": "Destruction",
|
||||||
"Elation": "Elation"
|
"Elation": "Elation",
|
||||||
|
"Propagation": "Propagation"
|
||||||
},
|
},
|
||||||
"Bonus": {
|
"Bonus": {
|
||||||
"name": "Blessings of Trailblaze",
|
"name": "Blessings of Trailblaze",
|
||||||
|
@ -806,7 +806,8 @@
|
|||||||
"Abundance": "Abundancia",
|
"Abundance": "Abundancia",
|
||||||
"The_Hunt": "Cacería",
|
"The_Hunt": "Cacería",
|
||||||
"Destruction": "Destrucción",
|
"Destruction": "Destrucción",
|
||||||
"Elation": "Exultación"
|
"Elation": "Exultación",
|
||||||
|
"Propagation": "Propagación"
|
||||||
},
|
},
|
||||||
"Bonus": {
|
"Bonus": {
|
||||||
"name": "Bendiciones",
|
"name": "Bendiciones",
|
||||||
|
@ -806,7 +806,8 @@
|
|||||||
"Abundance": "Abundance",
|
"Abundance": "Abundance",
|
||||||
"The_Hunt": "The_Hunt",
|
"The_Hunt": "The_Hunt",
|
||||||
"Destruction": "Destruction",
|
"Destruction": "Destruction",
|
||||||
"Elation": "Elation"
|
"Elation": "Elation",
|
||||||
|
"Propagation": "Propagation"
|
||||||
},
|
},
|
||||||
"Bonus": {
|
"Bonus": {
|
||||||
"name": "RogueWorld.Bonus.name",
|
"name": "RogueWorld.Bonus.name",
|
||||||
|
@ -806,7 +806,8 @@
|
|||||||
"Abundance": "丰饶",
|
"Abundance": "丰饶",
|
||||||
"The_Hunt": "巡猎",
|
"The_Hunt": "巡猎",
|
||||||
"Destruction": "毁灭",
|
"Destruction": "毁灭",
|
||||||
"Elation": "欢愉"
|
"Elation": "欢愉",
|
||||||
|
"Propagation": "繁育"
|
||||||
},
|
},
|
||||||
"Bonus": {
|
"Bonus": {
|
||||||
"name": "开拓祝福三选一",
|
"name": "开拓祝福三选一",
|
||||||
|
@ -806,7 +806,8 @@
|
|||||||
"Abundance": "豐饒",
|
"Abundance": "豐饒",
|
||||||
"The_Hunt": "巡獵",
|
"The_Hunt": "巡獵",
|
||||||
"Destruction": "毀滅",
|
"Destruction": "毀滅",
|
||||||
"Elation": "歡愉"
|
"Elation": "歡愉",
|
||||||
|
"Propagation": "繁育"
|
||||||
},
|
},
|
||||||
"Bonus": {
|
"Bonus": {
|
||||||
"name": "開拓祝福三選一",
|
"name": "開拓祝福三選一",
|
||||||
|
@ -63,6 +63,16 @@ CHECK_PRESERVATION = ButtonWrapper(
|
|||||||
button=(220, 308, 270, 358),
|
button=(220, 308, 270, 358),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
CHECK_PROPAGATION = ButtonWrapper(
|
||||||
|
name='CHECK_PROPAGATION',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/rogue/path/CHECK_PROPAGATION.png',
|
||||||
|
area=(206, 308, 286, 372),
|
||||||
|
search=(186, 288, 306, 392),
|
||||||
|
color=(126, 104, 75),
|
||||||
|
button=(206, 308, 286, 372),
|
||||||
|
),
|
||||||
|
)
|
||||||
CHECK_REMEMBRANCE = ButtonWrapper(
|
CHECK_REMEMBRANCE = ButtonWrapper(
|
||||||
name='CHECK_REMEMBRANCE',
|
name='CHECK_REMEMBRANCE',
|
||||||
share=Button(
|
share=Button(
|
||||||
@ -83,6 +93,26 @@ CHECK_THE_HUNT = ButtonWrapper(
|
|||||||
button=(221, 324, 271, 374),
|
button=(221, 324, 271, 374),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
CHOOSE_LEFT = ButtonWrapper(
|
||||||
|
name='CHOOSE_LEFT',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/rogue/path/CHOOSE_LEFT.png',
|
||||||
|
area=(44, 292, 102, 365),
|
||||||
|
search=(24, 272, 122, 385),
|
||||||
|
color=(30, 33, 42),
|
||||||
|
button=(44, 292, 102, 365),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
CHOOSE_RIGHT = ButtonWrapper(
|
||||||
|
name='CHOOSE_RIGHT',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/rogue/path/CHOOSE_RIGHT.png',
|
||||||
|
area=(1177, 291, 1236, 364),
|
||||||
|
search=(1157, 271, 1256, 384),
|
||||||
|
color=(32, 33, 39),
|
||||||
|
button=(1177, 291, 1236, 364),
|
||||||
|
),
|
||||||
|
)
|
||||||
CLICK_ABUNDANCE = ButtonWrapper(
|
CLICK_ABUNDANCE = ButtonWrapper(
|
||||||
name='CLICK_ABUNDANCE',
|
name='CLICK_ABUNDANCE',
|
||||||
share=Button(
|
share=Button(
|
||||||
@ -163,3 +193,20 @@ CONFIRM_PATH = ButtonWrapper(
|
|||||||
button=(865, 640, 1139, 675),
|
button=(865, 640, 1139, 675),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
PAGE_ROGUE_PATH = ButtonWrapper(
|
||||||
|
name='PAGE_ROGUE_PATH',
|
||||||
|
cn=Button(
|
||||||
|
file='./assets/cn/rogue/path/PAGE_ROGUE_PATH.png',
|
||||||
|
area=(713, 87, 759, 109),
|
||||||
|
search=(693, 67, 779, 129),
|
||||||
|
color=(122, 120, 119),
|
||||||
|
button=(713, 87, 759, 109),
|
||||||
|
),
|
||||||
|
en=Button(
|
||||||
|
file='./assets/en/rogue/path/PAGE_ROGUE_PATH.png',
|
||||||
|
area=(606, 89, 656, 108),
|
||||||
|
search=(586, 69, 676, 128),
|
||||||
|
color=(114, 112, 112),
|
||||||
|
button=(606, 89, 656, 108),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
@ -40,6 +40,7 @@ class RoguePathHandler(RogueUI):
|
|||||||
KEYWORDS_ROGUE_PATH.The_Hunt: CHECK_THE_HUNT,
|
KEYWORDS_ROGUE_PATH.The_Hunt: CHECK_THE_HUNT,
|
||||||
KEYWORDS_ROGUE_PATH.Destruction: CHECK_DESTRUCTION,
|
KEYWORDS_ROGUE_PATH.Destruction: CHECK_DESTRUCTION,
|
||||||
KEYWORDS_ROGUE_PATH.Elation: CHECK_ELATION,
|
KEYWORDS_ROGUE_PATH.Elation: CHECK_ELATION,
|
||||||
|
KEYWORDS_ROGUE_PATH.Propagation: CHECK_PROPAGATION
|
||||||
}
|
}
|
||||||
return buttons
|
return buttons
|
||||||
|
|
||||||
@ -60,11 +61,28 @@ class RoguePathHandler(RogueUI):
|
|||||||
return buttons
|
return buttons
|
||||||
|
|
||||||
def _get_path_click(self, path: RoguePath) -> ButtonWrapper:
|
def _get_path_click(self, path: RoguePath) -> ButtonWrapper:
|
||||||
try:
|
buttons = self._rogue_path_clicks
|
||||||
return self._rogue_path_clicks[path]
|
if ret := buttons.get(path):
|
||||||
except KeyError:
|
return ret
|
||||||
logger.critical(f'Invalid rogue path: {path}')
|
else:
|
||||||
raise ScriptError
|
# choose the closest path
|
||||||
|
paths = list(buttons.keys())
|
||||||
|
path_click = min(paths, key=lambda p: min(self._calculate_distance(p, path)))
|
||||||
|
return buttons.get(path_click)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _calculate_distance(path_1: RoguePath, path_2: RoguePath):
|
||||||
|
"""
|
||||||
|
click times from path1 to path2
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple: (left_times, right_times)
|
||||||
|
"""
|
||||||
|
length = len(path_1.instances)
|
||||||
|
distance = path_1.id - path_2.id
|
||||||
|
left_times = distance % length
|
||||||
|
right_times = -distance % length
|
||||||
|
return left_times, right_times
|
||||||
|
|
||||||
def _get_selected_path(self, skip_first_screenshot=True) -> RoguePath | None:
|
def _get_selected_path(self, skip_first_screenshot=True) -> RoguePath | None:
|
||||||
timeout = Timer(1, count=5).start()
|
timeout = Timer(1, count=5).start()
|
||||||
@ -86,8 +104,8 @@ class RoguePathHandler(RogueUI):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def _is_page_rogue_path(self) -> bool:
|
def _is_page_rogue_path(self) -> bool:
|
||||||
appear = [self.appear(button) for button in self._rogue_path_clicks.values()]
|
appear = self.appear(PAGE_ROGUE_PATH)
|
||||||
return all(appear)
|
return appear
|
||||||
|
|
||||||
def _is_team_prepared(self) -> bool:
|
def _is_team_prepared(self) -> bool:
|
||||||
"""
|
"""
|
||||||
@ -99,6 +117,30 @@ class RoguePathHandler(RogueUI):
|
|||||||
logger.attr('TeamSlotsPrepared', slots)
|
logger.attr('TeamSlotsPrepared', slots)
|
||||||
return slots > 0
|
return slots > 0
|
||||||
|
|
||||||
|
def _change_confirm_path(self, path: RoguePath, skip_first_screenshot=True) -> bool:
|
||||||
|
timeout = Timer(20, count=10).start()
|
||||||
|
selected_path_last = None
|
||||||
|
while 1:
|
||||||
|
if skip_first_screenshot:
|
||||||
|
skip_first_screenshot = False
|
||||||
|
else:
|
||||||
|
self.device.screenshot()
|
||||||
|
selected_path = self._get_selected_path()
|
||||||
|
if selected_path == path:
|
||||||
|
return True
|
||||||
|
elif selected_path != selected_path_last:
|
||||||
|
left_times, right_times = self._calculate_distance(selected_path, path)
|
||||||
|
if left_times <= right_times:
|
||||||
|
self.device.click(CHOOSE_LEFT)
|
||||||
|
else:
|
||||||
|
self.device.click(CHOOSE_RIGHT)
|
||||||
|
if timeout.reached():
|
||||||
|
break
|
||||||
|
selected_path_last = selected_path
|
||||||
|
|
||||||
|
logger.warning('Unable to change into chosen path')
|
||||||
|
return False
|
||||||
|
|
||||||
def rogue_path_select(self, path: str | RoguePath, skip_first_screenshot=True):
|
def rogue_path_select(self, path: str | RoguePath, skip_first_screenshot=True):
|
||||||
"""
|
"""
|
||||||
Raises:
|
Raises:
|
||||||
@ -110,7 +152,7 @@ class RoguePathHandler(RogueUI):
|
|||||||
or page_main if previous rogue run had bonus selected but didn't finish any domain
|
or page_main if previous rogue run had bonus selected but didn't finish any domain
|
||||||
"""
|
"""
|
||||||
logger.hr('Rogue path select', level=2)
|
logger.hr('Rogue path select', level=2)
|
||||||
path: RoguePath = RoguePath.find(path)
|
path: RoguePath = RoguePath.find_path(path)
|
||||||
logger.info(f'Select path: {path}')
|
logger.info(f'Select path: {path}')
|
||||||
entry = self._get_path_click(path)
|
entry = self._get_path_click(path)
|
||||||
while 1:
|
while 1:
|
||||||
@ -143,10 +185,6 @@ class RoguePathHandler(RogueUI):
|
|||||||
continue
|
continue
|
||||||
# Confirm path
|
# Confirm path
|
||||||
if self.appear(CONFIRM_PATH, interval=2):
|
if self.appear(CONFIRM_PATH, interval=2):
|
||||||
if self._get_selected_path() == path:
|
if self._change_confirm_path(path):
|
||||||
self.device.click(CONFIRM_PATH)
|
self.device.click(CONFIRM_PATH)
|
||||||
continue
|
continue
|
||||||
else:
|
|
||||||
logger.warning('Selected to the wrong path')
|
|
||||||
self.device.click(BACK)
|
|
||||||
continue
|
|
||||||
|
@ -2,6 +2,7 @@ from dataclasses import dataclass
|
|||||||
from typing import ClassVar
|
from typing import ClassVar
|
||||||
|
|
||||||
from dev_tools.keyword_extract import UI_LANGUAGES
|
from dev_tools.keyword_extract import UI_LANGUAGES
|
||||||
|
from module.exception import ScriptError
|
||||||
from module.ocr.keyword import Keyword
|
from module.ocr.keyword import Keyword
|
||||||
|
|
||||||
|
|
||||||
@ -35,6 +36,14 @@ class RoguePath(Keyword):
|
|||||||
return [self.__getattribute__(f"{server}_parsed").replace("the", '')
|
return [self.__getattribute__(f"{server}_parsed").replace("the", '')
|
||||||
for server in UI_LANGUAGES if hasattr(self, f"{server}_parsed")]
|
for server in UI_LANGUAGES if hasattr(self, f"{server}_parsed")]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def find_path(cls, name):
|
||||||
|
for instance in cls.instances.values():
|
||||||
|
if name == instance.name:
|
||||||
|
return instance
|
||||||
|
# Not found
|
||||||
|
raise ScriptError(f'Cannot find a {cls.__name__} instance that matches "{name}"')
|
||||||
|
|
||||||
|
|
||||||
@dataclass(repr=False)
|
@dataclass(repr=False)
|
||||||
class RogueResonance(Keyword):
|
class RogueResonance(Keyword):
|
||||||
|
Loading…
Reference in New Issue
Block a user