feat: Round 48 narrative systems improvements

- QuestSO: Add ValidateBranchCycles() DFS detection for branches[].nextQuest loop
- QuestSO: Mark three legacy prerequisite fields with v2.0 removal warning in Tooltip
- IQuestManager: Add QuestLockReason enum + QuestLockInfo struct (strongly-typed lock info)
- IQuestManager: Add GetQuestLockInfo() method to interface; GetQuestLockReason() now delegates to it
- IQuestEventSource: Add OnQuestStateChanged(questId, oldState, newState) unified event
- QuestManager: Implement GetQuestLockInfo(); fire OnQuestStateChanged on all state transitions
- DialogueManager: Add one-frame yield in HandleChoices before ShowChoices (skip-debounce fix)
- DialogueManager: Increment _playbackId in ForceEnd() to invalidate residual choice callbacks
- DialogueSequenceSO: Add UNITY_EDITOR debug log in TryGetActiveVariant on variant match
- WorldStateRegistry: Add OnBatchStateChanged event + BatchMark() batch-write API
- DialogueModule: List badge shows warning indicator for unconditional-shadowing variants
- DialogueModule: BuildVariantsCard shows logic mode (AND/OR) alongside flag conditions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-05-25 00:05:15 +08:00
parent 446fd5dcd0
commit 6eaa83dc71
72 changed files with 7080 additions and 373 deletions

View File

@@ -9,10 +9,25 @@ namespace BaseGames.Dialogue
bool IsDialogueActive { get; }
/// <summary>
/// 启动对话序列。若已有对话在播放则忽略新请求
/// 每次对话序列(含分支链)全部播完后触发
/// 测试代码可订阅此事件等待对话结束,无需依赖 VoidEventChannelSO 资产。
/// </summary>
event System.Action OnDialogueEnded;
/// <summary>
/// 启动对话序列。
/// 若已有对话在播放priority 高于当前对话时立即打断;否则进入队列(上限 8超出丢弃。
/// </summary>
/// <param name="sequence">要播放的对话序列 SO。</param>
/// <param name="npcId">NPC 标识符,对话结束时随 EVT_NpcDialogueCompleted 广播。</param>
void StartDialogue(DialogueSequenceSO sequence, string npcId = "");
/// <param name="priority">优先级(默认 0。数值越大越优先高优先级可打断低优先级对话。</param>
void StartDialogue(DialogueSequenceSO sequence, string npcId = "", int priority = 0);
/// <summary>
/// 立即强制结束当前对话(含清空等待队列),恢复游戏输入。
/// 适用于:场景切换、演出系统打断、死亡/传送等需要硬中断的场合。
/// 若当前没有活跃对话,则无操作。
/// </summary>
void ForceEnd();
}
}