// Copyright (c) Pixel Crushers. All rights reserved. using UnityEngine; using System; using System.Collections.Generic; namespace PixelCrushers.QuestMachine { /// /// Information about a specific quest state (Inactive, Active, etc.). /// [Serializable] public class QuestStateInfo { [Tooltip("Run these actions when this state becomes active.")] [SerializeField] private List m_actionList = new List(); [Tooltip("Content for each UI category (dialogue, journal, HUD).")] [SerializeField] private List m_categorizedContentList = new List(); public static int NumContentCategories = Enum.GetNames(typeof(QuestContentCategory)).Length - 3; // Omit Alert, Offer & OfferConditionsUnmet. /// /// Run these actions when this state becomes active. /// public List actionList { get { return m_actionList; } set { m_actionList = value; } } /// /// Contents for each UI category (dialogue, journal, etc.). This list is /// indexed by the int value of the QuestContentCategory enum, such as /// stateInfoList[(int)QuestContentCategory.Dialogue]. /// public List categorizedContentList { get { return m_categorizedContentList; } set { m_categorizedContentList = value; } } /// /// Constructs a new QuestStateInfo instance with empty lists for each /// content category. /// public QuestStateInfo() { if (categorizedContentList.Count >= NumContentCategories) return; for (int i = categorizedContentList.Count; i < NumContentCategories; i++) { categorizedContentList.Add(new QuestContentSet()); } } public void SetRuntimeReferences(Quest quest, QuestNode questNode) { if (actionList != null) { for (int i = 0; i < actionList.Count; i++) { if (actionList[i] != null) actionList[i].SetRuntimeReferences(quest, questNode); } } if (categorizedContentList != null) { for (int i = 0; i < categorizedContentList.Count; i++) { if (categorizedContentList[i] != null) categorizedContentList[i].SetRuntimeReferences(quest, questNode); } } } #region UI Content /// /// Checks if the quest state has any UI content for a specified category. /// /// The content category to check. /// true if there is content. public bool HasContent(QuestContentCategory category) { var contentList = GetContentList(category); return contentList != null && contentList.Count > 0; } /// /// Gets the UI content for a specified category. /// /// The content category for which to get content. /// The UI content. public List GetContentList(QuestContentCategory category) { var i = (int)category; if (categorizedContentList == null || i >= categorizedContentList.Count) return null; return m_categorizedContentList[i].contentList; } #endregion public void CloneSubassetsInto(QuestStateInfo copy) { // Assumes lists are identical except subassets haven't been copied. if (copy == null || copy.categorizedContentList == null) { if (Debug.isDebugBuild) Debug.LogWarning("Quest Machine: QuestStateInfo.CloneSubassetsInto() failed because the destination copy or its content list is null."); } else if (m_actionList == null || m_categorizedContentList == null) { if (Debug.isDebugBuild) Debug.LogWarning("Quest Machine: QuestStateInfo.CloneSubassetsInto() failed because the original state info's action list or content list is null."); } else if (copy.categorizedContentList.Count != m_categorizedContentList.Count) { if (Debug.isDebugBuild) Debug.LogWarning("Quest Machine: QuestStateInfo.CloneSubassetsInto() failed because the destination copy's content list is a different size than the original's."); } else { copy.actionList = QuestSubasset.CloneList(m_actionList); for (int i = 0; i < m_categorizedContentList.Count; i++) { if (copy.categorizedContentList[i] == null) copy.categorizedContentList[i] = new QuestContentSet(); copy.categorizedContentList[i].contentList = QuestSubasset.CloneList(m_categorizedContentList[i].contentList); } } } public void DestroySubassets() { QuestSubasset.DestroyList(actionList); if (categorizedContentList != null) { for (int i = 0; i < categorizedContentList.Count; i++) { categorizedContentList[i].DestroySubassets(); } } } #region Static Helper Methods public static int GetNumQuestStates() { return Enum.GetNames(typeof(QuestState)).Length; } public static int GetNumQuestNodeStates() { return Enum.GetNames(typeof(QuestNodeState)).Length; } public static QuestStateInfo GetStateInfo(List stateInfoList, QuestState questState) { ValidateStateInfoListCount(stateInfoList, GetNumQuestStates()); return stateInfoList[(int)questState]; } public static QuestStateInfo GetStateInfo(List stateInfoList, QuestNodeState questNodeState) { ValidateStateInfoListCount(stateInfoList, GetNumQuestNodeStates()); return stateInfoList[(int)questNodeState]; } public static void ValidateStateInfoListCount(List stateInfoList, int numStates = -1) { if (numStates == -1) numStates = GetNumQuestNodeStates(); // Default: QuestNodeState size. if (stateInfoList.Count >= numStates) return; for (int i = stateInfoList.Count; i < numStates; i++) { stateInfoList.Add(new QuestStateInfo()); } } public static void ValidateCategorizedContentListCount(List categorizedContentList, int numStates = -1) { if (numStates == -1) numStates = 3; // Default: Dialogue, Journal, HUD. if (categorizedContentList.Count >= numStates) return; for (int i = categorizedContentList.Count; i < numStates; i++) { categorizedContentList.Add(new QuestContentSet()); } } public static void CloneSubassets(List original, List copy) { // Assumes lists are identical except subassets haven't been copied. if (original == null) { if (Debug.isDebugBuild) Debug.LogWarning("Quest Machine: QuestStateInfo.CloneSubassets() failed because original is null."); } else if (copy == null) { if (Debug.isDebugBuild) Debug.LogWarning("Quest Machine: QuestStateInfo.CloneSubassets() failed because copy is null."); } else if (copy.Count != original.Count) { if (Debug.isDebugBuild) Debug.LogWarning("Quest Machine: QuestStateInfo.CloneSubassets() failed because original and copy are different sizes."); } else { for (int i = 0; i < original.Count; i++) { original[i].CloneSubassetsInto(copy[i]); } } } public static void DestroyListSubassets(List list) { if (list == null) return; for (int i = 0; i < list.Count; i++) { list[i].DestroySubassets(); } } #endregion } }