Fix: support (#64)

* Fix: support

* Upd: support

* Upd: support

* Upd: support

* Upd: support

* Upd: support

* Upd: support

* Upd: support

---------

Co-authored-by: LmeSzinc <lmeszincsales@gmail.com>
This commit is contained in:
X-Zero-L 2023-08-30 00:58:32 +08:00 committed by GitHub
parent 246c039dc8
commit eb28485d5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 161 additions and 9 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 B

View File

@ -1,23 +1,36 @@
import cv2 import cv2
import numpy as np import numpy as np
from scipy import signal from scipy import signal
from module.base.button import Button, ButtonWrapper
from module.base.timer import Timer from module.base.timer import Timer
from module.base.utils import area_size, crop, rgb2luma, load_image from module.base.utils import area_size, crop, rgb2luma, load_image, crop
from module.logger import logger from module.logger import logger
from module.ui.scroll import Scroll from module.ui.scroll import Scroll
from tasks.base.assets.assets_base_popup import CANCEL_POPUP
from tasks.base.ui import UI from tasks.base.ui import UI
from tasks.combat.assets.assets_combat_support import COMBAT_SUPPORT_ADD, COMBAT_SUPPORT_LIST, \ from tasks.combat.assets.assets_combat_support import COMBAT_SUPPORT_ADD, COMBAT_SUPPORT_LIST, \
COMBAT_SUPPORT_LIST_SCROLL, COMBAT_SUPPORT_SELECTED COMBAT_SUPPORT_LIST_SCROLL, COMBAT_SUPPORT_SELECTED, COMBAT_SUPPORT_LIST_GRID
from tasks.combat.assets.assets_combat_team import COMBAT_TEAM_SUPPORT, COMBAT_TEAM_DISMISSSUPPORT from tasks.combat.assets.assets_combat_team import COMBAT_TEAM_SUPPORT, COMBAT_TEAM_DISMISSSUPPORT
def get_position_in_original_image(position_in_croped_image, crop_area):
"""
Returns:
tuple: (x, y) of position in original image
"""
return (
position_in_croped_image[0] + crop_area[0], position_in_croped_image[1] + crop_area[1]) if position_in_croped_image else None
class SupportCharacter: class SupportCharacter:
_image_cache = {} _image_cache = {}
_crop_area = COMBAT_SUPPORT_LIST_GRID.matched_button.area
def __init__(self, name, screenshot, similarity=0.85): def __init__(self, name, screenshot, similarity=0.85):
self.name = name self.name = name
self.image = self._scale_character() self.image = self._scale_character()
self.screenshot = screenshot self.screenshot = crop(screenshot, SupportCharacter._crop_area)
self.similarity = similarity self.similarity = similarity
self.button = self._find_character() self.button = self._find_character()
@ -49,10 +62,12 @@ class SupportCharacter:
def _find_character(self): def _find_character(self):
character = np.array(self.image) character = np.array(self.image)
support_list_img = self.screenshot support_list_img = self.screenshot
res = cv2.matchTemplate(character, support_list_img, cv2.TM_CCOEFF_NORMED) res = cv2.matchTemplate(
character, support_list_img, cv2.TM_CCOEFF_NORMED)
_, max_val, _, max_loc = cv2.minMaxLoc(res) _, max_val, _, max_loc = cv2.minMaxLoc(res)
max_loc = get_position_in_original_image(
max_loc, SupportCharacter._crop_area)
character_width = character.shape[1] character_width = character.shape[1]
character_height = character.shape[0] character_height = character.shape[0]
@ -68,6 +83,66 @@ class SupportCharacter:
self.button[0], self.button[1] - 5, self.button[0] + 30, self.button[1]) if self.button else None self.button[0], self.button[1] - 5, self.button[0] + 30, self.button[1]) if self.button else None
class ArrowWrapper(ButtonWrapper):
def find_center(self, image):
res = cv2.matchTemplate(
self.matched_button.image, image, cv2.TM_CCOEFF_NORMED)
_, max_val, _, max_loc = cv2.minMaxLoc(res)
return (
(
(max_loc[0] + self.matched_button.image.shape[1] / 2),
(max_loc[1] + self.matched_button.image.shape[0] / 2),
)
if max_val > 0.75
else None
)
class NextSupportCharacter:
_arrow = ArrowWrapper(
name="NextSupportCharacterArrow",
share=Button(
file='./assets/support/selected_character_arrow.png',
area=None,
search=None,
color=None,
button=None,
)
)
_crop_area = (290, 115, 435, 634)
def __init__(self, screenshot):
self.name = "SupportCharacterArrow"
self.screenshot = crop(screenshot, NextSupportCharacter._crop_area)
self.arrow_center = self._find_center()
self.button = self._get_next_support_character_button()
def __bool__(self):
return self.button is not None
def _find_center(self):
center = NextSupportCharacter._arrow.find_center(self.screenshot)
center = get_position_in_original_image(
center, NextSupportCharacter._crop_area) if center else None
return center
def _get_next_support_character_button(self):
area = (self.arrow_center[0] - 200, min(self.arrow_center[1] + 65, 615), self.arrow_center[0] + 10, min(
self.arrow_center[1] + 80, 620)) if self.arrow_center and self.arrow_center[1] < 510 else None
return ButtonWrapper(
name="NextSupportCharacterButton",
share=Button(
file='./assets/support/selected_character_arrow.png',
area=area,
search=area,
# if next support was selected, the average color of the button will larger than 220
color=(220, 220, 220),
button=area,
)
) if self.arrow_center and self.arrow_center[1] < 510 else None
class SupportListScroll(Scroll): class SupportListScroll(Scroll):
def cal_position(self, main): def cal_position(self, main):
""" """
@ -130,11 +205,18 @@ class CombatSupport(UI):
return True return True
# Click # Click
if self.appear(COMBAT_TEAM_SUPPORT, interval=2): if self.appear(COMBAT_TEAM_SUPPORT, interval=1):
self.device.click(COMBAT_TEAM_SUPPORT) self.device.click(COMBAT_TEAM_SUPPORT)
self.interval_reset(COMBAT_TEAM_SUPPORT) self.interval_reset(COMBAT_TEAM_SUPPORT)
continue continue
if self.appear(COMBAT_SUPPORT_LIST, interval=2): if self.appear(CANCEL_POPUP, interval=1):
logger.warning(
"selected identical character, trying select another")
self._cancel_popup()
self._select_next_support()
self.interval_reset(CANCEL_POPUP)
continue
if self.appear(COMBAT_SUPPORT_LIST, interval=1):
if support_character_name != "FirstCharacter": if support_character_name != "FirstCharacter":
self._search_support( self._search_support(
support_character_name) # Search support support_character_name) # Search support
@ -167,7 +249,6 @@ class CombatSupport(UI):
logger.info("Searching support") logger.info("Searching support")
skip_first_screenshot = False skip_first_screenshot = False
character = None
while 1: while 1:
if skip_first_screenshot: if skip_first_screenshot:
skip_first_screenshot = False skip_first_screenshot = False
@ -175,7 +256,8 @@ class CombatSupport(UI):
self.device.screenshot() self.device.screenshot()
if not support_character_name.startswith("Trailblazer"): if not support_character_name.startswith("Trailblazer"):
character = SupportCharacter(support_character_name, self.device.image) character = SupportCharacter(
support_character_name, self.device.image)
else: else:
character = SupportCharacter(f"Stelle{support_character_name[11:]}", character = SupportCharacter(f"Stelle{support_character_name[11:]}",
self.device.image) or SupportCharacter( self.device.image) or SupportCharacter(
@ -223,3 +305,73 @@ class CombatSupport(UI):
self.device.click(character) self.device.click(character)
interval.reset() interval.reset()
continue continue
def _cancel_popup(self):
"""
Pages:
in: CANCEL_POPUP
out: COMBAT_SUPPORT_LIST
"""
logger.hr("Combat support cancel popup")
skip_first_screenshot = True
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End
if self.appear(COMBAT_SUPPORT_LIST):
logger.info("Popup canceled")
return
if self.appear(CANCEL_POPUP):
self.device.click(CANCEL_POPUP)
continue
def _select_next_support(self):
"""
Pages:
in: COMBAT_SUPPORT_LIST
out: COMBAT_SUPPORT_LIST
"""
skip_first_screenshot = True
scroll = SupportListScroll(area=COMBAT_SUPPORT_LIST_SCROLL.area, color=(194, 196, 205),
name=COMBAT_SUPPORT_LIST_SCROLL.name)
interval = Timer(1)
next_support = None
if scroll.appear(main=self):
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End
if next_support and self._next_support_selected(next_support):
return
if interval.reached():
next_support = NextSupportCharacter(self.device.image)
if next_support:
logger.info("Next support found, clicking")
self.device.click(next_support.button)
elif not scroll.at_bottom(main=self):
scroll.next_page(main=self, page=0.4)
else:
logger.warning("No more support")
return
interval.reset()
continue
def _next_support_selected(self, next_support: NextSupportCharacter):
"""
Returns:
bool: True if selected else False
"""
if self.match_color(next_support.button, threshold=20):
logger.info("Next support selected")
return True
return False