mirror of
https://github.com/LmeSzinc/StarRailCopilot.git
synced 2024-11-25 10:01:10 +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),
|
||||
),
|
||||
)
|
||||
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(
|
||||
name='RUN_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_direction(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)
|
||||
logger.info(
|
||||
f'MiniMap '
|
||||
|
@ -43,6 +43,12 @@ class ResourceConst:
|
||||
# Pad 600px, cause camera sight in game is larger than GIMAP
|
||||
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):
|
||||
# Usually to be 0.4~0.5
|
||||
self.position_similarity = 0.
|
||||
@ -50,6 +56,8 @@ class ResourceConst:
|
||||
self.position_similarity_local = 0.
|
||||
# Current position on GIMAP with an error of about 0.1 pixel
|
||||
self.position: tuple[float, float] = (0, 0)
|
||||
# Minimap scale factor, 1.0~1.25
|
||||
self.position_scale = 1.0
|
||||
|
||||
# Usually > 0.3
|
||||
# Warnings will be logged if similarity <= 0.8
|
||||
@ -82,3 +90,51 @@ class ResourceConst:
|
||||
file = self.filepath(file)
|
||||
print(f'Save image: {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