Support nearest resurrection route selection

This commit is contained in:
王鹏
2026-04-29 21:50:33 +08:00
parent e0ca04b52f
commit 12ce30d2df
3 changed files with 154 additions and 48 deletions

View File

@@ -1,82 +1,162 @@
import time
import math
import time
from hardware_control import hw_ctrl
class DeathManager:
def __init__(self, patrol_system, resurrection_waypoints_path=None,
release_spirit_key='9', resurrect_key='0'):
self.corpse_pos = None
ROUTE_SELECTION_EPSILON = 0.3
def __init__(
self,
patrol_system,
resurrection_waypoints_path=None,
resurrection_route_a_path=None,
resurrection_route_b_path=None,
release_spirit_key='9',
resurrect_key='0',
):
self.patrol_system = patrol_system
self.is_running_to_corpse = False
self._spirit_release_sent = False
self.resurrection_waypoints = self._load_waypoints(resurrection_waypoints_path)
self._resurrection_completed = False
self.release_spirit_key = str(release_spirit_key).strip() or '9'
self.resurrect_key = str(resurrect_key).strip() or '0'
self.resurrection_route_a = self._load_waypoints(
resurrection_route_a_path or resurrection_waypoints_path
)
self.resurrection_route_b = self._load_waypoints(resurrection_route_b_path)
self.corpse_pos = None
self.graveyard_pos = None
self.is_running_to_corpse = False
self.selected_resurrection_route = None
self.selected_resurrection_route_name = None
self._spirit_release_sent = False
self._route_selected = False
self._resurrection_completed = False
def _load_waypoints(self, path):
"""加载复活点路线 JSON可置空。"""
"""Load a resurrection route JSON file, allowing empty configuration."""
if not path:
return None
import json, os
import json
import os
if not os.path.exists(path):
return None
try:
with open(path, 'r', encoding='utf-8') as f:
data = json.load(f)
if isinstance(data, list) and len(data) > 0:
return [(float(p[0]), float(p[1])) for p in data]
if isinstance(data, list) and data:
return [(float(point[0]), float(point[1])) for point in data]
except Exception:
pass
return None
def _clear_death_run_state(self):
self.graveyard_pos = None
self.selected_resurrection_route = None
self.selected_resurrection_route_name = None
self._route_selected = False
self._resurrection_completed = False
def _build_resurrection_route_candidates(self):
candidates = []
if self.resurrection_route_a:
candidates.append(("A", self.resurrection_route_a))
if self.resurrection_route_b:
candidates.append(("B", self.resurrection_route_b))
return candidates
def _record_graveyard_pos(self, state):
if self.graveyard_pos is not None:
return True
x = state.get('x')
y = state.get('y')
if x is None or y is None:
return False
self.graveyard_pos = (float(x), float(y))
print(f">>> [系统] 记录墓地坐标: {self.graveyard_pos}")
return True
def _choose_resurrection_route(self):
if self.graveyard_pos is None:
return None, None
candidates = self._build_resurrection_route_candidates()
if not candidates:
return None, None
best_name = None
best_points = None
best_dist = None
for name, points in candidates:
start_pos = points[0]
dist = math.dist(self.graveyard_pos, start_pos)
print(f">>> [系统] 复活路线{name} 起点距离墓地: {dist:.3f} | 起点: {start_pos}")
if best_dist is None or dist + self.ROUTE_SELECTION_EPSILON < best_dist:
best_name = name
best_points = points
best_dist = dist
return best_name, best_points
def reset_when_alive(self):
"""存活时清标志,避免下次死亡无法再次释放灵魂/记录尸体坐标。"""
"""Clear death-related state after the character is alive again."""
self._spirit_release_sent = False
self.corpse_pos = None
self.is_running_to_corpse = False
self._resurrection_completed = False
self._clear_death_run_state()
def on_death(self, state):
"""1. 死亡瞬间调用:从 player_position 获取坐标并记录"""
"""Record corpse coordinates once, then release spirit."""
if self._spirit_release_sent:
return
self._spirit_release_sent = True
self._clear_death_run_state()
self.corpse_pos = (state['x'], state['y'])
self.is_running_to_corpse = True
print(f">>> [系统] 记录死亡坐标: {self.corpse_pos},准备释放灵魂...")
hw_ctrl.press(self.release_spirit_key)
time.sleep(5) # 等待加载界面
time.sleep(5)
def run_to_corpse(self, state, get_state=None):
"""
2. 跑尸寻路逻辑:坐标与朝向从 player_position 获取。
两阶段逻辑:
- 阶段1若配置了复活点路线先跑完该路线
- 阶段2路线跑完后或无路线跑向尸体
Run the configured resurrection route first, then navigate back to the corpse.
"""
if not self.corpse_pos:
return
# 阶段1复活路线未走完 → navigate_path 跑完路线
if self.resurrection_waypoints and not self._resurrection_completed:
if get_state is None:
return
if self.patrol_system.navigate_path(get_state, self.resurrection_waypoints):
self._resurrection_completed = True
print(">>> 复活路线跑完,开始跑向尸体...")
if not self._record_graveyard_pos(state):
return
if not self._route_selected:
route_name, route_points = self._choose_resurrection_route()
self.selected_resurrection_route_name = route_name
self.selected_resurrection_route = route_points
self._route_selected = True
if route_name:
print(f">>> [系统] 本次死亡选择复活路线: {route_name}")
else:
print(">>> [系统] 未配置可用复活路线,直接前往尸体...")
if self.selected_resurrection_route and not self._resurrection_completed:
if get_state is None:
return
if self.patrol_system.navigate_path(get_state, self.selected_resurrection_route):
self._resurrection_completed = True
print(
f">>> [系统] 复活路线{self.selected_resurrection_route_name}跑完,开始前往尸体..."
)
return
# 阶段2复活路线走完或无 → 直接跑向尸体
is_arrived = self.patrol_system.navigate_to_point(state, self.corpse_pos)
# 如果距离尸体很近0.005 约等于 10-20 码)
if is_arrived:
print(">>> 已到达尸体附近,尝试复活...")
hw_ctrl.press(self.resurrect_key)
time.sleep(5)
# 检查是否还是灵魂状态,如果是则再按一次复活键
if get_state:
new_state = get_state()
if new_state and new_state.get('death_state') == 2:
@@ -85,4 +165,4 @@ class DeathManager:
time.sleep(5)
self.is_running_to_corpse = False
self.corpse_pos = None
return
self._clear_death_run_state()