Example #1
0
 public static string GetFirstWords(Dialogue dialogue)
 {
     if (dialogue && dialogue.Words.Count > 0)
     {
         return(MiscFuntion.HandlingKeyWords(dialogue.Words[0].ToString(), true));
     }
     return(string.Empty);
 }
Example #2
0
    private void DoOneWords(DialogueWords words)
    {
        string talkerName = words.TalkerName;

        if (currentDialogue)
        {
            talkerName = currentDialogue.model.UseUnifiedNPC ? (currentDialogue.model.UseCurrentTalkerInfo ? currentTalker.GetData <TalkerData>().Info.Name : currentDialogue.model.UnifiedNPC.Name) : talkerName;
        }
        if (words.TalkerType == TalkerType.Player && PlayerManager.Instance.PlayerInfo)
        {
            talkerName = PlayerManager.Instance.PlayerInfo.Name;
        }
        nameText.text  = talkerName;
        wordsText.text = MiscFuntion.HandlingKeyWords(words.Content, true);
        HandlingWords();
    }
Example #3
0
    public void UpdateUI()
    {
        //Debug.Log(questHolder.TalkerName);
        bool hasObjective = questHolder.GetData <TalkerData>().objectivesTalkToThis.FindAll(x => x.AllPrevComplete && !x.IsComplete).Count > 0 ||
                            questHolder.GetData <TalkerData>().objectivesSubmitToThis.FindAll(x => x.AllPrevComplete && !x.IsComplete).Count > 0;

        if (questHolder.QuestInstances.Count < 1 && !hasObjective)
        {
            if (icon.enabled)
            {
                icon.enabled = false;
            }
            mapIcon.Hide();
            conditionShow = false;
            return;
        }
        //Debug.Log("enter");
        if (hasObjective)//该NPC身上有未完成的任务目标
        {
            icon.overrideSprite = accepted;
            mapIcon.iconImage.overrideSprite = accepted;
            conditionShow = true;
            return;
        }
        foreach (var quest in questHolder.QuestInstances)
        {
            if (!quest.IsComplete && !quest.InProgress && MiscFuntion.CheckCondition(quest.Model.AcceptCondition))//只要有一个没接取
            {
                icon.overrideSprite = notAccepted;
                mapIcon.iconImage.overrideSprite = notAccepted;
                conditionShow = true;
                return;
            }
            else if (quest.IsComplete && quest.InProgress)//只要有一个完成
            {
                icon.overrideSprite = complete;
                mapIcon.iconImage.overrideSprite = complete;
                conditionShow = true;
                return;
            }
        }
        conditionShow = false;
    }
Example #4
0
    private void HandlingQuestOptions()
    {
        var cmpltQuests = new List <QuestData>();
        var norQuests   = new List <QuestData>();

        foreach (var quest in currentTalker.QuestInstances)
        {
            if (MiscFuntion.CheckCondition(quest.Model.AcceptCondition) && !quest.IsFinished)
            {
                if (quest.IsComplete)
                {
                    cmpltQuests.Add(quest);
                }
                else
                {
                    norQuests.Add(quest);
                }
            }
        }
        buttonDatas.Clear();
        foreach (var quest in cmpltQuests)
        {
            buttonDatas.Add(new ButtonWithTextData(quest.Model.Title + "(完成)", delegate
            {
                currentQuest = quest;
                CurrentType  = DialogueType.Quest;
                ShowButtons(false, false, false, false);
                StartDialogue(quest.Model.CompleteDialogue);
            }));
        }
        foreach (var quest in norQuests)
        {
            buttonDatas.Add(new ButtonWithTextData(quest.Model.Title + (quest.InProgress ? "(进行中)" : string.Empty), delegate
            {
                currentQuest = quest;
                CurrentType  = DialogueType.Quest;
                ShowButtons(false, false, false, false);
                StartDialogue(quest.InProgress ? quest.Model.OngoingDialogue : quest.Model.BeginDialogue);
            }));
        }
        RefreshOptionUI();
    }
