1
0
mirror of https://github.com/sui-feng-cb/AzurLaneAutoScript1.git synced 2026-07-07 05:17:58 +08:00
Files
AzurLaneAutoScript/module/meowfficer/buy.py
2026-07-01 15:57:15 +08:00

155 lines
5.5 KiB
Python

from module.combat.assets import GET_ITEMS_1
from module.logger import logger
from module.meowfficer.assets import *
from module.meowfficer.base import MeowfficerBase
from module.ocr.ocr import Digit, DigitCounter
from module.ui.assets import MEOWFFICER_GOTO_DORMMENU
BUY_MAX = 15
BUY_PRIZE = 1500
MEOWFFICER = DigitCounter(OCR_MEOWFFICER, letter=(140, 113, 99), threshold=64)
MEOWFFICER_CHOOSE = Digit(OCR_MEOWFFICER_CHOOSE, letter=(140, 113, 99), threshold=64)
MEOWFFICER_COINS = Digit(OCR_MEOWFFICER_COINS, letter=(99, 69, 41), threshold=64)
class MeowfficerBuy(MeowfficerBase):
def meow_get_buy_count(self) -> int:
"""
OCR remaining buys and coins, combine with user configs to decide
how many meowfficer boxes to buy this run.
Baseline: buy up to Meowfficer_BuyAmount per day.
Overflow: when Meowfficer_OverflowCoins is not -1 and current coins
exceed it, keep buying extra boxes until coins drop to threshold or
today's quota runs out. The 1st box per day is free.
Pages:
in: page_meowfficer
Returns:
int: 0 to BUY_MAX, number of boxes to buy now.
"""
self.device.screenshot()
remain, bought, total = MEOWFFICER.ocr(self.device.image)
coins = MEOWFFICER_COINS.ocr(self.device.image)
logger.attr('Meowfficer_remain', remain)
logger.attr('Meowfficer_coins', coins)
if total != BUY_MAX:
logger.warning(f'Invalid meowfficer buy limit: {total}, revise to {BUY_MAX}')
total = BUY_MAX
bought = total - remain
today_left = max(0, total - bought)
if today_left <= 0:
logger.info(f'Already bought {bought}/{total} today, stopped')
return 0
# Baseline buy
baseline = min(max(0, self.config.Meowfficer_BuyAmount - bought), today_left)
# Overflow buy
overflow_th = self.config.Meowfficer_OverflowCoins
extra = 0
if overflow_th != -1 and coins > overflow_th:
extra = -(-(coins - overflow_th) // BUY_PRIZE)
extra = min(extra, today_left - baseline)
extra = max(0, extra)
count = baseline + extra
# Cap by affordable coins, the 1st box per day is free
free = 1 if bought == 0 else 0
affordable = coins // BUY_PRIZE + free
if count > affordable:
logger.info(f'Current coins only afford to buy {affordable}')
count = affordable
logger.info(
f'Meowfficer buy plan: count={count}, baseline={baseline}, '
f'overflow={extra}, bought={bought}/{total}, coins={coins}'
)
return count
def meow_choose(self, count) -> None:
"""
Navigate to MEOWFFICER_BUY and set buy index to `count`.
Pages:
in: page_meowfficer
out: MEOWFFICER_BUY
Args:
count (int): 1 to BUY_MAX.
"""
self.meow_enter(MEOWFFICER_BUY_ENTER, check_button=MEOWFFICER_BUY)
# info_bar may covers OCR_MEOWFFICER_CHOOSE,
# and OCR_MEOWFFICER_CHOOSE may detected as 0 causing extra clickings
# info_bar is usually from the previous Dorm task or meowfficer fort
self.handle_info_bar()
self.ui_ensure_index(count, letter=MEOWFFICER_CHOOSE, prev_button=MEOWFFICER_BUY_PREV,
next_button=MEOWFFICER_BUY_NEXT, skip_first_screenshot=True)
def meow_confirm(self, skip_first_screenshot=True) -> None:
"""
Pages:
in: MEOWFFICER_BUY
out: page_meowfficer
"""
# Here uses a simple click, to avoid clicking MEOWFFICER_BUY multiple times.
logger.hr('Meow confirm')
executed = False
with self.stat.new(
genre="meowfficer_buy",
method=self.config.DropRecord_MeowfficerBuy,
) as drop:
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.appear(MEOWFFICER_BUY, offset=(20, 20), interval=3):
if executed:
self.device.click(MEOWFFICER_GOTO_DORMMENU)
else:
self.device.click(MEOWFFICER_BUY)
continue
if self.handle_meow_popup_confirm():
executed = True
continue
if self.appear_then_click(MEOWFFICER_BUY_SKIP, interval=3):
executed = True
continue
if self.appear(GET_ITEMS_1, offset=5, interval=3):
if drop.save is True:
drop.handle_add(self, before=2)
self.device.click(MEOWFFICER_BUY_SKIP)
self.interval_clear(MEOWFFICER_BUY)
executed = True
continue
# Rare case that MEOWFFICER_INFO popups here
if self.meow_additional():
continue
# End
if self.match_template_color(MEOWFFICER_BUY_ENTER, offset=(20, 20)):
break
def meow_buy(self) -> None:
"""
Buy meowfficer boxes according to baseline and optional overflow plan.
Pages:
in: page_meowfficer
out: page_meowfficer
"""
logger.hr('Meowfficer buy', level=1)
count = self.meow_get_buy_count()
if count <= 0:
return
self.meow_choose(count)
self.meow_confirm()