diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 506630b5..495f47ca 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -446,15 +446,15 @@ namespace NewHorizons if (!foundFile) Logger.LogWarning($"{mod.ModHelper.Manifest.Name} has a folder for translations but none were loaded"); } - public NewHorizonsBody LoadConfig(IModBehaviour mod, string relativeDirectory) + public NewHorizonsBody LoadConfig(IModBehaviour mod, string relativePath) { NewHorizonsBody body = null; try { - var config = mod.ModHelper.Storage.Load(relativeDirectory); + var config = mod.ModHelper.Storage.Load(relativePath); if (config == null) { - Logger.LogError($"Couldn't load {relativeDirectory}. Is your Json formatted correctly?"); + Logger.LogError($"Couldn't load {relativePath}. Is your Json formatted correctly?"); return null; } @@ -479,11 +479,11 @@ namespace NewHorizons // Has to happen after we make sure theres a system config config.MigrateAndValidate(); - body = new NewHorizonsBody(config, mod, relativeDirectory); + body = new NewHorizonsBody(config, mod, relativePath); } catch (Exception e) { - Logger.LogError($"Error encounter when loading {relativeDirectory}: {e.Message} {e.StackTrace}"); + Logger.LogError($"Error encounter when loading {relativePath}: {e.Message} {e.StackTrace}"); } return body; diff --git a/NewHorizons/Utility/DebugMenu/DebugMenu.cs b/NewHorizons/Utility/DebugMenu/DebugMenu.cs index ca306e27..c33e77f5 100644 --- a/NewHorizons/Utility/DebugMenu/DebugMenu.cs +++ b/NewHorizons/Utility/DebugMenu/DebugMenu.cs @@ -28,17 +28,16 @@ namespace NewHorizons.Utility.DebugMenu static bool openMenuOnPause; static bool staticInitialized; - // menu params + // Menu params internal static IModBehaviour loadedMod = null; internal Dictionary loadedConfigFiles = new Dictionary(); private bool saveButtonUnlocked = false; private Vector2 recentModListScrollPosition = Vector2.zero; - // submenus + // Submenus private List submenus; private int activeSubmenu = 0; - private static JsonSerializerSettings jsonSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, @@ -55,7 +54,6 @@ namespace NewHorizons.Utility.DebugMenu new DebugMenuNomaiText() }; - submenus.ForEach((submenu) => submenu.OnAwake(this)); } @@ -89,6 +87,7 @@ namespace NewHorizons.Utility.DebugMenu pauseMenuButton = Main.Instance.ModHelper.Menus.PauseMenu.OptionsButton.Duplicate(TranslationHandler.GetTranslation("Toggle Dev Tools Menu", TranslationHandler.TextType.UI).ToUpper()); InitMenu(); } + public static void UpdatePauseMenuButton() { if (pauseMenuButton != null) @@ -99,11 +98,11 @@ namespace NewHorizons.Utility.DebugMenu } private void RestoreMenuOpennessState() { menuOpen = openMenuOnPause; } + private void ToggleMenu() { menuOpen = !menuOpen; openMenuOnPause = !openMenuOnPause; } private void CloseMenu() { menuOpen = false; } - private void OnGUI() { if (!menuOpen) return; @@ -113,8 +112,7 @@ namespace NewHorizons.Utility.DebugMenu GUILayout.BeginArea(new Rect(menuPosition.x, menuPosition.y, EditorMenuSize.x, EditorMenuSize.y), _editorMenuStyle); - // continue working on existing mod - + // Continue working on existing mod GUILayout.Label("Name of your mod"); if (loadedMod == null) { @@ -138,9 +136,9 @@ namespace NewHorizons.Utility.DebugMenu GUILayout.Space(5); - // save your work - - if (loadedMod != null) { + // Save your work + if (loadedMod != null) + { GUILayout.BeginHorizontal(); if (GUILayout.Button(saveButtonUnlocked ? " O " : " | ", GUILayout.ExpandWidth(false))) { @@ -157,23 +155,23 @@ namespace NewHorizons.Utility.DebugMenu } GUILayout.Space(20); - - // draw submenu stuff + + // Draw submenu stuff if (loadedMod != null) { GUILayout.BeginHorizontal(_tabBarStyle); GUILayout.Space(5); - for (int i = 0; i < submenus.Count; i++) + for (int i = 0; i < submenus.Count; i++) { GUI.enabled = i != activeSubmenu; var style = i == activeSubmenu ? _submenuStyle : _tabBarStyle; - if (GUILayout.Button(" "+submenus[i].SubmenuName()+" ", style, GUILayout.ExpandWidth(false))) - { + if (GUILayout.Button(" " + submenus[i].SubmenuName() + " ", style, GUILayout.ExpandWidth(false))) + { GUI.enabled = true; submenus[activeSubmenu].LoseActive(); activeSubmenu = i; submenus[activeSubmenu].GainActive(); - + } GUI.enabled = true; @@ -186,7 +184,6 @@ namespace NewHorizons.Utility.DebugMenu submenus[activeSubmenu].OnGUI(this); GUILayout.EndVertical(); } - GUILayout.EndArea(); } @@ -198,15 +195,16 @@ namespace NewHorizons.Utility.DebugMenu var folder = loadedMod.ModHelper.Manifest.ModFolderPath; - List bodiesForThisMod = Main.BodyDict.Values.SelectMany(x => x).Where(x => x.Mod == loadedMod).ToList(); - foreach (NewHorizonsBody body in bodiesForThisMod) + var bodiesForThisMod = Main.BodyDict.Values.SelectMany(x => x).Where(x => x.Mod == loadedMod).ToList(); + foreach (var body in bodiesForThisMod) { if (body.RelativePath == null) { - Logger.Log("Error loading config for " + body.Config.name + " in " + body.Config.starSystem); + Logger.Log($"Error loading config for {body.Config.name} in {body.Config.starSystem}"); + continue; } - loadedConfigFiles[folder + body.RelativePath] = (body.Config as PlanetConfig); + loadedConfigFiles[folder + body.RelativePath] = body.Config; submenus.ForEach(submenu => submenu.LoadConfigFile(this, body.Config)); } } @@ -215,12 +213,14 @@ namespace NewHorizons.Utility.DebugMenu { submenus.ForEach(submenu => submenu.PreSave(this)); - string backupFolderName = "configBackups\\" + DateTime.Now.ToString("yyyyMMddTHHmmss") + "\\"; + var backupFolderName = $"configBackups\\{DateTime.Now.ToString("yyyyMMddTHHmmss")}\\"; + Logger.Log($"Potentially saving {loadedConfigFiles.Keys.Count} files"); foreach (var filePath in loadedConfigFiles.Keys) { - Logger.Log("Possibly Saving... " + loadedConfigFiles[filePath].name + " @ " + filePath); + Logger.Log($"Possibly Saving... {loadedConfigFiles[filePath].name} @ {filePath}"); + if (loadedConfigFiles[filePath].starSystem != Main.Instance.CurrentStarSystem) continue; var relativePath = filePath.Replace(loadedMod.ModHelper.Manifest.ModFolderPath, ""); @@ -231,14 +231,17 @@ namespace NewHorizons.Utility.DebugMenu try { - Logger.Log("Saving... " + relativePath + " to " + filePath); + Logger.Log($"Saving... {relativePath} to {filePath}"); var path = loadedMod.ModHelper.Manifest.ModFolderPath + relativePath; var directoryName = Path.GetDirectoryName(path); Directory.CreateDirectory(directoryName); File.WriteAllText(path, json); } - catch (Exception e) { Logger.LogError("Failed to save file " + backupFolderName + relativePath); Logger.LogError(e.Message + "\n" + e.StackTrace); } + catch (Exception e) + { + Logger.LogError($"Failed to save file {relativePath}:\n{e.Message}\n{e.StackTrace}"); + } try { @@ -248,7 +251,10 @@ namespace NewHorizons.Utility.DebugMenu File.WriteAllText(path, json); } - catch (Exception e) { Logger.LogError("Failed to save backup file " + backupFolderName + relativePath); Logger.LogError(e.Message + "\n" + e.StackTrace); } + catch (Exception e) + { + Logger.LogError($"Failed to save backup file {backupFolderName}{relativePath}:\n{e.Message}\n{e.StackTrace}"); + } } } @@ -262,7 +268,6 @@ namespace NewHorizons.Utility.DebugMenu pauseMenuButton.OnClick += ToggleMenu; submenus.ForEach(submenu => submenu.OnInit(this)); - _editorMenuStyle = new GUIStyle { diff --git a/NewHorizons/Utility/DebugMenu/DebugMenuPropPlacer.cs b/NewHorizons/Utility/DebugMenu/DebugMenuPropPlacer.cs index b07b99ac..9d61f2f1 100644 --- a/NewHorizons/Utility/DebugMenu/DebugMenuPropPlacer.cs +++ b/NewHorizons/Utility/DebugMenu/DebugMenuPropPlacer.cs @@ -54,7 +54,7 @@ namespace NewHorizons.Utility.DebugMenu internal override void OnBeginLoadMod(DebugMenu debugMenu) { - + } internal override void GainActive() @@ -66,7 +66,7 @@ namespace NewHorizons.Utility.DebugMenu { DebugPropPlacer.active = false; } - + internal override void LoadConfigFile(DebugMenu menu, PlanetConfig config) { _dpp.FindAndRegisterPropsFromConfig(config, propsLoadedFromConfig); @@ -96,17 +96,17 @@ namespace NewHorizons.Utility.DebugMenu GUILayout.Space(5); GUILayout.Space(5); - - + + var arrow = propsCollapsed ? " > " : " v "; if (GUILayout.Button(arrow + "Recently placed objects", menu._tabBarStyle)) propsCollapsed = !propsCollapsed; - if (!propsCollapsed) DrawPropsList(menu); + if (!propsCollapsed) DrawPropsList(menu); GUILayout.Space(5); - + if (_dpp.mostRecentlyPlacedPropGO != null) { - arrow = propPositioningCollapsed ? " > " : " v "; - if (GUILayout.Button(arrow + "Position last placed prop", menu._tabBarStyle)) propPositioningCollapsed = !propPositioningCollapsed; + arrow = propPositioningCollapsed ? " > " : " v "; + if (GUILayout.Button(arrow + "Position last placed prop", menu._tabBarStyle)) propPositioningCollapsed = !propPositioningCollapsed; if (!propPositioningCollapsed) DrawPropsAdustmentControls(menu); } } @@ -114,16 +114,16 @@ namespace NewHorizons.Utility.DebugMenu private void DrawPropsAdustmentControls(DebugMenu menu) { var propPath = _dpp.mostRecentlyPlacedPropPath; - var propPathElements = propPath[propPath.Length-1] == '/' - ? propPath.Substring(0, propPath.Length-1).Split('/') + var propPathElements = propPath[propPath.Length - 1] == '/' + ? propPath.Substring(0, propPath.Length - 1).Split('/') : propPath.Split('/'); string propName = propPathElements[propPathElements.Length - 1]; GUILayout.Label($"Reposition {propName}: "); - + Vector3 latestPropPosDelta = VectorInput(_dpp.mostRecentlyPlacedPropGO.transform.localPosition, propPosDelta, out propPosDelta, "x", "y", "z"); _dpp.mostRecentlyPlacedPropGO.transform.localPosition += latestPropPosDelta; - if (latestPropPosDelta != Vector3.zero) mostRecentlyPlacedPropSphericalPos = DeltaSphericalPosition(mostRecentlyPlacedProp, Vector3.zero); + if (latestPropPosDelta != Vector3.zero) mostRecentlyPlacedPropSphericalPos = DeltaSphericalPosition(mostRecentlyPlacedProp, Vector3.zero); //GUILayout.Space(5); //Vector3 latestPropRotDelta = VectorInput(_dpp.mostRecentlyPlacedPropGO.transform.localEulerAngles, propRotDelta, out propRotDelta, "x", "y", "z"); @@ -143,54 +143,54 @@ namespace NewHorizons.Utility.DebugMenu if (latestPropSphericalPosDelta != Vector3.zero) { DeltaSphericalPosition(mostRecentlyPlacedProp, latestPropSphericalPosDelta); - mostRecentlyPlacedPropSphericalPos = mostRecentlyPlacedPropSphericalPos+latestPropSphericalPosDelta; + mostRecentlyPlacedPropSphericalPos = mostRecentlyPlacedPropSphericalPos + latestPropSphericalPosDelta; } GUILayout.Space(5); GUILayout.Space(5); - - - GUILayout.BeginHorizontal(); - GUILayout.Label("Rotate about up: ", GUILayout.Width(50)); - float deltaRot = 0; - if (GUILayout.Button("+", GUILayout.ExpandWidth(false))) deltaRot += propRotationAboutLocalUpDelta; - if (GUILayout.Button("-", GUILayout.ExpandWidth(false))) deltaRot -= propRotationAboutLocalUpDelta; - propRotationAboutLocalUpDelta = float.Parse(GUILayout.TextField(propRotationAboutLocalUpDelta+"", GUILayout.Width(100))); - if (deltaRot != 0) - { - Transform astroObject = mostRecentlyPlacedProp.transform.parent.parent; - mostRecentlyPlacedProp.transform.RotateAround(mostRecentlyPlacedProp.transform.position, mostRecentlyPlacedProp.transform.up, deltaRot); - } + + GUILayout.BeginHorizontal(); + GUILayout.Label("Rotate about up: ", GUILayout.Width(50)); + float deltaRot = 0; + if (GUILayout.Button("+", GUILayout.ExpandWidth(false))) deltaRot += propRotationAboutLocalUpDelta; + if (GUILayout.Button("-", GUILayout.ExpandWidth(false))) deltaRot -= propRotationAboutLocalUpDelta; + propRotationAboutLocalUpDelta = float.Parse(GUILayout.TextField(propRotationAboutLocalUpDelta + "", GUILayout.Width(100))); + + if (deltaRot != 0) + { + Transform astroObject = mostRecentlyPlacedProp.transform.parent.parent; + mostRecentlyPlacedProp.transform.RotateAround(mostRecentlyPlacedProp.transform.position, mostRecentlyPlacedProp.transform.up, deltaRot); + } GUILayout.EndHorizontal(); - - GUILayout.BeginHorizontal(); - GUILayout.Label("scale: ", GUILayout.Width(50)); - var scaleString = mostRecentlyPlacedProp.transform.localScale.x+""; - var newScaleString = GUILayout.TextField(scaleString , GUILayout.Width(50)); - var parsedScaleString = mostRecentlyPlacedProp.transform.localScale.x; try { parsedScaleString = float.Parse(newScaleString); } catch {} - float deltaScale = scaleString == newScaleString ? 0 : parsedScaleString - mostRecentlyPlacedProp.transform.localScale.x; - if (GUILayout.Button("+", GUILayout.ExpandWidth(false))) deltaScale += propScaleDelta; - if (GUILayout.Button("-", GUILayout.ExpandWidth(false))) deltaScale -= propScaleDelta; - propScaleDelta = float.Parse(GUILayout.TextField(propScaleDelta+"", GUILayout.Width(100))); - if (deltaScale != 0) - { - float newScale = mostRecentlyPlacedProp.transform.localScale.x + deltaScale; - mostRecentlyPlacedProp.transform.localScale = new Vector3(newScale, newScale, newScale); - } + GUILayout.BeginHorizontal(); + GUILayout.Label("scale: ", GUILayout.Width(50)); + var scaleString = mostRecentlyPlacedProp.transform.localScale.x + ""; + var newScaleString = GUILayout.TextField(scaleString, GUILayout.Width(50)); + var parsedScaleString = mostRecentlyPlacedProp.transform.localScale.x; try { parsedScaleString = float.Parse(newScaleString); } catch { } + float deltaScale = scaleString == newScaleString ? 0 : parsedScaleString - mostRecentlyPlacedProp.transform.localScale.x; + if (GUILayout.Button("+", GUILayout.ExpandWidth(false))) deltaScale += propScaleDelta; + if (GUILayout.Button("-", GUILayout.ExpandWidth(false))) deltaScale -= propScaleDelta; + propScaleDelta = float.Parse(GUILayout.TextField(propScaleDelta + "", GUILayout.Width(100))); + + if (deltaScale != 0) + { + float newScale = mostRecentlyPlacedProp.transform.localScale.x + deltaScale; + mostRecentlyPlacedProp.transform.localScale = new Vector3(newScale, newScale, newScale); + } GUILayout.EndHorizontal(); } private Vector3 DeltaSphericalPosition(GameObject prop, Vector3 deltaSpherical) { - Transform astroObject = prop.transform.parent.parent; - Transform sector = prop.transform.parent; + Transform astroObject = prop.transform.parent.parent; + Transform sector = prop.transform.parent; Vector3 originalLocalPos = astroObject.InverseTransformPoint(prop.transform.position); // parent is the sector, this gives localPos relative to the astroobject (what the DetailBuilder asks for) Vector3 sphericalPos = CoordinateUtilities.CartesianToSpherical(originalLocalPos); - + if (deltaSpherical == Vector3.zero) return sphericalPos; - Vector3 newSpherical = sphericalPos+deltaSpherical; + Vector3 newSpherical = sphericalPos + deltaSpherical; Vector3 finalLocalPosition = CoordinateUtilities.SphericalToCartesian(newSpherical); Vector3 finalAbsolutePosition = astroObject.TransformPoint(finalLocalPosition); @@ -217,36 +217,38 @@ namespace NewHorizons.Utility.DebugMenu // x GUILayout.BeginHorizontal(); - GUILayout.Label(labelX+": ", GUILayout.Width(50)); - var xString = input.x+""; - var newXString = GUILayout.TextField(xString, GUILayout.Width(50)); - var parsedXString = input.x; try { parsedXString = float.Parse(newXString); } catch {} - float deltaX = xString == newXString ? 0 : parsedXString - input.x; - if (GUILayout.Button("+", GUILayout.ExpandWidth(false))) deltaX += dx; - if (GUILayout.Button("-", GUILayout.ExpandWidth(false))) deltaX -= dx; - dx = float.Parse(GUILayout.TextField(dx+"", GUILayout.Width(100))); + GUILayout.Label(labelX + ": ", GUILayout.Width(50)); + var xString = input.x + ""; + var newXString = GUILayout.TextField(xString, GUILayout.Width(50)); + var parsedXString = input.x; try { parsedXString = float.Parse(newXString); } catch { } + float deltaX = xString == newXString ? 0 : parsedXString - input.x; + if (GUILayout.Button("+", GUILayout.ExpandWidth(false))) deltaX += dx; + if (GUILayout.Button("-", GUILayout.ExpandWidth(false))) deltaX -= dx; + dx = float.Parse(GUILayout.TextField(dx + "", GUILayout.Width(100))); GUILayout.EndHorizontal(); + // y GUILayout.BeginHorizontal(); - GUILayout.Label(labelY+": ", GUILayout.Width(50)); - var yString = input.y+""; - var newYString = GUILayout.TextField(yString, GUILayout.Width(50)); - var parsedYString = input.y; try { parsedYString = float.Parse(newYString); } catch {} - float deltaY = yString == newYString ? 0 : parsedYString - input.y; - if (GUILayout.Button("+", GUILayout.ExpandWidth(false))) deltaY += dy; - if (GUILayout.Button("-", GUILayout.ExpandWidth(false))) deltaY -= dy; - dy = float.Parse(GUILayout.TextField(dy+"", GUILayout.Width(100))); + GUILayout.Label(labelY + ": ", GUILayout.Width(50)); + var yString = input.y + ""; + var newYString = GUILayout.TextField(yString, GUILayout.Width(50)); + var parsedYString = input.y; try { parsedYString = float.Parse(newYString); } catch { } + float deltaY = yString == newYString ? 0 : parsedYString - input.y; + if (GUILayout.Button("+", GUILayout.ExpandWidth(false))) deltaY += dy; + if (GUILayout.Button("-", GUILayout.ExpandWidth(false))) deltaY -= dy; + dy = float.Parse(GUILayout.TextField(dy + "", GUILayout.Width(100))); GUILayout.EndHorizontal(); + // z GUILayout.BeginHorizontal(); - GUILayout.Label(labelZ+": ", GUILayout.Width(50)); - var zString = input.z+""; - var newZString = GUILayout.TextField(zString, GUILayout.Width(50)); - var parsedZString = input.z; try { parsedZString = float.Parse(newZString); } catch {} - float deltaZ = zString == newZString ? 0 : parsedZString - input.z; - if (GUILayout.Button("+", GUILayout.ExpandWidth(false))) deltaZ += dz; - if (GUILayout.Button("-", GUILayout.ExpandWidth(false))) deltaZ -= dz; - dz = float.Parse(GUILayout.TextField(dz+"", GUILayout.Width(100))); + GUILayout.Label(labelZ + ": ", GUILayout.Width(50)); + var zString = input.z + ""; + var newZString = GUILayout.TextField(zString, GUILayout.Width(50)); + var parsedZString = input.z; try { parsedZString = float.Parse(newZString); } catch { } + float deltaZ = zString == newZString ? 0 : parsedZString - input.z; + if (GUILayout.Button("+", GUILayout.ExpandWidth(false))) deltaZ += dz; + if (GUILayout.Button("-", GUILayout.ExpandWidth(false))) deltaZ -= dz; + dz = float.Parse(GUILayout.TextField(dz + "", GUILayout.Width(100))); GUILayout.EndHorizontal(); deltaControlsOut = new Vector3(dx, dy, dz); @@ -261,8 +263,8 @@ namespace NewHorizons.Utility.DebugMenu { GUILayout.BeginHorizontal(); - var propPathElements = propPath[propPath.Length-1] == '/' - ? propPath.Substring(0, propPath.Length-1).Split('/') + var propPathElements = propPath[propPath.Length - 1] == '/' + ? propPath.Substring(0, propPath.Length - 1).Split('/') : propPath.Split('/'); string propName = propPathElements[propPathElements.Length - 1]; @@ -289,7 +291,7 @@ namespace NewHorizons.Utility.DebugMenu GUILayout.EndHorizontal(); } - GUILayout.EndScrollView(); + GUILayout.EndScrollView(); } internal override void PreSave(DebugMenu menu) @@ -301,29 +303,34 @@ namespace NewHorizons.Utility.DebugMenu { var newDetails = _dpp.GetPropsConfigByBody(); - Logger.Log("Updating config files. New Details Counts by planet: " + string.Join(", ", newDetails.Keys.Select(x => $"{x.name} ({newDetails[x].Length})"))); + var newDetailsCountsByPlanet = string.Join(", ", newDetails.Keys.Select(x => $"{x.name} ({newDetails[x].Length})")); + Logger.Log($"Updating config files. New Details Counts by planet: {newDetailsCountsByPlanet}"); - Dictionary planetToConfigPath = new Dictionary(); + var planetToConfigPath = new Dictionary(); // Get all configs foreach (var filePath in menu.loadedConfigFiles.Keys) { - Logger.Log("potentially updating copy of config at " + filePath); - Logger.Log($"{menu.loadedConfigFiles[filePath].name} {AstroObjectLocator.GetAstroObject(menu.loadedConfigFiles[filePath].name)?.name}"); - Logger.Log($"{menu.loadedConfigFiles[filePath]}") ; + Logger.Log($"Potentially updating copy of config at {filePath}"); + Logger.Log($"{menu.loadedConfigFiles[filePath].name} {AstroObjectLocator.GetAstroObject(menu.loadedConfigFiles[filePath].name)?.name}"); + Logger.Log($"{menu.loadedConfigFiles[filePath].name}"); if (menu.loadedConfigFiles[filePath].starSystem != Main.Instance.CurrentStarSystem) return; - if (menu.loadedConfigFiles[filePath].name == null || AstroObjectLocator.GetAstroObject(menu.loadedConfigFiles[filePath].name) == null) { Logger.Log("Failed to update copy of config at " + filePath); continue; } + if (menu.loadedConfigFiles[filePath].name == null || AstroObjectLocator.GetAstroObject(menu.loadedConfigFiles[filePath].name) == null) + { + Logger.Log("Failed to update copy of config at " + filePath); + continue; + } var astroObject = AstroObjectLocator.GetAstroObject(menu.loadedConfigFiles[filePath].name); planetToConfigPath[astroObject] = filePath; if (!newDetails.ContainsKey(astroObject)) continue; - if (menu.loadedConfigFiles[filePath].Props == null) menu.loadedConfigFiles[filePath].Props = new External.Modules.PropModule(); + if (menu.loadedConfigFiles[filePath].Props == null) menu.loadedConfigFiles[filePath].Props = new PropModule(); menu.loadedConfigFiles[filePath].Props.details = newDetails[astroObject]; - Logger.Log($"successfully updated copy of config file for {astroObject.name}"); + Logger.Log($"Successfully updated copy of config file for {astroObject.name}"); } // find all new planets that do not yet have config paths @@ -332,14 +339,15 @@ namespace NewHorizons.Utility.DebugMenu { Logger.Log("Fabricating new config file for " + astroObject.name); - var filepath = "planets/" + Main.Instance.CurrentStarSystem + "/" + astroObject.name + ".json"; - PlanetConfig c = new PlanetConfig(); - c.starSystem = Main.Instance.CurrentStarSystem; - c.name = astroObject._name == AstroObject.Name.CustomString ? astroObject.GetCustomName() : astroObject._name.ToString(); - c.Props = new PropModule(); - c.Props.details = newDetails[astroObject]; + var filepath = $"planets/{Main.Instance.CurrentStarSystem}/{astroObject.name}.json"; + + var config = new PlanetConfig(); + config.starSystem = Main.Instance.CurrentStarSystem; + config.name = astroObject._name == AstroObject.Name.CustomString ? astroObject.GetCustomName() : astroObject._name.ToString(); + config.Props = new PropModule(); + config.Props.details = newDetails[astroObject]; - menu.loadedConfigFiles[filepath] = c; + menu.loadedConfigFiles[filepath] = config; } } } diff --git a/NewHorizons/Utility/DebugUtilities/DebugPropPlacer.cs b/NewHorizons/Utility/DebugUtilities/DebugPropPlacer.cs index 674a6dc7..e482d84f 100644 --- a/NewHorizons/Utility/DebugUtilities/DebugPropPlacer.cs +++ b/NewHorizons/Utility/DebugUtilities/DebugPropPlacer.cs @@ -1,284 +1,283 @@ -using NewHorizons.Builder.Props; -using NewHorizons.External.Configs; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using UnityEngine.InputSystem; -using static NewHorizons.External.Modules.PropModule; - -namespace NewHorizons.Utility.DebugUtilities -{ - - // - // The prop placer. Doesn't interact with any files, just places and tracks props. - // - - [RequireComponent(typeof(DebugRaycaster))] - class DebugPropPlacer : MonoBehaviour - { - private struct PropPlacementData - { - public AstroObject body; - public string system; - public GameObject gameObject; - public DetailInfo detailInfo; - } - - // VASE - public static readonly string DEFAULT_OBJECT = "BrittleHollow_Body/Sector_BH/Sector_NorthHemisphere/Sector_NorthPole/Sector_HangingCity/Sector_HangingCity_District1/Props_HangingCity_District1/OtherComponentsGroup/Props_HangingCity_Building_10/Prefab_NOM_VaseThin"; - - public string currentObject { get; private set; } // path of the prop to be placed - private bool hasAddedCurrentObjectToRecentsList = false; - private List props = new List(); - private List deletedProps = new List(); - private DebugRaycaster _rc; - - public static HashSet RecentlyPlacedProps = new HashSet(); - - public static bool active = false; - public GameObject mostRecentlyPlacedPropGO { get { return props.Count() <= 0 ? null : props[props.Count()-1].gameObject; } } - public string mostRecentlyPlacedPropPath { get { return props.Count() <= 0 ? "" : props[props.Count()-1].detailInfo.path; } } - - private void Awake() - { - _rc = this.GetRequiredComponent(); - currentObject = DEFAULT_OBJECT; - } - - private void Update() - { - if (!Main.Debug) return; - if (!active) return; - - if (Keyboard.current[Key.G].wasReleasedThisFrame) - { - PlaceObject(); - } - - if (Keyboard.current[Key.Minus].wasReleasedThisFrame) - { - DeleteLast(); - } - - if (Keyboard.current[Key.Equals].wasReleasedThisFrame) - { - UndoDelete(); - } +using NewHorizons.Builder.Props; +using NewHorizons.External.Configs; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using UnityEngine.InputSystem; +using static NewHorizons.External.Modules.PropModule; + +namespace NewHorizons.Utility.DebugUtilities +{ + + // + // The prop placer. Doesn't interact with any files, just places and tracks props. + // + + [RequireComponent(typeof(DebugRaycaster))] + class DebugPropPlacer : MonoBehaviour + { + private struct PropPlacementData + { + public AstroObject body; + public string system; + public GameObject gameObject; + public DetailInfo detailInfo; } - - public void SetCurrentObject(string s) - { - currentObject = s; - hasAddedCurrentObjectToRecentsList = false; - } - - internal void PlaceObject() - { - DebugRaycastData data = _rc.Raycast(); - PlaceObject(data, this.gameObject.transform.position); - - if (!hasAddedCurrentObjectToRecentsList) - { - hasAddedCurrentObjectToRecentsList = true; - - if (!RecentlyPlacedProps.Contains(currentObject)) - { - RecentlyPlacedProps.Add(currentObject); - } - } - } - - public void PlaceObject(DebugRaycastData data, Vector3 playerAbsolutePosition) - { - // TODO: implement sectors - // if this hits a sector, store that sector and add a config file option for it - - if (!data.hitBodyGameObject.name.EndsWith("_Body")) - { - Logger.Log("Cannot place object on non-body object: " + data.hitBodyGameObject.name); - } - - try - { - if (currentObject == "" || currentObject == null) - { - SetCurrentObject(DEFAULT_OBJECT); - } - - GameObject prop = DetailBuilder.MakeDetail(data.hitBodyGameObject, data.hitBodyGameObject.GetComponentInChildren(), currentObject, data.pos, data.norm, 1, false); + + // VASE + public static readonly string DEFAULT_OBJECT = "BrittleHollow_Body/Sector_BH/Sector_NorthHemisphere/Sector_NorthPole/Sector_HangingCity/Sector_HangingCity_District1/Props_HangingCity_District1/OtherComponentsGroup/Props_HangingCity_Building_10/Prefab_NOM_VaseThin"; + + public string currentObject { get; private set; } // path of the prop to be placed + private bool hasAddedCurrentObjectToRecentsList = false; + private List props = new List(); + private List deletedProps = new List(); + private DebugRaycaster _rc; + + public static HashSet RecentlyPlacedProps = new HashSet(); + + public static bool active = false; + public GameObject mostRecentlyPlacedPropGO { get { return props.Count() <= 0 ? null : props[props.Count() - 1].gameObject; } } + public string mostRecentlyPlacedPropPath { get { return props.Count() <= 0 ? "" : props[props.Count() - 1].detailInfo.path; } } + + private void Awake() + { + _rc = this.GetRequiredComponent(); + currentObject = DEFAULT_OBJECT; + } + + private void Update() + { + if (!Main.Debug) return; + if (!active) return; + + if (Keyboard.current[Key.G].wasReleasedThisFrame) + { + PlaceObject(); + } + + if (Keyboard.current[Key.Minus].wasReleasedThisFrame) + { + DeleteLast(); + } + + if (Keyboard.current[Key.Equals].wasReleasedThisFrame) + { + UndoDelete(); + } + } + + public void SetCurrentObject(string s) + { + currentObject = s; + hasAddedCurrentObjectToRecentsList = false; + } + + internal void PlaceObject() + { + DebugRaycastData data = _rc.Raycast(); + PlaceObject(data, this.gameObject.transform.position); + + if (!hasAddedCurrentObjectToRecentsList) + { + hasAddedCurrentObjectToRecentsList = true; + + if (!RecentlyPlacedProps.Contains(currentObject)) + { + RecentlyPlacedProps.Add(currentObject); + } + } + } + + public void PlaceObject(DebugRaycastData data, Vector3 playerAbsolutePosition) + { + // TODO: implement sectors + // if this hits a sector, store that sector and add a config file option for it + + if (!data.hitBodyGameObject.name.EndsWith("_Body")) + { + Logger.Log("Cannot place object on non-body object: " + data.hitBodyGameObject.name); + } + + try + { + if (currentObject == "" || currentObject == null) + { + SetCurrentObject(DEFAULT_OBJECT); + } + + GameObject prop = DetailBuilder.MakeDetail(data.hitBodyGameObject, data.hitBodyGameObject.GetComponentInChildren(), currentObject, data.pos, data.norm, 1, false); PropPlacementData propData = RegisterProp_WithReturn(data.hitBodyGameObject.GetComponent(), prop); - - SetGameObjectRotation(prop, data, playerAbsolutePosition); - } - catch - { - Logger.Log($"Failed to place object {currentObject} on body ${data.hitBodyGameObject} at location ${data.pos}."); - } - } + + SetGameObjectRotation(prop, data, playerAbsolutePosition); + } + catch + { + Logger.Log($"Failed to place object {currentObject} on body ${data.hitBodyGameObject} at location ${data.pos}."); + } + } public static void SetGameObjectRotation(GameObject prop, DebugRaycastData data, Vector3 playerAbsolutePosition) - { - // align with surface normal - Vector3 alignToSurface = (Quaternion.LookRotation(data.norm) * Quaternion.FromToRotation(Vector3.up, Vector3.forward)).eulerAngles; - prop.transform.localEulerAngles = alignToSurface; - - // rotate facing dir towards player - GameObject g = new GameObject("DebugProp"); - g.transform.parent = prop.transform.parent; - g.transform.localPosition = prop.transform.localPosition; - g.transform.localRotation = prop.transform.localRotation; - - prop.transform.parent = g.transform; - - var dirTowardsPlayer = prop.transform.parent.transform.InverseTransformPoint(playerAbsolutePosition) - prop.transform.localPosition; - dirTowardsPlayer.y = 0; - float rotation = Quaternion.LookRotation(dirTowardsPlayer).eulerAngles.y; - prop.transform.localEulerAngles = new Vector3(0, rotation, 0); - - prop.transform.parent = g.transform.parent; + { + // align with surface normal + Vector3 alignToSurface = (Quaternion.LookRotation(data.norm) * Quaternion.FromToRotation(Vector3.up, Vector3.forward)).eulerAngles; + prop.transform.localEulerAngles = alignToSurface; + + // rotate facing dir towards player + GameObject g = new GameObject("DebugProp"); + g.transform.parent = prop.transform.parent; + g.transform.localPosition = prop.transform.localPosition; + g.transform.localRotation = prop.transform.localRotation; + + prop.transform.parent = g.transform; + + var dirTowardsPlayer = prop.transform.parent.transform.InverseTransformPoint(playerAbsolutePosition) - prop.transform.localPosition; + dirTowardsPlayer.y = 0; + float rotation = Quaternion.LookRotation(dirTowardsPlayer).eulerAngles.y; + prop.transform.localEulerAngles = new Vector3(0, rotation, 0); + + prop.transform.parent = g.transform.parent; GameObject.Destroy(g); } - - public static string GetAstroObjectName(string bodyName) - { - var astroObject = AstroObjectLocator.GetAstroObject(bodyName); - if (astroObject == null) return null; - - var astroObjectName = astroObject.name; - - return astroObjectName; - } - - public void FindAndRegisterPropsFromConfig(PlanetConfig config, List pathsList = null) - { - if (config.starSystem != Main.Instance.CurrentStarSystem) return; - - AstroObject planet = AstroObjectLocator.GetAstroObject(config.name); - - if (planet == null) return; - if (config.Props == null || config.Props.details == null) return; - - var astroObject = AstroObjectLocator.GetAstroObject(config.name); - - foreach (var detail in config.Props.details) - { - GameObject spawnedProp = DetailBuilder.GetSpawnedGameObjectByDetailInfo(detail); - - if (spawnedProp == null) - { - Logger.LogError("No spawned prop found for " + detail.path); - continue; - } - - PropPlacementData data = RegisterProp_WithReturn(astroObject, spawnedProp, detail.path, detail); - - // note: we do not support placing props from assetbundles, so they will not be added to the - // selectable list of placed props - if (detail.assetBundle == null && !RecentlyPlacedProps.Contains(data.detailInfo.path)) - { - if (pathsList != null) pathsList.Add(data.detailInfo.path); - } - } - } - - public void RegisterProp(AstroObject body, GameObject prop) - { - RegisterProp_WithReturn(body, prop); - } - - private PropPlacementData RegisterProp_WithReturn(AstroObject body, GameObject prop, string propPath = null, DetailInfo detailInfo = null) - { - if (Main.Debug) - { - // TOOD: make this prop an item - } - - - //var body = AstroObjectLocator.GetAstroObject(bodyGameObjectName); - - Logger.Log($"Adding prop to {Main.Instance.CurrentStarSystem}::{body.name}"); - - - detailInfo = detailInfo == null ? new DetailInfo() : detailInfo; - detailInfo.path = propPath == null ? currentObject : propPath; - - PropPlacementData data = new PropPlacementData - { - body = body, - gameObject = prop, - system = Main.Instance.CurrentStarSystem, - detailInfo = detailInfo - }; - - props.Add(data); - return data; - } - - public Dictionary GetPropsConfigByBody() - { - var groupedProps = props - .GroupBy(p => p.system + "." + p.body) - .Select(grp => grp.ToList()) - .ToList(); - - Dictionary propConfigs = new Dictionary(); - - foreach (List bodyProps in groupedProps) - { - if (bodyProps == null || bodyProps.Count == 0) continue; + + public static string GetAstroObjectName(string bodyName) + { + var astroObject = AstroObjectLocator.GetAstroObject(bodyName); + if (astroObject == null) return null; + + var astroObjectName = astroObject.name; + + return astroObjectName; + } + + public void FindAndRegisterPropsFromConfig(PlanetConfig config, List pathsList = null) + { + if (config.starSystem != Main.Instance.CurrentStarSystem) return; + + AstroObject planet = AstroObjectLocator.GetAstroObject(config.name); + + if (planet == null) return; + if (config.Props == null || config.Props.details == null) return; + + var astroObject = AstroObjectLocator.GetAstroObject(config.name); + + foreach (var detail in config.Props.details) + { + GameObject spawnedProp = DetailBuilder.GetSpawnedGameObjectByDetailInfo(detail); + + if (spawnedProp == null) + { + Logger.LogError("No spawned prop found for " + detail.path); + continue; + } + + PropPlacementData data = RegisterProp_WithReturn(astroObject, spawnedProp, detail.path, detail); + + // note: we do not support placing props from assetbundles, so they will not be added to the + // selectable list of placed props + if (detail.assetBundle == null && !RecentlyPlacedProps.Contains(data.detailInfo.path)) + { + if (pathsList != null) pathsList.Add(data.detailInfo.path); + } + } + } + + public void RegisterProp(AstroObject body, GameObject prop) + { + RegisterProp_WithReturn(body, prop); + } + + private PropPlacementData RegisterProp_WithReturn(AstroObject body, GameObject prop, string propPath = null, DetailInfo detailInfo = null) + { + if (Main.Debug) + { + // TOOD: make this prop an item + } + + //var body = AstroObjectLocator.GetAstroObject(bodyGameObjectName); + + Logger.Log($"Adding prop to {Main.Instance.CurrentStarSystem}::{body.name}"); + + + detailInfo = detailInfo == null ? new DetailInfo() : detailInfo; + detailInfo.path = propPath == null ? currentObject : propPath; + + PropPlacementData data = new PropPlacementData + { + body = body, + gameObject = prop, + system = Main.Instance.CurrentStarSystem, + detailInfo = detailInfo + }; + + props.Add(data); + return data; + } + + public Dictionary GetPropsConfigByBody() + { + var groupedProps = props + .GroupBy(p => p.system + "." + p.body) + .Select(grp => grp.ToList()) + .ToList(); + + Dictionary propConfigs = new Dictionary(); + + foreach (List bodyProps in groupedProps) + { + if (bodyProps == null || bodyProps.Count == 0) continue; if (bodyProps[0].body == null) continue; - var body = bodyProps[0].body; - Logger.Log("getting prop group for body " + body.name); - //string bodyName = GetAstroObjectName(bodyProps[0].body); - - DetailInfo[] infoArray = new DetailInfo[bodyProps.Count]; - propConfigs[body] = infoArray; - - for(int i = 0; i < bodyProps.Count; i++) - { - var prop = bodyProps[i]; - var rootTransform = prop.gameObject.transform.root; - - // Objects are parented to the sector and not to the planet - // However, raycasted positions are reported relative to the root game object - // Normally these two are the same, but there are some notable exceptions (ex, floating islands) - // So we can't use local position/rotation here, we have to inverse transform the global position/rotation relative to root object - prop.detailInfo.position = rootTransform.InverseTransformPoint(prop.gameObject.transform.position); - prop.detailInfo.scale = prop.gameObject.transform.localScale.x; - if (!prop.detailInfo.alignToNormal) prop.detailInfo.rotation = rootTransform.InverseTransformRotation(prop.gameObject.transform.rotation).eulerAngles; - - infoArray[i] = prop.detailInfo; - } - } - - return propConfigs; - } - - public void DeleteLast() - { - if (props.Count <= 0) return; - - PropPlacementData last = props[props.Count-1]; - props.RemoveAt(props.Count-1); - - last.gameObject.SetActive(false); - - deletedProps.Add(last); - } - - public void UndoDelete() - { - if (deletedProps.Count <= 0) return; - - PropPlacementData last = deletedProps[deletedProps.Count-1]; - deletedProps.RemoveAt(deletedProps.Count-1); - - last.gameObject.SetActive(true); - - props.Add(last); - } - } -} + var body = bodyProps[0].body; + Logger.Log("getting prop group for body " + body.name); + //string bodyName = GetAstroObjectName(bodyProps[0].body); + + DetailInfo[] infoArray = new DetailInfo[bodyProps.Count]; + propConfigs[body] = infoArray; + + for (int i = 0; i < bodyProps.Count; i++) + { + var prop = bodyProps[i]; + var rootTransform = prop.gameObject.transform.root; + + // Objects are parented to the sector and not to the planet + // However, raycasted positions are reported relative to the root game object + // Normally these two are the same, but there are some notable exceptions (ex, floating islands) + // So we can't use local position/rotation here, we have to inverse transform the global position/rotation relative to root object + prop.detailInfo.position = rootTransform.InverseTransformPoint(prop.gameObject.transform.position); + prop.detailInfo.scale = prop.gameObject.transform.localScale.x; + if (!prop.detailInfo.alignToNormal) prop.detailInfo.rotation = rootTransform.InverseTransformRotation(prop.gameObject.transform.rotation).eulerAngles; + + infoArray[i] = prop.detailInfo; + } + } + + return propConfigs; + } + + public void DeleteLast() + { + if (props.Count <= 0) return; + + PropPlacementData last = props[props.Count - 1]; + props.RemoveAt(props.Count - 1); + + last.gameObject.SetActive(false); + + deletedProps.Add(last); + } + + public void UndoDelete() + { + if (deletedProps.Count <= 0) return; + + PropPlacementData last = deletedProps[deletedProps.Count - 1]; + deletedProps.RemoveAt(deletedProps.Count - 1); + + last.gameObject.SetActive(true); + + props.Add(last); + } + } +}