mirror of
https://github.com/LmeSzinc/StarRailCopilot.git
synced 2024-11-15 22:19:18 +00:00
Add: Set map rotation
This commit is contained in:
parent
e41d5b4ae4
commit
bfae03bc19
BIN
assets/share/map/control/ROTATION_SWIPE_AREA.png
Normal file
BIN
assets/share/map/control/ROTATION_SWIPE_AREA.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.5 KiB |
@ -33,6 +33,16 @@ JOYSTICK = ButtonWrapper(
|
|||||||
button=(234, 546, 262, 574),
|
button=(234, 546, 262, 574),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
ROTATION_SWIPE_AREA = ButtonWrapper(
|
||||||
|
name='ROTATION_SWIPE_AREA',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/map/control/ROTATION_SWIPE_AREA.png',
|
||||||
|
area=(264, 87, 990, 219),
|
||||||
|
search=(244, 67, 1010, 239),
|
||||||
|
color=(255, 255, 255),
|
||||||
|
button=(264, 87, 990, 219),
|
||||||
|
),
|
||||||
|
)
|
||||||
RUN_BUTTON = ButtonWrapper(
|
RUN_BUTTON = ButtonWrapper(
|
||||||
name='RUN_BUTTON',
|
name='RUN_BUTTON',
|
||||||
share=Button(
|
share=Button(
|
||||||
|
69
tasks/map/control/control.py
Normal file
69
tasks/map/control/control.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
from functools import cached_property
|
||||||
|
|
||||||
|
from module.base.timer import Timer
|
||||||
|
from module.logger import logger
|
||||||
|
from tasks.map.assets.assets_map_control import ROTATION_SWIPE_AREA
|
||||||
|
from tasks.map.control.joystick import MapControlJoystick
|
||||||
|
from tasks.map.minimap.minimap import Minimap
|
||||||
|
|
||||||
|
|
||||||
|
class MapControl(MapControlJoystick):
|
||||||
|
_rotation_swipe_interval = Timer(1.2, count=2)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def minimap(self) -> Minimap:
|
||||||
|
return Minimap()
|
||||||
|
|
||||||
|
def handle_rotation_set(self, target, threshold=15):
|
||||||
|
"""
|
||||||
|
Set rotation while running.
|
||||||
|
self.minimap.update_rotation() must be called first.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
target: Target degree (0~360)
|
||||||
|
threshold:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: If swiped rotation
|
||||||
|
"""
|
||||||
|
if self.minimap.is_rotation_near(target, threshold=threshold):
|
||||||
|
return False
|
||||||
|
if not self._rotation_swipe_interval.reached():
|
||||||
|
return False
|
||||||
|
|
||||||
|
logger.info(f'Rotation set: {target}')
|
||||||
|
diff = self.minimap.rotation_diff(target) * self.minimap.ROTATION_SWIPE_MULTIPLY
|
||||||
|
diff = min(diff, self.minimap.ROTATION_SWIPE_MAX_DISTANCE)
|
||||||
|
diff = max(diff, -self.minimap.ROTATION_SWIPE_MAX_DISTANCE)
|
||||||
|
|
||||||
|
self.device.swipe_vector((-diff, 0), box=ROTATION_SWIPE_AREA.area, duration=(0.2, 0.5))
|
||||||
|
self._rotation_swipe_interval.reset()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def rotation_set(self, target, threshold=15, skip_first_screenshot=False):
|
||||||
|
"""
|
||||||
|
Set rotation while standing.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
target: Target degree (0~360)
|
||||||
|
threshold:
|
||||||
|
skip_first_screenshot:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: If swiped rotation
|
||||||
|
"""
|
||||||
|
while 1:
|
||||||
|
if skip_first_screenshot:
|
||||||
|
skip_first_screenshot = False
|
||||||
|
else:
|
||||||
|
self.device.screenshot()
|
||||||
|
self.minimap.update_rotation(self.device.image)
|
||||||
|
self.minimap.log_minimap()
|
||||||
|
|
||||||
|
# End
|
||||||
|
if self.minimap.is_rotation_near(target, threshold=threshold):
|
||||||
|
logger.info(f'Rotation is now at: {target}')
|
||||||
|
break
|
||||||
|
|
||||||
|
if self.handle_rotation_set(target, threshold=threshold):
|
||||||
|
continue
|
@ -363,7 +363,9 @@ class Minimap(MapResource):
|
|||||||
self.update_position(image)
|
self.update_position(image)
|
||||||
self.update_direction(image)
|
self.update_direction(image)
|
||||||
self.update_rotation(image)
|
self.update_rotation(image)
|
||||||
|
self.log_minimap()
|
||||||
|
|
||||||
|
def log_minimap(self):
|
||||||
# MiniMap P:(567.5, 862.8) (1.00x|0.439|0.157), D:303.8 (0.253), R:304 (0.846)
|
# MiniMap P:(567.5, 862.8) (1.00x|0.439|0.157), D:303.8 (0.253), R:304 (0.846)
|
||||||
logger.info(
|
logger.info(
|
||||||
f'MiniMap '
|
f'MiniMap '
|
||||||
|
@ -43,6 +43,12 @@ class ResourceConst:
|
|||||||
# Pad 600px, cause camera sight in game is larger than GIMAP
|
# Pad 600px, cause camera sight in game is larger than GIMAP
|
||||||
BIGMAP_BORDER_PAD = int(600 * BIGMAP_SEARCH_SCALE)
|
BIGMAP_BORDER_PAD = int(600 * BIGMAP_SEARCH_SCALE)
|
||||||
|
|
||||||
|
# Swipe 400px is about 85~90 degree
|
||||||
|
# <rotation_diff> * ROTATION_SWIPE_MULTIPLY = <distance_to_swipe>
|
||||||
|
ROTATION_SWIPE_MULTIPLY = 400 / 85
|
||||||
|
# Max distance in one swipe, limited in -600px~600px
|
||||||
|
ROTATION_SWIPE_MAX_DISTANCE = 600
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# Usually to be 0.4~0.5
|
# Usually to be 0.4~0.5
|
||||||
self.position_similarity = 0.
|
self.position_similarity = 0.
|
||||||
@ -50,6 +56,8 @@ class ResourceConst:
|
|||||||
self.position_similarity_local = 0.
|
self.position_similarity_local = 0.
|
||||||
# Current position on GIMAP with an error of about 0.1 pixel
|
# Current position on GIMAP with an error of about 0.1 pixel
|
||||||
self.position: tuple[float, float] = (0, 0)
|
self.position: tuple[float, float] = (0, 0)
|
||||||
|
# Minimap scale factor, 1.0~1.25
|
||||||
|
self.position_scale = 1.0
|
||||||
|
|
||||||
# Usually > 0.3
|
# Usually > 0.3
|
||||||
# Warnings will be logged if similarity <= 0.8
|
# Warnings will be logged if similarity <= 0.8
|
||||||
@ -82,3 +90,51 @@ class ResourceConst:
|
|||||||
file = self.filepath(file)
|
file = self.filepath(file)
|
||||||
print(f'Save image: {file}')
|
print(f'Save image: {file}')
|
||||||
Image.fromarray(image).save(file)
|
Image.fromarray(image).save(file)
|
||||||
|
|
||||||
|
def position_diff(self, target):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
target: Target position (x, y)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
float: Distance to current position
|
||||||
|
"""
|
||||||
|
x1, y1 = self.position
|
||||||
|
x2, y2 = target
|
||||||
|
diff = ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5
|
||||||
|
return diff
|
||||||
|
|
||||||
|
def is_position_near(self, target, threshold=5):
|
||||||
|
return self.position_diff(target) <= threshold
|
||||||
|
|
||||||
|
def direction_diff(self, target):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
target: Target degree (0~360)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
float: Diff to current direction (-180~180)
|
||||||
|
"""
|
||||||
|
diff = (self.direction - target) % 360
|
||||||
|
if diff > 180:
|
||||||
|
diff -= 360
|
||||||
|
return diff
|
||||||
|
|
||||||
|
def is_direction_near(self, target, threshold=15):
|
||||||
|
return abs(self.direction_diff(target)) <= threshold
|
||||||
|
|
||||||
|
def rotation_diff(self, target):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
target: Target degree (0~360)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
float: Diff to current rotation (-180~180)
|
||||||
|
"""
|
||||||
|
diff = (self.rotation - target) % 360
|
||||||
|
if diff > 180:
|
||||||
|
diff -= 360
|
||||||
|
return diff
|
||||||
|
|
||||||
|
def is_rotation_near(self, target, threshold=15):
|
||||||
|
return abs(self.rotation_diff(target)) <= threshold
|
||||||
|
Loading…
Reference in New Issue
Block a user