add 回城修理模式
This commit is contained in:
@@ -69,3 +69,9 @@
|
|||||||
- `auto_bot_move.py`:在 `execute_logic` 的战斗/攻击分支中增加对 `state['target']` 的有效性判定,要求 `target_hp` 存在且 `> 0`,避免对无效/已死目标误触发攻击按键
|
- `auto_bot_move.py`:在 `execute_logic` 的战斗/攻击分支中增加对 `state['target']` 的有效性判定,要求 `target_hp` 存在且 `> 0`,避免对无效/已死目标误触发攻击按键
|
||||||
- 同步调整:战斗调用 `execute_combat_logic()` 以及脱战阶段的 `Tab` 寻怪条件,均改为基于有效目标 `effective_target`
|
- 同步调整:战斗调用 `execute_combat_logic()` 以及脱战阶段的 `Tab` 寻怪条件,均改为基于有效目标 `effective_target`
|
||||||
|
|
||||||
|
### 飞行模式后新增回城修理
|
||||||
|
|
||||||
|
- `wow_multikey_gui.py`:在“飞行模式”之后新增独立模式 `回城修理`,用于在回城时执行修理商交互
|
||||||
|
- 配置项:`回城修理` 模式增加 `修理商 JSON` 下拉选择,并将选择的 JSON 传给 `LogisticsManager`
|
||||||
|
- 行为约束:按下 GUI 的 `停止` 会将 `running` 置为 `False`,从而让回城路径行走在下一轮状态轮询中中断退出
|
||||||
|
|
||||||
|
|||||||
@@ -418,6 +418,46 @@ class GameLoopWorker(QThread):
|
|||||||
self.log_signal.emit(f"❌ 飞行模式依赖加载失败: {e}")
|
self.log_signal.emit(f"❌ 飞行模式依赖加载失败: {e}")
|
||||||
return
|
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':
|
if self.mode == 'record':
|
||||||
try:
|
try:
|
||||||
from recorder import WaypointRecorder
|
from recorder import WaypointRecorder
|
||||||
@@ -539,6 +579,7 @@ class WoWMultiKeyGUI(QMainWindow):
|
|||||||
('combat', '自动打怪'),
|
('combat', '自动打怪'),
|
||||||
('quest_follow', '任务跟随'),
|
('quest_follow', '任务跟随'),
|
||||||
('flight', '飞行模式'),
|
('flight', '飞行模式'),
|
||||||
|
('return_repair', '回城修理'),
|
||||||
]:
|
]:
|
||||||
btn = QPushButton(name)
|
btn = QPushButton(name)
|
||||||
btn.setCheckable(True)
|
btn.setCheckable(True)
|
||||||
@@ -648,6 +689,19 @@ class WoWMultiKeyGUI(QMainWindow):
|
|||||||
self.flight_group.setVisible(False)
|
self.flight_group.setVisible(False)
|
||||||
game_layout.addWidget(self.flight_group)
|
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 = QLabel("状态: ---")
|
||||||
self.state_label.setStyleSheet("font-family: monospace; padding: 6px; background: #1e1e1e; color: #d4d4d4;")
|
self.state_label.setStyleSheet("font-family: monospace; padding: 6px; background: #1e1e1e; color: #d4d4d4;")
|
||||||
self.state_label.setMinimumHeight(36)
|
self.state_label.setMinimumHeight(36)
|
||||||
@@ -1139,7 +1193,10 @@ class WoWMultiKeyGUI(QMainWindow):
|
|||||||
def _refresh_recorder_combos(self):
|
def _refresh_recorder_combos(self):
|
||||||
"""刷新巡逻点、修理商下拉列表"""
|
"""刷新巡逻点、修理商下拉列表"""
|
||||||
items = list_recorder_json()
|
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.clear()
|
||||||
combo.addItem("-- 请选择 --", "")
|
combo.addItem("-- 请选择 --", "")
|
||||||
for name, path in items:
|
for name, path in items:
|
||||||
@@ -1151,6 +1208,24 @@ class WoWMultiKeyGUI(QMainWindow):
|
|||||||
elif combo.count() > 1:
|
elif combo.count() > 1:
|
||||||
combo.setCurrentIndex(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):
|
def _refresh_flight_json_combo(self):
|
||||||
"""刷新飞行模式航线 JSON 下拉列表"""
|
"""刷新飞行模式航线 JSON 下拉列表"""
|
||||||
items = list_recorder_json()
|
items = list_recorder_json()
|
||||||
@@ -1180,8 +1255,11 @@ class WoWMultiKeyGUI(QMainWindow):
|
|||||||
self.combat_group.setVisible(mode == 'combat')
|
self.combat_group.setVisible(mode == 'combat')
|
||||||
self.quest_follow_group.setVisible(mode == 'quest_follow')
|
self.quest_follow_group.setVisible(mode == 'quest_follow')
|
||||||
self.flight_group.setVisible(mode == 'flight')
|
self.flight_group.setVisible(mode == 'flight')
|
||||||
|
self.repair_group.setVisible(mode == 'return_repair')
|
||||||
if mode == 'flight':
|
if mode == 'flight':
|
||||||
self._refresh_flight_json_combo()
|
self._refresh_flight_json_combo()
|
||||||
|
if mode == 'return_repair':
|
||||||
|
self._refresh_repair_vendor_json_combo()
|
||||||
|
|
||||||
def load_config(self):
|
def load_config(self):
|
||||||
if os.path.exists(self.config_path):
|
if os.path.exists(self.config_path):
|
||||||
@@ -1261,7 +1339,7 @@ class WoWMultiKeyGUI(QMainWindow):
|
|||||||
def start_game_loop(self):
|
def start_game_loop(self):
|
||||||
mode = self._current_game_mode
|
mode = self._current_game_mode
|
||||||
if mode is None:
|
if mode is None:
|
||||||
QMessageBox.warning(self, "提示", "请先选择模式(状态监控 / 巡逻打怪 / 自动打怪 / 任务跟随 / 飞行模式)")
|
QMessageBox.warning(self, "提示", "请先选择模式(状态监控 / 巡逻打怪 / 自动打怪 / 任务跟随 / 飞行模式 / 回城修理)")
|
||||||
return
|
return
|
||||||
waypoints_path = None
|
waypoints_path = None
|
||||||
vendor_path = None
|
vendor_path = None
|
||||||
@@ -1301,6 +1379,16 @@ class WoWMultiKeyGUI(QMainWindow):
|
|||||||
}
|
}
|
||||||
self._save_main_config()
|
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':
|
if mode == 'flight':
|
||||||
fp = self.flight_json_combo.currentData() or ""
|
fp = self.flight_json_combo.currentData() or ""
|
||||||
if not fp:
|
if not fp:
|
||||||
@@ -1366,6 +1454,7 @@ class WoWMultiKeyGUI(QMainWindow):
|
|||||||
'combat': '自动打怪',
|
'combat': '自动打怪',
|
||||||
'quest_follow': '任务跟随',
|
'quest_follow': '任务跟随',
|
||||||
'flight': '飞行模式',
|
'flight': '飞行模式',
|
||||||
|
'return_repair': '回城修理',
|
||||||
}
|
}
|
||||||
self.status_bar.showMessage(f"🟢 {mode_names[mode]} 运行中")
|
self.status_bar.showMessage(f"🟢 {mode_names[mode]} 运行中")
|
||||||
self.log(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):
|
if getattr(self.game_worker, "bot_move", None):
|
||||||
self.game_worker.bot_move.patrol_controller.stop_all()
|
self.game_worker.bot_move.patrol_controller.stop_all()
|
||||||
self.game_worker.bot_move.logistics_manager.is_returning = False
|
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:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
# 不在这里 wait(),避免阻塞 GUI;线程会在下一轮循环自然退出
|
# 不在这里 wait(),避免阻塞 GUI;线程会在下一轮循环自然退出
|
||||||
|
|||||||
Reference in New Issue
Block a user