From 3783066cd752a10a6b82dff9ff7b8b31c5d38454 Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Wed, 12 Jun 2024 23:12:45 +0800 Subject: [PATCH] Add: synthesize_amount_set() --- .../item/synthesize/SYNTHESIZE_SLIDER.png | Bin 0 -> 7120 bytes module/ui/scroll.py | 1 + tasks/item/assets/assets_item_synthesize.py | 10 ++ tasks/item/slider.py | 149 ++++++++++++++++++ tasks/item/synthesize.py | 16 +- 5 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 assets/share/item/synthesize/SYNTHESIZE_SLIDER.png create mode 100644 tasks/item/slider.py diff --git a/assets/share/item/synthesize/SYNTHESIZE_SLIDER.png b/assets/share/item/synthesize/SYNTHESIZE_SLIDER.png new file mode 100644 index 0000000000000000000000000000000000000000..b6a4317c00363a42c457b01f04dad8dac308aee0 GIT binary patch literal 7120 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 3)[0][0] + peaks = peaks[:right + 1] + except IndexError: + pass + # Calculate actual slider area + try: + length = peaks[-1] + self.area = (area[0], area[1], area[0] + length + 1, area[3]) + except IndexError: + length = total + self.area = self.slider.area + logger.info(f'Slider length: {length}/{total}') + + def set(self, value: int, total: int, skip_first_screenshot=True): + """ + Args: + value: Value to set + total: Maximum amount of slider + skip_first_screenshot: + + Returns: + bool: If success + """ + logger.info(f'Slider set {value}/{total}') + if value > total: + raise ScriptError(f'Slider.set value {value} > total {total}') + if total <= 0: + raise ScriptError(f'Slider.set total {total} <= 0') + if value <= 0: + raise ScriptError(f'Slider.set value {value} <= 0') + if value == total == 1: + logger.info('Slider set total==1, no need to set') + return True + # if value == 1: + # logger.info('Slider set value==1, no need to set') + # return True + + self.cal_slider() + + # 18px is the width of controller + length = self.area[2] - self.area[0] - 18 + + left = int((value - 2) / (total - 1) * length) + self.area[0] + right = int((value - 1) / (total - 1) * length) + self.area[0] + if right <= left: + right = left + 1 + # 10px is the radius of slider controller + # When you somewhere on the slider, left edge of controller is where you click + # if right - left < 10: + # logger.info('Setting high maximum slider') + # left -= 10 + # right -= 10 + + # Limit in slider + left = max(min(self.area[2] - 1, left), self.area[0]) + right = max(min(self.area[2], right), self.area[0] + 1) + # Click the right half + left = int((left + right) / 2) + button = ClickButton( + (left, self.area[1], right, self.area[3]), + name=f'Slider_{value}_{total}') + # Pad click area to search + pad = 15 + detect = (right - pad, self.area[1], right + pad, self.area[3]) + logger.info(f'Controller button={button.button}, detect={detect}') + + interval = Timer(1, count=3) + trial = 0 + while 1: + if skip_first_screenshot: + skip_first_screenshot = False + else: + self.main.device.screenshot() + + # End + if trial > 3: + logger.warning('Slider.set failed after 3 trial') + return False + if self.main.image_color_count(detect, color=(255, 255, 255), threshold=221, count=50): + logger.info('Slider set done') + return True + + # Click + if interval.reached(): + self.main.device.click(button) + interval.reset() + trial += 1 diff --git a/tasks/item/synthesize.py b/tasks/item/synthesize.py index 168f44642..0dddf784f 100644 --- a/tasks/item/synthesize.py +++ b/tasks/item/synthesize.py @@ -1,16 +1,18 @@ import cv2 import numpy as np +import module.config.server as server from module.base.decorator import cached_property from module.base.timer import Timer from module.base.utils import SelectedGrids, color_similarity_2d, crop, image_size from module.exception import ScriptError from module.logger import logger -from module.ocr.ocr import Ocr +from module.ocr.ocr import Digit, Ocr from tasks.base.page import page_synthesize from tasks.combat.obtain import CombatObtain from tasks.item.assets.assets_item_synthesize import * from tasks.item.inventory import InventoryManager +from tasks.item.slider import Slider from tasks.planner.keywords import ITEM_CLASSES, ItemCalyx, ItemTrace from tasks.planner.keywords.classes import ItemBase from tasks.planner.model import ObtainedAmmount @@ -332,6 +334,18 @@ class Synthesize(CombatObtain): logger.error(f'Unexpected switch_row={switch_row} during loop') return False + def synthesize_amount_set(self, value: int, total: int): + """ + Args: + value: Value to set + total: Maximum amount of slider + """ + logger.hr('Synthesize amount set', level=2) + slider = Slider(main=self, slider=SYNTHESIZE_SLIDER) + slider.set(value, total) + ocr = Digit(SYNTHESIZE_AMOUNT, lang=server.lang) + self.ui_ensure_index( + value, letter=ocr, next_button=SYNTHESIZE_PLUS, prev_button=SYNTHESIZE_MINUS, interval=(0.1, 0.2)) if __name__ == '__main__':