diff --git a/assets/share/combat/prepare/OCR_WAVE_COST.png b/assets/share/combat/prepare/OCR_WAVE_COST.png new file mode 100644 index 000000000..0adbfb8fa Binary files /dev/null and b/assets/share/combat/prepare/OCR_WAVE_COST.png differ diff --git a/tasks/combat/assets/assets_combat_prepare.py b/tasks/combat/assets/assets_combat_prepare.py index fd114f38f..418721326 100644 --- a/tasks/combat/assets/assets_combat_prepare.py +++ b/tasks/combat/assets/assets_combat_prepare.py @@ -23,6 +23,16 @@ OCR_TRAILBLAZE_POWER = ButtonWrapper( button=(998, 26, 1130, 48), ), ) +OCR_WAVE_COST = ButtonWrapper( + name='OCR_WAVE_COST', + share=Button( + file='./assets/share/combat/prepare/OCR_WAVE_COST.png', + area=(845, 649, 891, 667), + search=(825, 629, 911, 687), + color=(50, 53, 57), + button=(845, 649, 891, 667), + ), +) OCR_WAVE_COUNT = ButtonWrapper( name='OCR_WAVE_COUNT', share=Button( diff --git a/tasks/combat/combat.py b/tasks/combat/combat.py index 5f24e0b28..eb07b269a 100644 --- a/tasks/combat/combat.py +++ b/tasks/combat/combat.py @@ -11,29 +11,20 @@ from tasks.combat.team import CombatTeam class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam): - _combat_has_multi_wave = True - - @property - def combat_cost(self): - if self._combat_has_multi_wave: - return 10 - else: - return 30 - def handle_combat_prepare(self): """ Pages: in: COMBAT_PREPARE """ current = self.combat_get_trailblaze_power() - self._combat_has_multi_wave = self.combat_has_multi_wave() - if self._combat_has_multi_wave: - wave = min(current // self.combat_cost, 6) - logger.info(f'Current has {current}, combat costs {self.combat_cost}, able to do {wave} waves') + cost = self.combat_get_wave_cost() + if cost == 10: + wave = min(current // self.combat_wave_cost, 6) + logger.info(f'Current has {current}, combat costs {self.combat_wave_cost}, able to do {wave} waves') if wave > 0: self.combat_set_wave(wave) else: - logger.info(f'Current has {current}, combat costs {self.combat_cost}, do 1 wave') + logger.info(f'Current has {current}, combat costs {self.combat_wave_cost}, do 1 wave') def combat_prepare(self, team=1): """ @@ -70,7 +61,7 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam): self.interval_reset(COMBAT_PREPARE) if self.appear(COMBAT_PREPARE, interval=2): self.handle_combat_prepare() - if self.state.TrailblazePower < self.combat_cost: + if self.state.TrailblazePower < self.combat_wave_cost: return False self.device.click(COMBAT_PREPARE) self.interval_reset(COMBAT_PREPARE) @@ -115,16 +106,20 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam): in: COMBAT_AGAIN """ current = self.combat_get_trailblaze_power(expect_reduce=True) - if self._combat_has_multi_wave: - if current >= self.combat_cost * 6: - logger.info(f'Current has {current}, combat costs {self.combat_cost}, can run again') + if self.combat_wave_cost == 10: + if current >= self.combat_wave_cost * 6: + logger.info(f'Current has {current}, combat costs {self.combat_wave_cost}, can run again') return True else: - logger.info(f'Current has {current}, combat costs {self.combat_cost}, can not run again') + logger.info(f'Current has {current}, combat costs {self.combat_wave_cost}, can not run again') return False else: - logger.info(f'Current has {current}, combat costs {self.combat_cost}, no again') - return False + if current >= self.combat_wave_cost: + logger.info(f'Current has {current}, combat costs {self.combat_wave_cost}, can run again') + return True + else: + logger.info(f'Current has {current}, combat costs {self.combat_wave_cost}, can not run again') + return False def combat_finish(self) -> bool: """ @@ -219,7 +214,7 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam): self.combat_execute() # Finish finish = self.combat_finish() - if self.state.TrailblazePower >= self.combat_cost: + if self.state.TrailblazePower >= self.combat_wave_cost: logger.info('Still having some trailblaze power run with less waves to empty it') continue if finish: diff --git a/tasks/combat/prepare.py b/tasks/combat/prepare.py index 866bd22b1..acafa9f6c 100644 --- a/tasks/combat/prepare.py +++ b/tasks/combat/prepare.py @@ -1,10 +1,12 @@ import re from module.base.timer import Timer +from module.logger import logger from module.ocr.ocr import Digit, DigitCounter from tasks.base.ui import UI from tasks.combat.assets.assets_combat_prepare import ( OCR_TRAILBLAZE_POWER, + OCR_WAVE_COST, OCR_WAVE_COUNT, WAVE_MINUS, WAVE_PLUS @@ -21,6 +23,8 @@ class TrailblazePowerOcr(DigitCounter): class CombatPrepare(UI): + combat_wave_cost = True + def combat_set_wave(self, count=6): """ Args: @@ -69,3 +73,49 @@ class CombatPrepare(UI): self.state.TrailblazePower = current return current + + def combat_get_wave_cost(self): + """ + Get traiblaze power cost and set it to `combat_cost` + + Returns + int: 10, 30, 40 + + Pages: + in: COMBAT_PREPARE + """ + multi = self.combat_has_multi_wave() + logger.attr('CombatMultiWave', multi) + if multi: + cost = 10 + else: + cost = 40 + + timeout = Timer(1.5, count=6).start() + for _ in range(2): + cost = Digit(OCR_WAVE_COST).ocr_single_line(self.device.image) + if cost == 10: + if multi: + self.combat_wave_cost = cost + return cost + else: + logger.warning(f'Combat wave costs {cost} but does not has multiple waves') + self.combat_wave_cost = cost + return cost + elif cost in [30, 40]: + if multi: + logger.warning(f'Combat wave costs {cost} but has multiple waves, ' + f'probably wave amount is preset') + self.combat_set_wave(1) + timeout.reset() + continue + else: + self.combat_wave_cost = cost + return cost + else: + logger.warning(f'Unexpected combat wave cost: {cost}') + continue + + logger.warning(f'Get combat wave cost timeout, assume it costs {cost}') + self.combat_wave_cost = cost + return cost diff --git a/tasks/dungeon/ui.py b/tasks/dungeon/ui.py index ae4b830f2..1aa19e3eb 100644 --- a/tasks/dungeon/ui.py +++ b/tasks/dungeon/ui.py @@ -261,6 +261,11 @@ class DungeonUI(UI): self._dungeon_insight(dungeon) self._dungeon_enter(dungeon) return True + if dungeon.is_Cavern_of_Corrosion: + DUNGEON_NAV_LIST.select_row(KEYWORDS_DUNGEON_NAV.Cavern_of_Corrosion, main=self) + self._dungeon_insight(dungeon) + self._dungeon_enter(dungeon) + return True logger.error(f'Goto dungeon {dungeon} is not supported') return False