Use combat error signals for recovery actions
This commit is contained in:
43
auto_bot.py
43
auto_bot.py
@@ -214,12 +214,9 @@ class AutoBot:
|
|||||||
self.skinning_wait_sec = float(skinning_wait_sec) if skinning_wait_sec is not None else 1.5
|
self.skinning_wait_sec = float(skinning_wait_sec) if skinning_wait_sec is not None else 1.5
|
||||||
self.enable_mouse_loot = enable_mouse_loot
|
self.enable_mouse_loot = enable_mouse_loot
|
||||||
self.cursor_mgr = CursorManager()
|
self.cursor_mgr = CursorManager()
|
||||||
self.last_target_damage_time = None
|
self.last_turn_signal_time = 0.0
|
||||||
self.last_attack_scan_time = 0.0
|
self.combat_signal_retry_sec = 1.0
|
||||||
self.attack_stall_scan_threshold = 2.0
|
self.turn_error_hold_sec = 0.8
|
||||||
self.attack_scan_retry_sec = 2.0
|
|
||||||
self.attack_stall_s_hold_sec = 0.5
|
|
||||||
self.min_effective_target_damage_pct = 5
|
|
||||||
self._last_mouse_path_scale_signature = None
|
self._last_mouse_path_scale_signature = None
|
||||||
|
|
||||||
def execute_disengage_loot(self):
|
def execute_disengage_loot(self):
|
||||||
@@ -495,6 +492,7 @@ class AutoBot:
|
|||||||
def execute_logic(self, state):
|
def execute_logic(self, state):
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
target_hp = state.get('target_hp', 0)
|
target_hp = state.get('target_hp', 0)
|
||||||
|
combat_error_signal = int(state.get('combat_error_signal', 255) or 255)
|
||||||
|
|
||||||
effective_target = bool(state['target'] and target_hp > 0)
|
effective_target = bool(state['target'] and target_hp > 0)
|
||||||
in_combat_or_target = bool(state['combat'] or effective_target)
|
in_combat_or_target = bool(state['combat'] or effective_target)
|
||||||
@@ -515,25 +513,22 @@ class AutoBot:
|
|||||||
hw_ctrl.keyUp('s')
|
hw_ctrl.keyUp('s')
|
||||||
self._has_braked_for_target = True
|
self._has_braked_for_target = True
|
||||||
|
|
||||||
# 2. 只有超过 5% 的明显掉血才算“新的有效掉血”
|
# 2. 根据战斗信号执行纠偏动作
|
||||||
hp_drop_amount = max(0, self.last_target_hp - target_hp)
|
if (
|
||||||
significant_hp_dropped = (
|
combat_error_signal == 100
|
||||||
self.last_target_hp > 0
|
and (current_time - self.last_interaction_time) >= self.combat_signal_retry_sec
|
||||||
and hp_drop_amount > self.min_effective_target_damage_pct
|
):
|
||||||
)
|
hw_ctrl.press(KEY_LOOT)
|
||||||
if is_new_target or significant_hp_dropped or self.last_target_damage_time is None:
|
self.last_interaction_time = current_time
|
||||||
self.last_target_damage_time = current_time
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
state['combat']
|
combat_error_signal == 50
|
||||||
and self.last_target_damage_time is not None
|
and (current_time - self.last_turn_signal_time) >= self.combat_signal_retry_sec
|
||||||
and (current_time - self.last_target_damage_time) >= self.attack_stall_scan_threshold
|
|
||||||
and (current_time - self.last_attack_scan_time) >= self.attack_scan_retry_sec
|
|
||||||
):
|
):
|
||||||
hw_ctrl.keyDown('s')
|
hw_ctrl.keyDown('s')
|
||||||
time.sleep(self.attack_stall_s_hold_sec)
|
time.sleep(self.turn_error_hold_sec)
|
||||||
hw_ctrl.keyUp('s')
|
hw_ctrl.keyUp('s')
|
||||||
self.last_attack_scan_time = current_time
|
self.last_turn_signal_time = current_time
|
||||||
self.last_target_hp = target_hp
|
self.last_target_hp = target_hp
|
||||||
if state['combat']:
|
if state['combat']:
|
||||||
self.execute_combat_logic(state)
|
self.execute_combat_logic(state)
|
||||||
@@ -546,15 +541,15 @@ class AutoBot:
|
|||||||
self._was_in_combat_or_target = False
|
self._was_in_combat_or_target = False
|
||||||
self.last_tab_time = current_time + 1.0
|
self.last_tab_time = current_time + 1.0
|
||||||
self.last_target_hp = 0
|
self.last_target_hp = 0
|
||||||
self.last_target_damage_time = None
|
self.last_turn_signal_time = 0.0
|
||||||
self.last_attack_scan_time = 0.0
|
self.last_interaction_time = 0.0
|
||||||
self._has_braked_for_target = False
|
self._has_braked_for_target = False
|
||||||
return
|
return
|
||||||
|
|
||||||
self._was_in_combat_or_target = False
|
self._was_in_combat_or_target = False
|
||||||
self.last_target_hp = 0
|
self.last_target_hp = 0
|
||||||
self.last_target_damage_time = None
|
self.last_turn_signal_time = 0.0
|
||||||
self.last_attack_scan_time = 0.0
|
self.last_interaction_time = 0.0
|
||||||
self._has_braked_for_target = False
|
self._has_braked_for_target = False
|
||||||
|
|
||||||
self.tab_no_target_count = min(self.tab_no_target_count, 5)
|
self.tab_no_target_count = min(self.tab_no_target_count, 5)
|
||||||
|
|||||||
@@ -269,12 +269,9 @@ class AutoBotMove:
|
|||||||
self.attack_loop_config = load_attack_loop(attack_loop_path)
|
self.attack_loop_config = load_attack_loop(attack_loop_path)
|
||||||
self._prev_death_state = 0
|
self._prev_death_state = 0
|
||||||
self._eating_started_at = None
|
self._eating_started_at = None
|
||||||
self.last_target_damage_time = None
|
self.last_turn_signal_time = 0.0
|
||||||
self.last_attack_scan_time = 0.0
|
self.combat_signal_retry_sec = 1.0
|
||||||
self.attack_stall_scan_threshold = 2.0
|
self.turn_error_hold_sec = 0.8
|
||||||
self.attack_scan_retry_sec = 2.0
|
|
||||||
self.attack_stall_s_hold_sec = 0.5
|
|
||||||
self.min_effective_target_damage_pct = 5
|
|
||||||
self._last_mouse_path_scale_signature = None
|
self._last_mouse_path_scale_signature = None
|
||||||
# stop_check: 返回 True 表示需要立即停止(用于中断阻塞中的后勤/路线导航)
|
# stop_check: 返回 True 表示需要立即停止(用于中断阻塞中的后勤/路线导航)
|
||||||
self._stop_check = stop_check if callable(stop_check) else (lambda: False)
|
self._stop_check = stop_check if callable(stop_check) else (lambda: False)
|
||||||
@@ -633,6 +630,7 @@ class AutoBotMove:
|
|||||||
self.is_moving = False
|
self.is_moving = False
|
||||||
return
|
return
|
||||||
|
|
||||||
|
combat_error_signal = int(state.get('combat_error_signal', 255) or 255)
|
||||||
death = state.get('death_state', 0)
|
death = state.get('death_state', 0)
|
||||||
if self._prev_death_state in (1, 2) and death == 0:
|
if self._prev_death_state in (1, 2) and death == 0:
|
||||||
self.death_manager.reset_when_alive()
|
self.death_manager.reset_when_alive()
|
||||||
@@ -700,31 +698,22 @@ class AutoBotMove:
|
|||||||
hw_ctrl.keyUp('s')
|
hw_ctrl.keyUp('s')
|
||||||
self._has_braked_for_target = True
|
self._has_braked_for_target = True
|
||||||
|
|
||||||
# 2. 只有超过 5% 的明显掉血才算“新的有效掉血”
|
# 根据战斗信号执行纠偏动作
|
||||||
hp_drop_amount = max(0, self.last_target_hp - target_hp)
|
if (
|
||||||
significant_hp_dropped = (
|
combat_error_signal == 100
|
||||||
self.last_target_hp > 0
|
and (now - self.last_interaction_time) >= self.combat_signal_retry_sec
|
||||||
and hp_drop_amount > self.min_effective_target_damage_pct
|
):
|
||||||
)
|
hw_ctrl.press(KEY_LOOT)
|
||||||
if is_new_target or significant_hp_dropped or self.last_target_damage_time is None:
|
self.last_interaction_time = now
|
||||||
self.last_target_damage_time = now
|
|
||||||
|
|
||||||
# 目标血量100%且超过2秒没掉血,按交互键尝试选中/攻击
|
|
||||||
if target_hp >= 100 and self.last_target_damage_time is not None:
|
|
||||||
if (now - self.last_target_damage_time) >= 2.0:
|
|
||||||
hw_ctrl.press(KEY_LOOT)
|
|
||||||
self.last_target_damage_time = now
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
state['combat']
|
combat_error_signal == 50
|
||||||
and self.last_target_damage_time is not None
|
and (now - self.last_turn_signal_time) >= self.combat_signal_retry_sec
|
||||||
and (now - self.last_target_damage_time) >= self.attack_stall_scan_threshold
|
|
||||||
and (now - self.last_attack_scan_time) >= self.attack_scan_retry_sec
|
|
||||||
):
|
):
|
||||||
hw_ctrl.keyDown('s')
|
hw_ctrl.keyDown('s')
|
||||||
time.sleep(self.attack_stall_s_hold_sec)
|
time.sleep(self.turn_error_hold_sec)
|
||||||
hw_ctrl.keyUp('s')
|
hw_ctrl.keyUp('s')
|
||||||
self.last_attack_scan_time = now
|
self.last_turn_signal_time = now
|
||||||
|
|
||||||
self.last_target_hp = target_hp
|
self.last_target_hp = target_hp
|
||||||
# 执行正常的攻击循环
|
# 执行正常的攻击循环
|
||||||
@@ -732,8 +721,8 @@ class AutoBotMove:
|
|||||||
else:
|
else:
|
||||||
# 目标已死亡但还在战斗中,按 Tab 找下一个目标
|
# 目标已死亡但还在战斗中,按 Tab 找下一个目标
|
||||||
self.last_target_hp = 0
|
self.last_target_hp = 0
|
||||||
self.last_target_damage_time = None
|
self.last_turn_signal_time = 0.0
|
||||||
self.last_attack_scan_time = 0.0
|
self.last_interaction_time = 0.0
|
||||||
self._has_braked_for_target = False
|
self._has_braked_for_target = False
|
||||||
if state['combat']:
|
if state['combat']:
|
||||||
hw_ctrl.press(KEY_TAB)
|
hw_ctrl.press(KEY_TAB)
|
||||||
@@ -750,14 +739,14 @@ class AutoBotMove:
|
|||||||
# 扫尾动作执行完后,本 tick 强制结束,防止立即按下 Tab
|
# 扫尾动作执行完后,本 tick 强制结束,防止立即按下 Tab
|
||||||
self._was_in_combat_or_target = False
|
self._was_in_combat_or_target = False
|
||||||
self.target_acquired_time = None
|
self.target_acquired_time = None
|
||||||
self.last_target_damage_time = None
|
self.last_turn_signal_time = 0.0
|
||||||
self.last_attack_scan_time = 0.0
|
self.last_interaction_time = 0.0
|
||||||
self.last_tab_time = time.time() + 1.0 # 给找怪增加 1 秒额外冷却
|
self.last_tab_time = time.time() + 1.0 # 给找怪增加 1 秒额外冷却
|
||||||
return
|
return
|
||||||
|
|
||||||
self.target_acquired_time = None
|
self.target_acquired_time = None
|
||||||
self.last_target_damage_time = None
|
self.last_turn_signal_time = 0.0
|
||||||
self.last_attack_scan_time = 0.0
|
self.last_interaction_time = 0.0
|
||||||
self._was_in_combat_or_target = False
|
self._was_in_combat_or_target = False
|
||||||
|
|
||||||
# 4. 脱战低血量:就地吃面包(最多等待 30 秒或回满)
|
# 4. 脱战低血量:就地吃面包(最多等待 30 秒或回满)
|
||||||
|
|||||||
Reference in New Issue
Block a user