Example #5
0
    protected override void DrawAdditionalProperty(SerializedProperty objective, Rect rect, ref int lineCount)
    {
        SerializedProperty canNavigate  = objective.FindPropertyRelative("canNavigate");
        SerializedProperty showMapIcon  = objective.FindPropertyRelative("showMapIcon");
        SerializedProperty auxiliaryPos = objective.FindPropertyRelative("auxiliaryPos");

        EditorGUI.PropertyField(new Rect(rect.x, rect.y + lineHeightSpace * lineCount, rect.width * 0.5f, lineHeight), showMapIcon, new GUIContent("显示地图图标"));
        lineCount++;
        if (showMapIcon.boolValue)
        {
            EditorGUI.PropertyField(new Rect(rect.x + rect.width * 0.5f, rect.y + lineHeightSpace * (lineCount - 1), rect.width * 0.5f, lineHeight),
                                    canNavigate, new GUIContent("可导航"));
        }

        Quest quest = objective.serializedObject.targetObject as Quest;
        SerializedProperty _NPCToTalk = objective.FindPropertyRelative("_NPCToTalk");
        SerializedProperty dialogue   = objective.FindPropertyRelative("dialogue");

        new ObjectSelectionDrawer <TalkerInformation>(_NPCToTalk, "_name", talkerCache, "与此NPC交谈").DoDraw(new Rect(rect.x, rect.y + lineHeightSpace * lineCount, rect.width, lineHeight));
        lineCount++;
        EditorGUI.PropertyField(new Rect(rect.x, rect.y + lineHeightSpace * lineCount, rect.width, lineHeight), dialogue, new GUIContent("交谈时的对话"));
        lineCount++;
        if (dialogue.objectReferenceValue is Dialogue dialog)
        {
            Quest find = Array.Find(questCache, x => x != quest && x.Objectives.Exists(y => y is TalkObjective to && to.Dialogue == dialog));
            if (find)
            {
                EditorGUI.HelpBox(new Rect(rect.x, rect.y + lineHeightSpace * lineCount, rect.width, lineHeight * 2.4f),
                                  "已有任务目标使用该对话,游戏中可能会产生逻辑错误。\n任务名称:" + find.Title, MessageType.Warning);
                lineCount += 2;
            }
            if (dialog.Words != null && dialog.Words[0])
            {
                GUI.enabled = false;
                EditorGUI.TextArea(new Rect(rect.x, rect.y + lineHeightSpace * lineCount, rect.width, lineHeight),
                                   dialog.Words[0].TalkerName + "说:" + MiscFuntion.HandlingKeyWords(dialog.Words[0].Content));
                GUI.enabled = true;
                lineCount++;
            }
        }
    }
Example #6
0
 protected override bool CompareKey(Dialogue element, out string remark)
 {
     remark = string.Empty;
     if (!element)
     {
         return(false);
     }
     if (element.ID.Contains(keyWords))
     {
         remark = $"识别码:{ZetanUtility.Editor.TrimContentByKey(element.ID, keyWords, 16)}";
         return(true);
     }
     for (int i = 0; i < element.Words.Count; i++)
     {
         var words = element.Words[i];
         if (words.Content.Contains(keyWords))
         {
             remark = $"第[{i}]句:{ZetanUtility.Editor.TrimContentByKey(words.Content, keyWords, 20)}";
             return(true);
         }
         else if (MiscFuntion.HandlingKeyWords(words.Content).Contains(keyWords))
         {
             remark = $"第[{i}]句:{ZetanUtility.Editor.TrimContentByKey(MiscFuntion.HandlingKeyWords(words.Content, false, objects.ToArray()), keyWords, 20)}";
             return(true);
         }
         for (int j = 0; j < words.Options.Count; j++)
         {
             var option = words.Options[j];
             if (option.Title.Contains(keyWords))
             {
                 remark = $"第[{i}]句第[{j}]个选项标题:{ZetanUtility.Editor.TrimContentByKey(option.Title, keyWords, 16)}";
                 return(true);
             }
         }
     }
     return(false);
 }
