Destroy better (#699)

## Improvements
- Cleaned up how planets are destroyed. Should make load screens faster.
Implements #573
This commit is contained in:
Nick 2023-08-24 14:01:07 -04:00 committed by GitHub
commit 0720116e9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 195 additions and 191 deletions

View File

@ -169,8 +169,14 @@ namespace NewHorizons.Handlers
if (body.Config.destroy) if (body.Config.destroy)
{ {
var ao = existingPlanet.GetComponent<AstroObject>(); var ao = existingPlanet.GetComponent<AstroObject>();
if (ao != null) Delay.FireInNUpdates(() => PlanetDestructionHandler.RemoveBody(ao), 2); if (ao != null)
else Delay.FireInNUpdates(() => PlanetDestructionHandler.DisableBody(existingPlanet, false), 2); {
Delay.FireInNUpdates(() => PlanetDestructionHandler.DisableAstroObject(ao), 2);
}
else
{
Delay.FireInNUpdates(() => PlanetDestructionHandler.DisableGameObject(existingPlanet), 2);
}
} }
else if (body.Config.isQuantumState) else if (body.Config.isQuantumState)
{ {

View File

@ -12,48 +12,9 @@ namespace NewHorizons.Handlers
{ {
public static class PlanetDestructionHandler public static class PlanetDestructionHandler
{ {
private static readonly string[] _solarSystemBodies = new string[] public static readonly string[] _suspendBlacklist = new string[] { "Player_Body", "Probe_Body", "Ship_Body" };
{
"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 void RemoveStockPlanets() public static void RemoveStockPlanets()
{
if (Main.Instance.CurrentStarSystem == "EyeOfTheUniverse")
RemoveEyeOfTheUniverse();
else
RemoveSolarSystem();
}
public static void RemoveSolarSystem()
{ {
// Adapted from EOTS thanks corby // Adapted from EOTS thanks corby
var toDisable = new List<GameObject>(); var toDisable = new List<GameObject>();
@ -61,7 +22,7 @@ namespace NewHorizons.Handlers
// Collect all rigid bodies and proxies // Collect all rigid bodies and proxies
foreach (var rigidbody in CenterOfTheUniverse.s_rigidbodies) 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); toDisable.Add(rigidbody.gameObject);
} }
@ -83,32 +44,19 @@ namespace NewHorizons.Handlers
} }
GameObject.FindObjectOfType<SunProxy>().gameObject.SetActive(false); GameObject.FindObjectOfType<SunProxy>().gameObject.SetActive(false);
// force call update here to make it switch to an active star. idk why we didnt have to do this before if (Main.Instance.CurrentStarSystem != "EyeOfTheUniverse")
SunLightEffectsController.Instance.Update(); {
// Since we didn't call RemoveBody on the all planets there are some we have to call here
// Since we didn't call RemoveBody on the Stranger have to call this here StrangerRemoved();
StrangerRemoved(); TimberHearthRemoved();
GiantsDeepRemoved();
SunRemoved();
}
// Don't forget to fix THE WARP BUG
DisableBody(SearchUtilities.Find("StreamingGroup_TH"), true);
}, 2); // Have to wait or shit goes wild }, 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() public static void StrangerRemoved()
{ {
CloakHandler.FlagStrangerDisabled = true; CloakHandler.FlagStrangerDisabled = true;
@ -119,101 +67,122 @@ namespace NewHorizons.Handlers
} }
} }
public static void RemoveBody(AstroObject ao, bool delete = false, List<AstroObject> toDestroy = null) private static void SunRemoved()
{
var sun = SearchUtilities.Find("Sun_Body").GetComponent<AstroObject>();
var starController = sun.gameObject.GetComponent<StarController>();
SunLightEffectsController.RemoveStar(starController);
SunLightEffectsController.RemoveStarLight(sun.transform.Find("Sector_SUN/Effects_SUN/SunLight").GetComponent<Light>());
UnityEngine.Object.Destroy(starController);
var audio = sun.GetComponentInChildren<SunSurfaceAudioController>();
UnityEngine.Object.Destroy(audio);
foreach (var owAudioSource in sun.GetComponentsInChildren<OWAudioSource>())
{
owAudioSource.Stop();
UnityEngine.Object.Destroy(owAudioSource);
}
foreach (var audioSource in sun.GetComponentsInChildren<AudioSource>())
{
audioSource.Stop();
UnityEngine.Object.Destroy(audioSource);
}
foreach (var sunProxy in UnityEngine.Object.FindObjectsOfType<SunProxy>())
{
NHLogger.LogVerbose($"Destroying SunProxy {sunProxy.gameObject.name}");
UnityEngine.Object.Destroy(sunProxy.gameObject);
}
// Stop the sun from breaking stuff when the supernova gets triggered
GlobalMessenger.RemoveListener("TriggerSupernova", sun.GetComponent<SunController>().OnTriggerSupernova);
// Just to be safe
SunLightEffectsController.Instance.Update();
}
private static void TimberHearthRemoved()
{
// Always just fucking kill this one to stop THE WARP BUG!!!
GameObject.Destroy(SearchUtilities.Find("StreamingGroup_TH").gameObject);
var timberHearth = SearchUtilities.Find("TimberHearth_Body");
foreach (var obj in timberHearth.GetComponentsInChildren<DayNightTracker>())
{
GameObject.Destroy(obj.gameObject);
}
foreach (var obj in timberHearth.GetComponentsInChildren<VillageMusicVolume>())
{
GameObject.Destroy(obj.gameObject);
}
}
private static void GiantsDeepRemoved()
{
foreach (var jelly in UnityEngine.Object.FindObjectsOfType<JellyfishController>())
{
if (jelly.GetSector().GetRootSector().GetName() == Sector.Name.GiantsDeep)
{
DisableGameObject(jelly.gameObject);
}
}
}
#endregion
public static void DisableAstroObject(AstroObject ao, List<AstroObject> toDisable = null)
{ {
NHLogger.LogVerbose($"Removing [{ao.name}]"); NHLogger.LogVerbose($"Removing [{ao.name}]");
if (ao.GetAstroObjectName() == AstroObject.Name.RingWorld)
{
StrangerRemoved();
}
if (ao.gameObject == null || !ao.gameObject.activeInHierarchy) if (ao.gameObject == null || !ao.gameObject.activeInHierarchy)
{ {
NHLogger.LogVerbose($"[{ao.name}] was already removed"); NHLogger.LogVerbose($"[{ao.name}] was already removed");
return; return;
} }
if (toDestroy == null) toDestroy = new List<AstroObject>(); toDisable ??= new List<AstroObject>();
if (toDestroy.Contains(ao)) if (toDisable.Contains(ao))
{ {
NHLogger.LogVerbose($"Possible infinite recursion in RemoveBody: {ao.name} might be it's own primary body?"); NHLogger.LogVerbose($"Possible infinite recursion in RemoveBody: {ao.name} might be it's own primary body?");
return; return;
} }
toDestroy.Add(ao); toDisable.Add(ao);
try try
{ {
switch(ao._name) switch(ao._name)
{ {
case AstroObject.Name.BrittleHollow: case AstroObject.Name.BrittleHollow:
RemoveBody(AstroObjectLocator.GetAstroObject(AstroObject.Name.WhiteHole.ToString()), delete, toDestroy); DisableAstroObject(AstroObjectLocator.GetAstroObject(AstroObject.Name.WhiteHole.ToString()), toDisable);
// Might prevent leftover fragments from existing // Might prevent leftover fragments from existing
// Might also prevent people from using their own detachable fragments however // Might also prevent people from using their own detachable fragments however
foreach(var fragment in UnityEngine.Object.FindObjectsOfType<DetachableFragment>()) foreach(var fragment in UnityEngine.Object.FindObjectsOfType<DetachableFragment>())
{ {
DisableBody(fragment.gameObject, delete); DisableGameObject(fragment.gameObject);
} }
break; break;
case AstroObject.Name.CaveTwin: case AstroObject.Name.CaveTwin:
case AstroObject.Name.TowerTwin: case AstroObject.Name.TowerTwin:
DisableBody(SearchUtilities.Find("FocalBody"), delete); DisableGameObject(SearchUtilities.Find("FocalBody"));
DisableBody(SearchUtilities.Find("SandFunnel_Body", false), delete); DisableGameObject(SearchUtilities.Find("SandFunnel_Body", false));
break; break;
case AstroObject.Name.GiantsDeep: case AstroObject.Name.GiantsDeep:
// Might prevent leftover jellyfish from existing GiantsDeepRemoved();
// Might also prevent people from using their own jellyfish however
foreach (var jelly in UnityEngine.Object.FindObjectsOfType<JellyfishController>())
{
DisableBody(jelly.gameObject, delete);
}
// Else it will re-eanble the pieces
// ao.GetComponent<OrbitalProbeLaunchController>()._realDebrisSectorProxies = null;
break; break;
case AstroObject.Name.TimberHearth: case AstroObject.Name.TimberHearth:
// Always just fucking kill this one to stop THE WARP BUG!!! TimberHearthRemoved();
DisableBody(SearchUtilities.Find("StreamingGroup_TH"), true);
foreach (var obj in UnityEngine.Object.FindObjectsOfType<DayNightTracker>())
{
DisableBody(obj.gameObject, true);
}
foreach (var obj in UnityEngine.Object.FindObjectsOfType<VillageMusicVolume>())
{
DisableBody(obj.gameObject, true);
}
break; break;
case AstroObject.Name.Sun: case AstroObject.Name.Sun:
var starController = ao.gameObject.GetComponent<StarController>(); SunRemoved();
SunLightEffectsController.RemoveStar(starController); break;
SunLightEffectsController.RemoveStarLight(ao.transform.Find("Sector_SUN/Effects_SUN/SunLight").GetComponent<Light>()); case AstroObject.Name.RingWorld:
UnityEngine.Object.Destroy(starController); StrangerRemoved();
var audio = ao.GetComponentInChildren<SunSurfaceAudioController>();
UnityEngine.Object.Destroy(audio);
foreach (var owAudioSource in ao.GetComponentsInChildren<OWAudioSource>())
{
owAudioSource.Stop();
UnityEngine.Object.Destroy(owAudioSource);
}
foreach (var audioSource in ao.GetComponentsInChildren<AudioSource>())
{
audioSource.Stop();
UnityEngine.Object.Destroy(audioSource);
}
foreach (var sunProxy in UnityEngine.Object.FindObjectsOfType<SunProxy>())
{
NHLogger.LogVerbose($"Destroying SunProxy {sunProxy.gameObject.name}");
UnityEngine.Object.Destroy(sunProxy.gameObject);
}
// Stop the sun from breaking stuff when the supernova gets triggered
GlobalMessenger.RemoveListener("TriggerSupernova", ao.GetComponent<SunController>().OnTriggerSupernova);
break; break;
} }
@ -230,8 +199,14 @@ namespace NewHorizons.Handlers
// Some children might be astro objects and as such can have children of their own // Some children might be astro objects and as such can have children of their own
var childAO = child.GetComponent<AstroObject>(); var childAO = child.GetComponent<AstroObject>();
if (childAO != null) RemoveBody(childAO, false, toDestroy); if (childAO != null)
else DisableBody(child, true); {
DisableAstroObject(childAO, toDisable);
}
else
{
DisableGameObject(child);
}
} }
// Always delete moons // Always delete moons
@ -239,7 +214,7 @@ namespace NewHorizons.Handlers
{ {
if (obj == null) continue; if (obj == null) continue;
RemoveBody(obj.GetComponent<AstroObject>(), false, toDestroy); DisableAstroObject(obj.GetComponent<AstroObject>(), toDisable);
} }
} }
catch (Exception e) catch (Exception e)
@ -247,36 +222,7 @@ namespace NewHorizons.Handlers
NHLogger.LogError($"Exception thrown when trying to delete bodies related to [{ao.name}]:\n{e}"); NHLogger.LogError($"Exception thrown when trying to delete bodies related to [{ao.name}]:\n{e}");
} }
// Deal with proxies RemoveProxy(ao);
foreach (var p in UnityEngine.Object.FindObjectsOfType<ProxyOrbiter>())
{
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<ProxyBody>())
{
if (proxy?._realObjectTransform?.gameObject == ao.gameObject)
{
UnityEngine.Object.Destroy(proxy.gameObject);
}
}
}
public static void RemoveAllProxies()
{
UnityEngine.Object.Destroy(UnityEngine.Object.FindObjectOfType<DistantProxyManager>().gameObject);
foreach (var name in _solarSystemBodies)
{
RemoveProxy(name.Replace(" ", "").Replace("'", ""));
}
} }
private static bool CanSuspend(OWRigidbody rigidbody, string name) private static bool CanSuspend(OWRigidbody rigidbody, string name)
@ -286,7 +232,7 @@ namespace NewHorizons.Handlers
return CanSuspend(rigidbody._origParentBody, name); return CanSuspend(rigidbody._origParentBody, name);
} }
internal static void DisableBody(GameObject go, bool delete) internal static void DisableGameObject(GameObject go)
{ {
if (go == null) return; if (go == null) return;
@ -317,33 +263,18 @@ namespace NewHorizons.Handlers
} }
} }
if (delete) go.SetActive(false);
var ol = go.GetComponentInChildren<OrbitLine>();
if (ol)
{ {
UnityEngine.Object.Destroy(go); ol.enabled = false;
}
else
{
go.SetActive(false);
var ol = go.GetComponentInChildren<OrbitLine>();
if (ol)
{
ol.enabled = false;
}
} }
} }
private static void RemoveProxy(string name) private static void RemoveProxy(AstroObject ao)
{ {
if (name.Equals("TowerTwin")) name = "AshTwin"; ProxyHandler.GetVanillaProxyBody(ao.transform)?.gameObject?.SetActive(false);
if (name.Equals("CaveTwin")) name = "EmberTwin"; ProxyHandler.GetVanillaProxyOrbiter(ao.transform)?.gameObject?.SetActive(false);
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}");
} }
} }
} }

