From 5c705f12c8fd9dec9c66461504d99d700b7eee92 Mon Sep 17 00:00:00 2001 From: Nick Date: Fri, 6 May 2022 19:03:41 -0400 Subject: [PATCH] Can move existing planet but not change primary --- .../{BaseBuilder.cs => AstroObjectBuilder.cs} | 35 +------ .../Builder/General/DetectorBuilder.cs | 18 ++-- .../Builder/General/RigidBodyBuilder.cs | 43 +++++++++ .../Builder/Orbital/InitialMotionBuilder.cs | 5 + .../Builder/Orbital/OrbitlineBuilder.cs | 4 +- NewHorizons/Builder/Updater/OrbitUpdater.cs | 20 ---- NewHorizons/Handlers/PlanetCreationHandler.cs | 93 +++++++++++++++++-- NewHorizons/Main.cs | 1 - NewHorizons/Utility/AstroObjectLocator.cs | 5 + 9 files changed, 156 insertions(+), 68 deletions(-) rename NewHorizons/Builder/General/{BaseBuilder.cs => AstroObjectBuilder.cs} (63%) create mode 100644 NewHorizons/Builder/General/RigidBodyBuilder.cs delete mode 100644 NewHorizons/Builder/Updater/OrbitUpdater.cs diff --git a/NewHorizons/Builder/General/BaseBuilder.cs b/NewHorizons/Builder/General/AstroObjectBuilder.cs similarity index 63% rename from NewHorizons/Builder/General/BaseBuilder.cs rename to NewHorizons/Builder/General/AstroObjectBuilder.cs index 32fbe2eb..75087db2 100644 --- a/NewHorizons/Builder/General/BaseBuilder.cs +++ b/NewHorizons/Builder/General/AstroObjectBuilder.cs @@ -9,35 +9,10 @@ using NewHorizons.Components.Orbital; namespace NewHorizons.Builder.General { - static class BaseBuilder + static class AstroObjectBuilder { - public static Tuple Make(GameObject body, AstroObject primaryBody, IPlanetConfig config) + public static NHAstroObject Make(GameObject body, AstroObject primaryBody, IPlanetConfig config) { - body.AddComponent(); - - Rigidbody rigidBody = body.AddComponent(); - rigidBody.mass = 10000; - rigidBody.drag = 0f; - rigidBody.angularDrag = 0f; - rigidBody.useGravity = false; - rigidBody.isKinematic = true; - rigidBody.interpolation = RigidbodyInterpolation.None; - rigidBody.collisionDetectionMode = CollisionDetectionMode.Discrete; - - KinematicRigidbody kinematicRigidBody = body.AddComponent(); - kinematicRigidBody.centerOfMass = Vector3.zero; - - OWRigidbody owRigidBody = body.AddComponent(); - owRigidBody._kinematicSimulation = true; - owRigidBody._autoGenerateCenterOfMass = true; - owRigidBody.SetIsTargetable(true); - owRigidBody._maintainOriginalCenterOfMass = true; - owRigidBody._rigidbody = rigidBody; - owRigidBody._kinematicRigidbody = kinematicRigidBody; - owRigidBody._origParent = GameObject.Find("SolarSystemRoot").transform; - owRigidBody.EnableKinematicSimulation(); - owRigidBody.MakeKinematic(); - NHAstroObject astroObject = body.AddComponent(); astroObject.HideDisplayName = !config.Base.HasMapMarker; @@ -75,16 +50,16 @@ namespace NewHorizons.Builder.General { alignment._localAlignmentAxis = config.Orbit.AlignmentAxis; } - } if (config.Base.CenterOfSolarSystem) { Logger.Log($"Setting center of universe to {config.Name}"); - Main.Instance.ModHelper.Events.Unity.FireInNUpdates(() => Locator.GetCenterOfTheUniverse()._staticReferenceFrame = owRigidBody, 2); + // By the time it runs we'll be able to get the OWRB with the method + Main.Instance.ModHelper.Events.Unity.FireInNUpdates(() => Locator.GetCenterOfTheUniverse()._staticReferenceFrame = astroObject.GetAttachedOWRigidbody(), 2); } - return new Tuple(astroObject, owRigidBody); + return astroObject; } } } diff --git a/NewHorizons/Builder/General/DetectorBuilder.cs b/NewHorizons/Builder/General/DetectorBuilder.cs index fc992310..947d760f 100644 --- a/NewHorizons/Builder/General/DetectorBuilder.cs +++ b/NewHorizons/Builder/General/DetectorBuilder.cs @@ -42,6 +42,14 @@ namespace NewHorizons.Builder.General // Could copy the splash from the interloper as well some day } + SetDetector(primaryBody, astroObject, forceDetector); + + detectorGO.SetActive(true); + return detectorGO; + } + + public static void SetDetector(AstroObject primaryBody, AstroObject astroObject, ConstantForceDetector forceDetector) + { GravityVolume parentGravityVolume = primaryBody?.GetAttachedOWRigidbody()?.GetAttachedGravityVolume(); if (parentGravityVolume != null) { @@ -51,9 +59,10 @@ namespace NewHorizons.Builder.General { // It's probably a focal point (or its just broken) var binaryFocalPoint = primaryBody?.gameObject?.GetComponent(); - if(binaryFocalPoint != null) + if (binaryFocalPoint != null) { - if(astroObject.GetCustomName().Equals(binaryFocalPoint.PrimaryName)) { + if (astroObject.GetCustomName().Equals(binaryFocalPoint.PrimaryName)) + { binaryFocalPoint.Primary = astroObject; if (binaryFocalPoint.Secondary != null) { @@ -73,7 +82,7 @@ namespace NewHorizons.Builder.General else { // It's a planet - if(binaryFocalPoint.Primary != null && binaryFocalPoint.Secondary != null) + if (binaryFocalPoint.Primary != null && binaryFocalPoint.Secondary != null) { var fakeBarycenterGravityVolume = binaryFocalPoint.FakeMassBody.GetComponent().GetGravityVolume(); forceDetector._detectableFields = new ForceVolume[] { fakeBarycenterGravityVolume }; @@ -81,9 +90,6 @@ namespace NewHorizons.Builder.General } } } - - detectorGO.SetActive(true); - return detectorGO; } private static void SetBinaryForceDetectableFields(BinaryFocalPoint point, ConstantForceDetector primaryCFD, ConstantForceDetector secondaryCFD) diff --git a/NewHorizons/Builder/General/RigidBodyBuilder.cs b/NewHorizons/Builder/General/RigidBodyBuilder.cs new file mode 100644 index 00000000..40f78df3 --- /dev/null +++ b/NewHorizons/Builder/General/RigidBodyBuilder.cs @@ -0,0 +1,43 @@ +using NewHorizons.External.Configs; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.Builder.General +{ + public static class RigidBodyBuilder + { + public static OWRigidbody Make(GameObject body, IPlanetConfig config) + { + body.AddComponent(); + + Rigidbody rigidBody = body.AddComponent(); + rigidBody.mass = 10000; + rigidBody.drag = 0f; + rigidBody.angularDrag = 0f; + rigidBody.useGravity = false; + rigidBody.isKinematic = true; + rigidBody.interpolation = RigidbodyInterpolation.None; + rigidBody.collisionDetectionMode = CollisionDetectionMode.Discrete; + + KinematicRigidbody kinematicRigidBody = body.AddComponent(); + kinematicRigidBody.centerOfMass = Vector3.zero; + + OWRigidbody owRigidBody = body.AddComponent(); + owRigidBody._kinematicSimulation = true; + owRigidBody._autoGenerateCenterOfMass = true; + owRigidBody.SetIsTargetable(true); + owRigidBody._maintainOriginalCenterOfMass = true; + owRigidBody._rigidbody = rigidBody; + owRigidBody._kinematicRigidbody = kinematicRigidBody; + owRigidBody._origParent = GameObject.Find("SolarSystemRoot").transform; + owRigidBody.EnableKinematicSimulation(); + owRigidBody.MakeKinematic(); + + return owRigidBody; + } + } +} diff --git a/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs b/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs index b00574f0..774ac6c3 100644 --- a/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs +++ b/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs @@ -17,8 +17,13 @@ namespace NewHorizons.Builder.Orbital { public static InitialMotion Make(GameObject body, AstroObject primaryBody, AstroObject secondaryBody, OWRigidbody OWRB, OrbitModule orbit) { + // Doing it like this so the planet orbit updater can just use an existing initial motion with the other method InitialMotion initialMotion = body.AddComponent(); + return SetInitialMotion(initialMotion, primaryBody, secondaryBody, OWRB, orbit); + } + public static InitialMotion SetInitialMotion(InitialMotion initialMotion, AstroObject primaryBody, AstroObject secondaryBody, OWRigidbody OWRB, OrbitModule orbit) + { // This bit makes the initial motion not try to calculate the orbit velocity itself for reasons initialMotion._orbitImpulseScalar = 0f; diff --git a/NewHorizons/Builder/Orbital/OrbitlineBuilder.cs b/NewHorizons/Builder/Orbital/OrbitlineBuilder.cs index 3b3cef88..bf614acf 100644 --- a/NewHorizons/Builder/Orbital/OrbitlineBuilder.cs +++ b/NewHorizons/Builder/Orbital/OrbitlineBuilder.cs @@ -11,7 +11,7 @@ namespace NewHorizons.Builder.Orbital { static class OrbitlineBuilder { - public static void Make(GameObject body, NHAstroObject astroObject, bool isMoon, IPlanetConfig config) + public static OrbitLine Make(GameObject body, NHAstroObject astroObject, bool isMoon, IPlanetConfig config) { GameObject orbitGO = new GameObject("Orbit"); orbitGO.transform.parent = body.transform; @@ -75,6 +75,8 @@ namespace NewHorizons.Builder.Orbital orbitLine._numVerts = (int)Mathf.Clamp(config.Orbit.SemiMajorAxis / 1000f, numVerts, 4096); Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(orbitLine.InitializeLineRenderer); + + return orbitLine; } } } diff --git a/NewHorizons/Builder/Updater/OrbitUpdater.cs b/NewHorizons/Builder/Updater/OrbitUpdater.cs deleted file mode 100644 index 189263f9..00000000 --- a/NewHorizons/Builder/Updater/OrbitUpdater.cs +++ /dev/null @@ -1,20 +0,0 @@ -using NewHorizons.Builder.Orbital; -using NewHorizons.Utility; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using Logger = NewHorizons.Utility.Logger; - -namespace NewHorizons.Builder.Updater -{ - public static class OrbitUpdater - { - public static void Update(NewHorizonsBody body, GameObject go) - { - Logger.Log("OrbitUpdater does not work currently"); - } - } -} diff --git a/NewHorizons/Handlers/PlanetCreationHandler.cs b/NewHorizons/Handlers/PlanetCreationHandler.cs index fcd3dda0..b7cdface 100644 --- a/NewHorizons/Handlers/PlanetCreationHandler.cs +++ b/NewHorizons/Handlers/PlanetCreationHandler.cs @@ -3,7 +3,6 @@ using NewHorizons.Builder.Body; using NewHorizons.Builder.General; using NewHorizons.Builder.Orbital; using NewHorizons.Builder.Props; -using NewHorizons.Builder.Updater; using NewHorizons.Components; using NewHorizons.Components.Orbital; using NewHorizons.External.VariableSize; @@ -163,6 +162,17 @@ namespace NewHorizons.Handlers var sector = go.GetComponentInChildren(); var rb = go.GetAttachedOWRigidbody(); + // Since orbits are always there just check if they set a semi major axis + if (body.Config.Orbit != null && body.Config.Orbit.SemiMajorAxis != 0f) + { + // If we aren't able to update the orbit wait until later + if(!UpdateBodyOrbit(body, go)) + { + NextPassBodies.Add(body); + return null; + } + } + if (body.Config.ChildrenToDestroy != null && body.Config.ChildrenToDestroy.Length > 0) { foreach (var child in body.Config.ChildrenToDestroy) @@ -174,12 +184,6 @@ namespace NewHorizons.Handlers // Do stuff that's shared between generating new planets and updating old ones go = SharedGenerateBody(body, go, sector, rb); - // Since orbits are always there just check if they set a semi major axis - if (body.Config.Orbit != null && body.Config.Orbit.SemiMajorAxis != 0f) - { - OrbitUpdater.Update(body, go); - } - return go; } @@ -226,9 +230,8 @@ namespace NewHorizons.Handlers sphereOfInfluence = overrideSOI; } - var outputTuple = BaseBuilder.Make(go, primaryBody, body.Config); - var ao = outputTuple.Item1; - var owRigidBody = outputTuple.Item2; + var owRigidBody = RigidBodyBuilder.Make(go, body.Config); + var ao = AstroObjectBuilder.Make(go, primaryBody, body.Config); if (body.Config.Base.SurfaceGravity != 0) { @@ -386,6 +389,76 @@ namespace NewHorizons.Handlers return go; } + public static bool UpdateBodyOrbit(NewHorizonsBody body, GameObject go) + { + Logger.Log($"Updating orbit of [{body.Config.Name}] to [{body.Config.Orbit}]"); + + try + { + var ao = go.GetComponent(); + var aoName = ao.GetAstroObjectName(); + var aoType = ao.GetAstroObjectType(); + + var owrb = go.GetComponent(); + + var im = go.GetComponent(); + + // By default keep it with the same primary body else update to the new one + var primary = ao._primaryBody; + if (!string.IsNullOrEmpty(body.Config.Orbit.PrimaryBody)) + { + // If we can't find the new one we want to try again later (return false) + primary = AstroObjectLocator.GetAstroObject(body.Config.Orbit.PrimaryBody); + if (primary == null) return false; + } + + // Just destroy the existing AO after copying everything over + var newAO = AstroObjectBuilder.Make(go, primary, body.Config); + newAO._gravityVolume = ao._gravityVolume; + newAO._moon = ao._moon; + newAO._name = ao._name; + newAO._owRigidbody = ao._owRigidbody; + newAO._primaryBody = ao._primaryBody; + newAO._rootSector = ao._rootSector; + newAO._sandLevelController = ao._sandLevelController; + newAO._satellite = ao._satellite; + newAO._type = ao._type; + // We need these for later + var moons = AstroObjectLocator.GetMoons(ao); + GameObject.Destroy(ao); + + var orbitLine = go.GetComponentInChildren(); + var isMoon = newAO.GetAstroObjectType() == AstroObject.Type.Moon || newAO.GetAstroObjectType() == AstroObject.Type.Satellite; + var newOrbitLine = OrbitlineBuilder.Make(go, newAO, isMoon, body.Config); + + DetectorBuilder.SetDetector(primary, newAO, go.GetComponentInChildren()); + + // Get ready to move all the satellites + var relativeMoonPositions = moons.Select(x => x.transform.position - go.transform.position).ToArray(); + + // Move the primary + UpdatePosition(go, body, primary, newAO); + + for(int i = 0; i < moons.Count(); i++) + { + moons[i].transform.position = go.transform.position + relativeMoonPositions[i]; + } + + // Have to do this after setting position + InitialMotionBuilder.SetInitialMotion(im, primary, newAO, owrb, body.Config.Orbit); + + // Have to register this new AO to the locator + Locator.RegisterAstroObject(newAO); + } + catch (Exception ex) + { + Logger.LogError($"Couldn't update orbit of [{body.Config.Name}]: {ex.Message}, {ex.StackTrace}"); + // If it doesn't here there's no point trying again so we'll still return true + } + + return true; + } + //private static int j = 0; private static void UpdatePosition(GameObject go, NewHorizonsBody body, AstroObject primaryBody, AstroObject secondaryBody) { diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 8d41c2e3..b5098122 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -3,7 +3,6 @@ using NewHorizons.Builder.General; using NewHorizons.Builder.Orbital; using NewHorizons.Builder.Props; using NewHorizons.Builder.ShipLog; -using NewHorizons.Builder.Updater; using NewHorizons.Components; using NewHorizons.External; using NewHorizons.External.Configs; diff --git a/NewHorizons/Utility/AstroObjectLocator.cs b/NewHorizons/Utility/AstroObjectLocator.cs index 82daed2a..f9cd019f 100644 --- a/NewHorizons/Utility/AstroObjectLocator.cs +++ b/NewHorizons/Utility/AstroObjectLocator.cs @@ -122,5 +122,10 @@ namespace NewHorizons.Utility { _list.Remove(ao); } + + public static AstroObject[] GetMoons(AstroObject primary) + { + return _list.Where(x => x._primaryBody == primary).ToArray(); + } } }