fix: Round 54 priority dequeue, onComplete callback, prerequisiteObjectiveId validation, localizationTable guard, FailQuest timestamp, remove empty ValidateBranchDialogueKeys

- DialogueManager.EndDialogue: dequeue by max-priority index instead of FIFO index-0
- DialogueManager.EndDialogue: fire _onCompleteCallback on normal end (was only in ForceEnd)
- NpcSO.OnValidate: auto-restore localizationTable to 'UI' if cleared
- QuestSO.ValidateObjectiveIds: validate prerequisiteObjectiveId references exist in same quest
- QuestSO.OnValidate: remove call to empty ValidateBranchDialogueKeys stub + remove the stub itself
- QuestManager.DispatchEvent toFail loop: write _completedAtUtc timestamp on quest failure

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-05-25 07:20:55 +08:00
parent da2948dff8
commit 943178cbc1
4 changed files with 26 additions and 9 deletions

View File

@@ -1014,6 +1014,7 @@ namespace BaseGames.Quest
foreach (var qid in toFail)
{
_questStates[qid] = QuestStateEnum.Failed;
_completedAtUtc[qid] = System.DateTimeOffset.UtcNow.ToUnixTimeSeconds();
_notifiedReadyQuests.Remove(qid);
OnQuestStateChanged?.Invoke(qid, QuestStateEnum.Active, QuestStateEnum.Failed);
Chan_QuestFailed?.Raise(qid);

View File

@@ -118,7 +118,6 @@ namespace BaseGames.Quest
s_questIdsCacheTime = -10.0;
}
ValidateBranchDialogueKeys();
ValidateObjectiveIds();
ValidatePrerequisiteCycles();
ValidateBranchCycles();
@@ -138,6 +137,17 @@ namespace BaseGames.Quest
"在本任务内重复!同一个 ObjectiveSO 资产被引用多次会导致进度互相覆盖," +
"请为每个目标使用独立的 SO 资产。", this);
}
// 验证 prerequisiteObjectiveId 引用的 objectiveId 必须存在于本任务中
for (int i = 0; i < objectives.Length; i++)
{
var obj = objectives[i];
if (obj == null || string.IsNullOrEmpty(obj.prerequisiteObjectiveId)) continue;
if (!seen.Contains(obj.prerequisiteObjectiveId))
Debug.LogError(
$"[QuestSO] '{name}' 的 objectives[{i}].prerequisiteObjectiveId " +
$"'{obj.prerequisiteObjectiveId}' 在本任务中不存在请检查目标ID是否填写正确。", this);
}
}
/// <summary>
@@ -249,11 +259,6 @@ namespace BaseGames.Quest
visited.Remove(quest.questId); // 回溯
return false;
}
private void ValidateBranchDialogueKeys()
{
// npcDialogueSequence 是 SO 直接引用;旧字符串字段已移除。
}
#endif
}