Example #7
0
    public override void OnInspectorGUI()
    {
        if (!CheckEditComplete())
        {
            EditorGUILayout.HelpBox("该任务存在未补全信息。", MessageType.Warning);
        }
        else
        {
            EditorGUILayout.HelpBox("该任务信息已完整。", MessageType.Info);
        }
        barIndex = GUILayout.Toolbar(barIndex, new string[] { "基本", "条件", "奖励", "对话", "目标" });
        EditorGUILayout.Space();
        serializedObject.UpdateIfRequiredOrScript();
        EditorGUI.BeginChangeCheck();
        switch (barIndex)
        {
        case 0:
            #region case 0 基本
            EditorGUILayout.PropertyField(_ID, new GUIContent("识别码"));
            if (string.IsNullOrEmpty(_ID.stringValue) || Quest.IsIDDuplicate(quest, questCache))
            {
                if (!string.IsNullOrEmpty(_ID.stringValue) && Quest.IsIDDuplicate(quest, questCache))
                {
                    EditorGUILayout.HelpBox("此识别码已存在!", MessageType.Error);
                }
                else
                {
                    EditorGUILayout.HelpBox("识别码为空!", MessageType.Error);
                }
                if (GUILayout.Button("自动生成识别码"))
                {
                    _ID.stringValue = Quest.GetAutoID();
                    EditorGUI.FocusTextInControl(null);
                }
            }
            EditorGUILayout.PropertyField(title, new GUIContent("标题"));
            EditorGUILayout.PropertyField(description, new GUIContent("描述"));
            EditorGUILayout.PropertyField(abandonable, new GUIContent("可放弃"));
            EditorGUILayout.PropertyField(questType, new GUIContent("任务类型"));
            if (questType.enumValueIndex == (int)QuestType.Repeated)
            {
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.PropertyField(repeatFrequancy, new GUIContent("重复频率"));
                EditorGUILayout.PropertyField(timeUnit, new GUIContent(string.Empty));
                EditorGUILayout.EndHorizontal();
            }
            groupSelector.DoLayoutDraw();
            npcSelector.DoLayoutDraw();
            if (EditorGUI.EndChangeCheck())
            {
                serializedObject.ApplyModifiedProperties();                                //这一步一定要在DoLayoutList()之前做!否则无法修改DoList之前的数据
            }
            if (holder)
            {
                EditorGUILayout.Space();
                EditorGUILayout.BeginHorizontal();
                GUI.enabled = false;
                EditorGUILayout.ObjectField(new GUIContent("持有该任务的NPC"), holder, typeof(TalkerInformation), false);
                GUI.enabled = true;
                EditorGUILayout.EndHorizontal();
            }
            #endregion
            break;

        case 1:
            #region case 1 条件
            acceptConditionDrawer.DoLayoutDraw();
            #endregion
            break;

        case 2:
            #region case 2 奖励
            EditorGUILayout.HelpBox("目前只设计10个道具奖励。", MessageType.Info);
            rewardDrawer.DoLayoutDraw();
            rewardDrawer.List.displayAdd = rewardItems.arraySize < 10;
            if (EditorGUI.EndChangeCheck())
            {
                serializedObject.ApplyModifiedProperties();
            }
            #endregion
            break;

        case 3:
            #region case 3 对话
            EditorGUILayout.PropertyField(beginDialogue, new GUIContent("开始时的对话"));
            if (beginDialogue.objectReferenceValue)
            {
                if (GUILayout.Button("编辑"))
                {
                    EditorUtility.OpenPropertyEditor(beginDialogue.objectReferenceValue);
                }
                if (completeDialogue.objectReferenceValue == beginDialogue.objectReferenceValue || beginDialogue.objectReferenceValue == ongoingDialogue.objectReferenceValue)
                {
                    EditorGUILayout.HelpBox("进行时或完成时已使用该对话,游戏中可能会产生逻辑错误。", MessageType.Warning);
                }
                else
                {
                    Quest find = Array.Find(questCache, x => x != quest && (x.BeginDialogue == beginDialogue.objectReferenceValue || x.CompleteDialogue == beginDialogue.objectReferenceValue ||
                                                                            x.OngoingDialogue == beginDialogue.objectReferenceValue));
                    if (find)
                    {
                        EditorGUILayout.HelpBox("已有任务使用该对话,游戏中可能会产生逻辑错误。\n配置路径:\n" + AssetDatabase.GetAssetPath(find), MessageType.Warning);
                    }
                }
                PreviewDialogue(beginDialogue.objectReferenceValue as Dialogue);
            }
            else
            {
                NewDialogueFor(beginDialogue);
            }
            EditorGUILayout.PropertyField(ongoingDialogue, new GUIContent("进行中的对话"));
            if (ongoingDialogue.objectReferenceValue)
            {
                if (GUILayout.Button("编辑"))
                {
                    EditorUtility.OpenPropertyEditor(ongoingDialogue.objectReferenceValue);
                }
                if (ongoingDialogue.objectReferenceValue == beginDialogue.objectReferenceValue || completeDialogue.objectReferenceValue == ongoingDialogue.objectReferenceValue)
                {
                    EditorGUILayout.HelpBox("开始时或完成时已使用该对话,游戏中可能会产生逻辑错误。", MessageType.Warning);
                }
                else
                {
                    Quest find = Array.Find(questCache, x => x != quest && (x.BeginDialogue == ongoingDialogue.objectReferenceValue || x.CompleteDialogue == ongoingDialogue.objectReferenceValue ||
                                                                            x.OngoingDialogue == ongoingDialogue.objectReferenceValue));
                    if (find)
                    {
                        EditorGUILayout.HelpBox("已有任务使用该对话,游戏中可能会产生逻辑错误。\n配置路径:\n" + AssetDatabase.GetAssetPath(find), MessageType.Warning);
                    }
                }
                PreviewDialogue(ongoingDialogue.objectReferenceValue as Dialogue);
            }
            else
            {
                NewDialogueFor(ongoingDialogue);
            }
            EditorGUILayout.PropertyField(completeDialogue, new GUIContent("完成时的对话"));
            if (completeDialogue.objectReferenceValue)
            {
                if (GUILayout.Button("编辑"))
                {
                    EditorUtility.OpenPropertyEditor(completeDialogue.objectReferenceValue);
                }
                if (completeDialogue.objectReferenceValue == beginDialogue.objectReferenceValue || completeDialogue.objectReferenceValue == ongoingDialogue.objectReferenceValue)
                {
                    EditorGUILayout.HelpBox("开始时或进行时已使用该对话,游戏中可能会产生逻辑错误。", MessageType.Warning);
                }
                else
                {
                    Quest find = Array.Find(questCache, x => x != quest && (x.BeginDialogue == completeDialogue.objectReferenceValue || x.CompleteDialogue == completeDialogue.objectReferenceValue ||
                                                                            x.OngoingDialogue == completeDialogue.objectReferenceValue));
                    if (find)
                    {
                        EditorGUILayout.HelpBox("已有任务使用该对话,游戏中可能会产生逻辑错误。\n配置路径:\n" + AssetDatabase.GetAssetPath(find), MessageType.Warning);
                    }
                }
                PreviewDialogue(completeDialogue.objectReferenceValue as Dialogue);
            }
            else
            {
                NewDialogueFor(completeDialogue);
            }
            if (EditorGUI.EndChangeCheck())
            {
                serializedObject.ApplyModifiedProperties();
            }
            #endregion
            break;

        case 4:
            #region case 4 目标
            EditorGUILayout.PropertyField(cmpltObjctvInOrder, new GUIContent("按顺序完成目标"));
            if (quest.CmpltObjctvInOrder)
            {
                EditorGUILayout.HelpBox("勾选此项,则勾选按顺序的目标按执行顺序从小到大的顺序执行,若相同,则表示可以同时进行;" +
                                        "若目标没有勾选按顺序,则表示该目标不受顺序影响。", MessageType.Info);
            }

            showState.target = EditorGUILayout.Foldout(objectives.isExpanded, "任务目标\t\t"
                                                       + (objectives.isExpanded ? string.Empty : (objectives.arraySize > 0 ? "数量:" + objectives.arraySize : "无")), true);
            if (EditorGUILayout.BeginFadeGroup(showState.faded))
            {
                objectiveList.DoLayoutList();
            }
            EditorGUILayout.EndFadeGroup();
            EditorGUILayout.LabelField("目标显示预览");
            GUI.enabled = false;
            EditorGUILayout.TextArea(quest.GetObjectiveString());
            GUI.enabled = true;
            if (EditorGUI.EndChangeCheck())
            {
                serializedObject.ApplyModifiedProperties();
            }
            #endregion
            break;
        }

        void NewDialogueFor(SerializedProperty dialogue)
        {
            if (GUILayout.Button("新建"))
            {
                Dialogue dialogInstance = ZetanUtility.Editor.SaveFilePanel(CreateInstance <Dialogue>, "dialogue", ping: true);
                if (dialogInstance)
                {
                    dialogue.objectReferenceValue = dialogInstance;
                    EditorUtility.OpenPropertyEditor(dialogInstance);
                }
            }
        }

        void PreviewDialogue(Dialogue dialogue)
        {
            string dialoguePreview = string.Empty;

            for (int i = 0; i < dialogue.Words.Count; i++)
            {
                var words = dialogue.Words[i];
                dialoguePreview += "[" + words.TalkerName + "]说:\n-" + MiscFuntion.HandlingKeyWords(words.Content, false, talkerCache);
                for (int j = 0; j < words.Options.Count; j++)
                {
                    dialoguePreview += "\n--(选项" + (j + 1) + ")" + words.Options[j].Title;
                }
                dialoguePreview += i == dialogue.Words.Count - 1 ? string.Empty : "\n";
            }
            GUI.enabled = false;
            EditorGUILayout.TextArea(dialoguePreview);
            GUI.enabled = true;
        }
    }
