From 6f0e3a38d063248577643839918a0039ce44ccc7 Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Wed, 8 Dec 2021 01:16:41 +0800 Subject: [PATCH] Add: Handle shared CD of recon scan and submarine call - Add entrance of OpSi abyssal and stronghold --- alas.py | 8 ++++ module/campaign/os_run.py | 20 ++++++++-- module/config/config.py | 48 ++++++++++++++++++++++++ module/config/config_manual.py | 2 +- module/os/globe_camera.py | 2 +- module/os/operation_siren.py | 68 ++++++++++++++++++++++++---------- module/os_handler/map_order.py | 2 + 7 files changed, 126 insertions(+), 24 deletions(-) diff --git a/alas.py b/alas.py index 8561de8cb..87ae29f26 100644 --- a/alas.py +++ b/alas.py @@ -223,6 +223,14 @@ class AzurLaneAutoScript: from module.campaign.os_run import OSCampaignRun OSCampaignRun(config=self.config, device=self.device).opsi_obscure() + def opsi_abyssal(self): + from module.campaign.os_run import OSCampaignRun + OSCampaignRun(config=self.config, device=self.device).opsi_abyssal() + + def opsi_stronghold(self): + from module.campaign.os_run import OSCampaignRun + OSCampaignRun(config=self.config, device=self.device).opsi_stronghold() + def opsi_meowfficer_farming(self): from module.campaign.os_run import OSCampaignRun OSCampaignRun(config=self.config, device=self.device).opsi_meowfficer_farming() diff --git a/module/campaign/os_run.py b/module/campaign/os_run.py index 094c30ef5..31aeaa002 100644 --- a/module/campaign/os_run.py +++ b/module/campaign/os_run.py @@ -24,14 +24,14 @@ class OSCampaignRun(OSMapOperation): try: self.campaign.os_explore() except ActionPointLimit: - self.campaign.config.task_delay(minute=360) + self.config.opsi_task_delay(ap_limit=True) def opsi_daily(self): self.load_campaign() try: self.campaign.os_daily() except ActionPointLimit: - self.campaign.config.task_delay(minute=360) + self.config.opsi_task_delay(ap_limit=True) def opsi_meowfficer_farming(self): self.load_campaign() @@ -45,4 +45,18 @@ class OSCampaignRun(OSMapOperation): try: self.campaign.os_obscure() except ActionPointLimit: - self.campaign.config.task_delay(minute=360) + self.config.opsi_task_delay(ap_limit=True) + + def opsi_abyssal(self): + self.load_campaign() + try: + self.campaign.os_abyssal() + except ActionPointLimit: + self.config.opsi_task_delay(ap_limit=True) + + def opsi_stronghold(self): + self.load_campaign() + try: + self.campaign.os_stronghold() + except ActionPointLimit: + self.config.opsi_task_delay(ap_limit=True) diff --git a/module/config/config.py b/module/config/config.py index bd529a0bb..380428e79 100644 --- a/module/config/config.py +++ b/module/config/config.py @@ -10,6 +10,7 @@ from module.config.config_updater import ConfigUpdater from module.config.utils import * from module.exception import RequestHumanTakeover, ScriptError from module.logger import logger +from module.map.map_grids import SelectedGrids class TaskEnd(Exception): @@ -304,6 +305,53 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig): else: raise ScriptError('Missing argument in delay_next_run, should set at least one') + def opsi_task_delay(self, recon_scan=False, submarine_call=False, ap_limit=False): + """ + Delay the NextRun of all OpSi tasks. + + Args: + recon_scan (bool): True to delay all tasks requiring recon scan 30 min. + submarine_call (bool): True to delay all tasks requiring submarine call 60 min. + ap_limit (bool): True to delay all tasks requiring action points 360 min. + """ + if not recon_scan and not submarine_call and not ap_limit: + return None + kv = dict_to_kv({'recon_scan': recon_scan, 'submarine_call': submarine_call, 'ap_limit': ap_limit}) + + def delay_tasks(task_list, minutes): + next_run = datetime.now().replace(microsecond=0) + timedelta(minutes=minutes) + for task in task_list: + keys = f'{task}.Scheduler.NextRun' + current = deep_get(self.data, keys=keys, default=datetime(2020, 1, 1, 0, 0)) + if current < next_run: + logger.info(f'Delay task `{task}`` to {next_run} ({kv})') + self.modified[keys] = next_run + + def is_submarine_call(task): + return deep_get(self.data, keys=f'{task}.OpsiFleet.Submarine', default=False) \ + or 'submarine' in deep_get(self.data, keys=f'{task}.OpsiFleetFilter.Filter', default='').lower() + + def is_not_force_run(task): + return not (deep_get(self.data, keys=f'{task}.OpsiExplore.SpecialRadar', default=False) + or deep_get(self.data, keys=f'{task}.OpsiExplore.ForceRun', default=False) + or deep_get(self.data, keys=f'{task}.OpsiObscure.ForceRun', default=False) + or deep_get(self.data, keys=f'{task}.OpsiAbyssal.ForceRun', default=False) + or deep_get(self.data, keys=f'{task}.OpsiStronghold.ForceRun', default=False)) + + if recon_scan: + tasks = SelectedGrids(['OpsiExplore', 'OpsiObscure', 'OpsiStronghold']) + delay_tasks(tasks.filter(is_not_force_run).grids, minutes=30) + if submarine_call: + tasks = SelectedGrids(['OpsiExplore', 'OpsiDaily', 'OpsiObscure', 'OpsiAbyssal', 'OpsiFleetFilter', + 'OpsiMeowfficerFarming']) + delay_tasks(tasks.filter(is_submarine_call).filter(is_not_force_run).grids, minutes=60) + if ap_limit: + tasks = SelectedGrids(['OpsiExplore', 'OpsiDaily', 'OpsiObscure', 'OpsiAbyssal', 'OpsiFleetFilter', + 'OpsiMeowfficerFarming']) + delay_tasks(tasks.filter(is_submarine_call).filter(is_not_force_run).grids, minutes=360) + + self.save() + def task_call(self, task): """ Call another task to run. diff --git a/module/config/config_manual.py b/module/config/config_manual.py index e80d49a84..63d6c0294 100644 --- a/module/config/config_manual.py +++ b/module/config/config_manual.py @@ -10,7 +10,7 @@ class ManualConfig: > Gacha > SupplyPack > Reward > BattlePass > ShopFrequent > ShopOnce > Shipyard > DataKey - > OpsiExplore > OpsiObscure + > OpsiExplore > OpsiAbyssal > OpsiStronghold > OpsiObscure > Exercise > Daily > Hard > OpsiAshAssist > Sos > EventSp > EventAb > EventCd > RaidDaily > WarArchives > OpsiDaily > OpsiMeowfficerFarming diff --git a/module/os/globe_camera.py b/module/os/globe_camera.py index 86cbe4f2e..26c192a2a 100644 --- a/module/os/globe_camera.py +++ b/module/os/globe_camera.py @@ -127,7 +127,7 @@ class GlobeCamera(GlobeOperation, ZoneManager): out: IN_GLOBE, zone selected, ZONE_ENTRANCE """ zone = self.name_to_zone(zone) - logger.info(f'Globe focus_to: {zone}') + logger.info(f'Globe focus_to: {zone.zone_id}') interval = Timer(2, count=2) while 1: diff --git a/module/os/operation_siren.py b/module/os/operation_siren.py index 6d4e09f37..9c7b43e20 100644 --- a/module/os/operation_siren.py +++ b/module/os/operation_siren.py @@ -18,6 +18,7 @@ class OperationSiren(Reward, OSMap): out: IN_MAP """ logger.hr('OS init', level=1) + self.config.override(Submarine_Fleet=1, Submarine_Mode='every_combat') # UI switching if self.is_in_map(): @@ -230,6 +231,10 @@ class OperationSiren(Reward, OSMap): self.zone_init() if result > 1: self.globe_goto(self.zone, refresh=True) + self.fleet_set(self.config.OpsiFleet_Fleet) + self.os_order_execute( + recon_scan=False, + submarine_call=self.config.OpsiFleet_Submarine) self.run_auto_search() self.handle_fleet_repair(revert=False) self.config.check_task_switch() @@ -276,6 +281,10 @@ class OperationSiren(Reward, OSMap): else: logger.hr(f'OS meowfficer farming, zone_id={zone.zone_id}', level=1) self.globe_goto(zone) + self.fleet_set(self.config.OpsiFleet_Fleet) + self.os_order_execute( + recon_scan=False, + submarine_call=self.config.OpsiFleet_Submarine) self.run_auto_search() self.handle_fleet_repair(revert=False) self.globe_goto(self.zone_nearest_azur_port(zone=zone)) @@ -288,6 +297,10 @@ class OperationSiren(Reward, OSMap): logger.hr(f'OS meowfficer farming, zone_id={zones[0].zone_id}', level=1) self.globe_goto(zones[0]) + self.fleet_set(self.config.OpsiFleet_Fleet) + self.os_order_execute( + recon_scan=False, + submarine_call=self.config.OpsiFleet_Submarine) self.run_auto_search() self.handle_fleet_repair(revert=False) self.config.check_task_switch() @@ -325,11 +338,10 @@ class OperationSiren(Reward, OSMap): continue logger.hr(f'OS explore {zone}', level=1) - if self.config.OpsiExplore_SpecialRadar: - self.os_order_execute(recon_scan=False, submarine_call=False) - else: - self.os_order_execute(recon_scan=True, submarine_call=False) - self.config.task_delay(minute=30) + self.fleet_set(self.config.OpsiFleet_Fleet) + self.os_order_execute( + recon_scan=not self.config.OpsiExplore_SpecialRadar, + submarine_call=self.config.OpsiFleet_Submarine) self.run_auto_search() self.config.OpsiExplore_LastZone = zone logger.info(f'Zone cleared: {self.name_to_zone(zone)}') @@ -355,20 +367,11 @@ class OperationSiren(Reward, OSMap): self.zone_init() self.fleet_set(self.config.OpsiFleet_Fleet) - self.os_order_execute(recon_scan=True, submarine_call=self.config.OpsiFleet_Submarine) - - # Delay next run 30min or 60min. - if self.config.OpsiFleet_Submarine: - delta = 60 - backup_submarine = self.config.temporary(Submarine_Fleet=1, Submarine_Mode='every_combat') - else: - delta = 30 - backup_submarine = None - if not self.config.OpsiObscure_ForceRun: - self.config.task_delay(minute=delta) - + self.os_order_execute( + recon_scan=True, + submarine_call=self.config.OpsiFleet_Submarine) self.run_auto_search() - backup_submarine.recover() if backup_submarine is not None else None + self.map_exit() self.handle_fleet_repair(revert=False) @@ -384,7 +387,7 @@ class OperationSiren(Reward, OSMap): def clear_abyssal(self): """ Get one abyssal logger in storage, - Attack abyssal boss, + attack abyssal boss, repair fleets in port. Raises: @@ -411,6 +414,33 @@ class OperationSiren(Reward, OSMap): self.clear_abyssal() self.config.check_task_switch() + def clear_stronghold(self): + """ + Find a siren stronghold on globe map, + clear stronghold, + repair fleets in port. + + Raises: + ActionPointLimit: + TaskEnd: If no more strongholds. + RequestHumanTakeover: If unable to clear boss, fleets exhausted. + """ + logger.hr('OS clear stronghold', level=1) + zone = self.find_siren_stronghold() + if zone is None: + # No siren stronghold, delay next run to tomorrow. + self.config.task_delay(server_update=True) + self.config.task_stop() + + raise NotImplementedError + + self.fleet_repair(revert=False) + + def os_stronghold(self): + while 1: + self.clear_abyssal() + self.config.check_task_switch() + if __name__ == '__main__': self = OperationSiren('alas', task='OpsiObscure') diff --git a/module/os_handler/map_order.py b/module/os_handler/map_order.py index 9530c12be..3f0927645 100644 --- a/module/os_handler/map_order.py +++ b/module/os_handler/map_order.py @@ -114,6 +114,8 @@ class MapOrderHandler(MapOperation, ActionPointHandler, EnemySearchingHandler, Z if submarine_call: self.order_execute(ORDER_SUBMARINE) + self.config.opsi_task_delay(recon_scan=recon_scan, submarine_call=submarine_call) + # backup.recover() def handle_map_cat_attack(self):