Quest.cs
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
public class Quest : IEquatable<Quest> {
public Quest() { }
public int m_questID = 0;
public string m_questName = "";
public QuestState m_questState = QuestState.Unavailable;
public int m_levelRequirement = 0;
public List<int> m_prerequisiteQuestsByID = new List<int>();
public List<QuestItemDetails> m_prerequisiteItemsByID = new List<QuestItemDetails>();
public int m_questEntityID = -1;
public bool m_openOnAvailable = false;
public bool m_openOnCanComplete = false;
public string m_questAvailableText = "";
public string m_questActiveText = "";
public string m_questCompleteText = "";
public string m_questIncompleteText = "";
public string m_introSubtitleID = "";
public string m_outroSubtitleID = "";
public bool m_progress = false;
public List<QuestItemDetails> m_requiredItemsByID = new List<QuestItemDetails>();
public List<QuestItemDetails> m_rewardItemsByID = new List<QuestItemDetails>();
public int m_questDuration = 0;
public int m_questCooldown = 0;
public bool m_questExpires = false;
public string m_questExpiryDate = "";
public string m_questAvailableTimestamp = "";
public string m_questActiveTimestamp = "";
public string m_questCompleteTimestamp = "";
public string m_questFailedTimestamp = "";
public bool Equals(Quest other)
{
return (m_questID == other.m_questID);
}
public DateTime GetExpiryDate()
{
return DateTime.ParseExact(m_questExpiryDate, "MMM d, yyyy", null).AddDays(1);
}
}
public class Quests
{
public Quests() { }
public Quest[] m_questData;
public int[] m_entryPointsByID;
}
[Serializable]
public class QuestItemDetails : IEquatable<QuestItemDetails>, IComparable<QuestItemDetails>
{
public QuestItemDetails() { }
public int m_quantity = 1;
public string m_itemID = "";
public string m_altText = "";
public int m_awardedByEntityID = -1;
public float m_frequency = 1f;
public string m_orderModifier = "";
public float m_progress = 0f;
public bool Equals(QuestItemDetails other)
{
return (m_itemID == other.m_itemID);
}
public int CompareTo(QuestItemDetails other)
{
return m_itemID.CompareTo(other.m_itemID);
}
}
public enum QuestState {
Unavailable = 0,
Available = 1,
Active = 2,
CanComplete = 3,
Complete = 4,
Incomplete = 5,
CanFail = 6,
Failed = 7
}
public class QuestAttribute : PropertyAttribute
{
public QuestAttribute()
{
}
}
QuestEditorWindow.cs
using UnityEditor;
using UnityEngine;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using JsonFx.Json;
[InitializeOnLoad]
public class QuestEditorWindow : EditorWindow
{
static QuestEditorWindow()
{
Init();
}
private static QuestEditorWindow s_instance;
[MenuItem("Secret Relics/Quest Editor")]
public static void OpenWindow()
{
EditorWindow.GetWindow(
typeof(QuestEditorWindow),
false,
"Quest Editor"
);
}
public static void DeleteQuestByID(int id)
{
if (m_hasInit)
{
m_questData.m_quests.RemoveAll(item => item.m_questID == id);
foreach (QuestData qd in m_questData.m_quests)
{
qd.m_prerequisiteQuestsByID.RemoveAll(item => item == id);
}
m_questData.BuildQuestDictionary(true);
}
}
public static QuestData GetQuestByID(int id)
{
if (m_hasInit)
{
m_questData.BuildQuestDictionary();
if (m_questData.m_questDictionary.ContainsKey(id))
{
return m_questData.m_questDictionary[id];
}
else
{
string s = "Could not find Quest with ID: " + id + " Total QuestData: " + m_questData.m_questDictionary.Count.ToString();
foreach (KeyValuePair<int, QuestData> kvp in m_questData.m_questDictionary)
{
s += "\n ID: " + kvp.Key.ToString();
}
Debug.Log(s);
}
}
return null;
}
public static QuestEntityData GetQuestEntityByID(int id)
{
if (m_hasInit)
{
m_questData.BuildQuestEntityDictionary();
if (m_questData.m_questEntityDictionary.ContainsKey(id))
{
return m_questData.m_questEntityDictionary[id];
}
else
{
Debug.LogError("Could not find Quest Entity with ID: " + id);
}
}
return null;
}
public static MapEntityData GetMapEntityByID(int id)
{
if (m_hasInit)
{
m_questData.BuildMapEntityDictionary();
if (m_questData.m_mapEntityDictionary.ContainsKey(id))
{
return m_questData.m_mapEntityDictionary[id];
}
MapEntityData med = GetQuestEntityByID(id) as MapEntityData;
if (med != null)
{
return med;
}
}
Debug.LogError("Could not find Map Entity with ID: " + id);
return null;
}
public static string[] GetQuestNameArray()
{
if (m_hasInit)
{
m_questData.BuildQuestDictionary();
return m_questData.m_questNameArray;
}
Debug.Log("<color=red>Could not build Quest Name Array</color>");
QuestEditorWindow.Init();
return new string[] { "none selected" };
}
public static int[] GetQuestIDArray()
{
if (m_hasInit)
{
m_questData.BuildQuestDictionary();
return m_questData.m_questIDArray;
}
Debug.Log("<color=red>Could not build Quest ID Array</color>");
QuestEditorWindow.Init();
return new int[] { -1 };
}
public static string[] GetQuestEntityNameArray()
{
if (m_hasInit)
{
m_questData.BuildQuestEntityDictionary();
return m_questData.m_questEntityNameArray;
}
Debug.Log("<color=red>Could not build Quest Entity Name Array</color>");
QuestEditorWindow.Init();
return new string[] { "none selected" };
}
public static int[] GetQuestEntityIDArray()
{
if (m_hasInit)
{
m_questData.BuildQuestEntityDictionary();
return m_questData.m_questEntityIDArray;
}
Debug.Log("<color=red>Could not build Quest Entity ID Array</color>");
QuestEditorWindow.Init();
return new int[]{-1};
}
public static string[] GetMapEntityNameArray()
{
if (m_hasInit)
{
m_questData.BuildMapEntityDictionary();
return m_questData.m_mapEntityNameArray;
}
Debug.Log("<color=red>Could not build Map Entity Name Array</color>");
QuestEditorWindow.Init();
return new string[] { "none selected" };
}
public static int[] GetMapEntityIDArray()
{
if (m_hasInit)
{
m_questData.BuildMapEntityDictionary();
return m_questData.m_mapEntityIDArray;
}
Debug.Log("<color=red>Could not build Map Entity ID Array</color>");
QuestEditorWindow.Init();
return new int[] { -1 };
}
public static string[] GetAllEntityNameArray()
{
if (m_hasInit)
{
m_questData.BuildQuestEntityDictionary();
m_questData.BuildMapEntityDictionary();
return m_questData.m_allEntityNameArray;
}
Debug.Log("<color=red>Could not build All Entity Name Array</color>");
QuestEditorWindow.Init();
return new string[] { "none selected" };
}
public static int[] GetAllEntityIDArray()
{
if (m_hasInit)
{
m_questData.BuildQuestEntityDictionary();
m_questData.BuildMapEntityDictionary();
return m_questData.m_allEntityIDArray;
}
Debug.Log("<color=red>Could not build All Entity ID Array</color>");
QuestEditorWindow.Init();
return new int[] { -1 };
}
public static InventoryItem GetItemByID(string id)
{
if (m_hasInit)
{
InventoryItem foundItem = null;
foreach (var item in m_allItems.m_inventoryItems)
{
if (item.m_ID.Equals(id))
{
foundItem = item;
break;
}
}
return foundItem;
}
return null;
}
public static void ForceReInit()
{
m_hasInit = false;
Init();
}
private void OnDestory()
{
SaveEditorPrefrences();
}
private void OnLostFocus()
{
SaveEditorPrefrences();
}
private void OnFocus()
{
QuestEditorWindow.Init();
CheckEntities();
}
private void OnDidOpenScene()
{
m_startScene = "";
}
public void CheckEntities()
{
if (Application.isPlaying || EditorApplication.isPlaying)
{
Debug.Log("Did not Check Entities");
return;
}
if (!File.Exists(Application.dataPath.Substring(0, Application.dataPath.IndexOf("/Assets") + 1) + m_questData.m_gameMapPath))
{
Debug.LogError("Could not check entities in " + m_questData.m_gameMapPath);
return;
}
if (m_startScene != EditorApplication.currentScene && EditorApplication.currentScene != m_questData.m_gameMapPath && !Application.isPlaying)
{
EditorUtilityx.InScene(m_questData.m_gameMapPath, UpdateEntities);
m_startScene = EditorApplication.currentScene;
}
else if (EditorApplication.currentScene == m_questData.m_gameMapPath)
{
UpdateEntities(EditorApplication.currentScene);
m_startScene = EditorApplication.currentScene;
}
}
public void UpdateEntities(string scenePath)
{
MapEntityManager mem = FindObjectOfType<MapEntityManager>() as MapEntityManager;
if (mem == null)
{
Debug.LogError("Could not find MapEntityManager in " + scenePath);
return;
}
if (m_questData.m_questEntities == null)
{
m_questData.m_questEntities = new List<QuestEntityData>();
}
if (m_questData.m_mapEntities == null)
{
m_questData.m_mapEntities = new List<MapEntityData>();
}
List<int> validQuestEntityIDs = new List<int>();
List<int> validMapEntityIDs = new List<int>();
foreach (MapEntity me in mem.m_mapEntities)
{
if (me.EntityType != typeof(QuestEntity))
{
MapEntityData med = new MapEntityData();
med.m_name = me.name;
med.m_ID = me.m_id;
validMapEntityIDs.Add(me.m_id);
int mIndex = m_questData.m_mapEntities.FindIndex(item => item.m_ID == med.m_ID);
if (mIndex >= 0)
{
m_questData.m_mapEntities[mIndex] = med;
}
else
{
m_questData.m_mapEntities.Add(med);
m_questData.AddMapEntityToDictionary(med);
}
continue;
}
QuestEntity qe = me as QuestEntity;
QuestEntityData qed = new QuestEntityData();
qed.m_name = qe.name;
qed.m_ID = qe.m_id;
validQuestEntityIDs.Add(qe.m_id);
int qIndex = m_questData.m_questEntities.FindIndex(item => item.m_ID == qed.m_ID);
if (qIndex >= 0)
{
m_questData.m_questEntities[qIndex] = qed;
}
else
{
m_questData.m_questEntities.Add(qed);
m_questData.AddQuestEntityToDictionary(qed);
}
}
m_questData.m_questEntities.RemoveAll(item => !validQuestEntityIDs.Contains(item.m_ID));
m_questData.m_mapEntities.RemoveAll(item => !validMapEntityIDs.Contains(item.m_ID));
m_questData.BuildQuestEntityDictionary(true);
m_questData.BuildMapEntityDictionary(true);
}
private Rect m_questGraphSmallRect
{
get
{
m_questGraphSmallRectx.width = 0;
m_questGraphSmallRectx.height = 0;
foreach (QuestData qd in m_questData.m_quests)
{
if (qd.m_editorSmallRect.x + qd.m_editorSmallRect.width > m_questGraphSmallRectx.width)
{
m_questGraphSmallRectx.width = qd.m_editorSmallRect.x + qd.m_editorSmallRect.width + 200f;
}
if (qd.m_editorSmallRect.y + qd.m_editorSmallRect.height > m_questGraphSmallRectx.height)
{
m_questGraphSmallRectx.height = qd.m_editorSmallRect.y + qd.m_editorSmallRect.height + 200f;
}
}
return m_questGraphSmallRectx;
}
}
private static Rect m_questGraphSmallRectx;
private static InventoryItemList m_allItems = null;
private static QuestManagerData m_questData = null;
private static bool m_hasInit = false;
private static string m_startScene = "";
private static GUISkin m_editorSkin = null;
private static void Init()
{
if (m_hasInit)
{
return;
}
if (m_editorSkin == null)
{
m_editorSkin = (GUISkin)(Resources.LoadAssetAtPath("Assets/GameScripts/Quests/Editor/_Data/QuestEditorWindowSkin.guiskin", typeof(GUISkin)));
}
if (m_allItems == null)
{
m_allItems = EditorCustomAssets.GetOrCreateAsset<InventoryItemList>("Assets/InventoryItems/AllItems.asset", true);
}
if (m_questData == null)
{
m_questData = EditorCustomAssets.GetOrCreateAsset<QuestManagerData>("Assets/GameScripts/Quests/Editor/_Data/QuestManagerData.asset", true);
if (m_questData == null)
{
return; // QuestData can be null when Unity is recompiling or trying to play
}
}
if (string.IsNullOrEmpty(m_questData.m_gameMapPath))
{
m_questData.m_gameMapPath = "Assets/Scenes/GameMap.unity";
}
if (m_questData.m_quests == null || m_questData.m_quests.Count <= 0)
{
m_questData.m_quests = new List<QuestData>();
}
if (m_questData.m_questDictionary == null || m_questData.m_questDictionary.Count <= 0)
{
m_questData.BuildQuestDictionary(true);
}
if (m_questData.m_questEntityDictionary == null || m_questData.m_questEntityDictionary.Count <= 0)
{
m_questData.BuildQuestEntityDictionary();
}
if (m_questData.m_mapEntityDictionary == null || m_questData.m_mapEntityDictionary.Count <= 0)
{
m_questData.BuildMapEntityDictionary();
}
if (m_questData.m_quests == null || m_questData.m_quests.Count <= 0 ||
m_questData.m_questDictionary == null || m_questData.m_questDictionary.Count <= 0 ||
m_questData.m_questEntityDictionary == null || m_questData.m_questEntityDictionary.Count <= 0 ||
m_questData.m_mapEntityDictionary == null || m_questData.m_mapEntityDictionary.Count <= 0)
{
Debug.Log("<color=white>The <color=#FF6600>Quest Editor</color> has not been initialized. Open the <color=#FF6600>Quest Editor</color> to have all <color=#336600>[Quest]</color> and <color=#336600>[QuestEntity]</color> properties displayed correctly</color>");
}
else
{
Debug.Log("<color=white>The <color=#FF6600>Quest Editor</color> has been </color><color=green>initialized.</color>");
m_hasInit = true;
}
}
private static IEnumerator _DelayedReInit(float delay)
{
Debug.Log("Started Delayed Init");
float runningTime = 0f;
while (runningTime < delay)
{
runningTime += Time.deltaTime;
yield return null;
}
Debug.Log("Force ReInit Delayed Init!");
ForceReInit();
}
private void LoadEditorPrefrences()
{
}
private void SaveEditorPrefrences()
{
}
private void OnGUI()
{
QuestEditorWindow.Init();
wantsMouseMove = true;
if (m_editorSkin == null)
{
m_editorSkin = (GUISkin)(Resources.LoadAssetAtPath("Assets/GameScripts/Quests/Editor/_Data/QuestEditorWindowSkin.guiskin", typeof(GUISkin)));
}
GUI.skin = m_editorSkin;
BeginWindows();
// Quest List
m_questlistRect = GUI.Window(0, new Rect(0, 0, m_questlistRect.width, position.height), DrawQuestList, "Quest List");
// Toolbar
GUI.Window(1, new Rect(m_questlistRect.width, 0, position.width - m_questlistRect.width, 50), DrawToolbar, "Toolbar");
// Quest Graph
DrawQuestGraph();
// Cancel - Adding Prerequesite Quest Event
if (Event.current.type == EventType.MouseDown &&
Event.current.button == 1 &&
QuestData.m_addingPrerequisiteQuest)
{
QuestData.m_addingPrerequisiteQuest = false;
}
EndWindows();
}
private void Update()
{
UpdateQuestList();
}
#region Toolbar
private void Draw(int windowIndex)
{
GUI.DragWindow();
}
private void DrawToolbar(int windowIndex)
{
GUILayout.BeginHorizontal();
if (GUILayout.Button("New Quest"))
{
m_questData.NewQuest(m_questgraphScrollPos.x, m_questgraphScrollPos.y);
}
GUILayout.FlexibleSpace();
if (GUILayout.Button("Re-Init"))
{
ForceReInit();
}
if (GUILayout.Button("Save"))
{
m_questData.Save();
AssetDatabase.SaveAssets();
EditorUtility.SetDirty(m_questData);
/* // Might be needed to make the saving work better - used in item builder
EditorUtility.FocusProjectWindow();
Selection.activeObject = item;
*/
}
GUILayout.EndHorizontal();
}
#endregion
#region Quest List
private Vector2 m_questlistScrollPos = Vector2.zero;
private Rect m_questlistRect = new Rect(0, 0, 200, 100);
private void DrawQuestList(int windowIndex)
{
m_questlistScrollPos = GUILayout.BeginScrollView(m_questlistScrollPos);
GUILayout.BeginVertical();
GUILayout.EndVertical();
GUILayout.EndScrollView();
GUI.DragWindow();
}
private void UpdateQuestList()
{
if (m_questlistRect.x != 0)
{
m_questlistRect.width += m_questlistRect.x;
m_questlistRect.width = Mathf.Clamp(m_questlistRect.width, 100, 500);
m_questlistRect.x = 0;
}
m_questlistRect.y = -20;
m_questlistRect.height = position.height;
}
#endregion
#region Quest Graph
private Vector2 m_questgraphScrollPos = Vector2.zero;
private Vector2 m_questEditorScrollPos = Vector2.zero;
private Rect m_viewRect = new Rect(0, 0, 0, 0);
private void DrawQuestGraph()
{
m_questgraphScrollPos = GUI.BeginScrollView(new Rect(m_questlistRect.width, 46, position.width - m_questlistRect.width - (QuestData.m_selectedQuestData != null ? QuestData.m_selectedQuestData.m_editorRect.width + 16 : 0), position.height - 46), m_questgraphScrollPos, m_questGraphSmallRect);
Vector2 offset = Vector2.zero;
offset.x = -m_questlistRect.width;
Handles.BeginGUI();
// Draw Lines
foreach (QuestData qd in m_questData.m_quests)
{
if (qd != QuestData.m_selectedQuestData)
{
foreach (int qID in qd.m_prerequisiteQuestsByID)
{
float tangentModifier = 1;
QuestData targetQuest = GetQuestByID(qID);
if (targetQuest == null) // Fail safe for QuestWindow Init
{
//Debug.Log("Quest Graph NULL Quest");
ForceReInit();
GUI.EndScrollView();
Handles.EndGUI();
return;
}
if (qd.m_editorSmallRect.center.y > targetQuest.m_editorSmallRect.center.y)
{
tangentModifier = -1;
}
Handles.DrawBezier(qd.m_editorSmallRect.center, targetQuest.m_editorSmallRect.center,
qd.m_editorSmallRect.center + (tangentModifier * 50f * Vector2.up),
targetQuest.m_editorSmallRect.center + (tangentModifier * -50 * Vector2.up),
targetQuest == QuestData.m_selectedQuestData ? Color.yellow : Color.grey, null, 2f);
}
}
}
// Draw Lines for Selected Quest
if (QuestData.m_selectedQuestData != null)
{
foreach (int qID in QuestData.m_selectedQuestData.m_prerequisiteQuestsByID)
{
float tangentModifier = 1;
QuestData targetQuest = GetQuestByID(qID);
if (targetQuest == null) // Fail safe for QuestWindow Init
{
//Debug.Log("Quest Graph NULL Quest");
ForceReInit();
GUI.EndScrollView();
Handles.EndGUI();
return;
}
if (QuestData.m_selectedQuestData.m_editorSmallRect.center.y > targetQuest.m_editorSmallRect.center.y)
{
tangentModifier = -1;
}
Handles.DrawBezier(QuestData.m_selectedQuestData.m_editorSmallRect.center, targetQuest.m_editorSmallRect.center,
QuestData.m_selectedQuestData.m_editorSmallRect.center + (tangentModifier * 50f * Vector2.up),
targetQuest.m_editorSmallRect.center + (tangentModifier * -50 * Vector2.up),
Color.green, null, 2f);
}
}
// Draw Adding Prerequisite Line
if (QuestData.m_addingPrerequisiteQuest)
{
float tangentModifier = 1;
if (QuestData.m_selectedQuestData.m_editorSmallRect.center.y > Event.current.mousePosition.y)
{
tangentModifier = -1;
}
Handles.DrawBezier(QuestData.m_selectedQuestData.m_editorSmallRect.center, Event.current.mousePosition,
QuestData.m_selectedQuestData.m_editorSmallRect.center + (tangentModifier * 50f * Vector2.up),
Event.current.mousePosition + (tangentModifier * -50 * Vector2.up),
Color.cyan, null, 5f);
}
Handles.EndGUI();
bool setDirty = false;
m_viewRect.width = position.width;
m_viewRect.height = position.height;
m_viewRect.x = m_questgraphScrollPos.x;
m_viewRect.y = m_questgraphScrollPos.y;
foreach (QuestData qd in m_questData.m_quests)
{
if (qd != QuestData.m_selectedQuestData &&
(m_viewRect.Contains(qd.m_editorSmallRect.GetPosition()) || m_viewRect.Contains(qd.m_editorSmallRect.GetPosition() + qd.m_editorSmallRect.GetSize())))
{
qd.DrawSmallQuestWindow();
if (qd.m_setDirty)
{
setDirty = true;
}
}
}
if (QuestData.m_selectedQuestData != null &&
(m_viewRect.Contains(QuestData.m_selectedQuestData.m_editorSmallRect.GetPosition()) || m_viewRect.Contains(QuestData.m_selectedQuestData.m_editorSmallRect.GetPosition() + QuestData.m_selectedQuestData.m_editorSmallRect.GetSize())))
{
QuestData.m_selectedQuestData.DrawSmallQuestWindow();
if (QuestData.m_selectedQuestData == null || QuestData.m_selectedQuestData.m_setDirty)
{
setDirty = true;
}
}
if (setDirty && m_questData != null)
{
EditorUtility.SetDirty(m_questData);
}
Repaint();
GUI.EndScrollView();
m_questEditorScrollPos = GUI.BeginScrollView(new Rect(position.width - (QuestData.m_selectedQuestData != null ? QuestData.m_selectedQuestData.m_editorRect.width + 16 : 0), 46, (QuestData.m_selectedQuestData != null ? QuestData.m_selectedQuestData.m_editorRect.width + 16 : 0), position.height - 46), m_questEditorScrollPos, (QuestData.m_selectedQuestData != null ? QuestData.m_selectedQuestData.m_editorRect : new Rect(0,0,0,0)));
if (QuestData.m_selectedQuestData != null)
{
QuestData.m_selectedQuestData.DrawQuestWindow();
}
GUI.EndScrollView();
}
#endregion
}