add 脱战血量低就地吃面包

This commit is contained in:
王鹏
2026-03-25 10:51:25 +08:00
parent 9b4a9d5ab8
commit 9ab1e8737c
7 changed files with 174 additions and 2 deletions

View File

@@ -14,6 +14,9 @@ from logistics_manager import LogisticsManager
KEY_TAB = '3'
KEY_LOOT = '4' # 假设你在游戏里设置了互动按键为 F
KEY_ATTACK = '2' # 假设你的主攻击技能是 1
DEFAULT_FOOD_KEY = 'f1' # 面包快捷键
DEFAULT_EAT_HP_THRESHOLD = 30
DEFAULT_EAT_MAX_WAIT_SEC = 30.0
# 巡逻点配置文件
WAYPOINTS_FILE = 'waypoints.json'
@@ -79,7 +82,18 @@ def load_attack_loop(path):
class AutoBotMove:
def __init__(self, waypoints=None, waypoints_path=None, vendor_path=None, attack_loop_path=None, skinning_wait_sec=None):
def __init__(
self,
waypoints=None,
waypoints_path=None,
vendor_path=None,
attack_loop_path=None,
skinning_wait_sec=None,
food_key=None,
eat_hp_threshold=None,
eat_max_wait_sec=None,
stop_check=None,
):
self.last_tab_time = 0
self.is_running = True
self.is_moving = False
@@ -87,7 +101,14 @@ class AutoBotMove:
# 记录上一帧是否处于战斗/有目标,用于检测“刚刚脱战”的瞬间
self._was_in_combat_or_target = False
self.skinning_wait_sec = float(skinning_wait_sec) if skinning_wait_sec is not None else 1.5
self.food_key = (food_key or DEFAULT_FOOD_KEY).strip().lower() or DEFAULT_FOOD_KEY
self.eat_hp_threshold = int(eat_hp_threshold) if eat_hp_threshold is not None else DEFAULT_EAT_HP_THRESHOLD
self.eat_max_wait_sec = float(eat_max_wait_sec) if eat_max_wait_sec is not None else DEFAULT_EAT_MAX_WAIT_SEC
self.attack_loop_config = load_attack_loop(attack_loop_path)
self._prev_death_state = 0
self._eating_started_at = None
# stop_check: 返回 True 表示需要立即停止(用于中断阻塞中的后勤/路线导航)
self._stop_check = stop_check if callable(stop_check) else (lambda: False)
if waypoints is None:
path = waypoints_path or get_config_path(WAYPOINTS_FILE)
waypoints = load_waypoints(path) or DEFAULT_WAYPOINTS
@@ -102,6 +123,12 @@ class AutoBotMove:
vendor_file = vendor_path or get_config_path('vendor.json')
self.logistics_manager = LogisticsManager(vendor_file)
def _should_stop(self) -> bool:
try:
return bool(self._stop_check())
except Exception:
return False
def execute_disengage_loot(self):
"""从有战斗/目标切换到完全脱战的瞬间,执行拾取 + 剥皮。"""
try:
@@ -140,8 +167,39 @@ class AutoBotMove:
if random.random() < 0.3:
pydirectinput.press(KEY_ATTACK)
def _start_eating(self):
"""开始就地吃面包恢复。"""
self._eating_started_at = time.time()
pydirectinput.press(self.food_key)
def _should_keep_eating(self, state) -> bool:
"""
返回 True 表示继续等待回血(暂停巡逻与找怪);
返回 False 表示结束进食等待。
"""
if self._eating_started_at is None:
return False
hp = state.get('hp')
if hp is not None and hp >= 100:
self._eating_started_at = None
return False
if (time.time() - self._eating_started_at) >= self.eat_max_wait_sec:
self._eating_started_at = None
return False
return True
def execute_logic(self, state):
if self._should_stop():
# 在停止按钮点击后,确保马上松开移动键,并避免继续执行后勤交互。
self.patrol_controller.stop_all()
self.logistics_manager.is_returning = False
self.is_moving = False
return
death = state.get('death_state', 0)
if self._prev_death_state in (1, 2) and death == 0:
self.death_manager.reset_when_alive()
self._prev_death_state = death
# 1. 死亡状态:尸体(1) 记录坐标并释放灵魂;灵魂(2) 跑尸
if death == 1:
self.patrol_controller.stop_all()
@@ -160,12 +218,16 @@ class AutoBotMove:
self.patrol_controller.stop_all()
self.is_moving = False
self.patrol_controller.reset_stuck()
self.logistics_manager.run_route1_round(parse_game_state, self.patrol_controller)
# 中断策略:一旦 GUI 停止,后续 get_state 返回 None使 navigate_path 立即退出。
get_state = (lambda: None if self._should_stop() else parse_game_state())
self.logistics_manager.run_route1_round(get_state, self.patrol_controller)
return
# 3. 战斗/有目标:停止移动,执行攻击逻辑;仅在「跑向怪」短窗口内做卡死检测
in_combat_or_target = bool(state['combat'] or state['target'])
if in_combat_or_target:
# 被动进战时立即打断进食等待,转入正常战斗流程
self._eating_started_at = None
if self.target_acquired_time is None:
self.target_acquired_time = time.time()
if self.is_moving:
@@ -206,6 +268,18 @@ class AutoBotMove:
pass
self.target_acquired_time = None # 脱战/无目标时清零,下次获得目标再计时
self._was_in_combat_or_target = False
# 4. 脱战低血量:就地吃面包(最多等待 30 秒或回满)
hp = state.get('hp')
if self._eating_started_at is None and hp is not None and hp < self.eat_hp_threshold:
if self.is_moving:
self.patrol_controller.stop_all()
self.is_moving = False
self._start_eating()
if self._should_keep_eating(state):
# 进食期间不巡逻、不主动找目标(不按 Tab
return
# 4. 没战斗没目标:巡逻(卡死检测在 patrol_controller.navigate 内)
self.is_moving = True
self.patrol_controller.navigate(state)