mirror of
https://github.com/LmeSzinc/StarRailCopilot.git
synced 2024-11-25 01:49:41 +00:00
Add: synthesize_amount_set()
This commit is contained in:
parent
fc8ce808ca
commit
3783066cd7
BIN
assets/share/item/synthesize/SYNTHESIZE_SLIDER.png
Normal file
BIN
assets/share/item/synthesize/SYNTHESIZE_SLIDER.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.0 KiB |
@ -248,6 +248,7 @@ class AdaptiveScroll(Scroll):
|
|||||||
'prominence': 30,
|
'prominence': 30,
|
||||||
'wlen': wlen,
|
'wlen': wlen,
|
||||||
'width': 2,
|
'width': 2,
|
||||||
|
# 'distance': wlen / 2,
|
||||||
}
|
}
|
||||||
parameters.update(self.parameters)
|
parameters.update(self.parameters)
|
||||||
peaks, _ = signal.find_peaks(image, **parameters)
|
peaks, _ = signal.find_peaks(image, **parameters)
|
||||||
|
@ -83,3 +83,13 @@ SYNTHESIZE_PLUS = ButtonWrapper(
|
|||||||
button=(1125, 567, 1155, 589),
|
button=(1125, 567, 1155, 589),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
SYNTHESIZE_SLIDER = ButtonWrapper(
|
||||||
|
name='SYNTHESIZE_SLIDER',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/item/synthesize/SYNTHESIZE_SLIDER.png',
|
||||||
|
area=(660, 575, 1070, 581),
|
||||||
|
search=(640, 555, 1090, 601),
|
||||||
|
color=(118, 96, 77),
|
||||||
|
button=(660, 575, 1070, 581),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
149
tasks/item/slider.py
Normal file
149
tasks/item/slider.py
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
import numpy as np
|
||||||
|
from scipy import signal
|
||||||
|
|
||||||
|
from module.base.button import ButtonWrapper, ClickButton
|
||||||
|
from module.base.timer import Timer
|
||||||
|
from module.base.utils import rgb2gray
|
||||||
|
from module.exception import ScriptError
|
||||||
|
from module.logger import logger
|
||||||
|
from tasks.base.ui import UI
|
||||||
|
|
||||||
|
|
||||||
|
class Slider:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
main: UI,
|
||||||
|
slider: ButtonWrapper,
|
||||||
|
parameters: dict = None,
|
||||||
|
background=5
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
main:
|
||||||
|
slider: Slider button
|
||||||
|
parameters (dict): Parameters passing to scipy.find_peaks
|
||||||
|
background (int):
|
||||||
|
"""
|
||||||
|
self.main = main
|
||||||
|
self.slider = slider
|
||||||
|
|
||||||
|
if parameters is None:
|
||||||
|
parameters = {}
|
||||||
|
self.parameters = parameters
|
||||||
|
self.background = background
|
||||||
|
|
||||||
|
# Actual slider area
|
||||||
|
self.area = self.slider.area
|
||||||
|
|
||||||
|
def cal_slider(self):
|
||||||
|
"""
|
||||||
|
Slider always have its left side fixed, right side movable depending on the maximum number
|
||||||
|
Calculate the right side, similar to AdaptiveScroll.match_color
|
||||||
|
"""
|
||||||
|
area = self.slider.area
|
||||||
|
area = (area[0], area[1] - self.background, area[2], area[3] + self.background)
|
||||||
|
image = self.main.image_crop(area, copy=False)
|
||||||
|
image = rgb2gray(image)
|
||||||
|
image = image.flatten('F')
|
||||||
|
wlen = area[3] - area[1]
|
||||||
|
total = area[2] - area[0]
|
||||||
|
|
||||||
|
parameters = {
|
||||||
|
'prominence': 15,
|
||||||
|
'wlen': wlen,
|
||||||
|
'width': 4,
|
||||||
|
'distance': wlen / 2,
|
||||||
|
}
|
||||||
|
parameters.update(self.parameters)
|
||||||
|
peaks, _ = signal.find_peaks(image, **parameters)
|
||||||
|
peaks //= wlen
|
||||||
|
|
||||||
|
# Ignore non-continuous peaks, which may be the letter to the right of slider
|
||||||
|
try:
|
||||||
|
right = np.where(np.diff(peaks) >= 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
|
@ -1,16 +1,18 @@
|
|||||||
import cv2
|
import cv2
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
import module.config.server as server
|
||||||
from module.base.decorator import cached_property
|
from module.base.decorator import cached_property
|
||||||
from module.base.timer import Timer
|
from module.base.timer import Timer
|
||||||
from module.base.utils import SelectedGrids, color_similarity_2d, crop, image_size
|
from module.base.utils import SelectedGrids, color_similarity_2d, crop, image_size
|
||||||
from module.exception import ScriptError
|
from module.exception import ScriptError
|
||||||
from module.logger import logger
|
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.base.page import page_synthesize
|
||||||
from tasks.combat.obtain import CombatObtain
|
from tasks.combat.obtain import CombatObtain
|
||||||
from tasks.item.assets.assets_item_synthesize import *
|
from tasks.item.assets.assets_item_synthesize import *
|
||||||
from tasks.item.inventory import InventoryManager
|
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 import ITEM_CLASSES, ItemCalyx, ItemTrace
|
||||||
from tasks.planner.keywords.classes import ItemBase
|
from tasks.planner.keywords.classes import ItemBase
|
||||||
from tasks.planner.model import ObtainedAmmount
|
from tasks.planner.model import ObtainedAmmount
|
||||||
@ -332,6 +334,18 @@ class Synthesize(CombatObtain):
|
|||||||
logger.error(f'Unexpected switch_row={switch_row} during loop')
|
logger.error(f'Unexpected switch_row={switch_row} during loop')
|
||||||
return False
|
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__':
|
if __name__ == '__main__':
|
||||||
|
Loading…
Reference in New Issue
Block a user