From e8dcd8ac95ca154461e13f9302d5ddd385481bf6 Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Sat, 18 May 2024 02:35:44 +0800 Subject: [PATCH] Add: Do planner requested dungeon first --- tasks/combat/combat.py | 15 ++++++++++- tasks/dungeon/dungeon.py | 9 +++++++ tasks/planner/model.py | 55 +++++++++++++++++++++++++++++++--------- 3 files changed, 66 insertions(+), 13 deletions(-) diff --git a/tasks/combat/combat.py b/tasks/combat/combat.py index c460b1f77..4a6503a2e 100644 --- a/tasks/combat/combat.py +++ b/tasks/combat/combat.py @@ -5,15 +5,20 @@ from tasks.combat.assets.assets_combat_finish import COMBAT_AGAIN, COMBAT_EXIT from tasks.combat.assets.assets_combat_prepare import COMBAT_PREPARE from tasks.combat.assets.assets_combat_team import COMBAT_TEAM_PREPARE, COMBAT_TEAM_SUPPORT from tasks.combat.interact import CombatInteract +from tasks.combat.obtain import CombatObtain from tasks.combat.prepare import CombatPrepare from tasks.combat.skill import CombatSkill from tasks.combat.state import CombatState from tasks.combat.support import CombatSupport from tasks.combat.team import CombatTeam +from tasks.dungeon.keywords import DungeonList from tasks.map.control.joystick import MapControlJoystick -class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSupport, CombatSkill, MapControlJoystick): +class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSupport, CombatSkill, CombatObtain, + MapControlJoystick): + dungeon: DungeonList | None = None + def handle_combat_prepare(self): """ Returns: @@ -120,6 +125,9 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo self.interval_reset(COMBAT_PREPARE) self.map_A_timer.reset() if self.appear(COMBAT_PREPARE, interval=2): + if self.obtained_is_full(self.dungeon): + self.combat_exit() + self.config.task_stop() if not self.handle_combat_prepare(): return False self.device.click(COMBAT_PREPARE) @@ -191,6 +199,11 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo logger.info(f'Combat wave limit: {self.combat_wave_done}/{self.combat_wave_limit}, ' f'can not run again') return False + # Planner + logger.attr('obtain_frequent_check', self.obtain_frequent_check) + if self.obtain_frequent_check: + logger.info('Exit combat to check obtained items') + return False # Cost limit if self.combat_wave_cost == 10: diff --git a/tasks/dungeon/dungeon.py b/tasks/dungeon/dungeon.py index a2affe666..2887d1582 100644 --- a/tasks/dungeon/dungeon.py +++ b/tasks/dungeon/dungeon.py @@ -75,7 +75,9 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat): if relic == 0: return 0 # Combat + self.dungeon = dungeon count = self.combat(team=team, wave_limit=wave_limit, support_character=support_character) + self.dungeon = None # Update quest states with self.config.multi_set(): @@ -225,10 +227,13 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat): ran_calyx_golden = False ran_calyx_crimson = False ran_cavern_of_corrosion = False + planner = self.planner.get_dungeon(double_calyx=True) # Double calyx if self.config.stored.DungeonDouble.calyx > 0: logger.info('Run double calyx') dungeon = DungeonList.find(self.config.Dungeon_NameAtDoubleCalyx) + if planner is not None: + dungeon = planner self.running_double = True if self.dungeon_run(dungeon=dungeon, wave_limit=self.config.stored.DungeonDouble.calyx): if dungeon.is_Calyx_Golden: @@ -258,6 +263,10 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat): final = KEYWORDS_DUNGEON_LIST.Simulated_Universe_World_1 else: final = DungeonList.find(self.config.Dungeon_Name) + # Planner + planner = self.planner.get_dungeon() + if planner is not None: + final = planner # Run dungeon that required by daily quests # Calyx_Golden diff --git a/tasks/planner/model.py b/tasks/planner/model.py index 632e18874..672ec832d 100644 --- a/tasks/planner/model.py +++ b/tasks/planner/model.py @@ -284,6 +284,8 @@ class PlannerProgressParser: if not row.item.is_group_base: logger.error(f'from_config: item is not group base {row}') continue + row.update_synthesize() + row.update_progress() self.rows[row.item.name] = row return self @@ -296,43 +298,61 @@ class PlannerProgressParser: data[name] = dic return data - def iter_item_to_farm(self) -> t.Iterable[ItemBase]: - rows = [row for row in self.rows.values() if row.need_farm()] + def iter_row_to_farm(self, need_farm=True) -> t.Iterable[StoredPlannerProxy]: + """ + Args: + need_farm: True if filter rows that need farm + + Yields: + + """ + if need_farm: + rows = [row for row in self.rows.values() if row.need_farm()] + else: + rows = self.rows.values() + for row in rows: if row.item.is_ItemWeekly: - yield row.item + yield row for row in rows: if row.item.is_ItemAscension: - yield row.item + yield row for row in rows: if row.item.is_ItemTrace: - yield row.item + yield row for row in rows: if row.item.is_ItemExp: - yield row.item + yield row for row in rows: if row.item.is_ItemCurrency: - yield row.item + yield row - def get_dungeon(self) -> DungeonList | None: + def get_dungeon(self, double_calyx=False) -> DungeonList | None: """ Get dungeon to farm, or None if planner finished or the remaining items cannot be farmed """ - for item in self.iter_item_to_farm(): + for row in self.iter_row_to_farm(): + item = row.item if item.is_ItemWeekly: continue dungeon = item.dungeon if dungeon is None: logger.error(f'Item {item} has nowhere to be farmed') continue - logger.info(f'Planner farm: {dungeon}') - return dungeon + if double_calyx: + if dungeon.is_Calyx: + logger.info(f'Planner farm (double_calyx): {dungeon}') + return dungeon + else: + logger.info(f'Planner farm: {dungeon}') + return dungeon logger.info('Planner farm empty') return None def get_weekly(self) -> DungeonList | None: - for item in self.iter_item_to_farm(): + for row in self.iter_row_to_farm(): + item = row.item if not item.is_ItemWeekly: continue dungeon = item.dungeon @@ -345,6 +365,17 @@ class PlannerProgressParser: logger.info('Planner farm empty') return None + def row_come_from_dungeon(self, dungeon: DungeonList | None) -> StoredPlannerProxy | None: + """ + If any items in planner is able to be farmed from given dungeon + """ + if dungeon is None: + return None + for row in self.iter_row_to_farm(need_farm=False): + if row.item.dungeon == dungeon: + logger.info(f'Planner {row} come from {dungeon}') + return row + return None class PlannerMixin(UI):