Add: Do planner requested dungeon first

This commit is contained in:
LmeSzinc 2024-05-18 02:35:44 +08:00
parent d854a90c4c
commit e8dcd8ac95
3 changed files with 66 additions and 13 deletions

View File

@ -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_prepare import COMBAT_PREPARE
from tasks.combat.assets.assets_combat_team import COMBAT_TEAM_PREPARE, COMBAT_TEAM_SUPPORT from tasks.combat.assets.assets_combat_team import COMBAT_TEAM_PREPARE, COMBAT_TEAM_SUPPORT
from tasks.combat.interact import CombatInteract from tasks.combat.interact import CombatInteract
from tasks.combat.obtain import CombatObtain
from tasks.combat.prepare import CombatPrepare from tasks.combat.prepare import CombatPrepare
from tasks.combat.skill import CombatSkill from tasks.combat.skill import CombatSkill
from tasks.combat.state import CombatState from tasks.combat.state import CombatState
from tasks.combat.support import CombatSupport from tasks.combat.support import CombatSupport
from tasks.combat.team import CombatTeam from tasks.combat.team import CombatTeam
from tasks.dungeon.keywords import DungeonList
from tasks.map.control.joystick import MapControlJoystick 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): def handle_combat_prepare(self):
""" """
Returns: Returns:
@ -120,6 +125,9 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
self.interval_reset(COMBAT_PREPARE) self.interval_reset(COMBAT_PREPARE)
self.map_A_timer.reset() self.map_A_timer.reset()
if self.appear(COMBAT_PREPARE, interval=2): 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(): if not self.handle_combat_prepare():
return False return False
self.device.click(COMBAT_PREPARE) 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}, ' logger.info(f'Combat wave limit: {self.combat_wave_done}/{self.combat_wave_limit}, '
f'can not run again') f'can not run again')
return False 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 # Cost limit
if self.combat_wave_cost == 10: if self.combat_wave_cost == 10:

View File

@ -75,7 +75,9 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat):
if relic == 0: if relic == 0:
return 0 return 0
# Combat # Combat
self.dungeon = dungeon
count = self.combat(team=team, wave_limit=wave_limit, support_character=support_character) count = self.combat(team=team, wave_limit=wave_limit, support_character=support_character)
self.dungeon = None
# Update quest states # Update quest states
with self.config.multi_set(): with self.config.multi_set():
@ -225,10 +227,13 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat):
ran_calyx_golden = False ran_calyx_golden = False
ran_calyx_crimson = False ran_calyx_crimson = False
ran_cavern_of_corrosion = False ran_cavern_of_corrosion = False
planner = self.planner.get_dungeon(double_calyx=True)
# Double calyx # Double calyx
if self.config.stored.DungeonDouble.calyx > 0: if self.config.stored.DungeonDouble.calyx > 0:
logger.info('Run double calyx') logger.info('Run double calyx')
dungeon = DungeonList.find(self.config.Dungeon_NameAtDoubleCalyx) dungeon = DungeonList.find(self.config.Dungeon_NameAtDoubleCalyx)
if planner is not None:
dungeon = planner
self.running_double = True self.running_double = True
if self.dungeon_run(dungeon=dungeon, wave_limit=self.config.stored.DungeonDouble.calyx): if self.dungeon_run(dungeon=dungeon, wave_limit=self.config.stored.DungeonDouble.calyx):
if dungeon.is_Calyx_Golden: if dungeon.is_Calyx_Golden:
@ -258,6 +263,10 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat):
final = KEYWORDS_DUNGEON_LIST.Simulated_Universe_World_1 final = KEYWORDS_DUNGEON_LIST.Simulated_Universe_World_1
else: else:
final = DungeonList.find(self.config.Dungeon_Name) 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 # Run dungeon that required by daily quests
# Calyx_Golden # Calyx_Golden

View File

@ -284,6 +284,8 @@ class PlannerProgressParser:
if not row.item.is_group_base: if not row.item.is_group_base:
logger.error(f'from_config: item is not group base {row}') logger.error(f'from_config: item is not group base {row}')
continue continue
row.update_synthesize()
row.update_progress()
self.rows[row.item.name] = row self.rows[row.item.name] = row
return self return self
@ -296,43 +298,61 @@ class PlannerProgressParser:
data[name] = dic data[name] = dic
return data return data
def iter_item_to_farm(self) -> t.Iterable[ItemBase]: def iter_row_to_farm(self, need_farm=True) -> t.Iterable[StoredPlannerProxy]:
rows = [row for row in self.rows.values() if row.need_farm()] """
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: for row in rows:
if row.item.is_ItemWeekly: if row.item.is_ItemWeekly:
yield row.item yield row
for row in rows: for row in rows:
if row.item.is_ItemAscension: if row.item.is_ItemAscension:
yield row.item yield row
for row in rows: for row in rows:
if row.item.is_ItemTrace: if row.item.is_ItemTrace:
yield row.item yield row
for row in rows: for row in rows:
if row.item.is_ItemExp: if row.item.is_ItemExp:
yield row.item yield row
for row in rows: for row in rows:
if row.item.is_ItemCurrency: 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 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: if item.is_ItemWeekly:
continue continue
dungeon = item.dungeon dungeon = item.dungeon
if dungeon is None: if dungeon is None:
logger.error(f'Item {item} has nowhere to be farmed') logger.error(f'Item {item} has nowhere to be farmed')
continue continue
logger.info(f'Planner farm: {dungeon}') if double_calyx:
return dungeon 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') logger.info('Planner farm empty')
return None return None
def get_weekly(self) -> DungeonList | 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: if not item.is_ItemWeekly:
continue continue
dungeon = item.dungeon dungeon = item.dungeon
@ -345,6 +365,17 @@ class PlannerProgressParser:
logger.info('Planner farm empty') logger.info('Planner farm empty')
return None 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): class PlannerMixin(UI):