diff --git a/LogicBeacon/LogicBeacon.lua b/LogicBeacon/LogicBeacon.lua index e897709..36e3956 100644 --- a/LogicBeacon/LogicBeacon.lua +++ b/LogicBeacon/LogicBeacon.lua @@ -139,7 +139,41 @@ local function GetFollowSignal() return 0 end +local combatErrorSignal = 255 +local errorTimer = 0 + +local function UpdateCombatErrorSignal(message) + if not message or message == "" then + return + end + + if message == "你需要面对目标" or message == ERR_BADATTACKFACING then + combatErrorSignal = 50 + elseif message == "距离太远" or message == ERR_OUT_OF_RANGE then + combatErrorSignal = 100 + elseif message == "目标不在视野中" or message == ERR_NOT_IN_LOS then + combatErrorSignal = 150 + elseif message == "法术还没准备好" or message == "技能还没有准备好。" then + combatErrorSignal = 200 + elseif message == "能量不足" or message == "符文能量不足" or message == "没有足够的符文" then + combatErrorSignal = 220 + else + return + end + + errorTimer = GetTime() +end + +local errorFrame = CreateFrame("Frame") +errorFrame:RegisterEvent("UI_ERROR_MESSAGE") +errorFrame:SetScript("OnEvent", function(_, _, _, message) + UpdateCombatErrorSignal(message) +end) + f:SetScript("OnUpdate", function() + if combatErrorSignal ~= 255 and (GetTime() - errorTimer > 1.5) then + combatErrorSignal = 255 + end -- [1] 锚点:永远纯白 (255, 255, 255) pixels[1]:SetColorTexture(1, 1, 1) @@ -200,7 +234,7 @@ f:SetScript("OnUpdate", function() -- [10] R=跟随信号(0 / 0.5 需补跟随 / 1.0 跟随中) local followSig = GetFollowSignal() - pixels[10]:SetColorTexture(followSig, 0, 0, 1) + pixels[10]:SetColorTexture(followSig, combatErrorSignal / 255, 0, 1) end) -- 可拖动 diff --git a/auto_bot.py b/auto_bot.py index 39155a3..9d8a53a 100644 --- a/auto_bot.py +++ b/auto_bot.py @@ -218,6 +218,8 @@ class AutoBot: self.last_attack_scan_time = 0.0 self.attack_stall_scan_threshold = 2.0 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 def execute_disengage_loot(self): @@ -513,9 +515,13 @@ class AutoBot: hw_ctrl.keyUp('s') self._has_braked_for_target = True - # 2. 交互逻辑 - hp_dropped = self.last_target_hp > 0 and target_hp < self.last_target_hp - if is_new_target or hp_dropped or self.last_target_damage_time is None: + # 2. 只有超过 5% 的明显掉血才算“新的有效掉血” + hp_drop_amount = max(0, self.last_target_hp - target_hp) + significant_hp_dropped = ( + self.last_target_hp > 0 + and hp_drop_amount > self.min_effective_target_damage_pct + ) + if is_new_target or significant_hp_dropped or self.last_target_damage_time is None: self.last_target_damage_time = current_time if ( @@ -524,8 +530,9 @@ class AutoBot: 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 ): - if self.mouse_scan_attack_target(): - self.last_target_damage_time = current_time + hw_ctrl.keyDown('s') + time.sleep(self.attack_stall_s_hold_sec) + hw_ctrl.keyUp('s') self.last_attack_scan_time = current_time self.last_target_hp = target_hp if state['combat']: diff --git a/auto_bot_move.py b/auto_bot_move.py index e11bdd0..c10d41b 100644 --- a/auto_bot_move.py +++ b/auto_bot_move.py @@ -273,6 +273,8 @@ class AutoBotMove: self.last_attack_scan_time = 0.0 self.attack_stall_scan_threshold = 2.0 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 # stop_check: 返回 True 表示需要立即停止(用于中断阻塞中的后勤/路线导航) self._stop_check = stop_check if callable(stop_check) else (lambda: False) @@ -698,9 +700,13 @@ class AutoBotMove: hw_ctrl.keyUp('s') self._has_braked_for_target = True - # 2. 交互键(KEY_LOOT)按键策略: - hp_dropped = self.last_target_hp > 0 and target_hp < self.last_target_hp - if is_new_target or hp_dropped or self.last_target_damage_time is None: + # 2. 只有超过 5% 的明显掉血才算“新的有效掉血” + hp_drop_amount = max(0, self.last_target_hp - target_hp) + significant_hp_dropped = ( + self.last_target_hp > 0 + and hp_drop_amount > self.min_effective_target_damage_pct + ) + if is_new_target or significant_hp_dropped or self.last_target_damage_time is None: self.last_target_damage_time = now # 目标血量100%且超过2秒没掉血,按交互键尝试选中/攻击 @@ -715,8 +721,9 @@ class AutoBotMove: and (now - self.last_target_damage_time) >= self.attack_stall_scan_threshold and (now - self.last_attack_scan_time) >= self.attack_scan_retry_sec ): - if self.mouse_scan_attack_target(): - self.last_target_damage_time = now + hw_ctrl.keyDown('s') + time.sleep(self.attack_stall_s_hold_sec) + hw_ctrl.keyUp('s') self.last_attack_scan_time = now self.last_target_hp = target_hp diff --git a/game_state.py b/game_state.py index cb4dd8c..a1cde60 100644 --- a/game_state.py +++ b/game_state.py @@ -88,6 +88,22 @@ def _tri_state_label(value, low_mid_high): return low_mid_high[2] +_COMBAT_ERROR_SIGNALS = (50, 100, 150, 200, 220, 255) +_COMBAT_ERROR_LABELS = { + 50: '需转身', + 100: '距离远', + 150: '不在视野', + 200: '技能CD', + 220: '资源不足', + 255: '正常', +} + + +def _combat_error_signal_from_g(channel_byte): + """Lua G 通道离散状态码还原为最近的约定值。""" + return min(_COMBAT_ERROR_SIGNALS, key=lambda t: abs(t - int(channel_byte))) + + def format_game_state_line(state): """单行状态文字(中文),供 CLI 与 GUI 共用。""" death_txt = ('存活', '尸体', '灵魂')[state.get('death_state', 0)] @@ -108,12 +124,16 @@ def format_game_state_line(state): state.get('follow', 0), ('未跟随', '需补跟随', '跟随中'), ) + combat_error_txt = state.get('combat_error_label') or _COMBAT_ERROR_LABELS.get( + state.get('combat_error_signal', 255), '未知' + ) return ( f"{hp_part} | " f"{combat_txt} {target_txt} | " f"空格:{state.get('free_slots', 0)} 耐久:{state.get('durability', 0):.0%} {death_txt} | " f"x:{state['x']} y:{state['y']} 朝向:{state['facing']:.1f}° | " - f"{flight_txt} {mounted_txt} {flyable_txt} {follow_txt}" + f"{flight_txt} {mounted_txt} {flyable_txt} {follow_txt} | " + f"战斗信号:{combat_error_txt}" ) @@ -213,6 +233,8 @@ def parse_game_state(): # 第 10 像素(Lua pixels[10]):R=跟随信号 p10 = get_val(8) state['follow'] = _tri_state_from_r(p10[0]) + state['combat_error_signal'] = _combat_error_signal_from_g(p10[1]) + state['combat_error_label'] = _COMBAT_ERROR_LABELS.get(state['combat_error_signal'], '未知') return state