From 8c1460a5823bdfeadf753c66c148d83a29bd805c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=B9=8F?= Date: Thu, 26 Mar 2026 10:41:04 +0800 Subject: [PATCH] =?UTF-8?q?add=20=E5=9B=9E=E5=9F=8E=E4=BF=AE=E7=90=86?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/history.md | 6 +++ wow_multikey_gui.py | 97 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 101 insertions(+), 2 deletions(-) diff --git a/docs/history.md b/docs/history.md index 452bfcc..13cda90 100644 --- a/docs/history.md +++ b/docs/history.md @@ -69,3 +69,9 @@ - `auto_bot_move.py`:在 `execute_logic` 的战斗/攻击分支中增加对 `state['target']` 的有效性判定,要求 `target_hp` 存在且 `> 0`,避免对无效/已死目标误触发攻击按键 - 同步调整:战斗调用 `execute_combat_logic()` 以及脱战阶段的 `Tab` 寻怪条件,均改为基于有效目标 `effective_target` +### 飞行模式后新增回城修理 + +- `wow_multikey_gui.py`:在“飞行模式”之后新增独立模式 `回城修理`,用于在回城时执行修理商交互 +- 配置项:`回城修理` 模式增加 `修理商 JSON` 下拉选择,并将选择的 JSON 传给 `LogisticsManager` +- 行为约束:按下 GUI 的 `停止` 会将 `running` 置为 `False`,从而让回城路径行走在下一轮状态轮询中中断退出 + diff --git a/wow_multikey_gui.py b/wow_multikey_gui.py index dfea01d..fb26854 100644 --- a/wow_multikey_gui.py +++ b/wow_multikey_gui.py @@ -418,6 +418,46 @@ class GameLoopWorker(QThread): self.log_signal.emit(f"❌ 飞行模式依赖加载失败: {e}") return + if self.mode == 'return_repair': + if not self.vendor_path: + self.log_signal.emit("❌ 回城修理模式:未选择修理商 JSON") + return + try: + from logistics_manager import LogisticsManager + from coordinate_patrol import CoordinatePatrol + from game_state import load_layout_config + + layout = load_layout_config() + self.patrol_controller = CoordinatePatrol( + waypoints=[(0.0, 0.0)], + mount_key=str(layout.get("mount_key", "x") or "x"), + mount_hold_sec=float(layout.get("mount_hold_sec", 1.6)), + mount_retry_after_sec=float(layout.get("mount_retry_after_sec", 2.0)), + ) + self.logistics_manager = LogisticsManager(route_file=self.vendor_path) + + self.log_signal.emit(f"⛑️ 回城修理:开始执行路径({os.path.basename(self.vendor_path)})") + + get_state = lambda: parse_game_state() if self.running else None + ok = self.logistics_manager.run_route1_round( + get_state, + self.patrol_controller, + route_file=self.vendor_path, + ) + if ok: + self.log_signal.emit("✅ 回城修理:路径完成") + else: + self.log_signal.emit("⏹️ 回城修理:已中止或未完成") + except ImportError as e: + self.log_signal.emit(f"❌ 回城修理依赖加载失败: {e}") + return + except Exception as e: + self.log_signal.emit(f"❌ 回城修理执行失败: {e}") + return + finally: + self.running = False + return + if self.mode == 'record': try: from recorder import WaypointRecorder @@ -539,6 +579,7 @@ class WoWMultiKeyGUI(QMainWindow): ('combat', '自动打怪'), ('quest_follow', '任务跟随'), ('flight', '飞行模式'), + ('return_repair', '回城修理'), ]: btn = QPushButton(name) btn.setCheckable(True) @@ -648,6 +689,19 @@ class WoWMultiKeyGUI(QMainWindow): self.flight_group.setVisible(False) game_layout.addWidget(self.flight_group) + # 回城修理配置(在飞行模式之后新增一个独立模式) + self.repair_group = QGroupBox("回城修理配置") + repair_layout = QFormLayout(self.repair_group) + self.repair_vendor_combo = QComboBox() + self.repair_vendor_combo.setMinimumWidth(200) + self._refresh_repair_vendor_json_combo() + repair_refresh_btn = QPushButton("🔄 刷新列表") + repair_refresh_btn.clicked.connect(self._refresh_repair_vendor_json_combo) + repair_layout.addRow("修理商 JSON:", self.repair_vendor_combo) + repair_layout.addRow("", repair_refresh_btn) + self.repair_group.setVisible(False) + game_layout.addWidget(self.repair_group) + self.state_label = QLabel("状态: ---") self.state_label.setStyleSheet("font-family: monospace; padding: 6px; background: #1e1e1e; color: #d4d4d4;") self.state_label.setMinimumHeight(36) @@ -1139,7 +1193,10 @@ class WoWMultiKeyGUI(QMainWindow): def _refresh_recorder_combos(self): """刷新巡逻点、修理商下拉列表""" items = list_recorder_json() - for combo, default_name in [(self.waypoints_combo, 'waypoints.json'), (self.vendor_combo, 'vendor.json')]: + combos = [(self.waypoints_combo, 'waypoints.json'), (self.vendor_combo, 'vendor.json')] + if hasattr(self, "repair_vendor_combo"): + combos.append((self.repair_vendor_combo, 'vendor.json')) + for combo, default_name in combos: combo.clear() combo.addItem("-- 请选择 --", "") for name, path in items: @@ -1151,6 +1208,24 @@ class WoWMultiKeyGUI(QMainWindow): elif combo.count() > 1: combo.setCurrentIndex(1) + def _refresh_repair_vendor_json_combo(self): + """刷新“回城修理配置”的修理商下拉框。""" + if not hasattr(self, "repair_vendor_combo"): + return + items = list_recorder_json() + self.repair_vendor_combo.blockSignals(True) + self.repair_vendor_combo.clear() + self.repair_vendor_combo.addItem("-- 请选择 --", "") + for name, path in items: + self.repair_vendor_combo.addItem(name, path) + self.repair_vendor_combo.blockSignals(False) + if self.repair_vendor_combo.count() > 1: + idx = self.repair_vendor_combo.findData(os.path.join(get_recorder_dir(), 'vendor.json')) + if idx >= 0: + self.repair_vendor_combo.setCurrentIndex(idx) + else: + self.repair_vendor_combo.setCurrentIndex(1) + def _refresh_flight_json_combo(self): """刷新飞行模式航线 JSON 下拉列表""" items = list_recorder_json() @@ -1180,8 +1255,11 @@ class WoWMultiKeyGUI(QMainWindow): self.combat_group.setVisible(mode == 'combat') self.quest_follow_group.setVisible(mode == 'quest_follow') self.flight_group.setVisible(mode == 'flight') + self.repair_group.setVisible(mode == 'return_repair') if mode == 'flight': self._refresh_flight_json_combo() + if mode == 'return_repair': + self._refresh_repair_vendor_json_combo() def load_config(self): if os.path.exists(self.config_path): @@ -1261,7 +1339,7 @@ class WoWMultiKeyGUI(QMainWindow): def start_game_loop(self): mode = self._current_game_mode if mode is None: - QMessageBox.warning(self, "提示", "请先选择模式(状态监控 / 巡逻打怪 / 自动打怪 / 任务跟随 / 飞行模式)") + QMessageBox.warning(self, "提示", "请先选择模式(状态监控 / 巡逻打怪 / 自动打怪 / 任务跟随 / 飞行模式 / 回城修理)") return waypoints_path = None vendor_path = None @@ -1301,6 +1379,16 @@ class WoWMultiKeyGUI(QMainWindow): } self._save_main_config() + if mode == 'return_repair': + vp = self.repair_vendor_combo.currentData() or "" + if not vp: + QMessageBox.warning(self, "提示", "回城修理模式需选择修理商 JSON 文件") + return + if not os.path.exists(vp): + QMessageBox.warning(self, "提示", f"修理商文件不存在: {vp}") + return + vendor_path = vp + if mode == 'flight': fp = self.flight_json_combo.currentData() or "" if not fp: @@ -1366,6 +1454,7 @@ class WoWMultiKeyGUI(QMainWindow): 'combat': '自动打怪', 'quest_follow': '任务跟随', 'flight': '飞行模式', + 'return_repair': '回城修理', } self.status_bar.showMessage(f"🟢 {mode_names[mode]} 运行中") self.log(f"🎮 {mode_names[mode]} 已启动") @@ -1417,6 +1506,10 @@ class WoWMultiKeyGUI(QMainWindow): if getattr(self.game_worker, "bot_move", None): self.game_worker.bot_move.patrol_controller.stop_all() self.game_worker.bot_move.logistics_manager.is_returning = False + if getattr(self.game_worker, "patrol_controller", None): + self.game_worker.patrol_controller.stop_all() + if getattr(self.game_worker, "logistics_manager", None): + self.game_worker.logistics_manager.is_returning = False except Exception: pass # 不在这里 wait(),避免阻塞 GUI;线程会在下一轮循环自然退出