Add: Use skills in combat

This commit is contained in:
LmeSzinc 2023-09-24 02:08:36 +08:00
parent 1dcaf5355d
commit 6eb9317ac4
13 changed files with 233 additions and 1 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -0,0 +1,105 @@
from module.base.button import Button, ButtonWrapper
# This file was auto-generated, do not modify it manually. To generate:
# ``` python -m dev_tools.button_extract ```
CHECK_A = ButtonWrapper(
name='CHECK_A',
share=Button(
file='./assets/share/combat/skill/CHECK_A.png',
area=(967, 513, 1087, 623),
search=(947, 493, 1107, 643),
color=(91, 91, 97),
button=(967, 513, 1087, 623),
),
)
CHECK_E = ButtonWrapper(
name='CHECK_E',
share=Button(
file='./assets/share/combat/skill/CHECK_E.png',
area=(1111, 429, 1261, 519),
search=(1091, 409, 1280, 539),
color=(80, 81, 89),
button=(1111, 429, 1261, 519),
),
)
IN_SKILL = ButtonWrapper(
name='IN_SKILL',
share=Button(
file='./assets/share/combat/skill/IN_SKILL.png',
area=(35, 619, 59, 635),
search=(15, 599, 79, 655),
color=(106, 107, 110),
button=(35, 619, 59, 635),
),
)
USE_A = ButtonWrapper(
name='USE_A',
share=Button(
file='./assets/share/combat/skill/USE_A.png',
area=(1037, 579, 1097, 639),
search=(1017, 559, 1117, 659),
color=(107, 108, 111),
button=(1037, 579, 1097, 639),
),
)
USE_E = ButtonWrapper(
name='USE_E',
share=Button(
file='./assets/share/combat/skill/USE_E.png',
area=(1154, 490, 1214, 550),
search=(1134, 470, 1234, 570),
color=(120, 123, 127),
button=(1154, 490, 1214, 550),
),
)
USE_Q1 = ButtonWrapper(
name='USE_Q1',
share=Button(
file='./assets/share/combat/skill/USE_Q1.png',
area=(217, 548, 253, 578),
search=(197, 528, 273, 598),
color=(145, 151, 225),
button=(217, 548, 253, 578),
),
)
USE_Q2 = ButtonWrapper(
name='USE_Q2',
share=Button(
file='./assets/share/combat/skill/USE_Q2.png',
area=(405, 546, 441, 576),
search=(385, 526, 461, 596),
color=(155, 131, 207),
button=(405, 546, 441, 576),
),
)
USE_Q3 = ButtonWrapper(
name='USE_Q3',
share=Button(
file='./assets/share/combat/skill/USE_Q3.png',
area=(593, 545, 629, 575),
search=(573, 525, 649, 595),
color=(208, 208, 202),
button=(593, 545, 629, 575),
),
)
USE_Q4 = ButtonWrapper(
name='USE_Q4',
share=Button(
file='./assets/share/combat/skill/USE_Q4.png',
area=(781, 545, 817, 575),
search=(761, 525, 837, 595),
color=(151, 113, 206),
button=(781, 545, 817, 575),
),
)
USE_Q_AIM = ButtonWrapper(
name='USE_Q_AIM',
share=Button(
file='./assets/share/combat/skill/USE_Q_AIM.png',
area=(1074, 521, 1174, 621),
search=(1054, 501, 1194, 641),
color=(82, 60, 64),
button=(1074, 521, 1174, 621),
),
)

View File

@ -6,13 +6,14 @@ from tasks.combat.assets.assets_combat_prepare import COMBAT_PREPARE
from tasks.combat.assets.assets_combat_team import COMBAT_TEAM_PREPARE, COMBAT_TEAM_SUPPORT from tasks.combat.assets.assets_combat_team import COMBAT_TEAM_PREPARE, COMBAT_TEAM_SUPPORT
from tasks.combat.interact import CombatInteract from tasks.combat.interact import CombatInteract
from tasks.combat.prepare import CombatPrepare from tasks.combat.prepare import CombatPrepare
from tasks.combat.skill import CombatSkill
from tasks.combat.state import CombatState from tasks.combat.state import CombatState
from tasks.combat.support import CombatSupport from tasks.combat.support import CombatSupport
from tasks.combat.team import CombatTeam from tasks.combat.team import CombatTeam
from tasks.map.control.joystick import MapControlJoystick from tasks.map.control.joystick import MapControlJoystick
class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSupport, MapControlJoystick): class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSupport, CombatSkill, MapControlJoystick):
def handle_combat_prepare(self): def handle_combat_prepare(self):
""" """
Returns: Returns:

126
tasks/combat/skill.py Normal file
View File

@ -0,0 +1,126 @@
from module.base.button import match_template
from module.base.timer import Timer
from module.logger import logger
from tasks.base.ui import UI
from tasks.combat.assets.assets_combat_skill import *
class CombatSkill(UI):
def is_in_skill(self) -> bool:
"""
Combat paused, require manual skill use
"""
if not self.appear(IN_SKILL):
return False
if not self.image_color_count(IN_SKILL, color=(255, 255, 255), threshold=221, count=50):
return False
return True
def _skill_click(self, button, skip_first_screenshot=True):
"""
Click a skill button.
Not in skill page means skill has been used and skill animation is ongoing
"""
logger.info(f'Skill use: {button}')
interval = Timer(1)
clicked = False
prev_image = None
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.is_in_skill():
if interval.reached():
prev_image = self.image_crop(button)
self.device.click(button)
interval.reset()
clicked = True
continue
else:
# Skill animation on going
if clicked:
logger.info(f'Skill used: {button}')
break
# New skill icon
if prev_image is not None:
if not match_template(self.image_crop(button), prev_image):
logger.info(f'Skill used: {button}')
break
def _skill_switch(self, check_button, click_button, skip_first_screenshot=True):
"""
Switch to A or E
"""
logger.info(f'Skill switch: {check_button}')
interval = Timer(1)
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# Raw brown border
if self.image_color_count(check_button, color=(220, 196, 145), threshold=221, count=50):
logger.info(f'Skill switched: {check_button}')
break
if self.is_in_skill():
if interval.reached():
self.device.click(click_button)
interval.reset()
continue
def wait_next_skill(self, expected_end=None, skip_first_screenshot=True):
"""
Args:
expected_end: A function returns bool, True represents end.
skip_first_screenshot:
Returns:
bool: True if is_in_skill
False if triggered expected_end
"""
logger.info('Wait next skill')
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.is_in_skill():
return True
if callable(expected_end) and expected_end():
logger.info(f'Combat execute ended at {expected_end.__name__}')
return False
def use_A(self) -> bool:
logger.hr('Use A')
self._skill_switch(check_button=CHECK_A, click_button=USE_A)
self._skill_click(USE_A)
return True
def use_E(self) -> bool:
logger.hr('Use E')
self._skill_switch(check_button=CHECK_E, click_button=USE_E)
self._skill_click(USE_E)
return True
def use_Q(self, position: int) -> bool:
"""
Args:
position: 1 to 4
"""
logger.hr(f'Use Q {position}')
try:
button = [USE_Q1, USE_Q2, USE_Q3, USE_Q4][position - 1]
except IndexError:
logger.error(f'use_Q: position {position} does not exist')
return False
self._skill_click(button)
self._skill_click(USE_Q_AIM)
return True