Example #8
0
 private void StartTalking(Talker talker)
 {
     currentTalker = talker;
     CurrentType   = DialogueType.Normal;
     ShowButtons(talker.GetData <TalkerData>().Info.CanDEV_RLAT, talker.GetData <TalkerData>().Info.IsVendor, talker.GetData <TalkerData>().Info.IsWarehouseAgent, talker.QuestInstances.FindAll(q => !q.IsFinished && MiscFuntion.CheckCondition(q.Model.AcceptCondition)).Count > 0);
     HideQuestDescription();
     StartDialogue(talker.DefaultDialogue);
     talker.OnTalkBegin();
 }
Example #9
0
    private readonly List <QuestData> questsFinished = new List <QuestData>();//分开存储完成任务可减少不必要的检索开销

    #region 任务处理相关
    /// <summary>
    /// 接取任务
    /// </summary>
    /// <param name="quest">要接取的任务</param>
    public bool AcceptQuest(QuestData quest)
    {
        if (!quest || !IsQuestValid(quest.Model))
        {
            MessageManager.Instance.New("无效任务");
            return(false);
        }
        if (!MiscFuntion.CheckCondition(quest.Model.AcceptCondition) && !SaveManager.Instance.IsLoading)
        {
            MessageManager.Instance.New("未满足任务接取条件");
            return(false);
        }
        if (HasOngoingQuest(quest))
        {
            MessageManager.Instance.New("已经在执行");
            return(false);
        }
        ObjectiveData currentObjective = quest.Objectives[0];

        for (int i = 0; i < quest.Objectives.Count; i++)
        {
            var o = quest.Objectives[i];
            o.OnStateChangeEvent += OnObjectiveStateChange;
            if (o is CollectObjectiveData co)
            {
                BackpackManager.Instance.Inventory.OnItemAmountChanged += co.UpdateCollectAmount;
                if (o.AllPrevComplete)
                {
                    if (co.Model.CheckBagAtStart && !SaveManager.Instance.IsLoading)
                    {
                        co.CurrentAmount = BackpackManager.Instance.GetAmount(co.Model.ItemToCollect);
                    }
                    else if (!co.Model.CheckBagAtStart && !SaveManager.Instance.IsLoading)
                    {
                        co.amountWhenStart = BackpackManager.Instance.GetAmount(co.Model.ItemToCollect);
                    }
                }
            }
            if (o is KillObjectiveData ko)
            {
                switch (ko.Model.KillType)
                {
                case KillObjectiveType.Specific:
                    GameManager.Enemies[ko.Model.Enemy.ID].ForEach(e => e.OnDeathEvent += ko.UpdateKillAmount);
                    break;

                case KillObjectiveType.Race:
                    foreach (List <Enemy> enemies in GameManager.Enemies.Values.Where(x => x.Count > 0 && x[0].Info.Race && x[0].Info.Race == ko.Model.Race))
                    {
                        enemies.ForEach(e => e.OnDeathEvent += ko.UpdateKillAmount);
                    }
                    break;

                case KillObjectiveType.Group:
                    foreach (List <Enemy> enemies in GameManager.Enemies.Values.Where(x => x.Count > 0 && ko.Model.Group.Contains(x[0].Info.ID)))
                    {
                        enemies.ForEach(e => e.OnDeathEvent += ko.UpdateKillAmount);
                    }
                    break;

                case KillObjectiveType.Any:
                    foreach (List <Enemy> enemies in GameManager.Enemies.Select(x => x.Value))
                    {
                        enemies.ForEach(e => e.OnDeathEvent += ko.UpdateKillAmount);
                    }
                    break;
                }
            }
            if (o is TalkObjectiveData to)
            {
                if (!o.IsComplete)
                {
                    var talker = DialogueManager.Instance.Talkers[to.Model.NPCToTalk.ID];
                    talker.objectivesTalkToThis.Add(to);
                    o.OnStateChangeEvent += talker.TryRemoveObjective;
                }
            }
            if (o is MoveObjectiveData mo)
            {
                mo.targetPoint = CheckPointManager.Instance.CreateCheckPoint(mo.Model.AuxiliaryPos, mo.UpdateMoveState);
            }
            if (o is SubmitObjectiveData so)
            {
                if (!o.IsComplete)
                {
                    var talker = DialogueManager.Instance.Talkers[so.Model.NPCToSubmit.ID];
                    talker.objectivesSubmitToThis.Add(so);
                    o.OnStateChangeEvent += talker.TryRemoveObjective;
                }
            }
            if (o is TriggerObjectiveData cuo)
            {
                TriggerManager.Instance.RegisterTriggerEvent(cuo.UpdateTriggerState);
                var state = TriggerManager.Instance.GetTriggerState(cuo.Model.TriggerName);
                if (cuo.Model.CheckStateAtAcpt && state != TriggerState.NotExist)
                {
                    TriggerManager.Instance.SetTrigger(cuo.Model.TriggerName, state == TriggerState.On);
                }
            }
        }
        quest.InProgress = true;
        questsInProgress.Add(quest);
        if (quest.Model.NPCToSubmit)
        {
            DialogueManager.Instance.Talkers[quest.Model.NPCToSubmit.ID].TransferQuestToThis(quest);
        }
        if (!SaveManager.Instance.IsLoading)
        {
            MessageManager.Instance.New($"接取了任务 [{quest.Model.Title}]");
        }
        quest.latestHandleDays = TimeManager.Instance.Days;
        CreateObjectiveMapIcon(quest.Objectives[0]);
        NotifyCenter.PostNotify(QuestStateChanged, quest, false);
        return(true);
    }