From 734f6e1f6ae3b097f4ff5775655445b5f66812ac Mon Sep 17 00:00:00 2001 From: Nick Date: Thu, 24 Aug 2023 13:36:04 -0400 Subject: [PATCH] Clean up destruction, do proxies better --- NewHorizons/Handlers/PlanetCreationHandler.cs | 10 +- .../Handlers/PlanetDestructionHandler.cs | 316 +++++++----------- NewHorizons/Handlers/ProxyHandler.cs | 46 ++- NewHorizons/Main.cs | 1 + .../Patches/ProxyPatches/ProxyBodyPatches.cs | 25 +- .../ProxyPatches/ProxyOrbiterPatches.cs | 15 + 6 files changed, 201 insertions(+), 212 deletions(-) create mode 100644 NewHorizons/Patches/ProxyPatches/ProxyOrbiterPatches.cs diff --git a/NewHorizons/Handlers/PlanetCreationHandler.cs b/NewHorizons/Handlers/PlanetCreationHandler.cs index 2b014cbf..7c33c7b9 100644 --- a/NewHorizons/Handlers/PlanetCreationHandler.cs +++ b/NewHorizons/Handlers/PlanetCreationHandler.cs @@ -169,8 +169,14 @@ namespace NewHorizons.Handlers if (body.Config.destroy) { var ao = existingPlanet.GetComponent(); - if (ao != null) Delay.FireInNUpdates(() => PlanetDestructionHandler.RemoveBody(ao), 2); - else Delay.FireInNUpdates(() => PlanetDestructionHandler.DisableBody(existingPlanet, false), 2); + if (ao != null) + { + Delay.FireInNUpdates(() => PlanetDestructionHandler.DisableAstroObject(ao), 2); + } + else + { + Delay.FireInNUpdates(() => PlanetDestructionHandler.DisableGameObject(existingPlanet), 2); + } } else if (body.Config.isQuantumState) { diff --git a/NewHorizons/Handlers/PlanetDestructionHandler.cs b/NewHorizons/Handlers/PlanetDestructionHandler.cs index 92ac8577..866e48b4 100644 --- a/NewHorizons/Handlers/PlanetDestructionHandler.cs +++ b/NewHorizons/Handlers/PlanetDestructionHandler.cs @@ -11,48 +11,9 @@ namespace NewHorizons.Handlers { public static class PlanetDestructionHandler { - private static readonly string[] _solarSystemBodies = new string[] - { - "Ash Twin", - "Attlerock", - "Brittle Hollow", - "Dark Bramble", - "DreamWorld", - "Ember Twin", - "Giant's Deep", - "Hollow's Lantern", - "Interloper", - "Map Satellite", - "Orbital Probe Cannon", - "Quantum Moon", - "RingWorld", - "Sun", - "Sun Station", - "Timber Hearth", - "White Hole" - }; - - private static readonly string[] _eyeOfTheUniverseBodies = new string[] - { - "Eye Of The Universe", - "Vessel" - }; - - private static readonly string[] _suspendBlacklist = new string[] - { - "Player_Body", - "Ship_Body" - }; + public static readonly string[] _suspendBlacklist = new string[] { "Player_Body", "Probe_Body", "Ship_Body" }; public static void RemoveStockPlanets() - { - if (Main.Instance.CurrentStarSystem == "EyeOfTheUniverse") - RemoveEyeOfTheUniverse(); - else - RemoveSolarSystem(); - } - - public static void RemoveSolarSystem() { // Adapted from EOTS thanks corby var toDisable = new List(); @@ -60,7 +21,7 @@ namespace NewHorizons.Handlers // Collect all rigid bodies and proxies foreach (var rigidbody in CenterOfTheUniverse.s_rigidbodies) { - if (rigidbody.name is not ("Player_Body" or "Probe_Body" or "Ship_Body")) + if (!_suspendBlacklist.Contains(rigidbody.name)) { toDisable.Add(rigidbody.gameObject); } @@ -79,28 +40,18 @@ namespace NewHorizons.Handlers } GameObject.FindObjectOfType().gameObject.SetActive(false); - // Since we didn't call RemoveBody on the all planets there are some we have to call here - StrangerRemoved(); - TimberHearthRemoved(); - SunRemoved(); + if (Main.Instance.CurrentStarSystem != "EyeOfTheUniverse") + { + // Since we didn't call RemoveBody on the all planets there are some we have to call here + StrangerRemoved(); + TimberHearthRemoved(); + SunRemoved(); + } + }, 2); // Have to wait or shit goes wild - - foreach (var streamingAssetBundle in StreamingManager.s_activeBundles) - { - //streamingAssetBundle.Unload(); - } - } - - public static void RemoveEyeOfTheUniverse() - { - foreach (var name in _eyeOfTheUniverseBodies) - { - var ao = AstroObjectLocator.GetAstroObject(name); - if (ao != null) Delay.FireInNUpdates(() => RemoveBody(ao, false), 2); - else NHLogger.LogError($"Couldn't find [{name}]"); - } } + #region Planet specific removals public static void StrangerRemoved() { CloakHandler.FlagStrangerDisabled = true; @@ -111,120 +62,6 @@ namespace NewHorizons.Handlers } } - public static void RemoveBody(AstroObject ao, bool delete = false, List toDestroy = null) - { - NHLogger.LogVerbose($"Removing [{ao.name}]"); - - if (ao.gameObject == null || !ao.gameObject.activeInHierarchy) - { - NHLogger.LogVerbose($"[{ao.name}] was already removed"); - return; - } - - if (toDestroy == null) toDestroy = new List(); - - if (toDestroy.Contains(ao)) - { - NHLogger.LogVerbose($"Possible infinite recursion in RemoveBody: {ao.name} might be it's own primary body?"); - return; - } - - toDestroy.Add(ao); - - try - { - switch(ao._name) - { - case AstroObject.Name.BrittleHollow: - RemoveBody(AstroObjectLocator.GetAstroObject(AstroObject.Name.WhiteHole.ToString()), delete, toDestroy); - // Might prevent leftover fragments from existing - // Might also prevent people from using their own detachable fragments however - foreach(var fragment in UnityEngine.Object.FindObjectsOfType()) - { - DisableBody(fragment.gameObject, delete); - } - break; - - case AstroObject.Name.CaveTwin: - case AstroObject.Name.TowerTwin: - DisableBody(SearchUtilities.Find("FocalBody"), delete); - DisableBody(SearchUtilities.Find("SandFunnel_Body", false), delete); - break; - - case AstroObject.Name.GiantsDeep: - // Might prevent leftover jellyfish from existing - // Might also prevent people from using their own jellyfish however - - // TODO: Make this only affect those on GD? - foreach (var jelly in UnityEngine.Object.FindObjectsOfType()) - { - DisableBody(jelly.gameObject, delete); - } - break; - case AstroObject.Name.TimberHearth: - TimberHearthRemoved(); - break; - case AstroObject.Name.Sun: - SunRemoved(); - break; - case AstroObject.Name.RingWorld: - StrangerRemoved(); - break; - } - - // Always delete the children - NHLogger.LogVerbose($"Removing Children of [{ao._name}], [{ao._customName}]"); - foreach (var child in AstroObjectLocator.GetChildren(ao)) - { - if (child == null) continue; - - NHLogger.LogVerbose($"Removing child [{child.name}] of [{ao._name}]"); - - // Ship starts as a child of TH but obvious we want to keep that - if (child.name == "Ship_Body") continue; - - // Some children might be astro objects and as such can have children of their own - var childAO = child.GetComponent(); - if (childAO != null) RemoveBody(childAO, false, toDestroy); - else DisableBody(child, true); - } - - // Always delete moons - foreach (var obj in AstroObjectLocator.GetMoons(ao)) - { - if (obj == null) continue; - - RemoveBody(obj.GetComponent(), false, toDestroy); - } - } - catch (Exception e) - { - NHLogger.LogError($"Exception thrown when trying to delete bodies related to [{ao.name}]:\n{e}"); - } - - // Deal with proxies - // TODO: There has to be a better way of doing this - foreach (var p in UnityEngine.Object.FindObjectsOfType()) - { - if (p._originalBody == ao.gameObject) - { - DisableBody(p.gameObject, true); - break; - } - } - RemoveProxy(ao.name.Replace("_Body", "")); - - Delay.RunWhen(() => Main.IsSystemReady, () => DisableBody(ao.gameObject, delete)); - - foreach (ProxyBody proxy in UnityEngine.Object.FindObjectsOfType()) - { - if (proxy?._realObjectTransform?.gameObject == ao.gameObject) - { - UnityEngine.Object.Destroy(proxy.gameObject); - } - } - } - private static void SunRemoved() { var sun = SearchUtilities.Find("Sun_Body").GetComponent(); @@ -265,18 +102,112 @@ namespace NewHorizons.Handlers private static void TimberHearthRemoved() { // Always just fucking kill this one to stop THE WARP BUG!!! - DisableBody(SearchUtilities.Find("StreamingGroup_TH"), true); + GameObject.Destroy(SearchUtilities.Find("StreamingGroup_TH").gameObject); // TODO: These should only destroy those that are on TH foreach (var obj in UnityEngine.Object.FindObjectsOfType()) { - DisableBody(obj.gameObject, true); + GameObject.Destroy(obj.gameObject); } foreach (var obj in UnityEngine.Object.FindObjectsOfType()) { - DisableBody(obj.gameObject, true); + GameObject.Destroy(obj.gameObject); } } + #endregion + + public static void DisableAstroObject(AstroObject ao, List toDisable = null) + { + NHLogger.LogVerbose($"Removing [{ao.name}]"); + + if (ao.gameObject == null || !ao.gameObject.activeInHierarchy) + { + NHLogger.LogVerbose($"[{ao.name}] was already removed"); + return; + } + + toDisable ??= new List(); + + if (toDisable.Contains(ao)) + { + NHLogger.LogVerbose($"Possible infinite recursion in RemoveBody: {ao.name} might be it's own primary body?"); + return; + } + + toDisable.Add(ao); + + try + { + switch(ao._name) + { + case AstroObject.Name.BrittleHollow: + DisableAstroObject(AstroObjectLocator.GetAstroObject(AstroObject.Name.WhiteHole.ToString()), toDisable); + // Might prevent leftover fragments from existing + // Might also prevent people from using their own detachable fragments however + foreach(var fragment in UnityEngine.Object.FindObjectsOfType()) + { + DisableGameObject(fragment.gameObject); + } + break; + + case AstroObject.Name.CaveTwin: + case AstroObject.Name.TowerTwin: + DisableGameObject(SearchUtilities.Find("FocalBody")); + DisableGameObject(SearchUtilities.Find("SandFunnel_Body", false)); + break; + + case AstroObject.Name.GiantsDeep: + foreach (var jelly in UnityEngine.Object.FindObjectsOfType()) + { + if (jelly.GetSector().GetRootSector().GetName() == Sector.Name.GiantsDeep) + { + DisableGameObject(jelly.gameObject); + } + } + break; + case AstroObject.Name.TimberHearth: + TimberHearthRemoved(); + break; + case AstroObject.Name.Sun: + SunRemoved(); + break; + case AstroObject.Name.RingWorld: + StrangerRemoved(); + break; + } + + // Always delete the children + NHLogger.LogVerbose($"Removing Children of [{ao._name}], [{ao._customName}]"); + foreach (var child in AstroObjectLocator.GetChildren(ao)) + { + if (child == null) continue; + + NHLogger.LogVerbose($"Removing child [{child.name}] of [{ao._name}]"); + + // Ship starts as a child of TH but obvious we want to keep that + if (child.name == "Ship_Body") continue; + + // Some children might be astro objects and as such can have children of their own + var childAO = child.GetComponent(); + if (childAO != null) DisableAstroObject(childAO, toDisable); + else DisableGameObject(child); + } + + // Always delete moons + foreach (var obj in AstroObjectLocator.GetMoons(ao)) + { + if (obj == null) continue; + + DisableAstroObject(obj.GetComponent(), toDisable); + } + } + catch (Exception e) + { + NHLogger.LogError($"Exception thrown when trying to delete bodies related to [{ao.name}]:\n{e}"); + } + + RemoveProxy(ao); + } private static bool CanSuspend(OWRigidbody rigidbody, string name) { @@ -285,7 +216,7 @@ namespace NewHorizons.Handlers return CanSuspend(rigidbody._origParentBody, name); } - internal static void DisableBody(GameObject go, bool delete) + internal static void DisableGameObject(GameObject go) { if (go == null) return; @@ -316,33 +247,18 @@ namespace NewHorizons.Handlers } } - if (delete) + go.SetActive(false); + var ol = go.GetComponentInChildren(); + if (ol) { - UnityEngine.Object.Destroy(go); - } - else - { - go.SetActive(false); - var ol = go.GetComponentInChildren(); - if (ol) - { - ol.enabled = false; - } + ol.enabled = false; } } - private static void RemoveProxy(string name) + private static void RemoveProxy(AstroObject ao) { - if (name.Equals("TowerTwin")) name = "AshTwin"; - if (name.Equals("CaveTwin")) name = "EmberTwin"; - var distantProxy = SearchUtilities.Find(name + "_DistantProxy", false); - var distantProxyClone = SearchUtilities.Find(name + "_DistantProxy(Clone)", false); - - if (distantProxy != null) UnityEngine.Object.Destroy(distantProxy.gameObject); - if (distantProxyClone != null) UnityEngine.Object.Destroy(distantProxyClone.gameObject); - - if (distantProxy == null && distantProxyClone == null) - NHLogger.LogVerbose($"Couldn't find proxy for {name}"); + ProxyHandler.GetVanillaProxyBody(ao.transform)?.gameObject?.SetActive(false); + ProxyHandler.GetVanillaProxyOrbiter(ao.transform)?.gameObject?.SetActive(false); } } } diff --git a/NewHorizons/Handlers/ProxyHandler.cs b/NewHorizons/Handlers/ProxyHandler.cs index 090d519d..cb6544ee 100644 --- a/NewHorizons/Handlers/ProxyHandler.cs +++ b/NewHorizons/Handlers/ProxyHandler.cs @@ -1,11 +1,21 @@ using NewHorizons.Components; using System.Collections.Generic; +using UnityEngine; namespace NewHorizons.Handlers { public static class ProxyHandler { - private static List _proxies = new List(); + private static List _proxies = new(); + private static Dictionary _vanillaProxyBody = new(); + private static Dictionary _vanillaProxyOrbiter = new(); + + public static void OnSceneUnloaded() + { + _proxies.Clear(); + _vanillaProxyBody.Clear(); + _vanillaProxyOrbiter.Clear(); + } public static NHProxy GetProxy(string astroName) { @@ -17,6 +27,40 @@ namespace NewHorizons.Handlers return null; } + public static void RegisterVanillaProxyBody(ProxyBody proxy) + { + _vanillaProxyBody.Add(proxy.realObjectTransform, proxy); + } + + public static ProxyBody GetVanillaProxyBody(Transform t) + { + if (_vanillaProxyBody.TryGetValue(t, out ProxyBody proxy)) + { + return proxy; + } + else + { + return null; + } + } + + public static void RegisterVanillaProxyOrbiter(ProxyOrbiter proxy) + { + _vanillaProxyOrbiter.Add(proxy._originalPlanetBody, proxy); + } + + public static ProxyOrbiter GetVanillaProxyOrbiter(Transform t) + { + if (_vanillaProxyOrbiter.TryGetValue(t, out ProxyOrbiter proxy)) + { + return proxy; + } + else + { + return null; + } + } + public static void RegisterProxy(NHProxy proxy) { _proxies.SafeAdd(proxy); diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 2906f9be..74a201f7 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -264,6 +264,7 @@ namespace NewHorizons AudioUtilities.ClearCache(); AssetBundleUtilities.ClearCache(); EnumUtilities.ClearCache(); + ProxyHandler.OnSceneUnloaded(); IsSystemReady = false; } diff --git a/NewHorizons/Patches/ProxyPatches/ProxyBodyPatches.cs b/NewHorizons/Patches/ProxyPatches/ProxyBodyPatches.cs index 5ff71810..b8f648ac 100644 --- a/NewHorizons/Patches/ProxyPatches/ProxyBodyPatches.cs +++ b/NewHorizons/Patches/ProxyPatches/ProxyBodyPatches.cs @@ -1,15 +1,22 @@ using HarmonyLib; +using NewHorizons.Handlers; -namespace NewHorizons.Patches.ProxyPatches +namespace NewHorizons.Patches.ProxyPatches; + +[HarmonyPatch(typeof(ProxyBody))] +public static class ProxyBodyPatches { - [HarmonyPatch(typeof(ProxyBody))] - public static class ProxyBodyPatches + [HarmonyPostfix] + [HarmonyPatch(nameof(ProxyBody.Awake))] + public static void ProxyBody_Awake(ProxyBody __instance) { - [HarmonyPrefix] - [HarmonyPatch(nameof(ProxyBody.IsObjectInSupernova))] - public static bool ProxyBody_IsObjectInSupernova(ProxyBody __instance) - { - return Locator.GetSunController() != null; - } + ProxyHandler.RegisterVanillaProxyBody(__instance); + } + + [HarmonyPrefix] + [HarmonyPatch(nameof(ProxyBody.IsObjectInSupernova))] + public static bool ProxyBody_IsObjectInSupernova(ProxyBody __instance) + { + return Locator.GetSunController() != null; } } diff --git a/NewHorizons/Patches/ProxyPatches/ProxyOrbiterPatches.cs b/NewHorizons/Patches/ProxyPatches/ProxyOrbiterPatches.cs new file mode 100644 index 00000000..c505b5f4 --- /dev/null +++ b/NewHorizons/Patches/ProxyPatches/ProxyOrbiterPatches.cs @@ -0,0 +1,15 @@ +using HarmonyLib; +using NewHorizons.Handlers; + +namespace NewHorizons.Patches.ProxyPatches; + +[HarmonyPatch(typeof(ProxyOrbiter))] +public static class ProxyOrbiterPatches +{ + [HarmonyPostfix] + [HarmonyPatch(nameof(ProxyOrbiter.Awake))] + public static void ProxyOrbiter_Awake(ProxyOrbiter __instance) + { + ProxyHandler.RegisterVanillaProxyOrbiter(__instance); + } +}