StarRailCopilot/tasks/dungeon/dungeon.py

107 lines
4.4 KiB
Python
Raw Normal View History

from module.base.utils import area_offset
2023-06-17 17:09:09 +00:00
from module.logger import logger
from tasks.combat.combat import Combat
2023-07-10 15:36:35 +00:00
from tasks.dungeon.event import DungeonEvent
2023-07-10 14:20:35 +00:00
from tasks.dungeon.keywords import DungeonList, KEYWORDS_DUNGEON_LIST, KEYWORDS_DUNGEON_TAB
2023-06-17 17:09:09 +00:00
from tasks.dungeon.ui import DungeonUI
2023-07-10 15:36:35 +00:00
class Dungeon(DungeonUI, DungeonEvent, Combat):
def run(self, dungeon: DungeonList = None, team: int = None, use_support: str = None, is_daily: bool = False,
support_character: str = None):
2023-06-17 17:09:09 +00:00
if dungeon is None:
dungeon = DungeonList.find(self.config.Dungeon_Name)
if team is None:
team = self.config.Dungeon_Team
if use_support is None:
use_support = self.config.Dungeon_Support
if support_character is None:
support_character = self.config.Dungeon_SupportCharacter if use_support == "always_use" or use_support == "when_daily" and is_daily else None
2023-06-17 17:09:09 +00:00
2023-07-10 15:36:35 +00:00
# UI switches
switched = self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index)
if not switched:
# Nav must at top, reset nav states
self.ui_goto_main()
self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index)
# Check double events
if self.config.Dungeon_NameAtDoubleCalyx != 'do_not_participate' and self.has_double_calyx_event():
calyx = DungeonList.find(self.config.Dungeon_NameAtDoubleCalyx)
self._dungeon_nav_goto(calyx)
if remain := self.get_double_event_remain():
self.dungeon_goto(calyx)
if self.combat(team, wave_limit=remain, support_character=support_character):
2023-07-10 15:36:35 +00:00
self.delay_dungeon_task(calyx)
self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index)
2023-08-20 16:51:10 +00:00
if self.config.Dungeon_NameAtDoubleRelic != 'do_not_participate' and self.has_double_relic_event():
calyx = DungeonList.find(self.config.Dungeon_NameAtDoubleRelic)
self._dungeon_nav_goto(calyx)
if remain := self.get_double_event_remain():
self.dungeon_goto(calyx)
if self.combat(team, wave_limit=remain, support_character=support_character):
self.delay_dungeon_task(calyx)
self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index)
2023-07-10 15:36:35 +00:00
# Combat
self.dungeon_goto(dungeon)
2023-06-17 17:09:09 +00:00
if dungeon == KEYWORDS_DUNGEON_LIST.Stagnant_Shadow_Blaze:
if self.handle_destructible_around_blaze():
2023-07-10 14:20:35 +00:00
self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index)
self.dungeon_goto(dungeon)
self.combat(team=team, support_character=support_character)
2023-07-10 15:36:35 +00:00
self.delay_dungeon_task(dungeon)
2023-06-17 17:09:09 +00:00
2023-07-10 15:36:35 +00:00
def delay_dungeon_task(self, dungeon):
if dungeon.is_Cavern_of_Corrosion:
limit = 80
else:
limit = 60
2023-06-17 17:09:09 +00:00
# Recover 1 trailbaze power each 6 minutes
cover = max(limit - self.state.TrailblazePower, 0) * 6
logger.info(f'Currently has {self.state.TrailblazePower} need {cover} minutes to reach {limit}')
2023-06-17 17:09:09 +00:00
self.config.task_delay(minute=cover)
2023-08-20 16:51:10 +00:00
self.config.task_stop()
def handle_destructible_around_blaze(self):
"""
Stagnant_Shadow_Blaze has a destructible object nearby, attacks are aimed at it first
so destroy it first
Returns:
bool: If handled.
Pages:
in: COMBAT_PREPARE
out: page_main, map position changed if handled
"""
logger.hr('Handle destructible around blaze')
self.combat_exit()
# Check if there's a front sight at bottom-left corner
area = area_offset((-50, -150, 0, 0), offset=self.config.ASSETS_RESOLUTION)
skip_first_screenshot = True
self._map_A_timer.reset()
handled = False
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.image_color_count(area, color=(48, 170, 204), threshold=221, count=50):
logger.info(f'Found destructible object')
if self.handle_map_A():
handled = True
continue
else:
logger.info(f'No destructible object')
if not handled:
break
if self._map_A_timer.reached():
break
return handled