mirror of
https://github.com/LmeSzinc/StarRailCopilot.git
synced 2024-11-24 01:21:25 +00:00
6d6fcc5edb
- Add tips, when failed to retire ships
277 lines
9.1 KiB
Python
277 lines
9.1 KiB
Python
from module.base.button import ButtonGrid
|
|
from module.base.decorator import Config
|
|
from module.base.utils import get_color, color_similar
|
|
from module.combat.assets import GET_ITEMS_1
|
|
from module.exception import ScriptError
|
|
from module.logger import logger
|
|
from module.retire.assets import *
|
|
from module.retire.enhancement import Enhancement
|
|
|
|
CARD_GRIDS = ButtonGrid(
|
|
origin=(93, 76), delta=(164 + 2 / 3, 227), button_shape=(138, 204), grid_shape=(7, 2), name='CARD')
|
|
CARD_RARITY_GRIDS = ButtonGrid(
|
|
origin=(93, 76), delta=(164 + 2 / 3, 227), button_shape=(138, 5), grid_shape=(7, 2), name='RARITY')
|
|
|
|
CARD_RARITY_COLORS = {
|
|
'N': (174, 176, 187),
|
|
'R': (106, 195, 248),
|
|
'SR': (151, 134, 254),
|
|
'SSR': (248, 223, 107)
|
|
# Not support marriage cards.
|
|
}
|
|
|
|
|
|
class Retirement(Enhancement):
|
|
_unable_to_enhance = False
|
|
|
|
def _retirement_choose(self, amount=10, target_rarity=('N',)):
|
|
"""
|
|
Args:
|
|
amount (int): Amount of cards retire. 0 to 10.
|
|
target_rarity (tuple(str)): Card rarity. N, R, SR, SSR.
|
|
|
|
Returns:
|
|
int: Amount of cards have retired.
|
|
"""
|
|
cards = []
|
|
rarity = []
|
|
for x, y, button in CARD_RARITY_GRIDS.generate():
|
|
card_color = get_color(image=self.device.image, area=button.area)
|
|
f = False
|
|
for r, rarity_color in CARD_RARITY_COLORS.items():
|
|
|
|
if color_similar(card_color, rarity_color, threshold=15):
|
|
cards.append([x, y])
|
|
rarity.append(r)
|
|
f = True
|
|
|
|
if not f:
|
|
logger.warning(f'Unknown rarity color. Grid: ({x}, {y}). Color: {card_color}')
|
|
|
|
logger.info(' '.join([r.rjust(3) for r in rarity[:7]]))
|
|
logger.info(' '.join([r.rjust(3) for r in rarity[7:]]))
|
|
|
|
selected = 0
|
|
for card, r in zip(cards, rarity):
|
|
if r in target_rarity:
|
|
self.device.click(CARD_GRIDS[card])
|
|
self.device.sleep((0.1, 0.15))
|
|
selected += 1
|
|
if selected >= amount:
|
|
break
|
|
return selected
|
|
|
|
def _retirement_set_sort_method(self, method):
|
|
"""
|
|
Args:
|
|
method (str): ASC for ascending, DESC for descending.
|
|
|
|
Returns:
|
|
bool: If method change.
|
|
"""
|
|
current = 'UNKNOWN'
|
|
self.device.screenshot()
|
|
if self.appear(SORT_ASC):
|
|
current = 'ASC'
|
|
if self.appear(SORT_DESC):
|
|
current = 'DESC'
|
|
|
|
logger.info(f'Current sorting: {current}')
|
|
if current != method:
|
|
logger.info(f'Sorting set to {method}')
|
|
self.device.click(SORTING_CLICK)
|
|
self.handle_dock_cards_loading()
|
|
self.device.screenshot()
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
def _retirement_set_common_ship_filter(self, enable=False):
|
|
"""
|
|
Args:
|
|
enable (bool): If enable common_ship_filter
|
|
|
|
Returns:
|
|
bool: If changed.
|
|
"""
|
|
# self.device.screenshot()
|
|
if self.appear(COMMON_SHIP_FILTER_ENABLE):
|
|
current = True
|
|
elif self.appear(COMMON_SHIP_FILTER_DISABLE):
|
|
current = False
|
|
else:
|
|
logger.warning('Common ship filter not detected, skipped')
|
|
return False
|
|
|
|
if current != enable:
|
|
logger.info(f'Common ship filter set to {enable}')
|
|
self.device.click(COMMON_SHIP_FILTER_ENABLE)
|
|
self.handle_dock_cards_loading()
|
|
self.device.screenshot()
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
def _retirement_confirm(self):
|
|
executed = False
|
|
while 1:
|
|
self.device.screenshot()
|
|
if self.config.RETIRE_SR or self.config.RETIRE_SSR or self.config.RETIREMENT_METHOD == 'one_click_retire':
|
|
if self.handle_popup_confirm():
|
|
continue
|
|
if self.appear_then_click(SHIP_CONFIRM, offset=30, interval=2):
|
|
continue
|
|
if self.appear_then_click(SHIP_CONFIRM_2, offset=30, interval=2):
|
|
continue
|
|
if self.appear_then_click(EQUIP_CONFIRM, offset=30, interval=2):
|
|
continue
|
|
if self.appear_then_click(EQUIP_CONFIRM_2, offset=30, interval=2):
|
|
executed = True
|
|
continue
|
|
if self.appear(GET_ITEMS_1, interval=2):
|
|
self.device.click(GET_ITEMS_1_RETIREMENT_SAVE)
|
|
self.interval_reset(SHIP_CONFIRM)
|
|
continue
|
|
|
|
# End
|
|
if executed and self.appear(IN_RETIREMENT_CHECK):
|
|
# self._handle_retirement_cards_loading()
|
|
# self.device.screenshot()
|
|
self.handle_info_bar()
|
|
self.device.screenshot()
|
|
break
|
|
|
|
def retirement_appear(self):
|
|
return self.appear(RETIRE_APPEAR_1, offset=30) \
|
|
and self.appear(RETIRE_APPEAR_2, offset=30) \
|
|
and self.appear(RETIRE_APPEAR_3, offset=30)
|
|
|
|
def _retirement_quit_check_func(self):
|
|
return not self.appear(IN_RETIREMENT_CHECK)
|
|
|
|
def _retirement_quit(self):
|
|
self.ui_back(check_button=self._retirement_quit_check_func, skip_first_screenshot=True)
|
|
|
|
@property
|
|
def _retire_rarity(self):
|
|
rarity = set()
|
|
if self.config.RETIRE_N:
|
|
rarity.add('N')
|
|
if self.config.RETIRE_R:
|
|
rarity.add('R')
|
|
if self.config.RETIRE_SR:
|
|
rarity.add('SR')
|
|
if self.config.RETIRE_SSR:
|
|
rarity.add('SSR')
|
|
return rarity
|
|
|
|
@Config.when(RETIREMENT_METHOD='one_click_retire')
|
|
def retire_ships(self, amount=None, rarity=None):
|
|
logger.hr('Retirement')
|
|
logger.info('Using one click retirement.')
|
|
if amount is None:
|
|
amount = self._retire_amount
|
|
end = False
|
|
total = 0
|
|
|
|
while 1:
|
|
self.handle_info_bar()
|
|
|
|
while 1:
|
|
self.device.screenshot()
|
|
if self.appear(SHIP_CONFIRM_2):
|
|
break
|
|
if self.info_bar_count():
|
|
logger.info('No more ships to retire.')
|
|
end = True
|
|
break
|
|
if self.appear_then_click(ONE_CLICK_RETIREMENT, interval=2):
|
|
continue
|
|
|
|
if end:
|
|
break
|
|
self._retirement_confirm()
|
|
total += 10
|
|
if total >= amount:
|
|
break
|
|
|
|
logger.info(f'Total retired round: {total // 10}')
|
|
return total
|
|
|
|
@Config.when(RETIREMENT_METHOD='old_retire')
|
|
def retire_ships(self, amount=None, rarity=None):
|
|
"""
|
|
Args:
|
|
amount (int): Amount of cards retire. 0 to 2000.
|
|
rarity (tuple(str)): Card rarity. N, R, SR, SSR.
|
|
|
|
Returns:
|
|
int: Total retired.
|
|
"""
|
|
if amount is None:
|
|
amount = self._retire_amount
|
|
if rarity is None:
|
|
rarity = self._retire_rarity
|
|
logger.hr('Retirement')
|
|
logger.info(f'Amount={amount}. Rarity={rarity}')
|
|
self._retirement_set_sort_method('ASC')
|
|
self._retirement_set_common_ship_filter()
|
|
total = 0
|
|
|
|
while amount:
|
|
selected = self._retirement_choose(amount=10 if amount > 10 else amount, target_rarity=rarity)
|
|
total += selected
|
|
if selected == 0:
|
|
break
|
|
|
|
self._retirement_confirm()
|
|
|
|
amount -= selected
|
|
if amount <= 0:
|
|
break
|
|
|
|
self._retirement_set_sort_method('DESC')
|
|
logger.info(f'Total retired: {total}')
|
|
return total
|
|
|
|
def handle_retirement(self):
|
|
if not self.config.ENABLE_RETIREMENT:
|
|
return False
|
|
if not self.retirement_appear():
|
|
return False
|
|
|
|
if self._unable_to_enhance:
|
|
self.config.RETIREMENT_METHOD = 'one_click_retire'
|
|
total = self._retire_handler()
|
|
self.config.RETIREMENT_METHOD = 'enhance'
|
|
self._unable_to_enhance = False
|
|
if not total:
|
|
logger.warning('No ship retired, exit')
|
|
logger.info('This may happens because wrong options of one click retirement in game')
|
|
exit(1)
|
|
elif 'retire' in self.config.RETIREMENT_METHOD or self._unable_to_enhance:
|
|
total = self._retire_handler()
|
|
self._unable_to_enhance = False
|
|
if not total:
|
|
logger.warning('No ship retired, exit')
|
|
logger.info('This may happens because some filters are set in dock')
|
|
exit(1)
|
|
else:
|
|
total = self._enhance_handler()
|
|
if not total:
|
|
logger.info('No ship to enhance, but dock full, will try retire')
|
|
self._unable_to_enhance = True
|
|
|
|
return True
|
|
|
|
def _retire_handler(self):
|
|
self.ui_click(RETIRE_APPEAR_1, check_button=IN_RETIREMENT_CHECK, skip_first_screenshot=True)
|
|
self.handle_dock_cards_loading()
|
|
|
|
total = self.retire_ships()
|
|
|
|
self._retirement_quit()
|
|
self.config.DOCK_FULL_TRIGGERED = True
|
|
|
|
return total
|