905 lines
32 KiB
C#
905 lines
32 KiB
C#
// Copyright (c) Pixel Crushers. All rights reserved.
|
|
|
|
using UnityEngine;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using PixelCrushers.QuestMachine;
|
|
using PixelCrushers;
|
|
using TMPro;
|
|
using UnityEngine.UI;
|
|
|
|
namespace Beyond
|
|
{
|
|
/// <summary>
|
|
/// Unity UI implementation of Quest Journal UI.
|
|
/// </summary>
|
|
public class bUnityUIQuestJournalUI : bUnityUIBaseUI, IQuestJournalUI
|
|
{
|
|
#region Serialized Fields
|
|
|
|
[Header("Selection Panel")]
|
|
[SerializeField]
|
|
private RectTransform m_questSelectionContentContainer;
|
|
|
|
[SerializeField]
|
|
private bUnityUIFoldoutTemplate m_questGroupTemplate;
|
|
|
|
[SerializeField]
|
|
private bUnityUIQuestNameButtonTemplate m_activeQuestNameTemplate, m_succededQuestNameTemplate, m_failedQuestNameTemplate;
|
|
|
|
[SerializeField] private Image questImage;
|
|
|
|
[Tooltip("Show all groups expanded.")]
|
|
[SerializeField]
|
|
private bool m_alwaysExpandAllGroups = false;
|
|
|
|
[Tooltip("Show details when pointer hovers quest name.")]
|
|
[SerializeField]
|
|
private bool m_showDetailsOnFocus = false;
|
|
|
|
[Tooltip("Include completed questTemplates in selection panel.")]
|
|
[SerializeField]
|
|
private bool m_showSuccededQuests = true, m_showFailedQuests = true, m_showActiveQuests = true;
|
|
|
|
[Header("Details Panel")]
|
|
[SerializeField]
|
|
private RectTransform m_questDetailsContentContainer;
|
|
|
|
[SerializeField]
|
|
private UnityUITextTemplate m_questHeadingTextTemplate;
|
|
|
|
[SerializeField]
|
|
private UnityUITextTemplate[] m_subheadingTemplates;
|
|
|
|
[SerializeField]
|
|
private UnityUITextTemplate m_questBodyTextTemplate;
|
|
|
|
[SerializeField]
|
|
private UnityUIIconListTemplate m_iconListTemplate;
|
|
|
|
[SerializeField]
|
|
private UnityUIButtonListTemplate m_buttonListTemplate;
|
|
|
|
[SerializeField]
|
|
private RectTransform m_questDetailsButtonContainer;
|
|
|
|
[SerializeField]
|
|
private UnityUIButtonTemplate m_trackButtonTemplate;
|
|
|
|
[SerializeField]
|
|
private UnityUIButtonTemplate m_abandonButtonTemplate;
|
|
|
|
[Header("Abandon Quest Panel")]
|
|
[SerializeField]
|
|
private bUIPanel m_abandonQuestPanel;
|
|
|
|
[SerializeField]
|
|
private UITextField m_abandonQuestNameText;
|
|
|
|
[Header("Misc")]
|
|
[SerializeField]
|
|
private bool m_sortAlphabetically = true;
|
|
|
|
[SerializeField]
|
|
private bool m_showDisplayNameInHeading = false;
|
|
|
|
[SerializeField]
|
|
private bool m_showDialogueContentIfNoJournalContent = false;
|
|
|
|
[SerializeField]
|
|
private bool m_showQuestsThatHaveNoContent = true;
|
|
|
|
[SerializeField]
|
|
private bool m_showFirstQuestDetailsOnOpen = false;
|
|
|
|
[Tooltip("Show Track toggle button in quest details panel.")]
|
|
[SerializeField]
|
|
private bool m_showTrackButtonInDetails = false;
|
|
|
|
public enum SendMessageOnOpen
|
|
{ Never, Always, NotWhenUsingMouse }
|
|
|
|
[SerializeField]
|
|
private SendMessageOnOpen m_sendMessageOnOpen = SendMessageOnOpen.NotWhenUsingMouse;
|
|
|
|
[SerializeField]
|
|
private string m_openMessage = "Pause Player";
|
|
|
|
[SerializeField]
|
|
private string m_closeMessage = "Unpause Player";
|
|
|
|
[SerializeField] private TMP_Text questDescriptionTitle;
|
|
|
|
[SerializeField] private Slider contentSlider;
|
|
|
|
[SerializeField] private Image activeImage, completedImage, failedImage;
|
|
|
|
#endregion Serialized Fields
|
|
|
|
#region Accessor Properties for Serialized Fields
|
|
|
|
public RectTransform questSelectionContentContainer
|
|
{
|
|
get { return m_questSelectionContentContainer; }
|
|
set { m_questSelectionContentContainer = value; }
|
|
}
|
|
|
|
public bUnityUIFoldoutTemplate questGroupTemplate
|
|
{
|
|
get { return m_questGroupTemplate; }
|
|
set { m_questGroupTemplate = value; }
|
|
}
|
|
|
|
public bUnityUIQuestNameButtonTemplate activeQuestNameTemplate
|
|
{
|
|
get { return m_activeQuestNameTemplate; }
|
|
set { m_activeQuestNameTemplate = value; }
|
|
}
|
|
|
|
public bUnityUIQuestNameButtonTemplate succededQuestNameTemplate
|
|
{
|
|
get { return m_succededQuestNameTemplate; }
|
|
set { m_succededQuestNameTemplate = value; }
|
|
}
|
|
|
|
public bUnityUIQuestNameButtonTemplate failedQuestNameTemplate
|
|
{
|
|
get { return m_failedQuestNameTemplate; }
|
|
set { m_failedQuestNameTemplate = value; }
|
|
}
|
|
|
|
public bool alwaysExpandAllGroups
|
|
{
|
|
get { return m_alwaysExpandAllGroups; }
|
|
set { m_alwaysExpandAllGroups = value; }
|
|
}
|
|
|
|
public bool showDetailsOnFocus
|
|
{
|
|
get { return m_showDetailsOnFocus; }
|
|
set { m_showDetailsOnFocus = value; }
|
|
}
|
|
|
|
public bool showTrackButtonInDetails
|
|
{
|
|
get { return m_showTrackButtonInDetails; }
|
|
set { m_showTrackButtonInDetails = value; }
|
|
}
|
|
|
|
public bool showCompletedQuests
|
|
{
|
|
get { return showSuccededQuests && showFailedQuests; }
|
|
}
|
|
|
|
public bool showSuccededQuests
|
|
{
|
|
get { return m_showSuccededQuests; }
|
|
set { m_showSuccededQuests = value; }
|
|
}
|
|
|
|
public bool showFailedQuests
|
|
{
|
|
get { return m_showFailedQuests; }
|
|
set { m_showFailedQuests = value; }
|
|
}
|
|
|
|
public bool showActiveQuests
|
|
{
|
|
get { return m_showActiveQuests; }
|
|
set { m_showActiveQuests = value; }
|
|
}
|
|
|
|
public RectTransform questDetailsContentContainer
|
|
{
|
|
get { return m_questDetailsContentContainer; }
|
|
set { m_questDetailsContentContainer = value; }
|
|
}
|
|
|
|
public UnityUITextTemplate questHeadingTextTemplate
|
|
{
|
|
get { return m_questHeadingTextTemplate; }
|
|
set { m_questHeadingTextTemplate = value; }
|
|
}
|
|
|
|
public UnityUITextTemplate[] subheadingTemplates
|
|
{
|
|
get { return m_subheadingTemplates; }
|
|
set { m_subheadingTemplates = value; }
|
|
}
|
|
|
|
public UnityUITextTemplate questBodyTextTemplate
|
|
{
|
|
get { return m_questBodyTextTemplate; }
|
|
set { m_questBodyTextTemplate = value; }
|
|
}
|
|
|
|
public UnityUIIconListTemplate iconListTemplate
|
|
{
|
|
get { return m_iconListTemplate; }
|
|
set { m_iconListTemplate = value; }
|
|
}
|
|
|
|
public UnityUIButtonListTemplate buttonListTemplate
|
|
{
|
|
get { return m_buttonListTemplate; }
|
|
set { m_buttonListTemplate = value; }
|
|
}
|
|
|
|
public UnityUIButtonTemplate trackButtonTemplate
|
|
{
|
|
get { return m_trackButtonTemplate; }
|
|
set { m_trackButtonTemplate = value; }
|
|
}
|
|
|
|
public UnityUIButtonTemplate abandonButtonTemplate
|
|
{
|
|
get { return m_abandonButtonTemplate; }
|
|
set { m_abandonButtonTemplate = value; }
|
|
}
|
|
|
|
public bUIPanel abandonQuestPanel
|
|
{
|
|
get { return m_abandonQuestPanel; }
|
|
set { m_abandonQuestPanel = value; }
|
|
}
|
|
|
|
public UITextField abandonQuestNameText
|
|
{
|
|
get { return m_abandonQuestNameText; }
|
|
set { m_abandonQuestNameText = value; }
|
|
}
|
|
|
|
public bool showDisplayNameInHeading
|
|
{
|
|
get { return m_showDisplayNameInHeading; }
|
|
set { m_showDisplayNameInHeading = value; }
|
|
}
|
|
|
|
public bool showDialogueContentIfNoJournalContent
|
|
{
|
|
get { return m_showDialogueContentIfNoJournalContent; }
|
|
set { m_showDialogueContentIfNoJournalContent = value; }
|
|
}
|
|
|
|
public bool showQuestsThatHaveNoContent
|
|
{
|
|
get { return m_showQuestsThatHaveNoContent; }
|
|
set { m_showQuestsThatHaveNoContent = value; }
|
|
}
|
|
|
|
public bool showFirstQuestDetailsOnOpen
|
|
{
|
|
get { return m_showFirstQuestDetailsOnOpen; }
|
|
set { m_showFirstQuestDetailsOnOpen = value; }
|
|
}
|
|
|
|
#endregion Accessor Properties for Serialized Fields
|
|
|
|
#region Runtime Properties
|
|
|
|
protected UnityUIInstancedContentManager selectionPanelContentManager { get; set; }
|
|
protected UnityUIInstancedContentManager detailsPanelContentManager { get; set; }
|
|
protected bool isDrawingSelectionPanel { get; set; }
|
|
|
|
protected override RectTransform currentContentContainer
|
|
{ get { return isDrawingSelectionPanel ? questSelectionContentContainer : questDetailsContentContainer; } }
|
|
|
|
protected override UnityUIInstancedContentManager currentContentManager
|
|
{ get { return isDrawingSelectionPanel ? selectionPanelContentManager : detailsPanelContentManager; } }
|
|
|
|
protected override UnityUITextTemplate currentHeadingTemplate
|
|
{ get { return isDrawingSelectionPanel ? null : questHeadingTextTemplate; } }
|
|
|
|
protected override UnityUITextTemplate[] currentSubheadingTemplates
|
|
{ get { return subheadingTemplates; } }
|
|
|
|
protected override UnityUITextTemplate currentBodyTemplate
|
|
{ get { return isDrawingSelectionPanel ? null : questBodyTextTemplate; } }
|
|
|
|
protected override UnityUIIconListTemplate currentIconListTemplate
|
|
{ get { return isDrawingSelectionPanel ? null : iconListTemplate; } }
|
|
|
|
protected override UnityUIButtonListTemplate currentButtonListTemplate
|
|
{ get { return isDrawingSelectionPanel ? null : buttonListTemplate; } }
|
|
|
|
protected List<string> expandedGroupNames = new List<string>();
|
|
protected Quest selectedQuest { get; set; }
|
|
protected QuestJournal questJournal { get; set; }
|
|
|
|
private Coroutine m_refreshCoroutine = null;
|
|
|
|
private bool m_mustSendCloseMessage = false;
|
|
private bool m_hasInitialized = false;
|
|
|
|
private TMP_Text currentText;
|
|
|
|
private List<bUnityUIQuestNameButtonTemplate> questTemplates = new();
|
|
private List<QuestState> visibleQuestStates = new();
|
|
|
|
#endregion Runtime Properties
|
|
|
|
protected override void Awake()
|
|
{
|
|
base.Awake();
|
|
selectionPanelContentManager = new UnityUIInstancedContentManager();
|
|
detailsPanelContentManager = new UnityUIInstancedContentManager();
|
|
m_hasInitialized = true;
|
|
}
|
|
|
|
protected virtual void OnDisable()
|
|
{
|
|
m_refreshCoroutine = null;
|
|
}
|
|
|
|
protected override void InitializeTemplates()
|
|
{
|
|
if (Debug.isDebugBuild)
|
|
{
|
|
if (mainPanel == null) Debug.LogError("Quest Machine: Main Panel is unassigned.", this);
|
|
if (questSelectionContentContainer == null) Debug.LogError("Quest Machine: Quest Selection Content Container is unassigned.", this);
|
|
if (questGroupTemplate == null) Debug.LogError("Quest Machine: Quest Group Template is unassigned.", this);
|
|
if (activeQuestNameTemplate == null) Debug.LogError("Quest Machine: Active Quest Name Template is unassigned.", this);
|
|
if (succededQuestNameTemplate == null && showSuccededQuests) Debug.LogError("Quest Machine: Succeded Quest Name Template is unassigned.", this);
|
|
if (failedQuestNameTemplate == null && showFailedQuests) Debug.LogError("Quest Machine: Failed Quest Name Template is unassigned.", this);
|
|
if (questDetailsContentContainer == null) Debug.LogError("Quest Machine: Quest Details Content Container is unassigned.", this);
|
|
if (questHeadingTextTemplate == null) Debug.LogError("Quest Machine: Quest Heading Text Template is unassigned.", this);
|
|
if (questBodyTextTemplate == null) Debug.LogError("Quest Machine: Quest Body Text Template is unassigned.", this);
|
|
if (iconListTemplate == null) Debug.LogError("Quest Machine: Icon List Template is unassigned.", this);
|
|
if (iconListTemplate != null && iconListTemplate.iconTemplate == null) Debug.LogError("Quest Machine: Icon List Template's Icon Template is unassigned.", this);
|
|
if (buttonListTemplate == null) Debug.LogError("Quest Machine: Button List Template is unassigned.", this);
|
|
if (buttonListTemplate != null && buttonListTemplate.buttonTemplate == null) Debug.LogError("Quest Machine: Button List Template's Button Template is unassigned.", this);
|
|
if (abandonQuestPanel == null) Debug.LogError("Quest Machine: Abandon Quest Panel is unassigned.", this);
|
|
if (abandonQuestNameText == null) Debug.LogError("Quest Machine: Abandon Quest Name Text is unassigned.", this);
|
|
}
|
|
if (questGroupTemplate != null) questGroupTemplate.gameObject.SetActive(false);
|
|
if (activeQuestNameTemplate != null) activeQuestNameTemplate.gameObject.SetActive(false);
|
|
if (succededQuestNameTemplate != null) succededQuestNameTemplate.gameObject.SetActive(false);
|
|
if (failedQuestNameTemplate != null) failedQuestNameTemplate.gameObject.SetActive(false);
|
|
if (questHeadingTextTemplate != null) questHeadingTextTemplate.gameObject.SetActive(false);
|
|
if (questBodyTextTemplate != null) questBodyTextTemplate.gameObject.SetActive(false);
|
|
if (iconListTemplate != null) iconListTemplate.gameObject.SetActive(false);
|
|
if (buttonListTemplate != null) buttonListTemplate.gameObject.SetActive(false);
|
|
if (abandonButtonTemplate != null) abandonButtonTemplate.gameObject.SetActive(false);
|
|
if (trackButtonTemplate != null) trackButtonTemplate.gameObject.SetActive(false);
|
|
}
|
|
|
|
public virtual void Toggle(QuestJournal questJournal)
|
|
{
|
|
if (isVisible)
|
|
{
|
|
Hide();
|
|
}
|
|
else
|
|
{
|
|
Show(questJournal);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// True if the group is expanded in the UI.
|
|
/// </summary>
|
|
public virtual bool IsGroupExpanded(string groupName)
|
|
{
|
|
return alwaysExpandAllGroups || expandedGroupNames.Contains(groupName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Toggles whether a group is expanded or not.
|
|
/// </summary>
|
|
/// <param name="groupName">Group to toggle.</param>
|
|
public virtual void ToggleGroup(string groupName)
|
|
{
|
|
if (IsGroupExpanded(groupName))
|
|
{
|
|
expandedGroupNames.Remove(groupName);
|
|
}
|
|
else
|
|
{
|
|
expandedGroupNames.Add(groupName);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Opens the quest journal UI.
|
|
/// </summary>
|
|
public virtual void Show(QuestJournal questJournal)
|
|
{
|
|
this.questJournal = questJournal;
|
|
Show();
|
|
Repaint();
|
|
m_mustSendCloseMessage = ShouldSendOpenCloseMessage();
|
|
if (ShouldSendOpenCloseMessage()) MessageSystem.SendMessage(this, m_openMessage, string.Empty);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Opens the quest journal UI, showing a specified quest's details.
|
|
/// </summary>
|
|
public virtual void Show(QuestJournal questJournal, Quest quest)
|
|
{
|
|
Show(questJournal);
|
|
SelectQuest(quest);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Opens the quest journal UI, showing a specified quest's details.
|
|
/// </summary>
|
|
public virtual void Show(QuestJournal questJournal, StringField questID)
|
|
{
|
|
Show(questJournal);
|
|
if (questJournal != null) SelectQuest(questJournal.FindQuest(questID));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Opens the quest journal UI, showing a specified quest's details.
|
|
/// </summary>
|
|
public virtual void Show(QuestJournal questJournal, string questID)
|
|
{
|
|
Show(questJournal);
|
|
if (questJournal != null) SelectQuest(questJournal.FindQuest(questID));
|
|
}
|
|
|
|
public override void Hide()
|
|
{
|
|
base.Hide();
|
|
if (m_mustSendCloseMessage) MessageSystem.SendMessage(this, m_closeMessage, string.Empty);
|
|
m_mustSendCloseMessage = false;
|
|
}
|
|
|
|
private bool ShouldSendOpenCloseMessage()
|
|
{
|
|
switch (m_sendMessageOnOpen)
|
|
{
|
|
case SendMessageOnOpen.Always:
|
|
return true;
|
|
|
|
case SendMessageOnOpen.Never:
|
|
return false;
|
|
|
|
case SendMessageOnOpen.NotWhenUsingMouse:
|
|
return InputDeviceManager.currentInputDevice != InputDevice.Mouse;
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
protected virtual Quest GetFirstQuest()
|
|
{
|
|
if (questJournal.questList == null) //shouldnt really happen
|
|
{
|
|
return null;
|
|
}
|
|
SetVisibleQuestStates();
|
|
|
|
if (visibleQuestStates.Contains(QuestState.Active))
|
|
{
|
|
return null;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private void SetVisibleQuestStates()
|
|
{
|
|
visibleQuestStates = new();
|
|
if (showActiveQuests)
|
|
{
|
|
visibleQuestStates.Add(QuestState.Active);
|
|
}
|
|
|
|
if (showSuccededQuests)
|
|
{
|
|
visibleQuestStates.Add(QuestState.Successful);
|
|
}
|
|
|
|
if (showFailedQuests)
|
|
{
|
|
visibleQuestStates.Add(QuestState.Failed);
|
|
visibleQuestStates.Add(QuestState.Abandoned);
|
|
}
|
|
}
|
|
|
|
public virtual void Repaint(QuestJournal questJournal)
|
|
{
|
|
this.questJournal = questJournal;
|
|
Repaint();
|
|
}
|
|
|
|
public virtual void Repaint()
|
|
{
|
|
// if (!(isVisible && enabled && gameObject.activeInHierarchy)) return;
|
|
RefreshNow();
|
|
}
|
|
|
|
private IEnumerator RefreshAtEndOfFrame()
|
|
{
|
|
// Wait until end of frame so we only refresh once in case we receive multiple
|
|
// requests to refresh during the same frame.
|
|
yield return new WaitForEndOfFrame();
|
|
m_refreshCoroutine = null;
|
|
RefreshNow();
|
|
}
|
|
|
|
protected virtual void RefreshNow() //[TODO] Consider pooling.
|
|
{
|
|
isDrawingSelectionPanel = true;
|
|
questTemplates = new();
|
|
questGroups = new();
|
|
selectionPanelContentManager.Clear();
|
|
SetVisibleQuestStates();
|
|
RefreshHeading();
|
|
List<string> groupNames;
|
|
int numGroupless;
|
|
GetGroupNames(out groupNames, out numGroupless);
|
|
AddQuestsToUI(groupNames, numGroupless);
|
|
RefreshQuestsContent();
|
|
RefreshNavigableSelectables();
|
|
}
|
|
|
|
public void RefreshQuestsContent()
|
|
{
|
|
SetVisibleQuestStates();
|
|
|
|
questTemplates.ForEach(quest =>
|
|
{
|
|
quest.gameObject.SetActive(false);
|
|
quest.gameObject.SetActive(visibleQuestStates.Contains(quest.state));
|
|
});
|
|
questGroups.ForEach(group => LayoutRebuilder.ForceRebuildLayoutImmediate(group.interiorPanel));
|
|
|
|
List<bUnityUIQuestNameButtonTemplate> activeQuests = questTemplates.Where(quest => quest.gameObject.activeInHierarchy).ToList();
|
|
|
|
if (activeQuests.Count > 0 && showFirstQuestDetailsOnOpen)
|
|
{
|
|
bUnityUIButtonTemplate questButton = activeQuests[0].buttonTemplate;
|
|
questButton.onHoverEvent?.Invoke();
|
|
}
|
|
}
|
|
|
|
protected virtual void RefreshHeading()
|
|
{
|
|
if (entityImage != null) entityImage.sprite = questJournal.image;
|
|
if (showDisplayNameInHeading && entityName != null && !StringField.IsNullOrEmpty(questJournal.displayName)) entityName.text = questJournal.displayName.value;
|
|
}
|
|
|
|
protected virtual void GetGroupNames(out List<string> groupNames, out int numGroupless)
|
|
{
|
|
groupNames = new List<string>();
|
|
numGroupless = 0;
|
|
foreach (var quest in questJournal.questList)
|
|
{
|
|
if (quest == null) continue;
|
|
if (!quest.isTrackable) continue;
|
|
var questState = quest.GetState();
|
|
if (questState == QuestState.WaitingToStart) continue;
|
|
if (!showCompletedQuests && IsCompletedQuestState(questState)) continue;
|
|
var groupName = StringField.GetStringValue(quest.group);
|
|
if (string.IsNullOrEmpty(groupName)) numGroupless++;
|
|
if (string.IsNullOrEmpty(groupName) || groupNames.Contains(groupName)) continue;
|
|
groupNames.Add(groupName);
|
|
}
|
|
SortGroupNames(groupNames);
|
|
}
|
|
|
|
/// <summary>
|
|
/// You can override this method to sort differently.
|
|
/// </summary>
|
|
protected virtual void SortGroupNames(List<string> groupNames)
|
|
{
|
|
if (m_sortAlphabetically)
|
|
{
|
|
groupNames.Sort();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// You can override this method to sort differently.
|
|
/// </summary>
|
|
protected virtual void SortQuests(List<Quest> quests)
|
|
{
|
|
if (m_sortAlphabetically)
|
|
{
|
|
quests.Sort((x, y) => string.Compare(StringField.GetStringValue(x.title), StringField.GetStringValue(y.title)));
|
|
}
|
|
}
|
|
|
|
protected virtual bool IsCompletedQuestState(QuestState questState)
|
|
{
|
|
return questState == QuestState.Successful || questState == QuestState.Failed || questState == QuestState.Abandoned;
|
|
}
|
|
|
|
protected virtual bool IsActiveQuestState(QuestState questState)
|
|
{
|
|
return questState == QuestState.Active;
|
|
}
|
|
|
|
private bool IsSuccessfulQuestState(QuestState questState)
|
|
{
|
|
return questState == QuestState.Successful;
|
|
}
|
|
|
|
private bool IsFailedQuestState(QuestState questState)
|
|
{
|
|
return questState is QuestState.Abandoned or QuestState.Failed;
|
|
}
|
|
|
|
protected virtual void AddQuestsToUI(List<string> groupNames, int numGroupless)
|
|
{
|
|
var quests = new List<Quest>(questJournal.questList);
|
|
SortQuests(quests);
|
|
|
|
AddGroupedQuestsToUI(quests, groupNames);
|
|
if (numGroupless > 0)
|
|
{
|
|
AddQuestsToUI(quests, string.Empty, questSelectionContentContainer);
|
|
}
|
|
}
|
|
|
|
private void AddQuestsToUI()
|
|
{
|
|
var quests = new List<Quest>(questJournal.questList);
|
|
foreach (var quest in quests)
|
|
{
|
|
string questGroupName = StringField.GetStringValue(quest.group);
|
|
foreach (var group in questGroups)
|
|
{
|
|
if (questGroupName == group.name)
|
|
{
|
|
AddQuestToUI(quest, group.interiorPanel);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected virtual void AddGroupedQuestsToUI(List<Quest> quests, List<string> groupNames)
|
|
{
|
|
foreach (var groupName in groupNames)
|
|
{
|
|
AddQuestGroupToUI(quests, groupName);
|
|
}
|
|
}
|
|
|
|
private List<bUnityUIFoldoutTemplate> questGroups = new();
|
|
|
|
protected void AddQuestGroupToUI(List<Quest> quests, string groupName)
|
|
{
|
|
// Add foldout for group:
|
|
var groupFoldout = Instantiate<bUnityUIFoldoutTemplate>(questGroupTemplate);
|
|
questGroups.Add(groupFoldout);
|
|
selectionPanelContentManager.Add(groupFoldout, questSelectionContentContainer);
|
|
groupFoldout.Assign(groupName, IsGroupExpanded(groupName));
|
|
if (alwaysExpandAllGroups)
|
|
{
|
|
groupFoldout.foldoutButton.interactable = false;
|
|
}
|
|
else
|
|
{
|
|
groupFoldout.foldoutButton.interactable = true;
|
|
groupFoldout.foldoutButton.onClick.AddListener(() => { OnClickGroup(groupName, groupFoldout); });
|
|
}
|
|
|
|
// Add group's questTemplates:
|
|
AddQuestsToUI(quests, groupName, groupFoldout.interiorPanel);
|
|
}
|
|
|
|
/// <summary>
|
|
/// shouldnt be needed
|
|
/// </summary>
|
|
protected virtual void AddGrouplessQuestsToUI()
|
|
{
|
|
foreach (var quest in questJournal.questList)
|
|
{
|
|
if (quest.GetState() == QuestState.WaitingToStart) continue;
|
|
var groupName = StringField.GetStringValue(quest.group);
|
|
if (!string.IsNullOrEmpty(groupName)) continue;
|
|
var questName = Instantiate<bUnityUIQuestNameButtonTemplate>(GetQuestNameTemplateForState(quest.GetState()));
|
|
questName.Assign(quest, OnToggleTracking);
|
|
selectionPanelContentManager.Add(questName, questSelectionContentContainer);
|
|
var target = quest;
|
|
SetupQuestNameUIEvents(questName.buttonTemplate, target);
|
|
}
|
|
}
|
|
|
|
protected virtual void AddQuestsToUI(List<Quest> quests, string requiredGroupName, RectTransform container)
|
|
{
|
|
AddQuestsToUI(quests, requiredGroupName, container, true);
|
|
}
|
|
|
|
protected virtual void AddQuestsToUI(List<Quest> quests, string requiredGroupName, RectTransform container, bool onlyAddActive)
|
|
{
|
|
foreach (var quest in quests)
|
|
{
|
|
if (quest == null) continue;
|
|
var questState = quest.GetState();
|
|
if (questState == QuestState.WaitingToStart) continue;
|
|
var groupName = StringField.GetStringValue(quest.group);
|
|
if (string.Equals(groupName, requiredGroupName))
|
|
{
|
|
AddQuestToUI(quest, container);
|
|
}
|
|
}
|
|
this.questTemplates.OrderBy(quest => (int)quest.state);
|
|
}
|
|
|
|
protected virtual void AddQuestToUI(Quest quest, RectTransform container)
|
|
{
|
|
if (quest == null || container == null) return;
|
|
if (!showQuestsThatHaveNoContent)
|
|
{
|
|
var contents = GetQuestContents(quest);
|
|
if (contents == null || contents.Count <= 1) return;
|
|
}
|
|
var questName = Instantiate(GetQuestNameTemplateForState(quest.GetState()));
|
|
questTemplates.Add(questName);
|
|
questName.Assign(quest, OnToggleTracking);
|
|
selectionPanelContentManager.Add(questName, container);
|
|
var target = quest;
|
|
SetupQuestNameUIEvents(questName.buttonTemplate, target);
|
|
}
|
|
|
|
private void SetupQuestNameUIEvents(bUnityUIButtonTemplate buttonTemplate, Quest target)
|
|
{
|
|
if (buttonTemplate == null || target == null) return;
|
|
buttonTemplate.onHoverEvent.AddListener(() => { OnClickQuest(target); });
|
|
buttonTemplate.onHoverEvent.AddListener(() => { ChangeText(buttonTemplate); });
|
|
}
|
|
|
|
public void ChangeText(bUnityUIButtonTemplate buttonTemplate)
|
|
{
|
|
if (!buttonTemplate) return;
|
|
|
|
if (currentText)
|
|
{
|
|
currentText.color = bItemSlot.GetDefaultButtonTextColor();
|
|
}
|
|
|
|
currentText = buttonTemplate.captionText.textMeshProUGUI;
|
|
currentText.color = bItemSlot.GetSelectedButtonTextColor();
|
|
}
|
|
|
|
private bUnityUIQuestNameButtonTemplate GetQuestNameTemplateForState(QuestState state)
|
|
{
|
|
switch (state)
|
|
{
|
|
case QuestState.WaitingToStart:
|
|
break;
|
|
|
|
case QuestState.Active:
|
|
return activeQuestNameTemplate;
|
|
break;
|
|
|
|
case QuestState.Successful:
|
|
return succededQuestNameTemplate;
|
|
break;
|
|
|
|
case QuestState.Failed:
|
|
return failedQuestNameTemplate;
|
|
break;
|
|
|
|
case QuestState.Abandoned:
|
|
break;
|
|
|
|
case QuestState.Disabled:
|
|
break;
|
|
|
|
default:
|
|
return activeQuestNameTemplate;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
protected virtual void OnClickGroup(string groupName, bUnityUIFoldoutTemplate groupFoldout)
|
|
{
|
|
ToggleGroup(groupName);
|
|
groupFoldout.ToggleInterior();
|
|
}
|
|
|
|
protected virtual void OnClickQuest(Quest quest)
|
|
{
|
|
SelectQuest(quest);
|
|
}
|
|
|
|
public virtual void SelectQuest(Quest quest)
|
|
{
|
|
selectedQuest = quest;
|
|
RepaintSelectedQuest();
|
|
}
|
|
|
|
protected virtual void RepaintSelectedQuest()
|
|
{
|
|
if (!m_hasInitialized) return;
|
|
isDrawingSelectionPanel = false;
|
|
currentContentManager.Clear();
|
|
currentIconList = null;
|
|
currentButtonList = null;
|
|
|
|
if (selectedQuest != null)
|
|
{
|
|
questImage.sprite = selectedQuest.icon;
|
|
var contents = GetQuestContents(selectedQuest);
|
|
|
|
if (IsActiveQuestState(selectedQuest.GetState()))
|
|
{
|
|
activeImage.enabled = true;
|
|
completedImage.enabled = false;
|
|
failedImage.enabled = false;
|
|
}
|
|
else if (IsSuccessfulQuestState(selectedQuest.GetState()))
|
|
{
|
|
activeImage.enabled = false;
|
|
completedImage.enabled = true;
|
|
failedImage.enabled = false;
|
|
}
|
|
else
|
|
{
|
|
activeImage.enabled = false;
|
|
completedImage.enabled = false;
|
|
failedImage.enabled = true;
|
|
}
|
|
|
|
questDescriptionTitle.text = selectedQuest.group.text;
|
|
AddContents(contents);
|
|
StartCoroutine(UpdateSliderPositionCoroutine());
|
|
var isQuestActive = selectedQuest.GetState() == QuestState.Active;
|
|
var showTrack = showTrackButtonInDetails && isQuestActive && selectedQuest.isTrackable;
|
|
var showAbandon = isQuestActive && selectedQuest.isAbandonable;
|
|
if (trackButtonTemplate != null) trackButtonTemplate.gameObject.SetActive(showTrack);
|
|
if (abandonButtonTemplate != null) abandonButtonTemplate.gameObject.SetActive(showAbandon);
|
|
if (m_questDetailsButtonContainer != null) m_questDetailsButtonContainer.transform.SetAsLastSibling();
|
|
|
|
if (m_questDetailsButtonContainer == null) m_questDetailsButtonContainer = null; // Silence warning about never assigned.
|
|
}
|
|
isDrawingSelectionPanel = true;
|
|
|
|
RefreshNavigableSelectables();
|
|
}
|
|
|
|
private IEnumerator UpdateSliderPositionCoroutine()
|
|
{
|
|
contentSlider.value = 1;
|
|
yield return new WaitForSecondsRealtime(Time.unscaledDeltaTime);
|
|
contentSlider.value = 1;
|
|
yield return new WaitForSecondsRealtime(Time.unscaledDeltaTime);
|
|
contentSlider.value = 1;
|
|
}
|
|
|
|
protected virtual List<QuestContent> GetQuestContents(Quest quest)
|
|
{
|
|
var contents = quest.GetContentList(QuestContentCategory.Journal);
|
|
if (contents.Count == 0 && showDialogueContentIfNoJournalContent) contents = quest.GetContentList(QuestContentCategory.Dialogue);
|
|
return contents;
|
|
}
|
|
|
|
public void OnToggleTracking(bool value, object data)
|
|
{
|
|
var quest = data as Quest;
|
|
if (quest == null) return;
|
|
quest.showInTrackHUD = value;
|
|
QuestMachineMessages.RefreshUIs(quest);
|
|
}
|
|
|
|
public void ToggleTracking()
|
|
{
|
|
if (selectedQuest != null && selectedQuest.isTrackable)
|
|
{
|
|
OnToggleTracking(!selectedQuest.showInTrackHUD, selectedQuest);
|
|
}
|
|
}
|
|
|
|
public void OpenAbandonQuestConfirmationDialog()
|
|
{
|
|
if (abandonQuestPanel == null || selectedQuest == null) return;
|
|
if (abandonQuestNameText != null) abandonQuestNameText.text = StringField.GetStringValue(selectedQuest.title);
|
|
abandonQuestPanel.Open();
|
|
}
|
|
|
|
public void ConfirmAbandonQuest()
|
|
{
|
|
if (questJournal == null) return;
|
|
questJournal.AbandonQuest(selectedQuest);
|
|
Repaint();
|
|
}
|
|
}
|
|
} |