1
0
mirror of https://gitee.com/sui-feng-cb/AzurLaneAutoScript1 synced 2026-03-14 14:16:04 +08:00
Files
AzurLaneAutoScript/module/shop/shop_general.py
2026-03-13 14:08:02 +08:00

223 lines
7.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from module.base.decorator import cached_property
from module.logger import logger
from module.shop.base import ShopItemGrid, ShopItemGrid_250814
from module.shop.clerk import ShopClerk
from module.shop.shop_status import ShopStatus
from module.shop.ui import ShopUI
import re
class GeneralShop_250814(ShopClerk, ShopUI, ShopStatus):
gems = 0
shop_template_folder = './assets/shop/general'
@cached_property
def shop_filter(self):
"""
Returns:
str:
"""
return self.config.GeneralShop_Filter.strip()
@cached_property
def skinbox_allowed_positions(self):
"""
The set of configured absolute grid positions (1-based),
or None if no restrictions are applied.
If all the input is invalid, returns an empty set which will block all purchases.
Returns:
set[int]:
"""
raw_filter = self.config.GeneralShop_SkinBoxPositionFilter.strip()
if not raw_filter:
return None
raw_filter = re.sub(r'[>﹥›˃ᐳ❯]', '>', raw_filter)
allowed = {int(pos) for pos in raw_filter.split('>') if pos.strip().isdigit()}
logger.attr('SkinBox_filter', ' > '.join([str(pos) for pos in allowed]))
# raw_filter = raw_filter.replace('', ',')
# allowed = {int(pos) for pos in raw_filter.split(',') if pos.strip().isdigit()}
# logger.attr('SkinBox_filter', ', '.join([str(pos) for pos in allowed]))
# raw_filter = raw_filter.replace('', ',')
# allowed = set()
# for item in raw_filter.split(','):
# pos_str = item.strip()
# if not pos_str:
# continue
# if pos_str.isdigit():
# allowed.add(int(pos_str))
# continue
# logger.warning(f"Invalid position index: {pos_str}")
# logger.attr('SkinBox_filter', ', '.join([str(pos) for pos in allowed]))
if not allowed:
logger.warning("No valid positions found")
return allowed
# New UI in 2025-08-14
@cached_property
def shop_general_items(self):
"""
Returns:
ShopItemGrid:
"""
shop_grid = self.shop_grid
shop_general_items = ShopItemGrid_250814(
shop_grid,
templates={},
template_area=(25, 20, 82, 72),
amount_area=(42, 50, 65, 65),
cost_area=(-12, 115, 60, 155),
price_area=(14, 121, 85, 150),
)
shop_general_items.load_template_folder(self.shop_template_folder)
shop_general_items.load_cost_template_folder('./assets/shop/cost')
return shop_general_items
def shop_items(self):
"""
Shared alias for all shops
If there are server-lang
differences, reference
shop_guild/medal for @Config
example
Returns:
ShopItemGrid:
"""
return self.shop_general_items
currency_rechecked = 0
def shop_currency(self):
"""
Ocr shop guild currency if needed
(gold coins and gems)
Then return gold coin count
Returns:
int: gold coin amount
"""
while 1:
self._currency = self.status_get_gold_coins()
self.gems = self.status_get_gems()
logger.info(f'Gold coins: {self._currency}, Gems: {self.gems}')
if self.currency_rechecked >= 3:
logger.warning('Failed to handle fix currency bug in general shop, skip')
break
# if self._currency == 0 and self.gems == 0:
# logger.info('Game bugged, coins and gems disappeared, switch between shops to reset')
# self.currency_rechecked += 1
#
# # 2022.06.01 General shop no longer at an expected location
# # NavBar 'get_active' (0 index-based) and swap with its left
# # adjacent neighbor then back (NavBar 'set' is 1 index-based)
# index = self._shop_bottom_navbar.get_active(self)
# self.shop_bottom_navbar_ensure(left=index)
# self.shop_bottom_navbar_ensure(left=index + 1)
# continue
# else:
# break
# 2023.07.13 Shop UI changed entirely, remove all these
break
return self._currency
def shop_check_item(self, item):
"""
Args:
item: Item to check
Returns:
bool: whether item can be bought
"""
if item.cost == 'Coins':
if item.price > self._currency:
return False
return True
if self.config.GeneralShop_UseGems:
if item.cost == 'Gems':
if item.price > self.gems:
return False
return True
return False
def _skinbox_position_check(self, item):
"""
Check if the skin box is at a designated purchase position.
Args:
item: Item to check
Returns:
bool: True if the skin box is targeted for purchase.
"""
allowed = self.skinbox_allowed_positions
if allowed is None:
return True
grids = self.shop_general_items.grids
abs_pos = round((item.button[0] - grids.origin[0]) / grids.delta[0]) + 1
return abs_pos in allowed
def shop_check_custom_item(self, item):
"""
Check a custom item that should be bought with specific option.
Args:
item: Item to check
Returns:
bool: whether item is custom
"""
if self.config.GeneralShop_ConsumeCoins and self._currency >= 550000:
if item.cost == 'Coins':
return True
mode = self.config.GeneralShop_BuySkinBox
if (
mode == 'unlimited'
or (mode == 'specified' and self.config.GeneralShop_BuySkinBoxAmount > 0)
):
if (not item.is_known_item() and item.amount == 1 and item.cost == 'Coins' and item.price == 7000):
# check a custom item that cannot be template matched as color
# and design constantly changes i.e. equip skin box
logger.info(f'Item {item} is considered to be an equip skin box')
if self._currency >= item.price and self._skinbox_position_check(item):
if mode == 'specified':
self.config.GeneralShop_BuySkinBoxAmount -= 1
return True
return False
def run(self):
"""
Run General Shop
"""
# Base case; exit run if filter empty
if not self.shop_filter:
return
# When called, expected to be in
# corrected General Shop interface
logger.hr('General Shop', level=1)
# Execute buy operations
# Refresh if enabled and available
refresh = self.config.GeneralShop_Refresh
for _ in range(2):
success = self.shop_buy()
if not success:
break
if refresh and self.shop_refresh():
continue
break