1
0
mirror of https://github.com/0O0o0oOoO00/Alas.git synced 2026-05-14 15:29:25 +08:00
Files
Alas/module/equipment/equipment.py
Zuosizhu 31c99d8953 Merge remote-tracking branch 'Lme/master' into dev
# Conflicts:
#	module/campaign/os_run.py
#	module/config/argument/args.json
#	module/os/operation_siren.py
#	module/retire/assets.py
#	module/shop/shop_reward.py
#	module/shop/ui.py
#	module/ui/assets.py
2025-10-12 11:28:13 +08:00

697 lines
25 KiB
Python

import collections
from module.base.button import ButtonGrid
from module.base.decorator import cached_property
from module.base.timer import Timer
from module.base.utils import ApiCollectionSwitch
from module.config.config import AzurLaneConfig
from module.device.device import Device
from module.equipment.assets import *
from module.logger import logger
from module.retire.assets import DOCK_CHECK, EQUIP_CONFIRM as RETIRE_EQUIP_CONFIRM
from module.storage.storage import StorageHandler
from module.ui.assets import BACK_ARROW
from module.ui.navbar import Navbar
from module.ui.switch import Switch
from module.equipment.assets_override import equip_assets_override
import gl
equipping_filter = Switch('Equiping_filter')
equipping_filter.add_state('on', check_button=EQUIPPING_ON)
equipping_filter.add_state('off', check_button=EQUIPPING_OFF)
SWIPE_DISTANCE = 250
SWIPE_RANDOM_RANGE = (-40, -20, 40, 20)
# patch to handle both blue (folded) and orange (expanded) button
EQUIPMENT_OPEN.match = EQUIPMENT_OPEN.match_luma
class EquipmentOld(StorageHandler):
equipment_has_take_on = False
@equip_assets_override("old")
def equipping_set(self, enable=False):
if equipping_filter.set('on' if enable else 'off', main=self):
self.wait_until_stable(SWIPE_AREA)
@equip_assets_override("old")
def _equip_view_swipe(self, distance, check_button=EQUIPMENT_OPEN):
swipe_count = 0
swipe_timer = Timer(5, count=10)
self.handle_info_bar()
SWIPE_CHECK.load_color(self.device.image)
SWIPE_CHECK._match_init = True # Disable ensure_template() on match(), allows ship to be properly determined
# whether actually different or not
while 1:
if not swipe_timer.started() or swipe_timer.reached():
swipe_timer.reset()
self.device.swipe_vector(vector=(distance, 0), box=SWIPE_AREA.area, random_range=SWIPE_RANDOM_RANGE,
padding=0, duration=(0.1, 0.12), name='EQUIP_SWIPE')
# self.wait_until_appear(check_button, offset=(30, 30))
skip_first_screenshot = True
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.appear(check_button, offset=(30, 30)):
break
if self.appear(RETIRE_EQUIP_CONFIRM, offset=(30, 30)):
logger.info('RETIRE_EQUIP_CONFIRM popup in _equip_view_swipe()')
return False
swipe_count += 1
self.device.screenshot()
if self.appear(RETIRE_EQUIP_CONFIRM, offset=(30, 30)):
logger.info('RETIRE_EQUIP_CONFIRM popup in _equip_view_swipe()')
return False
if SWIPE_CHECK.match(self.device.image):
if swipe_count > 1:
logger.info('Same ship on multiple swipes')
return False
continue
if self.appear(check_button, offset=(30, 30)) and not SWIPE_CHECK.match(self.device.image):
logger.info('New ship detected on swipe')
return True
@equip_assets_override("old")
def equip_view_next(self, check_button=EQUIPMENT_OPEN):
return self._equip_view_swipe(distance=-SWIPE_DISTANCE, check_button=check_button)
@equip_assets_override("old")
def equip_view_prev(self, check_button=EQUIPMENT_OPEN):
return self._equip_view_swipe(distance=SWIPE_DISTANCE, check_button=check_button)
@equip_assets_override("old")
def equip_enter(self, click_button, check_button=EQUIPMENT_OPEN, long_click=True, skil_first_screenshot=True):
enter_timer = Timer(10)
while 1:
if skil_first_screenshot:
skil_first_screenshot = False
else:
self.device.screenshot()
# End
if self.appear(check_button):
break
# Long click accidentally became normal click, exit from dock
if long_click:
if self.appear(DOCK_CHECK, offset=(20, 20), interval=3):
logger.info(f'equip_enter {DOCK_CHECK} -> {BACK_ARROW}')
self.device.click(BACK_ARROW)
continue
if enter_timer.reached():
if long_click:
self.device.long_click(click_button, duration=(1.5, 1.7))
else:
self.device.click(click_button)
enter_timer.reset()
@cached_property
@equip_assets_override("old")
def _equip_side_navbar(self):
"""
pry_sidebar 3 options
research.
equipment.
detail.
regular_sidebar 4 options
enhancement.
limit break.
equipment.
detail.
retrofit_sidebar 5 options
retrofit.
enhancement.
limit break.
equipment.
detail.
"""
equip_side_navbar = ButtonGrid(
origin=(21, 118), delta=(0, 94.5), button_shape=(60, 75), grid_shape=(1, 5), name='DETAIL_SIDE_NAVBAR')
return Navbar(grids=equip_side_navbar,
active_color=(247, 255, 173), active_threshold=221,
inactive_color=(140, 162, 181), inactive_threshold=221)
@equip_assets_override("old")
def equip_side_navbar_ensure(self, upper=None, bottom=None):
"""
Ensure able to transition to page
Whether page has completely loaded is handled
separately and optionally
Args:
upper (int):
pry|regular|retrofit
1|N/A|N/A for research.
N/A|N/A|1 for retrofit.
N/A|1|2 for enhancement.
N/A|2|3 for limit break.
2|3|4 for equipment.
3|4|5 for detail.
bottom (int):
pry|regular|retrofit
3|N/A|N/A for research.
N/A|N/A|5 for retrofit.
N/A|4|4 for enhancement.
N/A|3|3 for limit break.
2 for equipment.
1 for detail.
Returns:
bool: if side_navbar set ensured
"""
if self._equip_side_navbar.get_total(main=self) == 3:
if upper == 1 or bottom == 3:
logger.warning('Transitions to "research" is not supported')
return False
if self._equip_side_navbar.set(self, upper=upper, bottom=bottom):
return True
return False
@equip_assets_override("old")
def _equip_take_off_one(self, skip_first_screenshot=True):
bar_timer = Timer(5)
off_timer = Timer(5)
confirm_timer = Timer(5)
while 1:
if skip_first_screenshot:
self.device.screenshot()
else:
skip_first_screenshot = False
# End
# if self.handle_info_bar():
# break
if off_timer.started() and self.info_bar_count():
break
if self.handle_storage_full():
continue
if confirm_timer.reached() and self.handle_popup_confirm():
confirm_timer.reset()
continue
if off_timer.reached():
if not self.info_bar_count() and self.appear_then_click(EQUIP_OFF, offset=(20, 20)):
off_timer.reset()
continue
if bar_timer.reached():
if self.appear(EQUIPMENT_OPEN, offset=(20, 20)) and not self.appear(EQUIP_OFF, offset=(20, 20)):
self.device.click(EQUIPMENT_OPEN)
bar_timer.reset()
continue
@equip_assets_override("old")
def equipment_take_off(self, enter, out, fleet):
"""
Args:
enter (Button): Long click to edit equipment.
out (Button): Button to confirm exit success.
fleet (list[int]): list of equipment record. [3, 1, 1, 1, 1, 1]
"""
logger.hr('Equipment take off')
self.equip_enter(enter)
for index in '9'.join([str(x) for x in fleet if x > 0]):
index = int(index)
if index == 9:
self.equip_view_next()
else:
self._equip_take_off_one()
self.ui_click(click_button=EQUIPMENT_CLOSE, check_button=EQUIPMENT_OPEN, offset=None)
self.ui_back(out)
self.equipment_has_take_on = False
@equip_assets_override("old")
def _equip_take_on_one(self, index, skip_first_screenshot=True):
bar_timer = Timer(5)
on_timer = Timer(5)
while 1:
if skip_first_screenshot:
self.device.screenshot()
else:
skip_first_screenshot = False
# End
# if self.handle_info_bar():
# break
if on_timer.started() and self.info_bar_count():
break
if bar_timer.reached() and not self.appear(EQUIP_1, offset=10):
self.device.click(EQUIPMENT_OPEN)
# self.device.sleep(0.3)
bar_timer.reset()
continue
if on_timer.reached() and self.appear(EQUIP_1, offset=10) and not self.info_bar_count():
if index == 1:
self.device.click(EQUIP_1)
elif index == 2:
self.device.click(EQUIP_2)
elif index == 3:
self.device.click(EQUIP_3)
on_timer.reset()
continue
@equip_assets_override("old")
def equipment_take_on(self, enter, out, fleet):
"""
Args:
enter (Button): Long click to edit equipment.
out (Button): Button to confirm exit success.
fleet (list[int]): list of equipment record. [3, 1, 1, 1, 1, 1]
"""
logger.hr('Equipment take on')
self.equip_enter(enter)
for index in '9'.join([str(x) for x in fleet if x > 0]):
index = int(index)
if index == 9:
self.equip_view_next()
else:
self._equip_take_on_one(index=index)
self.ui_click(click_button=EQUIPMENT_CLOSE, check_button=EQUIPMENT_OPEN, offset=None)
self.ui_back(out)
self.equipment_has_take_on = True
class EquipmentNew(StorageHandler):
equipment_has_take_on = False
@equip_assets_override("new")
def _ship_view_swipe(self, distance, check_button=EQUIPMENT_OPEN):
swipe_count = 0
swipe_timer = Timer(5, count=10)
self.handle_info_bar()
SWIPE_CHECK.load_color(self.device.image)
SWIPE_CHECK._match_init = True # Disable ensure_template() on match(), allows ship to be properly determined
# whether actually different or not
while 1:
if not swipe_timer.started() or swipe_timer.reached():
swipe_timer.reset()
self.device.swipe_vector(vector=(distance, 0), box=SWIPE_AREA.area, random_range=SWIPE_RANDOM_RANGE,
padding=0, duration=(0.1, 0.12), name='SHIP_SWIPE')
# self.wait_until_appear(check_button, offset=(30, 30))
skip_first_screenshot = True
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.appear(check_button, offset=(30, 30)):
break
if self.appear(RETIRE_EQUIP_CONFIRM, offset=(30, 30)):
logger.info('RETIRE_EQUIP_CONFIRM popup in _ship_view_swipe()')
return False
# Popup when enhancing a NPC ship
if self.handle_popup_confirm('SHIP_VIEW_SWIPE'):
continue
swipe_count += 1
self.device.screenshot()
if self.appear(RETIRE_EQUIP_CONFIRM, offset=(30, 30)):
logger.info('RETIRE_EQUIP_CONFIRM popup in _ship_view_swipe()')
return False
if SWIPE_CHECK.match(self.device.image):
if swipe_count > 1:
logger.info('Same ship on multiple swipes')
return False
continue
if self.appear(check_button, offset=(30, 30)) and not SWIPE_CHECK.match(self.device.image):
logger.info('New ship detected on swipe')
return True
@equip_assets_override("new")
def ship_view_next(self, check_button=EQUIPMENT_OPEN):
return self._ship_view_swipe(distance=-SWIPE_DISTANCE, check_button=check_button)
@equip_assets_override("new")
def ship_view_prev(self, check_button=EQUIPMENT_OPEN):
return self._ship_view_swipe(distance=SWIPE_DISTANCE, check_button=check_button)
@equip_assets_override("new")
def ship_info_enter(self, click_button, check_button=EQUIPMENT_OPEN, long_click=True, skil_first_screenshot=True):
enter_timer = Timer(10)
while 1:
if skil_first_screenshot:
skil_first_screenshot = False
else:
self.device.screenshot()
# End
if self.appear(check_button):
break
# Long click accidentally became normal click, exit from dock
if long_click:
if self.appear(DOCK_CHECK, offset=(20, 20), interval=3):
logger.info(f'ship_info_enter {DOCK_CHECK} -> {BACK_ARROW}')
self.device.click(BACK_ARROW)
continue
if enter_timer.reached():
if long_click:
self.device.long_click(click_button, duration=(1.5, 1.7))
else:
self.device.click(click_button)
enter_timer.reset()
if self.handle_game_tips():
continue
@cached_property
@equip_assets_override("new")
def _ship_side_navbar(self):
"""
pry_sidebar 3 options
research.
equipment.
detail.
regular_sidebar 4 options
enhancement.
limit break.
equipment.
detail.
retrofit_sidebar 5 options
retrofit.
enhancement.
limit break.
equipment.
detail.
"""
ship_side_navbar = ButtonGrid(
origin=(21, 118), delta=(0, 94.5), button_shape=(60, 75), grid_shape=(1, 5), name='DETAIL_SIDE_NAVBAR')
return Navbar(grids=ship_side_navbar,
active_color=(247, 255, 173), active_threshold=221,
inactive_color=(140, 162, 181), inactive_threshold=221)
@equip_assets_override("new")
def ship_side_navbar_ensure(self, upper=None, bottom=None):
"""
Ensure able to transition to page
Whether page has completely loaded is handled
separately and optionally
Args:
upper (int):
pry|regular|retrofit
1|N/A|N/A for research.
N/A|N/A|1 for retrofit.
N/A|1|2 for enhancement.
N/A|2|3 for limit break.
2|3|4 for equipment.
3|4|5 for detail.
bottom (int):
pry|regular|retrofit
3|N/A|N/A for research.
N/A|N/A|5 for retrofit.
N/A|4|4 for enhancement.
N/A|3|3 for limit break.
2 for equipment.
1 for detail.
Returns:
bool: if side_navbar set ensured
"""
if self._ship_side_navbar.get_total(main=self) == 3:
if upper == 1 or bottom == 3:
logger.warning('Transitions to "research" is not supported')
return False
if self._ship_side_navbar.set(self, upper=upper, bottom=bottom):
return True
return False
@equip_assets_override("new")
def ship_equipment_take_off(self, skip_first_screenshot=True):
logger.info('Equipment take off')
bar_timer = Timer(5)
off_timer = Timer(5)
confirm_timer = Timer(5)
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End
# if self.handle_info_bar():
# break
if off_timer.started() and self.info_bar_count():
break
if self.handle_storage_full():
continue
if confirm_timer.reached() and self.handle_popup_confirm():
confirm_timer.reset()
off_timer.reset()
bar_timer.reset()
continue
if off_timer.reached():
if not self.info_bar_count() and self.appear_then_click(EQUIP_OFF, offset=(20, 20)):
off_timer.reset()
bar_timer.reset()
continue
if bar_timer.reached():
if self.appear(EQUIPMENT_OPEN, offset=(20, 20)) and not self.appear(EQUIP_OFF, offset=(20, 20)):
self.device.click(EQUIPMENT_OPEN)
bar_timer.reset()
continue
logger.info('Equipment take off ended')
def fleet_equipment_take_off(self, enter, long_click, out):
"""
Args:
enter (Button): Button to edit equipment.
long_click (bool): How to click enter
out (Button): Button to confirm exit success.
"""
logger.hr('Equipment take off')
self.ship_info_enter(enter, long_click=long_click)
while True:
self.ship_equipment_take_off()
self.ui_click(click_button=EQUIPMENT_CLOSE, check_button=EQUIPMENT_OPEN, offset=None)
if not self.ship_view_next():
break
self.ui_back(out)
self.equipment_has_take_on = False
@equip_assets_override("new")
def ship_equipment_take_on_preset(self, index, skip_first_screenshot=True):
logger.info('Equipment take on preset')
bar_timer = Timer(5)
on_timer = Timer(5)
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End
# if self.handle_info_bar():
# break
if on_timer.started() and self.info_bar_count():
break
if bar_timer.reached() and not self.appear(EQUIP_1, offset=10):
self.device.click(EQUIPMENT_OPEN)
# self.device.sleep(0.3)
bar_timer.reset()
continue
if on_timer.reached() and self.appear(EQUIP_1, offset=10) and not self.info_bar_count():
if index == 1:
self.device.click(EQUIP_1)
elif index == 2:
self.device.click(EQUIP_2)
elif index == 3:
self.device.click(EQUIP_3)
on_timer.reset()
bar_timer.reset()
continue
logger.info('Equipment take on ended')
def fleet_equipment_take_on_preset(self, preset_record, enter, long_click, out):
"""
Args:
preset_record (list[int]): list of equipment record. [3, 1, 1, 1, 1, 1]
enter (Button): Button to edit equipment.
long_click (bool): How to click enter
out (Button): Button to confirm exit success.
"""
logger.hr('Equipment take on')
self.ship_info_enter(enter, long_click=long_click)
for index in '9'.join([str(x) for x in preset_record if x > 0]):
index = int(index)
if index == 9:
self.ship_view_next()
else:
self.ship_equipment_take_on_preset(index=index)
self.ui_click(click_button=EQUIPMENT_CLOSE, check_button=EQUIPMENT_OPEN, offset=None)
self.ui_back(out)
self.equipment_has_take_on = True
def equip_redirect_inherit_to_old() -> bool:
current_task = gl.gl_get("g_current_task", "")
current_config = gl.gl_get("g_config", None)
if current_task == "GemsFarming":
return True
elif current_task.find("Main") != -1:
return True
elif current_task.find("Event") != -1:
return True
elif current_task == "OpsiAshBeacon":
return True
else:
return False
return False
class Equipment(StorageHandler):
def __init__(self, config, device=None, task=None):
conf = AzurLaneConfig.build_azurlane_config(config, task)
dev = Device.build_device(conf, device)
self.equipment_old: EquipmentOld = EquipmentOld(config=conf, device=dev, task=task)
self.equipment_new: EquipmentNew = EquipmentNew(config=conf, device=dev, task=task)
StorageHandler.__init__(self, config=conf, device=dev, task=task)
self.equipment_switch_stack = collections.deque()
self.equipment_current_use = self.equipment_new
def switch_equipment_to_old(self):
self.equipment_switch_stack.append(self.equipment_current_use)
self.equipment_current_use = self.equipment_new
def switch_equipment_to_new(self):
self.equipment_switch_stack.append(self.equipment_current_use)
self.equipment_current_use = self.equipment_new
def switch_equipment_back(self):
if len(self.equipment_switch_stack) == 0:
self.equipment_current_use = self.equipment_new
return
self.equipment_current_use = self.equipment_switch_stack.pop()
'''
EquipmentOld
'''
@cached_property
def equipment_has_take_on(self):
return self.equipment_old.equipment_has_take_on
def equipping_set(self, enable=False):
return self.equipment_old.equipping_set(enable=enable)
def _equip_view_swipe(self, distance, check_button=EQUIPMENT_OPEN):
return self.equipment_old._equip_view_swipe(distance=distance, check_button=check_button)
def equip_view_next(self, check_button=EQUIPMENT_OPEN):
return self.equipment_old.equip_view_next(check_button=check_button)
def equip_view_prev(self, check_button=EQUIPMENT_OPEN):
return self.equipment_old.equip_view_prev(check_button=check_button)
def equip_enter(self, click_button, check_button=EQUIPMENT_OPEN, long_click=True, skil_first_screenshot=True):
return self.equipment_old.equip_enter(click_button, check_button, long_click, skil_first_screenshot)
@cached_property
def _equip_side_navbar(self):
return self.equipment_old._equip_side_navbar
def equip_side_navbar_ensure(self, upper=None, bottom=None):
return self.equipment_old.equip_side_navbar_ensure(upper=upper, bottom=bottom)
def _equip_take_off_one(self, skip_first_screenshot=True):
return self.equipment_old._equip_take_off_one(skip_first_screenshot=skip_first_screenshot)
def equipment_take_off(self, enter, out, fleet):
return self.equipment_old.equipment_take_off(enter, out, fleet)
def _equip_take_on_one(self, index, skip_first_screenshot=True):
return self.equipment_old._equip_take_on_one(index, skip_first_screenshot=skip_first_screenshot)
def equipment_take_on(self, enter, out, fleet):
return self.equipment_old.equipment_take_off(enter, out, fleet)
'''
EquipmentNew
'''
@cached_property
def equipment_has_take_on(self):
return self.equipment_new.equipment_has_take_on
def _ship_view_swipe(self, distance, check_button=EQUIPMENT_OPEN):
return self.equipment_new._ship_view_swipe(distance=distance, check_button=check_button)
def ship_view_next(self, check_button=EQUIPMENT_OPEN):
return self.equipment_new.ship_view_next(check_button=check_button)
def ship_view_prev(self, check_button=EQUIPMENT_OPEN):
return self.equipment_new.ship_view_next(check_button=check_button)
def ship_info_enter(self, click_button, check_button=EQUIPMENT_OPEN, long_click=True, skil_first_screenshot=True):
return self.equipment_new.ship_info_enter(click_button=click_button, check_button=check_button, skil_first_screenshot=skil_first_screenshot)
@cached_property
def _ship_side_navbar(self):
return self.equipment_new._ship_side_navbar
def ship_side_navbar_ensure(self, upper=None, bottom=None):
return self.equipment_new.ship_side_navbar_ensure(upper=upper, bottom=bottom)
def ship_equipment_take_off(self, skip_first_screenshot=True):
return self.equipment_new.ship_equipment_take_off(skip_first_screenshot=skip_first_screenshot)
def fleet_equipment_take_off(self, enter, long_click, out):
return self.equipment_new.fleet_equipment_take_off(enter, long_click, out)
def ship_equipment_take_on_preset(self, index, skip_first_screenshot=True):
return self.equipment_new.ship_equipment_take_off(index, skip_first_screenshot=skip_first_screenshot)
def fleet_equipment_take_on_preset(self, preset_record, enter, long_click, out):
return self.equipment_new.fleet_equipment_take_on_preset(preset_record, enter, long_click, out)
'''
Public
'''