update move
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from src.classes.action import DefineAction, ChunkActionMixin
|
||||
from src.classes.action.move_helper import clamp_manhattan_with_diagonal_priority
|
||||
|
||||
|
||||
class Move(DefineAction, ChunkActionMixin):
|
||||
@@ -16,10 +17,9 @@ class Move(DefineAction, ChunkActionMixin):
|
||||
移动到某个tile
|
||||
"""
|
||||
world = self.world
|
||||
# 基于境界的移动步长:每轴最多移动 move_step_length 格
|
||||
# 基于境界的移动步长:曼哈顿限制,优先斜向
|
||||
step = getattr(self.avatar, "move_step_length", 1)
|
||||
clamped_dx = max(-step, min(step, delta_x))
|
||||
clamped_dy = max(-step, min(step, delta_y))
|
||||
clamped_dx, clamped_dy = clamp_manhattan_with_diagonal_priority(delta_x, delta_y, step)
|
||||
|
||||
new_x = self.avatar.pos_x + clamped_dx
|
||||
new_y = self.avatar.pos_y + clamped_dy
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from src.classes.action import TimedAction
|
||||
from src.classes.action import TimedAction, Move
|
||||
from src.classes.event import Event
|
||||
from src.classes.action.move_helper import clamp_manhattan_with_diagonal_priority
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from src.classes.avatar import Avatar
|
||||
|
||||
|
||||
class MoveAwayFromAvatar(TimedAction):
|
||||
@@ -15,7 +20,7 @@ class MoveAwayFromAvatar(TimedAction):
|
||||
DOABLES_REQUIREMENTS = "任何时候都可以执行"
|
||||
PARAMS = {"avatar_name": "AvatarName"}
|
||||
|
||||
def _find_avatar_by_name(self, name: str) -> "Avatar|None":
|
||||
def _find_avatar_by_name(self, name: str) -> "Avatar | None":
|
||||
for v in self.world.avatar_manager.avatars.values():
|
||||
if v.name == name:
|
||||
return v
|
||||
@@ -27,15 +32,12 @@ class MoveAwayFromAvatar(TimedAction):
|
||||
target = self._find_avatar_by_name(avatar_name)
|
||||
if target is None:
|
||||
return
|
||||
# 计算远离方向:使曼哈顿距离尽量增大
|
||||
dx = 1 if self.avatar.pos_x >= target.pos_x else -1
|
||||
dy = 1 if self.avatar.pos_y >= target.pos_y else -1
|
||||
nx = self.avatar.pos_x + dx
|
||||
ny = self.avatar.pos_y + dy
|
||||
if self.world.map.is_in_bounds(nx, ny):
|
||||
self.avatar.pos_x = nx
|
||||
self.avatar.pos_y = ny
|
||||
self.avatar.tile = self.world.map.get_tile(nx, ny)
|
||||
# 远离方向:以目标到自身的向量取反
|
||||
raw_dx = -(target.pos_x - self.avatar.pos_x)
|
||||
raw_dy = -(target.pos_y - self.avatar.pos_y)
|
||||
step = getattr(self.avatar, "move_step_length", 1)
|
||||
dx, dy = clamp_manhattan_with_diagonal_priority(raw_dx, raw_dy, step)
|
||||
Move(self.avatar, self.world).execute(dx, dy)
|
||||
|
||||
def can_start(self, avatar_name: str | None = None) -> bool:
|
||||
return True
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from src.classes.action import InstantAction
|
||||
from src.classes.action import InstantAction, Move
|
||||
from src.classes.event import Event
|
||||
from src.classes.action.move_helper import clamp_manhattan_with_diagonal_priority
|
||||
|
||||
|
||||
class MoveAwayFromRegion(InstantAction):
|
||||
@@ -10,15 +11,26 @@ class MoveAwayFromRegion(InstantAction):
|
||||
PARAMS = {"region": "RegionName"}
|
||||
|
||||
def _execute(self, region: str) -> None:
|
||||
# 简化:向地图边缘移动一步
|
||||
dx = 1 if self.avatar.pos_x < self.world.map.width - 1 else -1
|
||||
dy = 1 if self.avatar.pos_y < self.world.map.height - 1 else -1
|
||||
nx = max(0, min(self.world.map.width - 1, self.avatar.pos_x + dx))
|
||||
ny = max(0, min(self.world.map.height - 1, self.avatar.pos_y + dy))
|
||||
if self.world.map.is_in_bounds(nx, ny):
|
||||
self.avatar.pos_x = nx
|
||||
self.avatar.pos_y = ny
|
||||
self.avatar.tile = self.world.map.get_tile(nx, ny)
|
||||
# 策略:朝最近的边界方向移动,曼哈顿步长限制,优先斜向
|
||||
width = self.world.map.width
|
||||
height = self.world.map.height
|
||||
x = self.avatar.pos_x
|
||||
y = self.avatar.pos_y
|
||||
|
||||
# 离四边的距离
|
||||
dist_left = x
|
||||
dist_right = width - 1 - x
|
||||
dist_top = y
|
||||
dist_bottom = height - 1 - y
|
||||
|
||||
# 选择更近的两个边界方向组成一个大致“远离区域”的方向
|
||||
# 简化:朝左右中更近的一侧+上下中更近的一侧移动
|
||||
dir_x = -1 if dist_left < dist_right else (1 if dist_right < dist_left else 0)
|
||||
dir_y = -1 if dist_top < dist_bottom else (1 if dist_bottom < dist_top else 0)
|
||||
|
||||
step = getattr(self.avatar, "move_step_length", 1)
|
||||
dx, dy = clamp_manhattan_with_diagonal_priority(dir_x * step, dir_y * step, step)
|
||||
Move(self.avatar, self.world).execute(dx, dy)
|
||||
|
||||
def can_start(self, region: str | None = None) -> bool:
|
||||
return True
|
||||
|
||||
46
src/classes/action/move_helper.py
Normal file
46
src/classes/action/move_helper.py
Normal file
@@ -0,0 +1,46 @@
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
def clamp_manhattan_with_diagonal_priority(dx: int, dy: int, step: int) -> tuple[int, int]:
|
||||
"""
|
||||
在不超过给定曼哈顿步长 step 的前提下,对 (dx, dy) 进行裁剪,且优先斜向移动。
|
||||
|
||||
规则:
|
||||
- 返回的 (mx, my) 满足 |mx| + |my| <= step
|
||||
- 每轴不超过原目标量:|mx| <= |dx|, |my| <= |dy|
|
||||
- 优先分配斜向步(即同时占用 x 与 y 各 1 步),其后再把剩余步数分配给剩余距离更大的轴
|
||||
- 保持原方向(符号)
|
||||
"""
|
||||
if step <= 0 or (dx == 0 and dy == 0):
|
||||
return 0, 0
|
||||
|
||||
abs_dx = abs(dx)
|
||||
abs_dy = abs(dy)
|
||||
sign_x = 1 if dx > 0 else (-1 if dx < 0 else 0)
|
||||
sign_y = 1 if dy > 0 else (-1 if dy < 0 else 0)
|
||||
|
||||
# 实际可用预算不超过所需的曼哈顿距离
|
||||
budget = min(step, abs_dx + abs_dy)
|
||||
|
||||
# 先分配尽量多的斜向步:每个斜向步消耗 2 点预算
|
||||
diagonal_steps = min(min(abs_dx, abs_dy), budget // 2)
|
||||
move_x = diagonal_steps
|
||||
move_y = diagonal_steps
|
||||
|
||||
remaining = budget - 2 * diagonal_steps
|
||||
|
||||
# 若还有剩余预算,分配给剩余距离更大的轴
|
||||
rem_x = abs_dx - move_x
|
||||
rem_y = abs_dy - move_y
|
||||
if remaining > 0:
|
||||
if rem_x >= rem_y:
|
||||
add_x = min(remaining, rem_x)
|
||||
move_x += add_x
|
||||
remaining -= add_x
|
||||
if remaining > 0:
|
||||
add_y = min(remaining, rem_y)
|
||||
move_y += add_y
|
||||
|
||||
return move_x * sign_x, move_y * sign_y
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ from src.classes.action import DefineAction, ActualActionMixin
|
||||
from src.classes.event import Event
|
||||
from src.classes.action import Move
|
||||
from src.classes.action_runtime import ActionResult, ActionStatus
|
||||
from src.classes.action.move_helper import clamp_manhattan_with_diagonal_priority
|
||||
|
||||
|
||||
class MoveToAvatar(DefineAction, ActualActionMixin):
|
||||
@@ -30,12 +31,11 @@ class MoveToAvatar(DefineAction, ActualActionMixin):
|
||||
return
|
||||
cur_loc = (self.avatar.pos_x, self.avatar.pos_y)
|
||||
target_loc = (target.pos_x, target.pos_y)
|
||||
delta_x = target_loc[0] - cur_loc[0]
|
||||
delta_y = target_loc[1] - cur_loc[1]
|
||||
raw_dx = target_loc[0] - cur_loc[0]
|
||||
raw_dy = target_loc[1] - cur_loc[1]
|
||||
step = getattr(self.avatar, "move_step_length", 1)
|
||||
delta_x = max(-step, min(step, delta_x))
|
||||
delta_y = max(-step, min(step, delta_y))
|
||||
Move(self.avatar, self.world).execute(delta_x, delta_y)
|
||||
dx, dy = clamp_manhattan_with_diagonal_priority(raw_dx, raw_dy, step)
|
||||
Move(self.avatar, self.world).execute(dx, dy)
|
||||
|
||||
def can_start(self, avatar_name: str | None = None) -> bool:
|
||||
return True
|
||||
|
||||
@@ -5,6 +5,7 @@ from src.classes.event import Event
|
||||
from src.classes.region import Region
|
||||
from src.classes.action import Move
|
||||
from src.classes.action_runtime import ActionResult, ActionStatus
|
||||
from src.classes.action.move_helper import clamp_manhattan_with_diagonal_priority
|
||||
|
||||
|
||||
class MoveToRegion(DefineAction, ActualActionMixin):
|
||||
@@ -41,13 +42,11 @@ class MoveToRegion(DefineAction, ActualActionMixin):
|
||||
region = self._resolve_region(region)
|
||||
cur_loc = (self.avatar.pos_x, self.avatar.pos_y)
|
||||
region_center_loc = region.center_loc
|
||||
delta_x = region_center_loc[0] - cur_loc[0]
|
||||
delta_y = region_center_loc[1] - cur_loc[1]
|
||||
# 横纵向一次最多移动 move_step_length 格(可以同时横纵移动)
|
||||
raw_dx = region_center_loc[0] - cur_loc[0]
|
||||
raw_dy = region_center_loc[1] - cur_loc[1]
|
||||
step = getattr(self.avatar, "move_step_length", 1)
|
||||
delta_x = max(-step, min(step, delta_x))
|
||||
delta_y = max(-step, min(step, delta_y))
|
||||
Move(self.avatar, self.world).execute(delta_x, delta_y)
|
||||
dx, dy = clamp_manhattan_with_diagonal_priority(raw_dx, raw_dy, step)
|
||||
Move(self.avatar, self.world).execute(dx, dy)
|
||||
|
||||
def can_start(self, region: Region | str | None = None) -> bool:
|
||||
return True
|
||||
|
||||
@@ -41,10 +41,10 @@ LEVELS_PER_REALM = 30
|
||||
LEVELS_PER_STAGE = 10
|
||||
|
||||
REALM_TO_MOVE_STEP = {
|
||||
Realm.Qi_Refinement: 1,
|
||||
Realm.Foundation_Establishment: 2,
|
||||
Realm.Core_Formation: 2,
|
||||
Realm.Nascent_Soul: 2,
|
||||
Realm.Qi_Refinement: 2,
|
||||
Realm.Foundation_Establishment: 3,
|
||||
Realm.Core_Formation: 4,
|
||||
Realm.Nascent_Soul: 5,
|
||||
}
|
||||
|
||||
class CultivationProgress:
|
||||
|
||||
Reference in New Issue
Block a user