Add: [EN] Support for OS world clearing

This commit is contained in:
nEEtdo0d 2021-05-14 16:19:55 -04:00
parent e0aa32e18b
commit 43ee1f35fe
8 changed files with 62 additions and 4 deletions

View File

@ -231,6 +231,12 @@ class AzurLaneAutoScript:
az = OSCampaignRun(self.config, device=self.device)
az.run()
def os_world_clear(self):
from module.campaign.os_run import OSCampaignRun
az = OSCampaignRun(self.config, device=self.device)
az.run_clear_os_world()
self.reward_when_finished()
def os_fully_auto(self):
from module.campaign.os_run import OSCampaignRun
az = OSCampaignRun(self.config, device=self.device)

View File

@ -222,6 +222,10 @@ enable_os_semi_story_skip = yes
[Os_clear_map]
enable_os_ash_attack = yes
[Os_world_clear]
os_world_max_level = 4
os_world_repair_after_clear = 3
[Os_fully_auto]
do_os_in_daily = no
enable_os_mission_accept = yes

View File

@ -43,3 +43,7 @@ class OSCampaignRun(OSMapOperation):
def run_daily(self):
self.load_campaign()
self.campaign.operation_siren_daily()
def run_clear_os_world(self):
self.load_campaign()
self.campaign.clear_os_world()

View File

@ -579,6 +579,17 @@ def main(ini_name=''):
# os_semi = os_semi_parser.add_argument_group('os_clear_map', 'Only recommended to use in save zones. To use in normal zones, execute air search manually first.\nUsage: Enter map manually and run\nRecommend to re-check map manually after run', gooey_options={'label_color': '#931D03'})
# os_semi.add_argument('--enable_os_ash_attack', default=default('--enable_os_ash_attack'), choices=['yes', 'no'], help='Attack ash if beacon data is full', gooey_options={'label_color': '#4B5F83'})
# ==========OS clear world==========
os_world_parser = subs.add_parser('os_world_clear')
os_world = os_world_parser.add_argument_group('os_world_clear', 'Explore all unsafe zones and turn into safe', gooey_options={'label_color': '#931D03'})
os_world.add_argument('--os_world_max_level', default=default('--os_world_max_level'),
help='Stop unsafe exploration after completing all zones of at '
'least the configured hazard level. '
'Recommended 4 or lower for single fleet clear, 5 and higher '
'tend to be more difficult depending on adaptibility numbers',
gooey_options={'label_color': '#4B5F83'})
os_world.add_argument('--os_world_repair_after_clear', default=default('--os_world_repair_after_clear'), help='Number of zone clears before retreating to port for repair', gooey_options={'label_color': '#4B5F83'})
# ==========OS fully auto==========
os_parser = subs.add_parser('os_fully_auto')
os = os_parser.add_argument_group('OS fully auto', 'Run sequence: Accept dailies and buy supplies > do dailies > do obscure zone > meowfficer farming\nPort shop is a limited pool of items. Ports have the same items, but appear randomly. Buy all if you want good items\nShop priority format: ActionPoint > PurpleCoins > TuringSample > RepairPack', gooey_options={'label_color': '#931D03'})

View File

