mirror of
https://github.com/LmeSzinc/AzurLaneAutoScript.git
synced 2025-01-08 12:27:33 +08:00
326 lines
12 KiB
Python
326 lines
12 KiB
Python
from module.base.button import ButtonGrid
|
|
from module.base.timer import Timer
|
|
from module.logger import logger
|
|
from module.meowfficer.assets import *
|
|
from module.meowfficer.base import MeowfficerBase
|
|
from module.ui.switch import Switch
|
|
|
|
MEOWFFICER_TALENT_GRID_1 = ButtonGrid(
|
|
origin=(875, 559), delta=(105, 0), button_shape=(16, 16), grid_shape=(3, 1),
|
|
name='MEOWFFICER_TALENT_GRID_1')
|
|
MEOWFFICER_TALENT_GRID_2 = MEOWFFICER_TALENT_GRID_1.move(vector=(-40, -20),
|
|
name='MEOWFFICER_TALENT_GRID_2')
|
|
MEOWFFICER_SHIFT_DETECT = Button(
|
|
area=(1260, 669, 1280, 720), color=(117, 106, 84), button=(1260, 669, 1280, 720),
|
|
name='MEOWFFICER_SHIFT_DETECT')
|
|
|
|
SWITCH_LOCK = Switch(name='Meowfficer_Lock', offset=(40, 40))
|
|
SWITCH_LOCK.add_state(
|
|
'lock',
|
|
check_button=MEOWFFICER_APPLY_UNLOCK,
|
|
click_button=MEOWFFICER_APPLY_LOCK
|
|
)
|
|
SWITCH_LOCK.add_state(
|
|
'unlock',
|
|
check_button=MEOWFFICER_APPLY_LOCK,
|
|
click_button=MEOWFFICER_APPLY_UNLOCK
|
|
)
|
|
|
|
|
|
class MeowfficerCollect(MeowfficerBase):
|
|
def _meow_detect_shift(self, skip_first_screenshot=True):
|
|
"""
|
|
Serves as innate wait mechanism for loading
|
|
of meowfficer acquisition complete screen
|
|
During which screen may shift left randomly
|
|
|
|
Args:
|
|
skip_first_screenshot (bool):
|
|
|
|
Returns:
|
|
bool
|
|
"""
|
|
flag = False
|
|
confirm_timer = Timer(3, count=6).start()
|
|
while 1:
|
|
if skip_first_screenshot:
|
|
skip_first_screenshot = False
|
|
else:
|
|
self.device.screenshot()
|
|
|
|
# End - Random left shift
|
|
if self.image_color_count(MEOWFFICER_SHIFT_DETECT,
|
|
color=MEOWFFICER_SHIFT_DETECT.color, threshold=221, count=650):
|
|
if not flag:
|
|
confirm_timer.reset()
|
|
flag = True
|
|
if confirm_timer.reached():
|
|
break
|
|
continue
|
|
|
|
# End - No shift at all
|
|
if self.appear(MEOWFFICER_GET_CHECK, offset=(40, 40)):
|
|
if flag:
|
|
confirm_timer.reset()
|
|
flag = False
|
|
if confirm_timer.reached():
|
|
break
|
|
return flag
|
|
|
|
def _meow_check_popup_exit(self):
|
|
"""
|
|
If in appropriate page after exiting
|
|
either lock popup or talent detail panel
|
|
|
|
Returns:
|
|
bool
|
|
"""
|
|
if self.match_template_color(MEOWFFICER_GET_CHECK, offset=(40, 40)):
|
|
return True
|
|
|
|
if self.appear(MEOWFFICER_TRAIN_START, offset=(20, 20)):
|
|
return True
|
|
|
|
return False
|
|
|
|
def _meow_talent_cap_handle(self, btn, drop=None):
|
|
"""
|
|
Handle talent screen capture drop record
|
|
|
|
Args:
|
|
btn (Button):
|
|
drop (DropImage):
|
|
"""
|
|
self.ui_click(btn, check_button=MEOWFFICER_TALENT_CLOSE,
|
|
appear_button=MEOWFFICER_GET_CHECK, offset=(40, 40),
|
|
skip_first_screenshot=True)
|
|
drop.add(self.device.image)
|
|
self.ui_click(MEOWFFICER_TALENT_CLOSE, check_button=self._meow_check_popup_exit,
|
|
appear_button=MEOWFFICER_TALENT_CLOSE, skip_first_screenshot=True)
|
|
self.device.click_record.pop()
|
|
self.device.click_record.pop()
|
|
|
|
def _meow_is_special_talented(self, drop=None):
|
|
"""
|
|
Validate if meowfficer has at least
|
|
one special talent
|
|
|
|
Args:
|
|
drop (DropImage):
|
|
|
|
Returns:
|
|
bool
|
|
"""
|
|
# Wait for complete load before examining talents
|
|
logger.info('Wait complete load and examine base talents')
|
|
|
|
special_talent = False
|
|
grid = MEOWFFICER_TALENT_GRID_2 if self._meow_detect_shift() else MEOWFFICER_TALENT_GRID_1
|
|
handle_drop = self.config.DropRecord_MeowfficerTalent != 'do_not'
|
|
if handle_drop:
|
|
drop.add(self.device.image)
|
|
|
|
for btn in grid.buttons:
|
|
# Empty slot; check for many white pixels
|
|
if self.image_color_count(btn, color=(255, 255, 247), threshold=221, count=200):
|
|
continue
|
|
|
|
# Non-empty slot; check for few white pixels
|
|
# i.e. roman numerals
|
|
if self.image_color_count(btn, color=(255, 255, 255), threshold=221, count=25):
|
|
if handle_drop:
|
|
self._meow_talent_cap_handle(btn, drop)
|
|
continue
|
|
|
|
# Detected special talent
|
|
if handle_drop:
|
|
self._meow_talent_cap_handle(btn, drop)
|
|
special_talent = True
|
|
|
|
log_insert = 'Found' if special_talent else 'No'
|
|
logger.info(f'{log_insert} special talent abilities in meowfficer')
|
|
return special_talent
|
|
|
|
def _meow_skip_lock(self):
|
|
"""
|
|
Applicable to only gold variant meowfficer
|
|
Handle skip transitions; proceeds slowly
|
|
with caution to prevent unintentional actions
|
|
"""
|
|
|
|
def additional():
|
|
if self.appear(MEOWFFICER_TRAIN_EVALUATE, offset=(20, 20), interval=3):
|
|
self.device.click(MEOWFFICER_TRAIN_EVALUATE)
|
|
return True
|
|
return False
|
|
|
|
# Trigger lock popup appearance to initiate sequence
|
|
self.ui_click(MEOWFFICER_TRAIN_CLICK_SAFE_AREA,
|
|
appear_button=MEOWFFICER_GET_CHECK, check_button=MEOWFFICER_CONFIRM, additional=additional,
|
|
offset=(40, 40), retry_wait=3, skip_first_screenshot=True)
|
|
|
|
self.ui_click(MEOWFFICER_CANCEL, check_button=self._meow_check_popup_exit, additional=additional,
|
|
offset=(40, 20), retry_wait=3, skip_first_screenshot=True)
|
|
self.device.click_record.pop()
|
|
self.device.click_record.pop()
|
|
|
|
def _meow_apply_lock(self, lock=True):
|
|
"""
|
|
Apply designated lock status onto
|
|
the acquired trained meowfficer
|
|
Prevents the meowfficer being used
|
|
as feed / enhance material
|
|
|
|
Args:
|
|
lock (bool):
|
|
"""
|
|
# Apply designated lock status
|
|
SWITCH_LOCK.set('lock' if lock else 'unlock', main=self)
|
|
|
|
# Wait until info bar disappears
|
|
self.ensure_no_info_bar(timeout=1)
|
|
|
|
def _meow_skip_popup_after_locking(self, skip_first_screenshot=True):
|
|
"""
|
|
Since 2023-11-16 update, even locked gold meow will still have popup.
|
|
If gold meow is locked and have popup, click MEOWFFICER_CONFIRM,
|
|
if gold meow is unlocked, this method should not be executed.
|
|
"""
|
|
while 1:
|
|
if skip_first_screenshot:
|
|
skip_first_screenshot = False
|
|
else:
|
|
self.device.screenshot()
|
|
|
|
# Next meow MEOWFFICER_APPLY_LOCK load faster than MEOWFFICER_GET_CHECK,
|
|
# make sure exit with a full screenshot
|
|
if self.appear(MEOWFFICER_GET_CHECK, offset=(40, 40), interval=3):
|
|
if self.appear(MEOWFFICER_APPLY_LOCK, offset=(40, 40)):
|
|
break
|
|
|
|
if self.appear(MEOWFFICER_APPLY_UNLOCK, offset=(40, 40), interval=3):
|
|
self.device.click(MEOWFFICER_TRAIN_CLICK_SAFE_AREA)
|
|
continue
|
|
if self.appear(MEOWFFICER_CONFIRM, offset=(40, 20), interval=3):
|
|
self.device.click(MEOWFFICER_CONFIRM)
|
|
continue
|
|
elif self.appear(MEOWFFICER_CANCEL, offset=(40, 20), interval=3):
|
|
self.device.click(MEOWFFICER_CONFIRM)
|
|
continue
|
|
if self.appear(MEOWFFICER_TRAIN_EVALUATE, offset=(20, 20), interval=3):
|
|
self.device.click(MEOWFFICER_TRAIN_EVALUATE)
|
|
continue
|
|
|
|
self.device.click_record.pop()
|
|
self.device.click_record.pop()
|
|
self.interval_reset((MEOWFFICER_GET_CHECK, MEOWFFICER_APPLY_LOCK,
|
|
MEOWFFICER_CONFIRM, MEOWFFICER_CANCEL))
|
|
|
|
def meow_get(self, skip_first_screenshot=True):
|
|
"""
|
|
Transition through all the necessary screens
|
|
to acquire each trained meowfficer
|
|
Animation is waited for as the amount can vary
|
|
Only gold variant meowfficer will prompt for
|
|
confirmation
|
|
|
|
Args:
|
|
skip_first_screenshot (bool): Skip first
|
|
screen shot or not
|
|
|
|
Pages:
|
|
in: MEOWFFICER_GET_CHECK
|
|
out: MEOWFFICER_TRAIN
|
|
"""
|
|
# Loop through possible screen transitions
|
|
confirm_timer = Timer(1.5, count=3).start()
|
|
count = 0
|
|
while 1:
|
|
if skip_first_screenshot:
|
|
skip_first_screenshot = False
|
|
else:
|
|
self.device.screenshot()
|
|
|
|
if self.handle_meow_popup_dismiss():
|
|
confirm_timer.reset()
|
|
continue
|
|
if self.appear(MEOWFFICER_GET_CHECK, offset=(40, 40), interval=3):
|
|
if self.appear(MEOWFFICER_APPLY_UNLOCK, offset=(40, 40)):
|
|
self._meow_skip_popup_after_locking(skip_first_screenshot=True)
|
|
confirm_timer.reset()
|
|
|
|
count += 1
|
|
logger.attr('Meow_get', count)
|
|
with self.stat.new(
|
|
genre="meowfficer_talent",
|
|
method=self.config.DropRecord_MeowfficerTalent
|
|
) as drop:
|
|
special_talent = self._meow_is_special_talented(drop=drop)
|
|
if self.appear(MEOWFFICER_GOLD_CHECK, offset=(40, 40)):
|
|
if not self.config.MeowfficerTrain_RetainTalentedGold or not special_talent:
|
|
self._meow_skip_lock()
|
|
skip_first_screenshot = True
|
|
confirm_timer.reset()
|
|
continue
|
|
self._meow_apply_lock()
|
|
|
|
if self.appear(MEOWFFICER_PURPLE_CHECK, offset=(40, 40)):
|
|
if self.config.MeowfficerTrain_RetainTalentedPurple and special_talent:
|
|
self._meow_apply_lock()
|
|
|
|
# Susceptible to exception when collecting multiple
|
|
# Mitigate by popping click_record
|
|
self.device.click(MEOWFFICER_TRAIN_CLICK_SAFE_AREA)
|
|
self.device.click_record.pop()
|
|
confirm_timer.reset()
|
|
self.interval_reset(MEOWFFICER_GET_CHECK)
|
|
continue
|
|
|
|
# If click MEOWFFICER_TRAIN_FINISH_ALL, will enter evaluate page
|
|
if self.appear(MEOWFFICER_TRAIN_EVALUATE, offset=(20, 20), interval=3):
|
|
self.device.click(MEOWFFICER_TRAIN_EVALUATE)
|
|
continue
|
|
|
|
# End
|
|
if self.appear(MEOWFFICER_TRAIN_START, offset=(20, 20)):
|
|
if confirm_timer.reached():
|
|
break
|
|
else:
|
|
confirm_timer.reset()
|
|
|
|
def meow_collect(self, collect_all=True):
|
|
"""
|
|
Collect one or all trained meowfficer(s)
|
|
Completed slots are automatically moved
|
|
to top of queue, assume to check top-left
|
|
slot only
|
|
|
|
Args:
|
|
collect_all (bool): Collect all or collect single
|
|
|
|
Pages:
|
|
in: MEOWFFICER_TRAIN
|
|
out: MEOWFFICER_TRAIN
|
|
|
|
Returns:
|
|
bool: whether collected or not
|
|
"""
|
|
logger.hr('Meowfficer collect', level=2)
|
|
|
|
if self.appear(MEOWFFICER_TRAIN_COMPLETE, offset=(20, 20)):
|
|
# Today is Sunday, finish all else get just one
|
|
if collect_all:
|
|
logger.info('Collect all trained meowfficers')
|
|
button = MEOWFFICER_TRAIN_FINISH_ALL
|
|
else:
|
|
logger.info('Collect single trained meowfficer')
|
|
button = MEOWFFICER_TRAIN_COMPLETE
|
|
self.ui_click(button, check_button=MEOWFFICER_GET_CHECK,
|
|
additional=self.handle_meow_popup_dismiss,
|
|
offset=(40, 40), skip_first_screenshot=True)
|
|
|
|
# Get loop mechanism to collect trained meowfficer(s)
|
|
self.meow_get()
|
|
return True
|
|
return False
|