Пример #1
0
    /// <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);
    }
Пример #2
0
    /// <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;
    }
Пример #3
0
    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();
        }
    }