add 任务跟随模式

This commit is contained in:
王鹏
2026-03-20 10:11:05 +08:00
parent 8ad9d1b695
commit 9bcc3a467c
3 changed files with 115 additions and 6 deletions

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
WoW 多功能控制器 GUI
集成:状态监控、巡逻打怪、自动打怪、巡逻点录制、多键控制
集成:状态监控、巡逻打怪、自动打怪、任务跟随、巡逻点录制、多键控制
"""
import json
@@ -289,10 +289,10 @@ class KeyWorker(QThread):
self.log_signal.emit(f"❌ 按键 {self.key_name} 失败: {e}")
# ============ 游戏主循环(状态监控 / 巡逻打怪 / 自动打怪 / 录制) ============
# ============ 游戏主循环(状态监控 / 巡逻打怪 / 自动打怪 / 任务跟随 / 录制) ============
class GameLoopWorker(QThread):
"""游戏状态主循环:支持状态监控、巡逻打怪、自动打怪、巡逻点录制"""
"""游戏状态主循环:支持状态监控、巡逻打怪、自动打怪、任务跟随、巡逻点录制"""
state_signal = pyqtSignal(str)
log_signal = pyqtSignal(str)
@@ -305,12 +305,16 @@ class GameLoopWorker(QThread):
record_min_distance=None,
attack_loop_path=None,
skinning_wait_sec=None,
quest_follow_follow_key=None,
quest_follow_interact_key=None,
quest_follow_interval_sec=None,
):
super().__init__()
self.mode = mode # 'monitor' | 'patrol' | 'combat' | 'record'
self.mode = mode # 'monitor' | 'patrol' | 'combat' | 'quest_follow' | 'record'
self.running = True
self.bot_move = None
self.bot_combat = None
self.quest_follow_bot = None
self.recorder = None
self.waypoints_path = waypoints_path
self.vendor_path = vendor_path
@@ -318,6 +322,12 @@ class GameLoopWorker(QThread):
self.record_min_distance = record_min_distance
self.attack_loop_path = attack_loop_path or None
self.skinning_wait_sec = skinning_wait_sec
self.quest_follow_follow_key = (quest_follow_follow_key or "f").strip().lower() or "f"
self.quest_follow_interact_key = (quest_follow_interact_key or "4").strip().lower() or "4"
try:
self.quest_follow_interval_sec = float(quest_follow_interval_sec)
except (TypeError, ValueError):
self.quest_follow_interval_sec = 3.0
def run(self):
try:
@@ -350,6 +360,19 @@ class GameLoopWorker(QThread):
self.log_signal.emit(f"❌ 自动打怪依赖加载失败: {e}")
return
if self.mode == 'quest_follow':
try:
from quest_follow import QuestFollowBot
self.quest_follow_bot = QuestFollowBot(
follow_key=self.quest_follow_follow_key,
interact_key=self.quest_follow_interact_key,
interval_sec=self.quest_follow_interval_sec,
log_callback=lambda m: self.log_signal.emit(m),
)
except ImportError as e:
self.log_signal.emit(f"❌ 任务跟随依赖加载失败: {e}")
return
if self.mode == 'record':
try:
from recorder import WaypointRecorder
@@ -392,6 +415,8 @@ class GameLoopWorker(QThread):
self.bot_combat.execute_logic(state)
elif self.mode == 'record' and self.recorder:
self.recorder.record(state)
if self.mode == 'quest_follow' and self.quest_follow_bot:
self.quest_follow_bot.execute_logic(state)
time.sleep(0.1)
def save_recorder(self):
@@ -477,6 +502,7 @@ class WoWMultiKeyGUI(QMainWindow):
('monitor', '状态监控'),
('patrol', '巡逻打怪'),
('combat', '自动打怪'),
('quest_follow', '任务跟随'),
]:
btn = QPushButton(name)
btn.setCheckable(True)
@@ -514,6 +540,31 @@ class WoWMultiKeyGUI(QMainWindow):
self.combat_group.setVisible(False)
game_layout.addWidget(self.combat_group)
qf_cfg = ((self.config or {}).get('bot') or {}).get('quest_follow') or {}
self.quest_follow_group = QGroupBox("任务跟随配置")
qf_layout = QFormLayout(self.quest_follow_group)
self.quest_follow_follow_edit = QLineEdit()
self.quest_follow_follow_edit.setPlaceholderText("如 f跟随队友")
self.quest_follow_follow_edit.setMaxLength(8)
self.quest_follow_follow_edit.setText(str(qf_cfg.get('follow_key', 'f')).strip() or 'f')
self.quest_follow_interact_edit = QLineEdit()
self.quest_follow_interact_edit.setPlaceholderText("如 4与互动键一致")
self.quest_follow_interact_edit.setMaxLength(8)
self.quest_follow_interact_edit.setText(str(qf_cfg.get('interact_key', '4')).strip() or '4')
self.quest_follow_interval_spin = QDoubleSpinBox()
self.quest_follow_interval_spin.setRange(0.5, 120.0)
self.quest_follow_interval_spin.setSingleStep(0.5)
try:
self.quest_follow_interval_spin.setValue(float(qf_cfg.get('interval_sec', 3.0)))
except (TypeError, ValueError):
self.quest_follow_interval_spin.setValue(3.0)
self.quest_follow_interval_spin.setSuffix("")
qf_layout.addRow("跟随键:", self.quest_follow_follow_edit)
qf_layout.addRow("交互键:", self.quest_follow_interact_edit)
qf_layout.addRow("按键间隔:", self.quest_follow_interval_spin)
self.quest_follow_group.setVisible(False)
game_layout.addWidget(self.quest_follow_group)
self.state_label = QLabel("状态: ---")
self.state_label.setStyleSheet("font-family: monospace; padding: 6px; background: #1e1e1e; color: #d4d4d4;")
self.state_label.setMinimumHeight(36)
@@ -981,6 +1032,7 @@ class WoWMultiKeyGUI(QMainWindow):
self._refresh_attack_loop_combo()
self.patrol_group.setVisible(mode == 'patrol')
self.combat_group.setVisible(mode == 'combat')
self.quest_follow_group.setVisible(mode == 'quest_follow')
def load_config(self):
if os.path.exists(self.config_path):
@@ -1060,7 +1112,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
@@ -1089,6 +1141,16 @@ class WoWMultiKeyGUI(QMainWindow):
if attack_loop_path and not os.path.exists(attack_loop_path):
attack_loop_path = None
if mode == 'quest_follow':
self.config = self.config or {}
self.config.setdefault('bot', {})
self.config['bot']['quest_follow'] = {
'follow_key': self.quest_follow_follow_edit.text().strip() or 'f',
'interact_key': self.quest_follow_interact_edit.text().strip() or '4',
'interval_sec': float(self.quest_follow_interval_spin.value()),
}
self._save_main_config()
skinning_wait_sec = None
try:
skinning_wait_sec = float(((self.config or {}).get('bot') or {}).get('skinning_wait_sec', 1.5))
@@ -1099,6 +1161,9 @@ class WoWMultiKeyGUI(QMainWindow):
mode, waypoints_path=waypoints_path, vendor_path=vendor_path,
attack_loop_path=attack_loop_path,
skinning_wait_sec=skinning_wait_sec,
quest_follow_follow_key=self.quest_follow_follow_edit.text(),
quest_follow_interact_key=self.quest_follow_interact_edit.text(),
quest_follow_interval_sec=self.quest_follow_interval_spin.value(),
)
self.game_worker.state_signal.connect(self.state_label.setText)
self.game_worker.log_signal.connect(self.log)
@@ -1106,7 +1171,12 @@ class WoWMultiKeyGUI(QMainWindow):
self.game_worker.start()
self.game_start_btn.setEnabled(False)
self.game_stop_btn.setEnabled(True)
mode_names = {'monitor': '状态监控', 'patrol': '巡逻打怪', 'combat': '自动打怪'}
mode_names = {
'monitor': '状态监控',
'patrol': '巡逻打怪',
'combat': '自动打怪',
'quest_follow': '任务跟随',
}
self.status_bar.showMessage(f"🟢 {mode_names[mode]} 运行中")
self.log(f"🎮 {mode_names[mode]} 已启动")