protected void DrawSectionMissionEntry(Rect rect, int index, bool isActive, bool isFocused) { var missionIDProperty = List.serializedProperty.GetArrayElementAtIndex(index); KMMission mission = KMMissionTableOfContentsEditor.GetMission(missionIDProperty.stringValue); string sectionLabel = String.Format("{0}.{1}", sectionNum, index + 1); EditorGUI.PrefixLabel(new Rect(rect.x, rect.y, 30, EditorGUIUtility.singleLineHeight), new GUIContent(sectionLabel)); EditorGUI.LabelField( new Rect(rect.x + 30, rect.y, 200, EditorGUIUtility.singleLineHeight), missionIDProperty.stringValue); if (!IsValidMission(missionIDProperty.stringValue)) { EditorGUI.HelpBox(new Rect(rect.x + 30 + 200, rect.y, 200, EditorGUIUtility.singleLineHeight), "Mission not found!", MessageType.Error); } else if (!IsMissionUnique(missionIDProperty.stringValue)) { EditorGUI.HelpBox(new Rect(rect.x + 30 + 200, rect.y, 100, EditorGUIUtility.singleLineHeight), "Duplicate!", MessageType.Warning); } else if (mission != null) { float x = 30 + 200; //Display Name EditorGUI.LabelField(new Rect(rect.x + x, rect.y, 300, EditorGUIUtility.singleLineHeight), mission.DisplayName); x += 300; } }
/// <summary> /// Draws and responds to a toggle box for a component type. Clears Special types, if set. /// </summary> private void DrawToggle(int poolIndex, KMComponentPool.ComponentTypeEnum typeToToggle) { KMMission mission = (KMMission)serializedObject.targetObject; KMComponentPool componentPool = mission.GeneratorSetting.ComponentPools[poolIndex]; bool previousValue = componentPool.ComponentTypes.Contains(typeToToggle); if (EditorGUILayout.ToggleLeft( typeToToggle.ToString(), previousValue)) { if (!componentPool.ComponentTypes.Contains(typeToToggle)) { componentPool.ComponentTypes.Add(typeToToggle); } } else { componentPool.ComponentTypes.RemoveAll(x => x == typeToToggle); } //If we just toggled something, clear any special flags too bool currentValue = componentPool.ComponentTypes.Contains(typeToToggle); if (previousValue != currentValue) { componentPool.SpecialComponentType = KMComponentPool.SpecialComponentTypeEnum.None; } }
private object CreateMission(CustomMission mission) { KMMission template = (KMMission)ScriptableObject.CreateInstance(typeof(KMMission)); template.name = mission.ID; template.DisplayName = mission.Name; template.PacingEventsEnabled = mission.PacingEvents; KMGeneratorSetting generator = new KMGeneratorSetting(); generator.FrontFaceOnly = mission.FrontFaceOnly; generator.NumStrikes = mission.Strikes; generator.TimeLimit = mission.TimeLimit; generator.TimeBeforeNeedyActivation = mission.TimeBeforeNeedyActivation; foreach (var pool in mission.ComponentPools) { KMComponentPool componentpool = ConvertPool(mission, pool); generator.ComponentPools.Add(componentpool); } template.GeneratorSetting = generator; var type = FindType("ModMission"); var instance = ScriptableObject.CreateInstance(type); var InstType = instance.GetType(); InstType.GetMethod("ConfigureFrom", @public).Invoke(instance, new object[] { template, "MissionMaker" }); InstType.GetProperty("name", @public).SetValue(instance, mission.ID, null); //InstType.GetProperty("INVALID_MISSION_ID", BindingFlags.Public | BindingFlags.Static).SetValue(instance, mission.ID, null); // This should block out any kind of records being set for these custom missions. return(instance); }
/// <summary> /// Launches a custom KMMission with the mission id set to 'custom' /// </summary> /// <param name="mission"></param> /// <param name="seed"></param> public void StartMission(KMMission mission, string seed) { if (OnStartCustomMission != null) { OnStartCustomMission(mission, seed); } }
public void RunMission(KMMission mission) { if (CurrentState == KMGameInfo.State.Setup) { GetComponent <KMGameCommands>().StartMission(mission, "-1"); OtherModes.RefreshModes(KMGameInfo.State.Transitioning); } }
public static int CalculateTotalComponents(KMMission mission) { int numComponents = 0; if ((mission.GeneratorSetting != null) && (mission.GeneratorSetting.ComponentPools != null)) { foreach (KMComponentPool pool in mission.GeneratorSetting.ComponentPools) { numComponents += pool.Count; } } return(numComponents); }
public static void CreateNewMission() { if (!AssetDatabase.IsValidFolder("Assets/" + MISSION_FOLDER)) { AssetDatabase.CreateFolder("Assets", MISSION_FOLDER); } KMMission mission = ScriptableObject.CreateInstance <KMMission>(); string path = AssetDatabase.GenerateUniqueAssetPath("Assets/" + MISSION_FOLDER + "/mission.asset"); AssetDatabase.CreateAsset(mission, path); AssetImporter.GetAtPath(path).assetBundleName = AssetBundler.BUNDLE_FILENAME; EditorGUIUtility.PingObject(mission); }
/// <summary> /// Draw the array of mod module names to be selected from. /// </summary> /// <param name="poolIndex"></param> protected void DrawModTypesList(int poolIndex) { KMMission mission = (KMMission)serializedObject.targetObject; KMComponentPool componentPool = mission.GeneratorSetting.ComponentPools[poolIndex]; SerializedProperty componentPools = serializedObject.FindProperty("GeneratorSetting.ComponentPools"); var element = componentPools.GetArrayElementAtIndex(poolIndex); EditorGUILayout.PropertyField(element.FindPropertyRelative("ModTypes"), true); //Clear any special flags if needed if (componentPool.ModTypes != null && componentPool.ModTypes.Count > 0) { componentPool.SpecialComponentType = KMComponentPool.SpecialComponentTypeEnum.None; } }
/// <summary> /// Search the AssetDatabase for all missions. /// </summary> /// <param name="missionID"></param> /// <returns></returns> public static List <KMMission> GetAllMissions() { string[] guids = AssetDatabase.FindAssets("t:KMMission"); List <KMMission> missions = new List <KMMission>(); foreach (string guid in guids) { KMMission mission = AssetDatabase.LoadAssetAtPath <KMMission>(AssetDatabase.GUIDToAssetPath(guid)); if (mission != null) { missions.Add(mission); } } return(missions); }
protected void OnSelect(ReorderableList list) { //Deselect all other section lists, because otherwise each section will have //an active selection int oldIndex = list.index; editor.ClearTableOfContentsSectionSelections(); list.index = oldIndex; SerializedProperty missionIDProperty = list.serializedProperty.GetArrayElementAtIndex(list.index); KMMission mission = KMMissionTableOfContentsEditor.GetMission(missionIDProperty.stringValue); if (mission != null) { EditorGUIUtility.PingObject(mission); } }
bool StartMission() { KMGeneratorSetting generatorSettings = new KMGeneratorSetting(); generatorSettings.NumStrikes = 3; generatorSettings.TimeLimit = time; generatorSettings.ComponentPools = BuildComponentPools(); generatorSettings.OptionalWidgetCount = widgets; KMMission mission = ScriptableObject.CreateInstance <KMMission>() as KMMission; mission.DisplayName = "Custom Freeplay"; mission.GeneratorSetting = generatorSettings; GetComponent <KMGameCommands>().StartMission(mission, "" + UnityEngine.Random.Range(0, int.MaxValue)); return(false); }
/// <summary> /// Search the AssetDatabase for a mission with this ID and return it if it exists. /// </summary> /// <param name="missionID"></param> /// <returns></returns> public static KMMission GetMission(string missionID) { string[] guids = AssetDatabase.FindAssets(string.Format("t:KMMission {0}", missionID)); if (guids.Length > 0) { foreach (string guid in guids) { KMMission mission = AssetDatabase.LoadAssetAtPath <KMMission>(AssetDatabase.GUIDToAssetPath(guid)); if (mission.ID.Equals(missionID)) { return(mission); } } } return(null); }
/// <summary> /// Draws and responds to an enum picker for a special component type. Clears regular and special types, if set. /// </summary> private void DrawSpecialPicker(int poolIndex) { KMMission mission = (KMMission)serializedObject.targetObject; KMComponentPool componentPool = mission.GeneratorSetting.ComponentPools[poolIndex]; KMComponentPool.SpecialComponentTypeEnum previousValue = componentPool.SpecialComponentType; componentPool.SpecialComponentType = (KMComponentPool.SpecialComponentTypeEnum)EditorGUILayout.EnumPopup( "Type:", componentPool.SpecialComponentType, GUILayout.MinWidth(400)); //If we just changed the special type, clear any component types too KMComponentPool.SpecialComponentTypeEnum currentValue = componentPool.SpecialComponentType; if (previousValue != currentValue) { componentPool.ComponentTypes.Clear(); componentPool.ModTypes.Clear(); } }
protected bool IsMissionInTableOfContents(KMMission mission) { bool isInToC = false; KMMissionTableOfContents tableOfContents = (KMMissionTableOfContents)serializedObject.targetObject; foreach (var section in tableOfContents.Sections) { foreach (var missionID in section.MissionIDs) { if (missionID.Equals(mission.ID)) { isInToC = true; break; } } } return(isInToC); }
/// <summary> /// Draws and responds to a picker for a component sources. /// </summary> private void DrawComponentSourcePicker(int poolIndex) { string[] options = new string[] { "Base", "Mods", "Base and Mods" }; KMMission mission = (KMMission)serializedObject.targetObject; KMComponentPool componentPool = mission.GeneratorSetting.ComponentPools[poolIndex]; KMComponentPool.ComponentSource previousValue = componentPool.AllowedSources; bool allowBase = (previousValue & KMComponentPool.ComponentSource.Base) == KMComponentPool.ComponentSource.Base; bool allowMods = (previousValue & KMComponentPool.ComponentSource.Mods) == KMComponentPool.ComponentSource.Mods; int index = 0; if (allowBase) { if (allowMods) { index = 2; } else { index = 0; } } else { index = 1; } index = EditorGUILayout.Popup("Source:", index, options, GUILayout.MinWidth(400)); switch (index) { case 0: { componentPool.AllowedSources = KMComponentPool.ComponentSource.Base; } break; case 1: { componentPool.AllowedSources = KMComponentPool.ComponentSource.Mods; } break; case 2: { componentPool.AllowedSources = KMComponentPool.ComponentSource.Base | KMComponentPool.ComponentSource.Mods; } break; } }
/// <summary> /// Draw the array of mod module names to be selected from. /// </summary> /// <param name="poolIndex"></param> protected void DrawModTypesList(int poolIndex) { KMMission mission = (KMMission)serializedObject.targetObject; KMComponentPool componentPool = mission.GeneratorSetting.ComponentPools[poolIndex]; SerializedProperty componentPools = serializedObject.FindProperty("GeneratorSetting.ComponentPools"); var modTypesElement = componentPools.GetArrayElementAtIndex(poolIndex).FindPropertyRelative("ModTypes"); EditorGUILayout.PropertyField(modTypesElement, true); // Trim whitespace from mod types for (int i = 0; i < modTypesElement.arraySize; i++) { modTypesElement.GetArrayElementAtIndex(i).stringValue = modTypesElement.GetArrayElementAtIndex(i).stringValue.Trim(); } //Clear any special flags if needed if (componentPool.ModTypes != null && componentPool.ModTypes.Count > 0) { componentPool.SpecialComponentType = KMComponentPool.SpecialComponentTypeEnum.None; } }
/// <summary> /// Draws a label summarizing the component types selected, or a warning if none are. /// </summary> /// <param name="componentFlags"></param> private void DrawComponentPoolSummaryLabel(int poolIndex) { KMMission mission = (KMMission)serializedObject.targetObject; KMComponentPool pool = mission.GeneratorSetting.ComponentPools[poolIndex]; string[] nonEmptyModNames = pool.ModTypes.Where(t => !string.IsNullOrEmpty(t)).ToArray(); if (pool.SpecialComponentType != KMComponentPool.SpecialComponentTypeEnum.None) { string specialSummary = string.Format("{0} ({1})", pool.SpecialComponentType.ToString(), pool.AllowedSources.ToString()); EditorGUILayout.LabelField(specialSummary); } else if (pool.ComponentTypes.Count > 0 || nonEmptyModNames.Length > 0) { EditorStyles.label.wordWrap = true; string componentTypeNames = String.Join(", ", pool.ComponentTypes.Select(x => x.ToString()).ToArray()); if (nonEmptyModNames.Length > 0) { if (componentTypeNames.Length > 0) { componentTypeNames += ", "; } componentTypeNames += String.Join(", ", nonEmptyModNames); } EditorGUILayout.LabelField(componentTypeNames); } else { EditorGUILayout.HelpBox("No component type selected!", MessageType.Error); } }
private bool ParseTextToMission(string text, out KMMission mission, out List <string> messages) { messages = new List <string>(); var matches = tokenRegex.Matches(text); if (matches.Count == 0 || (matches.Count == 1 && !matches[0].Value.Any(c => !char.IsWhiteSpace(c))) || matches[matches.Count - 1].Index + matches[matches.Count - 1].Length < text.Length) { messages.Add("Syntax error"); mission = null; return(false); } bool timeSpecified = false, strikesSpecified = false, anySolvableModules = false; mission = ScriptableObject.CreateInstance <KMMission>(); mission.PacingEventsEnabled = true; mission.GeneratorSetting = new KMGeneratorSetting(); List <KMComponentPool> pools = new List <KMComponentPool>(); foreach (Match match in matches) { if (match.Groups["Min"].Success) { if (timeSpecified) { messages.Add("Time specified multiple times"); } else { timeSpecified = true; mission.GeneratorSetting.TimeLimit = (match.Groups["Hr"].Success ? int.Parse(match.Groups["Hr"].Value) * 3600 : 0) + int.Parse(match.Groups["Min"].Value) * 60 + int.Parse(match.Groups["Sec"].Value); if (mission.GeneratorSetting.TimeLimit <= 0) { messages.Add("Invalid time limit"); } } } else if (match.Groups["Strikes"].Success) { if (strikesSpecified) { messages.Add("Strike limit specified multiple times"); } else { strikesSpecified = true; mission.GeneratorSetting.NumStrikes = int.Parse(match.Groups["Strikes"].Value); if (mission.GeneratorSetting.NumStrikes <= 0) { messages.Add("Invalid strike limit"); } } } else if (match.Groups["Setting"].Success) { switch (match.Groups["Setting"].Value.ToLowerInvariant()) { case "strikes": if (match.Groups["Value"].Success) { if (strikesSpecified) { messages.Add("Strike limit specified multiple times"); } else { strikesSpecified = true; mission.GeneratorSetting.NumStrikes = int.Parse(match.Groups["Value"].Value); if (mission.GeneratorSetting.NumStrikes <= 0) { messages.Add("Invalid strike limit"); } } } break; case "needyactivationtime": if (match.Groups["Value"].Success) { mission.GeneratorSetting.TimeBeforeNeedyActivation = int.Parse(match.Groups["Value"].Value); } break; case "widgets": if (match.Groups["Value"].Success) { mission.GeneratorSetting.OptionalWidgetCount = int.Parse(match.Groups["Value"].Value); } break; case "nopacing": mission.PacingEventsEnabled = false; break; case "frontonly": mission.GeneratorSetting.FrontFaceOnly = true; break; } } else if (match.Groups["ID"].Success) { KMComponentPool pool = new KMComponentPool { Count = match.Groups["Count"].Success ? int.Parse(match.Groups["Count"].Value) : 1, ComponentTypes = new List <KMComponentPool.ComponentTypeEnum>(), ModTypes = new List <string>() }; if (pool.Count <= 0) { messages.Add("Invalid module pool count"); } bool allSolvable = true; string list = match.Groups["ID"].Value.Replace("\"", "").Trim(); switch (list) { case "ALL_SOLVABLE": anySolvableModules = true; pool.AllowedSources = KMComponentPool.ComponentSource.Base | KMComponentPool.ComponentSource.Mods; pool.SpecialComponentType = KMComponentPool.SpecialComponentTypeEnum.ALL_SOLVABLE; break; case "ALL_NEEDY": pool.AllowedSources = KMComponentPool.ComponentSource.Base | KMComponentPool.ComponentSource.Mods; pool.SpecialComponentType = KMComponentPool.SpecialComponentTypeEnum.ALL_NEEDY; break; case "ALL_VANILLA": anySolvableModules = true; pool.AllowedSources = KMComponentPool.ComponentSource.Base; pool.SpecialComponentType = KMComponentPool.SpecialComponentTypeEnum.ALL_SOLVABLE; break; case "ALL_MODS": anySolvableModules = true; pool.AllowedSources = KMComponentPool.ComponentSource.Mods; pool.SpecialComponentType = KMComponentPool.SpecialComponentTypeEnum.ALL_SOLVABLE; break; case "ALL_VANILLA_NEEDY": pool.AllowedSources = KMComponentPool.ComponentSource.Base; pool.SpecialComponentType = KMComponentPool.SpecialComponentTypeEnum.ALL_NEEDY; break; case "ALL_MODS_NEEDY": pool.AllowedSources = KMComponentPool.ComponentSource.Mods; pool.SpecialComponentType = KMComponentPool.SpecialComponentTypeEnum.ALL_NEEDY; break; default: foreach (string id in list.Split(',', '+').Select(s => s.Trim())) { switch (id) { case "WireSequence": pool.ComponentTypes.Add(KMComponentPool.ComponentTypeEnum.WireSequence); break; case "Wires": pool.ComponentTypes.Add(KMComponentPool.ComponentTypeEnum.Wires); break; case "WhosOnFirst": pool.ComponentTypes.Add(KMComponentPool.ComponentTypeEnum.WhosOnFirst); break; case "Simon": pool.ComponentTypes.Add(KMComponentPool.ComponentTypeEnum.Simon); break; case "Password": pool.ComponentTypes.Add(KMComponentPool.ComponentTypeEnum.Password); break; case "Morse": pool.ComponentTypes.Add(KMComponentPool.ComponentTypeEnum.Morse); break; case "Memory": pool.ComponentTypes.Add(KMComponentPool.ComponentTypeEnum.Memory); break; case "Maze": pool.ComponentTypes.Add(KMComponentPool.ComponentTypeEnum.Maze); break; case "Keypad": pool.ComponentTypes.Add(KMComponentPool.ComponentTypeEnum.Keypad); break; case "Venn": pool.ComponentTypes.Add(KMComponentPool.ComponentTypeEnum.Venn); break; case "BigButton": pool.ComponentTypes.Add(KMComponentPool.ComponentTypeEnum.BigButton); break; case "NeedyCapacitor": allSolvable = false; pool.ComponentTypes.Add(KMComponentPool.ComponentTypeEnum.NeedyCapacitor); break; case "NeedyVentGas": allSolvable = false; pool.ComponentTypes.Add(KMComponentPool.ComponentTypeEnum.NeedyVentGas); break; case "NeedyKnob": allSolvable = false; pool.ComponentTypes.Add(KMComponentPool.ComponentTypeEnum.NeedyKnob); break; default: if (!((IEnumerable <string>)DynamicMissionGenerator.ModSelectorApi["AllSolvableModules"]).Contains(id) && !((IEnumerable <string>)DynamicMissionGenerator.ModSelectorApi["AllNeedyModules"]).Contains(id)) { messages.Add($"'{id}' is an unknown module ID."); } else if (((IEnumerable <string>)DynamicMissionGenerator.ModSelectorApi["DisabledSolvableModules"]).Contains(id) || ((IEnumerable <string>)DynamicMissionGenerator.ModSelectorApi["DisabledNeedyModules"]).Contains(id)) { messages.Add($"'{id}' is disabled."); } else { if (((IEnumerable <string>)DynamicMissionGenerator.ModSelectorApi["AllNeedyModules"]).Contains(id)) { allSolvable = false; } pool.ModTypes.Add(id); } break; } } break; } if (allSolvable) { anySolvableModules = true; } if (pool.ModTypes.Count == 0) { pool.ModTypes = null; } if (pool.ComponentTypes.Count == 0) { pool.ComponentTypes = null; } pools.Add(pool); } } if (!anySolvableModules) { messages.Add("No regular modules"); } mission.GeneratorSetting.ComponentPools = pools; if (mission.GeneratorSetting.GetComponentCount() > GetMaxModules()) { messages.Add($"Too many modules for any available bomb casing ({mission.GeneratorSetting.GetComponentCount()} specified; {GetMaxModules()} possible)."); } if (messages.Count > 0) { Destroy(mission); mission = null; return(false); } messages = null; mission.DisplayName = "Custom Freeplay"; if (!timeSpecified) { mission.GeneratorSetting.TimeLimit = mission.GeneratorSetting.GetComponentCount() * 120; } if (!strikesSpecified) { mission.GeneratorSetting.NumStrikes = Math.Max(3, mission.GeneratorSetting.GetComponentCount() / 12); } return(true); }
public override void OnInspectorGUI() { if (target != null) { serializedObject.Update(); //Basic mission meta-data EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("ID"); EditorGUILayout.SelectableLabel(serializedObject.targetObject.name); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("ID In-Game"); EditorGUILayout.SelectableLabel(string.Format("mod_{0}_{1}", ModConfig.ID, serializedObject.targetObject.name)); EditorGUILayout.EndHorizontal(); SerializedProperty displayNameProperty = serializedObject.FindProperty("DisplayName"); EditorGUILayout.PropertyField(displayNameProperty); displayNameProperty.stringValue = displayNameProperty.stringValue.Trim(); EditorGUILayout.PropertyField(serializedObject.FindProperty("Description")); EditorGUILayout.PropertyField(serializedObject.FindProperty("PacingEventsEnabled")); SerializedProperty componentPools = serializedObject.FindProperty("GeneratorSetting.ComponentPools"); if (factoryMode <= FactoryMode.FiniteSequenceGlobalTimeStrikes) { int newTotalBombCount = EditorGUILayout.IntField("Bomb Count", totalBombCount); setTotalBombCount(newTotalBombCount); } else { bool wasEnabled = GUI.enabled; GUI.enabled = false; EditorGUILayout.TextField("Bomb Count", "Infinite"); GUI.enabled = wasEnabled; } FactoryMode newFactoryMode = (FactoryMode)EditorGUILayout.Popup("Factory Mode", (int)factoryMode, FactoryModeFriendlyNames); if (newFactoryMode != factoryMode) { if (newFactoryMode == FactoryMode.Static) { if (factoryModeComponentPool != -1) { componentPools.DeleteArrayElementAtIndex(factoryModeComponentPool); readCurrentMission(); } } else if (factoryModeComponentPool == -1) { int index = addComponentPool(serializedObject.FindProperty("GeneratorSetting")); SerializedProperty componentPool = componentPools.GetArrayElementAtIndex(index); componentPool.FindPropertyRelative("Count").intValue = (int)newFactoryMode; componentPool.FindPropertyRelative("ModTypes").arraySize = 1; componentPool.FindPropertyRelative("ModTypes").GetArrayElementAtIndex(0).stringValue = FACTORY_MODE_COMPONENT_POOL_ID; factoryModeComponentPool = index; } else { componentPools.GetArrayElementAtIndex(factoryModeComponentPool).FindPropertyRelative("Count").intValue = (int)newFactoryMode; } if (newFactoryMode >= FactoryMode.InfiniteSequence) { setTotalBombCount(1); } factoryMode = newFactoryMode; } //Generator Settings EditorGUILayout.Separator(); EditorGUILayout.LabelField("Generator Settings"); List <string> unusedGeneratorSettings = new List <string>(); List <KeyValuePair <int, string> > tabMap = new List <KeyValuePair <int, string> >(); tabMap.Add(new KeyValuePair <int, string>(0, "Bomb 0")); foreach (KeyValuePair <int, KeyValuePair <KMGeneratorSetting, int> > kv in multipleBombsGeneratorSettings) { if (kv.Key < totalBombCount || factoryMode >= FactoryMode.InfiniteSequence) { tabMap.Add(new KeyValuePair <int, string>(kv.Key, "Bomb " + kv.Key)); } else { unusedGeneratorSettings.Add(kv.Key.ToString()); } } tabMap.Sort((x, y) => x.Key.CompareTo(y.Key)); if (unusedGeneratorSettings.Count > 0) { string unusedGeneratorSettingsWarningMessage = "The mission contains unused generator settings (for " + (unusedGeneratorSettings.Count > 1 ? "bombs " + string.Join(", ", unusedGeneratorSettings.ToArray()) : "bomb " + unusedGeneratorSettings[0]) + ")."; EditorGUILayout.HelpBox(unusedGeneratorSettingsWarningMessage, MessageType.Warning); } EditorGUILayout.BeginVertical("box"); int currentTab = activeGeneratorSetting != -1 ? tabMap.FindIndex((x) => x.Key == activeGeneratorSetting) : tabMap.Count; if (currentTab == -1) { activeGeneratorSetting = 0; currentTab = 0; } List <string> tabs = new List <string>(); tabs.Add(tabMap[0].Value); float minWidth = new GUIStyle("ButtonLeft").CalcSize(new GUIContent(tabMap[0].Value)).x; for (int i = 1; i < tabMap.Count; i++) { tabs.Add(tabMap[i].Value); float width = new GUIStyle("Button").CalcSize(new GUIContent(tabMap[i].Value)).x; if (width > minWidth) { minWidth = width; } } tabs.Add("+"); bool fits = Screen.width / tabs.Count > minWidth; //Screen.width is not an accurate measure of the available width but having the bar space always visible was too ugly if (!fits) { scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition, GUILayout.Height(40)); } int newTab = GUILayout.Toolbar(currentTab, tabs.ToArray()); if (!fits) { EditorGUILayout.EndScrollView(); } if (newTab != currentTab) { if (newTab == tabs.Count - 1) { activeGeneratorSetting = -1; } else { activeGeneratorSetting = tabMap[newTab].Key; activeComponentPool = -1; GUIUtility.keyboardControl = 0; } } if (activeGeneratorSetting == -1) { if (factoryMode <= FactoryMode.FiniteSequenceGlobalTimeStrikes) { List <int> vaildBombs = new List <int>(); for (int i = 1; i < totalBombCount; i++) { if (!multipleBombsGeneratorSettings.ContainsKey(i)) { vaildBombs.Add(i); } } if (vaildBombs.Count == 0) { EditorGUILayout.HelpBox("All of the bombs have a Generator Setting.", MessageType.None); } else { if (!vaildBombs.Contains(currentAddGeneratorSettingIndex)) { currentAddGeneratorSettingIndex = vaildBombs[0]; } EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Add Generator Setting for bomb"); currentAddGeneratorSettingIndex = vaildBombs[EditorGUILayout.Popup(vaildBombs.IndexOf(currentAddGeneratorSettingIndex), vaildBombs.Select((x) => x.ToString()).ToArray(), GUILayout.Width(60))]; EditorGUILayout.EndHorizontal(); } bool wasEnabled = GUI.enabled; GUI.enabled = vaildBombs.Count != 0; if (GUILayout.Button("Add Generator Setting")) { addGeneratorSetting(currentAddGeneratorSettingIndex); } GUI.enabled = wasEnabled; } else { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Add Generator Setting for bomb"); currentAddGeneratorSettingIndex = EditorGUILayout.IntField(currentAddGeneratorSettingIndex, GUILayout.Width(60)); EditorGUILayout.EndHorizontal(); bool isVaildBomb = currentAddGeneratorSettingIndex != 0 && !multipleBombsGeneratorSettings.ContainsKey(currentAddGeneratorSettingIndex); if (!isVaildBomb) { EditorGUILayout.HelpBox("Bomb " + currentAddGeneratorSettingIndex + " already has a Generator Setting.", MessageType.None); } bool wasEnabled = GUI.enabled; GUI.enabled = isVaildBomb; if (GUILayout.Button("Add Generator Setting")) { addGeneratorSetting(currentAddGeneratorSettingIndex); } GUI.enabled = wasEnabled; } } else if (activeGeneratorSetting == 0) { bool wasEnabled = GUI.enabled; GUI.enabled = false; EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Button("Delete"); EditorGUILayout.EndHorizontal(); GUI.enabled = wasEnabled; drawGeneratorSetting(serializedObject.FindProperty("GeneratorSetting"), true); } else { EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); bool delete = GUILayout.Button("Delete"); EditorGUILayout.EndHorizontal(); if (delete) { removeGeneratorSetting(activeGeneratorSetting); } else { KeyValuePair <KMGeneratorSetting, int> activeKV = multipleBombsGeneratorSettings[activeGeneratorSetting]; KMMission dummyMission = CreateInstance <KMMission>(); dummyMission.GeneratorSetting = activeKV.Key; SerializedObject dummyMissionObject = new SerializedObject(dummyMission); drawGeneratorSetting(dummyMissionObject.FindProperty("GeneratorSetting"), false); if (dummyMissionObject.ApplyModifiedProperties()) { serializedObject.FindProperty("GeneratorSetting").FindPropertyRelative("ComponentPools").GetArrayElementAtIndex(activeKV.Value).FindPropertyRelative("ModTypes").GetArrayElementAtIndex(0).stringValue = "Multiple Bombs:" + activeGeneratorSetting + ":" + JsonConvert.SerializeObject(activeKV.Key); } } } EditorGUILayout.EndVertical(); } serializedObject.ApplyModifiedProperties(); }
public static string GetDmgString(KMMission mission) { string result = ""; // Mission doc comments result += string.Format("//// {0}\n{1}\n\n", mission.DisplayName, mission.Description.Trim().Split('\n').Select(line => "/// " + line.Trim()) .Join("\n")); // No pacing events if (!mission.PacingEventsEnabled) { result += "nopacing\n"; } // Bomb settings result += GetBombSettingsString(mission.GeneratorSetting) + "\n"; // Pools string pools = ""; List <KMGeneratorSetting> otherBombs = new List <KMGeneratorSetting>(); mission.GeneratorSetting.ComponentPools.ForEach(pool => { // Factory mode if (pool.ModTypes.Contains("Factory Mode")) { string factoryMode; if (pool.Count < 0 || pool.Count >= FactoryModes.Length) { Debug.LogError("Invalid factory mode"); return; } factoryMode = FactoryModes[pool.Count]; result += string.Format("factory:{0}\n", factoryMode); } // Multiple Bombs bomb count else if (pool.ModTypes.Contains("Multiple Bombs")) { // ignore } // Multiple Bombs bomb JSON else if (pool.ModTypes.Count == 1 && pool.ModTypes[0].StartsWith("Multiple Bombs")) { otherBombs.Add( JsonConvert.DeserializeObject <KMGeneratorSetting>(pool.ModTypes[0].Split(new[] { ':' }, 3)[2])); } // Normal pool else { pools += GetPoolDmgString(pool) + "\n"; } }); // Determine whether to output as Multiple Bombs or as a single bomb if (otherBombs.Count != 0) { // Create bomb sets var bombSets = new List <Pair <int, KMGeneratorSetting> > { new Pair <int, KMGeneratorSetting> { First = 1, Second = mission.GeneratorSetting } }; // Group equal bombs foreach (var bomb in otherBombs) { if (bomb.SameMission(bombSets.Last().Second)) { bombSets.Last().First++; } else { bombSets.Add(new Pair <int, KMGeneratorSetting> { First = 1, Second = bomb }); } } result = result.TrimEnd(); // Output each bomb result = bombSets.Aggregate(result, (current, bomb) => current + ("\n\n" + (bomb.First != 1 ? bomb.First + "*" : "") + "(\n" + Indent((GetBombSettingsString(bomb.Second, mission.GeneratorSetting) + "\n\n" + bomb.Second.ComponentPools.FilterPools() .Select(GetPoolDmgString).Join("\n")).Trim()) + "\n)")); } else { result += "\n" + pools.TrimEnd(); } return(result); }