View File

@ -1,11 +1,21 @@
using NewHorizons.Components; using NewHorizons.Components;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine;
namespace NewHorizons.Handlers namespace NewHorizons.Handlers
{ {
public static class ProxyHandler public static class ProxyHandler
{ {
private static List<NHProxy> _proxies = new List<NHProxy>(); private static List<NHProxy> _proxies = new();
private static Dictionary<Transform, ProxyBody> _vanillaProxyBody = new();
private static Dictionary<Transform, ProxyOrbiter> _vanillaProxyOrbiter = new();
public static void OnSceneUnloaded()
{
_proxies.Clear();
_vanillaProxyBody.Clear();
_vanillaProxyOrbiter.Clear();
}
public static NHProxy GetProxy(string astroName) public static NHProxy GetProxy(string astroName)
{ {
@ -17,6 +27,40 @@ namespace NewHorizons.Handlers
return null; 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) public static void RegisterProxy(NHProxy proxy)
{ {
_proxies.SafeAdd(proxy); _proxies.SafeAdd(proxy);

View File

@ -264,6 +264,7 @@ namespace NewHorizons
AudioUtilities.ClearCache(); AudioUtilities.ClearCache();
AssetBundleUtilities.OnSceneUnloaded(); AssetBundleUtilities.OnSceneUnloaded();
EnumUtilities.ClearCache(); EnumUtilities.ClearCache();
ProxyHandler.OnSceneUnloaded();
IsSystemReady = false; IsSystemReady = false;
} }

View File

@ -1,15 +1,22 @@
using HarmonyLib; using HarmonyLib;
using NewHorizons.Handlers;
namespace NewHorizons.Patches.ProxyPatches namespace NewHorizons.Patches.ProxyPatches;
[HarmonyPatch(typeof(ProxyBody))]
public static class ProxyBodyPatches
{ {
[HarmonyPatch(typeof(ProxyBody))] [HarmonyPostfix]
public static class ProxyBodyPatches [HarmonyPatch(nameof(ProxyBody.Awake))]
public static void ProxyBody_Awake(ProxyBody __instance)
{ {
[HarmonyPrefix] ProxyHandler.RegisterVanillaProxyBody(__instance);
[HarmonyPatch(nameof(ProxyBody.IsObjectInSupernova))] }
public static bool ProxyBody_IsObjectInSupernova(ProxyBody __instance)
{ [HarmonyPrefix]
return Locator.GetSunController() != null; [HarmonyPatch(nameof(ProxyBody.IsObjectInSupernova))]
} public static bool ProxyBody_IsObjectInSupernova(ProxyBody __instance)
{
return Locator.GetSunController() != null;
} }
} }

View File

@ -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);
}
}