@ -510,6 +510,12 @@ class AzurLaneConfig:
"""
ENABLE_OS_SEMI_STORY_SKIP = True
"""
Os_world_clear
"""
OS_WORLD_MAX_LEVEL = 4
OS_WORLD_REPAIR_AFTER_CLEAR = 3
"""
module.os
"""
@ -805,6 +811,11 @@ class AzurLaneConfig:
option = config['Os_clear_map']
self.ENABLE_OS_ASH_ATTACK = to_bool(option['enable_os_ash_attack'])
# OS clear world
option = config['Os_world_clear']
self.OS_WORLD_MAX_LEVEL = int(option['os_world_max_level']) + 1
self.OS_WORLD_REPAIR_AFTER_CLEAR = int(option['os_world_repair_after_clear'])
# OS fully auto
option = config['Os_fully_auto']
for attr in ['do_os_in_daily', 'enable_os_mission_accept', 'enable_os_mission_finish', 'enable_os_supply_buy',

View File

@ -237,6 +237,8 @@ dic_true_eng_to_eng = {
'ammo_pick_up_124': 'ammo_pick_up_124',
'default_serial_list': 'default_serial_list',
'enable_os_semi_story_skip': 'enable_os_semi_story_skip',
'os_world_max_level': 'os_world_max_level',
'os_world_repair_after_clear': 'os_world_repair_after_clear',
'do_os_in_daily': 'do_os_in_daily',
'enable_os_mission_accept': 'enable_os_mission_accept',
'enable_os_mission_finish': 'enable_os_mission_finish',

View File

@ -118,13 +118,16 @@ class GlobeOperation(ActionPointHandler, MapEventHandler):
"""
return len(self.get_zone_select()) > 0
def zone_type_select(self, types=('SAFE', 'DANGEROUS')):
def zone_type_select(self, types=('SAFE', 'DANGEROUS'), exclusive=False):
"""
Args:
types (tuple[str], list[str], str): Zone types, or a list of them.
Available types: DANGEROUS, SAFE, OBSCURE, LOGGER, STRONGHOLD.
Try the the first selection in type list, if not available, try the next one.
Do nothing if no selection satisfied input.
exclusive (bool): If target type not found, default to fallback to return to
pinned state however return 'False' to indicate did not perform intended
selection
Returns:
bool: If success.
@ -153,6 +156,7 @@ class GlobeOperation(ActionPointHandler, MapEventHandler):
logger.info(f'Already selected at {pinned}')
return True
found = True
for _ in range(3):
self.ui_click(ZONE_SWITCH, appear_button=self.is_zone_pinned, check_button=self.is_in_zone_select,
skip_first_screenshot=True)
@ -164,9 +168,12 @@ class GlobeOperation(ActionPointHandler, MapEventHandler):
logger.warning('No such zone type to select, fallback to default')
types = ('SAFE', 'DANGEROUS')
button = get_button(selection)
found = False
self.ui_click(button, check_button=self.is_zone_pinned, offset=self._zone_select_offset,
skip_first_screenshot=True)
if exclusive and not found:
return False
if self.pinned_to_name(button) == self.pinned_to_name(self.get_zone_pinned()):
return True

View File

@ -81,11 +81,13 @@ class OperationSiren(OSMap):
self.globe_focus_to(zone)
if stop_if_safe:
pinned = self.pinned_to_name(self.get_zone_pinned())
if pinned == 'SAFE':
if pinned == 'SAFE' or \
(self.zone_has_switch() and self.zone_type_select(types='SAFE', exclusive=True)):
logger.info('Zone is safe, stopped')
self.ensure_no_zone_pinned()
return False
self.zone_type_select(types=types)
else:
self.zone_type_select(types=types)
self.globe_enter(zone)
# IN_MAP
if hasattr(self, 'zone'):
@ -203,7 +205,7 @@ class OperationSiren(OSMap):
self.run_auto_search()
def _clear_os_world(self):
for hazard_level in range(1, 7):
for hazard_level in range(1, self.config.OS_WORLD_MAX_LEVEL):
zones = self.zone_select(hazard_level=hazard_level) \
.delete(SelectedGrids(self.zones.select(is_port=True))) \
.sort_by_clock_degree(center=(1252, 1012), start=self.zone.location)
@ -212,6 +214,7 @@ class OperationSiren(OSMap):
if not self.globe_goto(zone, stop_if_safe=True):
continue
self.run_auto_search()
self._repair_after(self.config.OS_WORLD_REPAIR_AFTER_CLEAR)
def clear_os_world(self):
"""
@ -221,6 +224,7 @@ class OperationSiren(OSMap):
# Force to use AP boxes
backup = self.config.cover(OS_ACTION_POINT_PRESERVE=40, OS_ACTION_POINT_BOX_USE=True)
self.fleet_repair(revert=False)
try:
self._clear_os_world()
except ActionPointLimit:
@ -281,3 +285,12 @@ class OperationSiren(OSMap):
backup.recover()
return True
_zone_complete = 0
def _repair_after(self, threshold):
self._zone_complete += 1
if self._zone_complete >= threshold:
self.get_current_zone()
self.fleet_repair(revert=False)
self._zone_complete = 0