dispatcher = $dispatcher; $this->stateManager = $stateManager; $this->input = $input; $this->output = $output; $this->helper = $helper; } public function handleEvent(Event $event): void { switch ($event->getType()) { case 'AttemptInteractEvent': // 假设 MapSystem 会提供当前 Tile 上的 NPC ID $npcId = $event->getPayload()['npcId']; $this->startInteraction($npcId); break; } } /** * 1. 初始化 NPC 交互 */ private function startInteraction(string $npcId): void { $npc = $this->loadNPC($npcId); if (!$npc) { $this->dispatcher->dispatch(new Event('SystemMessage', ['message' => "这里没有人可以交谈。"])); return; } $this->dispatcher->dispatch(new Event('SystemMessage', [ 'message' => "👤 你走近了 {$npc->getName()}。" ])); // 启动对话流程 $this->dialogueLoop($npc); // 交互结束后,重新打印主菜单请求 $this->dispatcher->dispatch(new Event('ShowMenuEvent')); } /** * 2. 核心对话循环 */ private function dialogueLoop(NPC $npc): void { $currentDialogueKey = 'greeting'; $running = true; while ($running) { // 打印 NPC 对话 $text = $npc->getDialogueText($currentDialogueKey); $this->dispatcher->dispatch(new Event('SystemMessage', [ 'message' => "{$npc->getName()}:{$text}" ])); // 检查交互类型并获取玩家选择 $choice = $this->promptPlayerChoice(); switch ($choice) { case 'T': // 触发任务/特殊事件 $this->dispatcher->dispatch(new Event('QuestCheckEvent', ['npcId' => $npc->id])); $currentDialogueKey = 'quest_response'; break; case 'S': // 触发商店 $this->dispatcher->dispatch(new Event('OpenShopEvent', ['npcId' => $npc->id])); $currentDialogueKey = 'shop_response'; break; case 'E': // 结束对话 $running = false; $this->dispatcher->dispatch(new Event('SystemMessage', ['message' => "🤝 你结束了与 {$npc->getName()} 的对话。"])); break; default: $this->dispatcher->dispatch(new Event('SystemMessage', ['message' => '无效的交互指令。'])); } } } /** * 获取玩家交互指令 */ private function promptPlayerChoice(): string { $this->dispatcher->dispatch(new Event('SystemMessage', [ 'message' => "\n--- 交互菜单 --- [T] 任务 | [S] 商店 | [E] 结束" ])); $question = new Question("> 请选择指令 (T/S/E):"); $choice = strtoupper($this->helper->ask($this->input, $this->output, $question) ?? ''); return $choice; } /** * 模拟从配置中加载 NPC 数据 */ private function loadNPC(string $id): ?NPC { $data = match ($id) { 'VILLAGER_1' => [ 'name' => '老村长', 'dialogue' => [ 'greeting' => '你好,旅行者。你看起来很强大。', 'quest_response' => '你想要帮忙吗?我们的地窖里有老鼠。', 'shop_response' => '我现在没有东西卖给你。', ] ], default => null, }; if ($data) { return new NPC($id, $data['name'], $data['dialogue']); } return null; } }