load('quests.json'); // 使用 ID 作为键进行存储 (原始 data) $this->data = array_combine(array_column($loadedData, 'id'), $loadedData); // ⭐ 构建 questsByNpc 索引 $this->buildNpcQuestIndex(); } /** * ⭐ 新增方法:构建按 NPC ID 查找任务的索引 */ private function buildNpcQuestIndex(): void { foreach ($this->data as $questId => $questData) { // 优先使用 triggerType = NPC 的 triggerValue if (isset($questData['triggerType']) && $questData['triggerType'] === 'NPC' && isset($questData['triggerValue'])) { $npcId = $questData['triggerValue']; $this->questsByNpc[$npcId][] = $questId; } // 兼容旧数据:检查 target_npc_id (如果是 talk 类型或者仅仅是关联) // 但如果不作为触发条件,可能不应该在这里索引? // 保持兼容性:如果还没索引过,且有 target_npc_id elseif (isset($questData['target_npc_id'])) { $targetId = $questData['target_npc_id']; // 避免重复? if (!in_array($questId, $this->questsByNpc[$targetId] ?? [])) { $this->questsByNpc[$targetId][] = $questId; } } } } public function find(int|string $id): ?array { return $this->data[$id] ?? null; } public function findAll(): array { return $this->data; } /** * ⭐ 新增功能:通过 NPC ID 获取所有相关的任务 ID 列表 * 这个列表可能包含起始任务、后续任务等,需要业务逻辑进一步筛选 */ public function getQuestsByNpc(string $npcId): array { // 返回该 NPC ID 对应的所有任务 ID 列表,如果没有则返回空数组 return $this->questsByNpc[$npcId] ?? []; } /** * 辅助方法:获取起始任务的 ID (方便游戏启动) */ public function getStartingQuestId(): ?string { // 假设第一个任务就是起始任务 return array_key_first($this->data); } }