public static string GetFirstWords(Dialogue dialogue) { if (dialogue && dialogue.Words.Count > 0) { return(MiscFuntion.HandlingKeyWords(dialogue.Words[0].ToString(), true)); } return(string.Empty); }
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(); }
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; }
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(); }
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++; } } }
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); }
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; } }
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(); }
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); }