/// <summary> /// 生成分支对话选项 /// </summary> private void MakeNormalOption() { if (wordsToSay.Count < 1 || wordsToSay.Peek().Options.Count < 1) { return; } DialogueWords currentWords = wordsToSay.Peek(); dialogueDatas.TryGetValue(currentDialog.ID, out DialogueData dialogDataFound); if (CurrentType == DialogueType.Normal) { ClearOptions(OptionType.Quest, OptionType.Objective); } else { ClearOptions(); } bool isLastWords = currentDialog.IndexOfWords(wordsToSay.Peek()) == currentDialog.Words.Count - 1; foreach (WordsOption option in currentWords.Options) { if (option.OptionType == WordsOptionType.Choice && dialogDataFound != null) { DialogueWordsData wordsDataFound = dialogDataFound.wordsDatas.Find(x => x.wordsIndex == currentDialog.IndexOfWords(currentWords)); //这个选择型分支是否完成了 if (isLastWords || wordsDataFound != null && wordsDataFound.IsOptionCmplt(currentWords.IndexOfOption(option))) { continue;//是最后一句话或者选项完成则跳过创建 } } if (option.IsValid) { if (option.OptionType == WordsOptionType.OnlyGet && (option.ShowOnlyWhenNotHave && BackpackManager.Instance.HasItemWithID(option.ItemCanGet.ItemID) || option.OnlyForQuest && option.BindedQuest && !QuestManager.Instance.HasOngoingQuestWithID(option.BindedQuest.ID))) { continue;//若已持有当前选项给的道具,或者需任务驱动但任务未接取,则跳过创建 } else if (option.OptionType == WordsOptionType.SubmitAndGet && option.OnlyForQuest && option.BindedQuest && !QuestManager.Instance.HasOngoingQuestWithID(option.BindedQuest.ID)) { continue;//若需当前选项需任务驱动但任务未接取,则跳过创建 } OptionAgent oa = ObjectPool.Get(UI.optionPrefab, UI.optionsParent, false).GetComponent <OptionAgent>(); oa.Init(option.Title, option); optionAgents.Add(oa); } } //把第一页以外的选项隐藏 for (int i = UI.lineAmount - (int)(UI.wordsText.preferredHeight / UI.textLineHeight); i < optionAgents.Count; i++) { ZetanUtility.SetActive(optionAgents[i].gameObject, false); } if (optionAgents.Count < 1) { MakeContinueOption();//如果所有选择型分支都完成了,则可以进行下一句对话 } CheckPages(); //Debug.Log("make"); //Debug.Log(optionAgents.Count); }
/// <summary> /// 处理最后一句分支对话 /// </summary> private void HandlingLastOptionWords() { WordsOption topOptionInstance = wordsOptionInstances.Pop(); if (topOptionInstance.runtimeDialogParent) { DialogueWords topWordsParent = null; if (topOptionInstance.runtimeWordsParentIndex > -1 && topOptionInstance.runtimeWordsParentIndex < topOptionInstance.runtimeDialogParent.Words.Count) { topWordsParent = topOptionInstance.runtimeDialogParent.Words[topOptionInstance.runtimeWordsParentIndex];//找到包含当前分支的语句 } if (topWordsParent != null) { int indexOfWordsParent = topOptionInstance.runtimeDialogParent.IndexOfWords(topWordsParent); string dialogParentID = topOptionInstance.runtimeDialogParent.ID; if (topOptionInstance.OptionType == WordsOptionType.Choice && topWordsParent.NeedToChusCorrectOption) //该对话需要选择正确选项,且该选项是选择型选项 { if (topWordsParent.IsCorrectOption(currentOption)) //该选项是正确选项 //传入currentOption而不是topOptionInstance是因为前者是存于本地的原始数据,后者是实例化的数据 { foreach (WordsOption option in topWordsParent.Options.Where(x => x.OptionType == WordsOptionType.Choice)) //则其他选择型选项就跟着完成了 { CompleteOption(option, out var result); result.complete = true; var choiceOptions = topWordsParent.Options.Where(x => x.OptionType == WordsOptionType.Choice).ToList(); for (int i = 0; i < choiceOptions.Count; i++) { if (result.IsOptionCmplt(i) || !choiceOptions[i].DeleteWhenCmplt) { continue; } result.complete = false; break; } } StartDialogue(topOptionInstance.runtimeDialogParent, topOptionInstance.runtimeIndexToGoBack, false); } else if (topOptionInstance.DeleteWhenCmplt)//若该选项不是正确选项,但完成后需要删除 { CompleteOption(currentOption, out _); } } void CompleteOption(WordsOption option, out DialogueWordsData result) { dialogueDatas.TryGetValue(dialogParentID, out var dFound); if (dFound == null) { dFound = new DialogueData(option.runtimeDialogParent); dialogueDatas.Add(dialogParentID, dFound); } result = dFound.wordsDatas.Find(x => x.wordsIndex == indexOfWordsParent); if (result == null) { result = new DialogueWordsData(indexOfWordsParent); dFound.wordsDatas.Add(result); } int indexOfOption = topWordsParent.IndexOfOption(option); if (!result.cmpltOptionIndexes.Contains(indexOfOption)) { result.cmpltOptionIndexes.Add(indexOfOption); //该分支已完成 } //Debug.Log($"完成选项{indexOfOption}: " + option.Title); } if (dialogueDatas.TryGetValue(dialogParentID, out var dfind)) { if (dfind.wordsDatas.TrueForAll(x => x.complete)) { ExecuteEvents(topWordsParent); } } else if (!topWordsParent.NeedToChusCorrectOption)//找不到,且该句子不需要选择正确选项,可以直接完成 { ExecuteEvents(topWordsParent); } if (topWordsParent != null && topWordsParent.NeedToChusCorrectOption && !topWordsParent.IsCorrectOption(currentOption))//选择错误,则说选择错误时应该说的话 { StartOneWords(new DialogueWords(topWordsParent.TalkerInfo, topWordsParent.WordsWhenChusWB, topWordsParent.TalkerType), topOptionInstance.runtimeDialogParent, topOptionInstance.runtimeIndexToGoBack); } else if (topOptionInstance.GoBack)//处理普通的带返回的分支 { StartDialogue(topOptionInstance.runtimeDialogParent, topOptionInstance.runtimeIndexToGoBack, false); } } } currentOption = null; }
public void StartOptionDialogue(WordsOption option) { if (option == null || !option.IsValid) { return; } var optionInstance = option.Cloned; optionInstance.runtimeWordsParentIndex = currentDialog.IndexOfWords(currentWords); if (currentWords.NeedToChusCorrectOption) { optionInstance.runtimeDialogParent = currentDialog; if (currentWords.IndexOfCorrectOption == currentWords.IndexOfOption(option)) { optionInstance.runtimeIndexToGoBack = optionInstance.runtimeWordsParentIndex + 1; } else { optionInstance.runtimeIndexToGoBack = optionInstance.runtimeWordsParentIndex; } } else if (option.GoBack) { optionInstance.runtimeDialogParent = currentDialog; if (option.OptionType == WordsOptionType.SubmitAndGet || option.OptionType == WordsOptionType.OnlyGet || option.IndexToGoBack < 0) { optionInstance.runtimeIndexToGoBack = optionInstance.runtimeWordsParentIndex; } else { optionInstance.runtimeIndexToGoBack = option.IndexToGoBack; } } wordsOptionInstances.Push(optionInstance); currentOption = option; if (option.OptionType == WordsOptionType.SubmitAndGet && option.IsValid) { if (BackpackManager.Instance.TryLoseItem_Boolean(option.ItemToSubmit, option.ItemCanGet)) { BackpackManager.Instance.LoseItem(option.ItemToSubmit, option.ItemCanGet); } else { wordsOptionInstances.Pop(); currentOption = null; return; } } if (option.OptionType == WordsOptionType.OnlyGet && option.IsValid) { if (!BackpackManager.Instance.TryGetItem_Boolean(option.ItemCanGet)) { wordsOptionInstances.Pop(); currentOption = null; return; } else { BackpackManager.Instance.GetItem(option.ItemCanGet); } } if (option.OptionType == WordsOptionType.Choice && (!option.HasWordsToSay || option.HasWordsToSay && string.IsNullOrEmpty(option.Words))) { HandlingLastOptionWords(); SayNextWords(); return; } if (option.OptionType == WordsOptionType.BranchDialogue && option.Dialogue) { StartDialogue(optionInstance.Dialogue, optionInstance.SpecifyIndex); } else if (!string.IsNullOrEmpty(option.Words)) { TalkerInformation talkerInfo = null; if (optionInstance.TalkerType == TalkerType.NPC) { if (!currentDialog.UseUnifiedNPC && optionInstance.runtimeWordsParentIndex > -1 && optionInstance.runtimeWordsParentIndex < currentDialog.Words.Count) { talkerInfo = currentDialog.Words[optionInstance.runtimeWordsParentIndex].TalkerInfo; //Debug.Log(talkerInfo + "A"); } else if (currentDialog.UseUnifiedNPC && currentDialog.UseCurrentTalkerInfo) { talkerInfo = CurrentTalker.Info; //Debug.Log(talkerInfo + "B"); } else if (currentDialog.UseUnifiedNPC && !currentDialog.UseCurrentTalkerInfo) { talkerInfo = currentDialog.UnifiedNPC; //Debug.Log(talkerInfo + "C"); } } if (option.GoBack) { StartOneWords(new DialogueWords(talkerInfo, optionInstance.Words, optionInstance.TalkerType), currentDialog, optionInstance.runtimeIndexToGoBack); } else { StartOneWords(new DialogueWords(talkerInfo, optionInstance.Words, optionInstance.TalkerType)); } SayNextWords(); } }