using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using RPGCreationKit; using UnityEditorInternal; namespace RPGCreationKit { public class FactionsWindow : EditorWindow { List allFactions = new List(); Vector2 indexesScrollView; Vector2 contentScrollView; Vector2 alliedRListScrollView; Vector2 hostileRListScrollView; GUIStyle guiLayoutDarkColor = new GUIStyle(); GUIStyle guiLayoutLightColor = new GUIStyle(); SerializedObject serializedObject; bool hasSelectedFaction = false; int selectedFactionIndex = -1; bool isCreatingNewFaction = false; Texture refreshButtonIcon; public ReorderableList alliedFactionsRList; public ReorderableList hostileFactionRList; public bool isReady = false; [MenuItem("RPG Creation Kit/Factions Editor")] public static void ShowWindow() { EditorWindow thisWindow = GetWindow(typeof(FactionsWindow)); // Set Title Texture icon = AssetDatabase.LoadAssetAtPath(EditorIconsPath.FactionEditorIcon); GUIContent titleContent = new GUIContent("Factions Editor", icon); thisWindow.titleContent = titleContent; thisWindow.minSize = new Vector2(865, 575); thisWindow.maxSize = new Vector2(865, 575); } void Init() { guiLayoutDarkColor.normal.background = MakeTex(600, 1, new Color(5.0f, 5.0f, 5.0f, .1f)); guiLayoutLightColor.normal.background = MakeTex(600, 1, new Color(37.0f, 79.0f, 133.0f, .4f)); refreshButtonIcon = AssetDatabase.LoadAssetAtPath(EditorIconsPath.RefreshButton); RefreshFactionList(); isReady = true; } private Texture2D MakeTex(int width, int height, Color col) { Color[] pix = new Color[width * height]; for (int i = 0; i < pix.Length; i++) pix[i] = col; Texture2D result = new Texture2D(width, height); result.SetPixels(pix); result.Apply(); return result; } public void RefreshFactionList() { allFactions = GetAllFactions(); allFactions.Sort(SortByID); } private void OnGUI() { if (!isReady) Init(); GUIStyle ButtonStyle = new GUIStyle(GUI.skin.button) { alignment = TextAnchor.MiddleCenter }; ButtonStyle.border = new RectOffset(2, 2, 2, 2); ButtonStyle.fontSize = 16; ButtonStyle.font = (Font)AssetDatabase.LoadAssetAtPath("Assets/RPG Creation Kit/Fonts/monofonto.ttf"); GUIStyle HeaderStyle = new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleLeft }; HeaderStyle.fontSize = 14; HeaderStyle.font = (Font)AssetDatabase.LoadAssetAtPath("Assets/RPG Creation Kit/Fonts/monofonto.ttf"); GUIStyle TitleStyle = new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleLeft }; TitleStyle.fontSize = 20; TitleStyle.font = (Font)AssetDatabase.LoadAssetAtPath("Assets/RPG Creation Kit/Fonts/monofonto.ttf"); EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginVertical("box", GUILayout.MaxWidth(200.0f), GUILayout.ExpandWidth(false)); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("FACTIONS", HeaderStyle, GUILayout.MaxWidth(165.0f), GUILayout.ExpandWidth(false)); if (GUILayout.Button(new GUIContent(refreshButtonIcon, "Refreshes the Factions list."), GUILayout.MaxWidth(32))) RefreshFactionList(); EditorGUILayout.EndHorizontal(); indexesScrollView = EditorGUILayout.BeginScrollView(indexesScrollView, GUIStyle.none, GUI.skin.verticalScrollbar, GUILayout.Width(200.0f), GUILayout.Height(500.0f)); indexesScrollView.x = (indexesScrollView.x / 2); Rect clickArea = EditorGUILayout.BeginVertical(guiLayoutDarkColor, GUILayout.Width(200.0f), GUILayout.Height(500.0f)); Event current = Event.current; GUI.enabled = !isCreatingNewFaction; Color defaultColor = GUI.color; // Display all current quest stages for (int i = 0; i < allFactions.Count; i++) { if (selectedFactionIndex == i && hasSelectedFaction) GUI.color = Color.green; GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button(allFactions[i].ID, GUILayout.MaxWidth(170.0f))) { GUI.FocusControl(null); selectedFactionIndex = i; hasSelectedFaction = true; OnSelectedFactionChanges(); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUI.color = defaultColor; } GUI.enabled = true; if (!isCreatingNewFaction) { // DROPDOWN TO CREATE NEW STAGES if (clickArea.Contains(current.mousePosition) && current.type == EventType.ContextClick) { GenericMenu menu = new GenericMenu(); menu.AddDisabledItem(new GUIContent("Factions")); menu.AddSeparator(""); menu.AddItem(new GUIContent("New"), false, CreateNew); menu.AddItem(new GUIContent("Delete Selected"), false, DeleteSelected); menu.ShowAsContext(); current.Use(); } void CreateNew() { Debug.Log("Creating new Faction"); } void DeleteSelected() { if (hasSelectedFaction) Debug.Log("Deleting: " + allFactions[selectedFactionIndex].ID); } } EditorGUILayout.EndScrollView(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); if (hasSelectedFaction && serializedObject != null) { EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); float previousWidth = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = this.position.width - 200; EditorGUILayout.LabelField("Faction: " + serializedObject.FindProperty("ID").stringValue, TitleStyle); EditorGUIUtility.labelWidth = previousWidth; GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); GUILayout.Space(20); contentScrollView = EditorGUILayout.BeginScrollView(contentScrollView, GUIStyle.none, GUI.skin.verticalScrollbar, GUILayout.Width(650.0f), GUILayout.Height(500.0f)); EditorGUILayout.PropertyField(serializedObject.FindProperty("ID"), GUILayout.MaxWidth(350)); EditorGUILayout.PropertyField(serializedObject.FindProperty("factionName"), GUILayout.MaxWidth(350)); EditorGUILayout.PropertyField(serializedObject.FindProperty("friendlyFire"), GUILayout.MaxWidth(350)); GUILayout.Space(50); EditorGUILayout.BeginHorizontal(); #region close alliedFactionsRList.elementHeight = EditorGUIUtility.singleLineHeight * 2f; alliedRListScrollView = EditorGUILayout.BeginScrollView(alliedRListScrollView, GUIStyle.none, GUI.skin.verticalScrollbar, GUILayout.Width(300.0f), GUILayout.Height(250.0f)); alliedFactionsRList.DoLayoutList(); alliedFactionsRList.drawHeaderCallback = (Rect rect) => { EditorGUI.LabelField(rect, "Allied Factions", HeaderStyle); }; alliedFactionsRList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { var factionElement = alliedFactionsRList.serializedProperty.GetArrayElementAtIndex(index).FindPropertyRelative("faction"); var dispositionElement = alliedFactionsRList.serializedProperty.GetArrayElementAtIndex(index).FindPropertyRelative("disposition"); rect.y -= 12; EditorGUI.LabelField(rect, "Faction:"); rect.x += 200; EditorGUI.LabelField(rect, "Disposition:"); rect.x -= 200; rect.y += 30; EditorGUI.PropertyField( new Rect(rect.x, rect.y, 190, EditorGUIUtility.singleLineHeight), factionElement, GUIContent.none); rect.x += 200; EditorGUI.PropertyField( new Rect(rect.x, rect.y, 40, EditorGUIUtility.singleLineHeight), dispositionElement, GUIContent.none); }; EditorGUILayout.EndScrollView(); GUILayout.Space(10); hostileFactionRList.elementHeight = EditorGUIUtility.singleLineHeight * 2f; hostileRListScrollView = EditorGUILayout.BeginScrollView(hostileRListScrollView, GUIStyle.none, GUI.skin.verticalScrollbar, GUILayout.Width(300.0f), GUILayout.Height(250.0f)); hostileFactionRList.DoLayoutList(); hostileFactionRList.drawHeaderCallback = (Rect rect) => { EditorGUI.LabelField(rect, "Hostile Factions", HeaderStyle); }; hostileFactionRList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { var factionElement = hostileFactionRList.serializedProperty.GetArrayElementAtIndex(index).FindPropertyRelative("faction"); var dispositionElement = hostileFactionRList.serializedProperty.GetArrayElementAtIndex(index).FindPropertyRelative("disposition"); rect.y -= 12; EditorGUI.LabelField(rect, "Faction:"); rect.x += 200; EditorGUI.LabelField(rect, "Disposition:"); rect.x -= 200; rect.y += 30; EditorGUI.PropertyField( new Rect(rect.x, rect.y, 190, EditorGUIUtility.singleLineHeight), factionElement, GUIContent.none); rect.x += 200; EditorGUI.PropertyField( new Rect(rect.x, rect.y, 40, EditorGUIUtility.singleLineHeight), dispositionElement, GUIContent.none); }; EditorGUILayout.EndScrollView(); #endregion EditorGUILayout.EndHorizontal(); GUILayout.Space(25); EditorGUILayout.HelpBox("The Disposition controls how much the Faction likes/hate this faction. A Disposition of 100 in an Allied Faction means that the said faction will behave at the best, while 0 means they will be neutral. A Disposition of 100 in an Hostile faction means they will be neutral, while they will fight to death if it is 0.", MessageType.Info, true); EditorGUILayout.EndScrollView(); EditorGUILayout.EndVertical(); } EditorGUILayout.EndVertical(); GUILayout.BeginHorizontal(); if (GUILayout.Button("SAVE", ButtonStyle)) { serializedObject.ApplyModifiedProperties(); } if (GUILayout.Button("SAVE & CLOSE", ButtonStyle)) { serializedObject.ApplyModifiedProperties(); this.Close(); } if (GUILayout.Button("CANCEL", ButtonStyle)) { this.Close(); } GUILayout.EndHorizontal(); } void OnSelectedFactionChanges() { // Create a new object of this race serializedObject = new SerializedObject(allFactions[selectedFactionIndex]); alliedFactionsRList = new ReorderableList(serializedObject, serializedObject.FindProperty("alliedFactions"), true, true, true, true); hostileFactionRList = new ReorderableList(serializedObject, serializedObject.FindProperty("hostileFactions"), true, true, true, true); } private static int SortByID(Faction f1, Faction f2) { return f1.ID.CompareTo(f1.ID); } public static List GetAllFactions() where T : Faction { string[] guids = AssetDatabase.FindAssets("t:" + typeof(T).Name); List a = new List(guids.Length); for (int i = 0; i < guids.Length; i++) { string path = AssetDatabase.GUIDToAssetPath(guids[i]); a.Add(AssetDatabase.LoadAssetAtPath(path)); } return a; } } }