Tidied up AstroObjectLocator

Orbit updating breaks if you make an existing planet a moon of something and then you move that planet.
This commit is contained in:
Nick 2022-05-07 04:32:47 -04:00
parent 59109671c9
commit a41bd8c352
5 changed files with 207 additions and 214 deletions

View File

@ -40,7 +40,7 @@ namespace NewHorizons.Builder.General
var sunVolumes = GameObject.Find("Sun_Body/Sector_SUN/Volumes_SUN"); var sunVolumes = GameObject.Find("Sun_Body/Sector_SUN/Volumes_SUN");
sunVolumes.SetActive(false); sunVolumes.SetActive(false);
foreach(var name in _solarSystemBodies) foreach (var name in _solarSystemBodies)
{ {
var ao = AstroObjectLocator.GetAstroObject(name); var ao = AstroObjectLocator.GetAstroObject(name);
if (ao != null) Main.Instance.ModHelper.Events.Unity.FireInNUpdates(() => RemoveBody(ao, false), 2); if (ao != null) Main.Instance.ModHelper.Events.Unity.FireInNUpdates(() => RemoveBody(ao, false), 2);
@ -68,7 +68,7 @@ namespace NewHorizons.Builder.General
if (ao.GetAstroObjectName() == AstroObject.Name.BrittleHollow) if (ao.GetAstroObjectName() == AstroObject.Name.BrittleHollow)
{ {
RemoveBody(AstroObjectLocator.GetAstroObject(AstroObject.Name.WhiteHole), delete, toDestroy); RemoveBody(AstroObjectLocator.GetAstroObject(AstroObject.Name.WhiteHole.ToString()), delete, toDestroy);
} }
// Check if any other objects depend on it and remove them too // Check if any other objects depend on it and remove them too
@ -77,12 +77,12 @@ namespace NewHorizons.Builder.General
{ {
if (obj?.gameObject == null || !obj.gameObject.activeInHierarchy) if (obj?.gameObject == null || !obj.gameObject.activeInHierarchy)
{ {
AstroObjectLocator.RemoveAstroObject(obj); AstroObjectLocator.DeregisterCustomAstroObject(obj);
continue; continue;
} }
if (ao.Equals(obj.GetPrimaryBody())) if (ao.Equals(obj.GetPrimaryBody()))
{ {
AstroObjectLocator.RemoveAstroObject(obj); AstroObjectLocator.DeregisterCustomAstroObject(obj);
RemoveBody(obj, delete, toDestroy); RemoveBody(obj, delete, toDestroy);
} }
} }
@ -147,12 +147,13 @@ namespace NewHorizons.Builder.General
} }
// Just delete the children // Just delete the children
foreach(var child in AstroObjectLocator.GetChildren(ao)) foreach (var child in AstroObjectLocator.GetChildren(ao))
{ {
if (child.name == "Ship_Body") continue;
DisableBody(child, true); DisableBody(child, true);
} }
} }
catch(Exception e) catch (Exception e)
{ {
Logger.LogWarning($"Exception thrown when trying to delete bodies related to [{ao.name}]: {e.Message}, {e.StackTrace}"); Logger.LogWarning($"Exception thrown when trying to delete bodies related to [{ao.name}]: {e.Message}, {e.StackTrace}");
} }
@ -183,7 +184,7 @@ namespace NewHorizons.Builder.General
{ {
GameObject.Destroy(GameObject.FindObjectOfType<DistantProxyManager>().gameObject); GameObject.Destroy(GameObject.FindObjectOfType<DistantProxyManager>().gameObject);
foreach(var name in _solarSystemBodies) foreach (var name in _solarSystemBodies)
{ {
RemoveProxy(name.Replace(" ", "").Replace("'", "")); RemoveProxy(name.Replace(" ", "").Replace("'", ""));
} }

View File

@ -19,10 +19,10 @@ namespace NewHorizons.Builder.Orbital
{ {
// Doing it like this so the planet orbit updater can just use an existing initial motion with the other method // Doing it like this so the planet orbit updater can just use an existing initial motion with the other method
InitialMotion initialMotion = body.AddComponent<InitialMotion>(); InitialMotion initialMotion = body.AddComponent<InitialMotion>();
return SetInitialMotion(initialMotion, primaryBody, secondaryBody, OWRB, orbit); return SetInitialMotionFromConfig(initialMotion, primaryBody, secondaryBody, orbit);
} }
public static InitialMotion SetInitialMotion(InitialMotion initialMotion, AstroObject primaryBody, AstroObject secondaryBody, OWRigidbody OWRB, OrbitModule orbit) public static InitialMotion SetInitialMotionFromConfig(InitialMotion initialMotion, AstroObject primaryBody, AstroObject secondaryBody, OrbitModule orbit)
{ {
// This bit makes the initial motion not try to calculate the orbit velocity itself for reasons // This bit makes the initial motion not try to calculate the orbit velocity itself for reasons
initialMotion._orbitImpulseScalar = 0f; initialMotion._orbitImpulseScalar = 0f;
@ -34,43 +34,7 @@ namespace NewHorizons.Builder.Orbital
if (!orbit.IsStatic && primaryBody != null) if (!orbit.IsStatic && primaryBody != null)
{ {
var focalPoint = primaryBody.GetComponent<BinaryFocalPoint>(); SetInitialMotion(initialMotion, primaryBody, secondaryBody);
if (focalPoint)
{
// Focal stuff
var name = secondaryBody.GetCustomName();
if (name == focalPoint.PrimaryName || name == focalPoint.SecondaryName)
{
// The one we're currently looking at is always null
var otherBody = focalPoint.Primary ?? focalPoint.Secondary;
if (otherBody != null)
{
// We set the positions and velocities of both right now
if (name == focalPoint.PrimaryName)
{
SetBinaryInitialMotion(primaryBody, secondaryBody as NHAstroObject, otherBody as NHAstroObject);
}
else
{
SetBinaryInitialMotion(primaryBody, otherBody as NHAstroObject, secondaryBody as NHAstroObject);
}
}
}
else
{
// It's a circumbinary moon/planet
var fakePrimaryBody = focalPoint.FakeMassBody.GetComponent<AstroObject>();
SetMotionFromPrimary(fakePrimaryBody, secondaryBody as NHAstroObject, initialMotion);
}
}
else if (primaryBody.GetGravityVolume())
{
SetMotionFromPrimary(primaryBody, secondaryBody as NHAstroObject, initialMotion);
}
else
{
Logger.Log($"No primary gravity or focal point for {primaryBody}");
}
} }
else else
{ {
@ -81,6 +45,47 @@ namespace NewHorizons.Builder.Orbital
return initialMotion; return initialMotion;
} }
public static void SetInitialMotion(InitialMotion initialMotion, AstroObject primaryBody, AstroObject secondaryBody)
{
var focalPoint = primaryBody.GetComponent<BinaryFocalPoint>();
if (focalPoint)
{
// Focal stuff
var name = secondaryBody.GetCustomName();
if (name == focalPoint.PrimaryName || name == focalPoint.SecondaryName)
{
// The one we're currently looking at is always null
var otherBody = focalPoint.Primary ?? focalPoint.Secondary;
if (otherBody != null)
{
// We set the positions and velocities of both right now
if (name == focalPoint.PrimaryName)
{
SetBinaryInitialMotion(primaryBody, secondaryBody as NHAstroObject, otherBody as NHAstroObject);
}
else
{
SetBinaryInitialMotion(primaryBody, otherBody as NHAstroObject, secondaryBody as NHAstroObject);
}
}
}
else
{
// It's a circumbinary moon/planet
var fakePrimaryBody = focalPoint.FakeMassBody.GetComponent<AstroObject>();
SetMotionFromPrimary(fakePrimaryBody, secondaryBody as NHAstroObject, initialMotion);
}
}
else if (primaryBody.GetGravityVolume())
{
SetMotionFromPrimary(primaryBody, secondaryBody as NHAstroObject, initialMotion);
}
else
{
Logger.Log($"No primary gravity or focal point for {primaryBody}");
}
}
private static void SetMotionFromPrimary(AstroObject primaryBody, NHAstroObject secondaryBody, InitialMotion initialMotion) private static void SetMotionFromPrimary(AstroObject primaryBody, NHAstroObject secondaryBody, InitialMotion initialMotion)
{ {
initialMotion.SetPrimaryBody(primaryBody.GetAttachedOWRigidbody()); initialMotion.SetPrimaryBody(primaryBody.GetAttachedOWRigidbody());

View File

@ -166,7 +166,7 @@ namespace NewHorizons.Handlers
if (body.Config.Orbit != null && body.Config.Orbit.SemiMajorAxis != 0f) if (body.Config.Orbit != null && body.Config.Orbit.SemiMajorAxis != 0f)
{ {
// If we aren't able to update the orbit wait until later // If we aren't able to update the orbit wait until later
if(!UpdateBodyOrbit(body, go)) if (!UpdateBodyOrbit(body, go))
{ {
NextPassBodies.Add(body); NextPassBodies.Add(body);
return null; return null;
@ -418,14 +418,18 @@ namespace NewHorizons.Handlers
newAO._moon = ao._moon; newAO._moon = ao._moon;
newAO._name = ao._name; newAO._name = ao._name;
newAO._owRigidbody = ao._owRigidbody; newAO._owRigidbody = ao._owRigidbody;
newAO._primaryBody = primary;
newAO._rootSector = ao._rootSector; newAO._rootSector = ao._rootSector;
newAO._sandLevelController = ao._sandLevelController; newAO._sandLevelController = ao._sandLevelController;
newAO._satellite = ao._satellite; newAO._satellite = ao._satellite;
newAO._type = ao._type; newAO._type = ao._type;
// We need these for later // We need these for later
var moons = AstroObjectLocator.GetMoons(ao); var children = AstroObjectLocator.GetChildren(ao).Concat(AstroObjectLocator.GetMoons(ao)).ToArray();
AstroObjectLocator.DeregisterCustomAstroObject(ao);
GameObject.Destroy(ao); GameObject.Destroy(ao);
AstroObjectLocator.RegisterCustomAstroObject(newAO);
newAO._primaryBody = primary;
var orbitLine = go.GetComponentInChildren<OrbitLine>(); var orbitLine = go.GetComponentInChildren<OrbitLine>();
var isMoon = newAO.GetAstroObjectType() == AstroObject.Type.Moon || newAO.GetAstroObjectType() == AstroObject.Type.Satellite; var isMoon = newAO.GetAstroObjectType() == AstroObject.Type.Moon || newAO.GetAstroObjectType() == AstroObject.Type.Satellite;
@ -434,18 +438,40 @@ namespace NewHorizons.Handlers
DetectorBuilder.SetDetector(primary, newAO, go.GetComponentInChildren<ConstantForceDetector>()); DetectorBuilder.SetDetector(primary, newAO, go.GetComponentInChildren<ConstantForceDetector>());
// Get ready to move all the satellites // Get ready to move all the satellites
var relativeMoonPositions = moons.Select(x => x.transform.position - go.transform.position).ToArray(); var relativeMoonPositions = children.Select(x => x.transform.position - go.transform.position).ToArray();
// If its tidally locked change the alignment
var alignment = go.GetComponent<AlignWithTargetBody>();
if (alignment != null)
{
alignment.SetTargetBody(primary.GetComponent<OWRigidbody>());
}
// Move the primary // Move the primary
UpdatePosition(go, body, primary, newAO); UpdatePosition(go, body, primary, newAO);
for(int i = 0; i < moons.Count(); i++) for (int i = 0; i < children.Count(); i++)
{ {
moons[i].transform.position = go.transform.position + relativeMoonPositions[i]; var child = children[i];
// If the child is an AO we do stuff too
var childAO = child.GetComponent<AstroObject>();
if (childAO != null)
{
foreach (var childChild in AstroObjectLocator.GetChildren(childAO))
{
var dPos = childChild.transform.position - child.transform.position;
childChild.transform.position = go.transform.position + relativeMoonPositions[i] + dPos;
}
// Make sure the moons get updated to the new AO
childAO._primaryBody = newAO;
}
child.transform.position = go.transform.position + relativeMoonPositions[i];
} }
// Have to do this after setting position // Have to do this after setting position
InitialMotionBuilder.SetInitialMotion(im, primary, newAO, owrb, body.Config.Orbit); InitialMotionBuilder.SetInitialMotion(im, primary, newAO);
// Have to register this new AO to the locator // Have to register this new AO to the locator
Locator.RegisterAstroObject(newAO); Locator.RegisterAstroObject(newAO);
@ -461,7 +487,7 @@ namespace NewHorizons.Handlers
private static void UpdatePosition(GameObject go, NewHorizonsBody body, AstroObject primaryBody, AstroObject secondaryBody) private static void UpdatePosition(GameObject go, NewHorizonsBody body, AstroObject primaryBody, AstroObject secondaryBody)
{ {
Logger.Log($"Placing [{secondaryBody.name}] around [{primaryBody.name}]"); Logger.Log($"Placing [{secondaryBody?.name}] around [{primaryBody?.name}]");
go.transform.parent = Locator.GetRootTransform(); go.transform.parent = Locator.GetRootTransform();

View File

@ -245,7 +245,7 @@ namespace NewHorizons
if (map != null) map._maxPanDistance = FurthestOrbit * 1.5f; if (map != null) map._maxPanDistance = FurthestOrbit * 1.5f;
// Fix the map satellite // Fix the map satellite
AstroObjectLocator.GetAstroObject(AstroObject.Name.MapSatellite).gameObject.AddComponent<MapSatelliteOrbitFix>(); GameObject.Find("HearthianMapSatellite_Body").AddComponent<MapSatelliteOrbitFix>();
} }
else else
{ {

View File

@ -9,168 +9,129 @@ namespace NewHorizons.Utility
{ {
public static class AstroObjectLocator public static class AstroObjectLocator
{ {
private static AstroObject _timberMoon; private static Dictionary<string, AstroObject> _customAstroObjectDictionary = new Dictionary<string, AstroObject>();
private static AstroObject _volcanicMoon;
private static AstroObject _sunStation;
private static AstroObject _mapSatellite;
private static Dictionary<string, AstroObject> _customAstroObjectDictionary = new Dictionary<string, AstroObject>();
private static List<AstroObject> _list = new List<AstroObject>(); public static void Init()
public static void Init()
{
_list = new List<AstroObject>();
_customAstroObjectDictionary = new Dictionary<string, AstroObject>();
foreach (AstroObject ao in GameObject.FindObjectsOfType<AstroObject>())
{
AddAstroObject(ao);
}
}
public static AstroObject GetAstroObject(string name, bool flag = false)
{ {
if (_customAstroObjectDictionary.ContainsKey(name)) return _customAstroObjectDictionary[name]; _customAstroObjectDictionary = new Dictionary<string, AstroObject>();
foreach (AstroObject ao in GameObject.FindObjectsOfType<AstroObject>())
var stringID = name.ToUpper().Replace(" ", "_").Replace("'", "");
if (stringID.Equals("ATTLEROCK")) stringID = "TIMBER_MOON";
if (stringID.Equals("HOLLOWS_LANTERN")) stringID = "VOLCANIC_MOON";
if (stringID.Equals("ASH_TWIN")) stringID = "TOWER_TWIN";
if (stringID.Equals("EMBER_TWIN")) stringID = "CAVE_TWIN";
if (stringID.Equals("INTERLOPER")) stringID = "COMET";
if (stringID.ToUpper().Replace("_", "").Equals("MAPSATELLITE"))
return GetAstroObject(AstroObject.Name.MapSatellite);
var aoName = AstroObject.StringIDToAstroObjectName(stringID);
if (aoName != AstroObject.Name.None && aoName != AstroObject.Name.CustomString) return GetAstroObject(aoName);
// Try again
if (!flag) return GetAstroObject(name.Replace(" ", ""), true);
return null;
}
public static AstroObject GetAstroObject(AstroObject.Name astroObjectName, string customName = null)
{
switch (astroObjectName)
{
case AstroObject.Name.Sun:
case AstroObject.Name.CaveTwin:
case AstroObject.Name.TowerTwin:
case AstroObject.Name.TimberHearth:
case AstroObject.Name.BrittleHollow:
case AstroObject.Name.GiantsDeep:
case AstroObject.Name.DarkBramble:
case AstroObject.Name.Comet:
case AstroObject.Name.WhiteHole:
case AstroObject.Name.WhiteHoleTarget:
case AstroObject.Name.QuantumMoon:
case AstroObject.Name.RingWorld:
case AstroObject.Name.ProbeCannon:
case AstroObject.Name.DreamWorld:
return Locator.GetAstroObject(astroObjectName);
case AstroObject.Name.TimberMoon:
if (_timberMoon == null) _timberMoon = GameObject.Find("Moon_Body")?.gameObject?.GetComponent<AstroObject>();
return _timberMoon;
case AstroObject.Name.VolcanicMoon:
if (_volcanicMoon == null) _volcanicMoon = GameObject.Find("VolcanicMoon_Body")?.gameObject?.GetComponent<AstroObject>();
return _volcanicMoon;
case AstroObject.Name.SunStation:
if (_sunStation == null) _sunStation = GameObject.Find("SunStation_Body")?.gameObject?.GetComponent<AstroObject>();
return _sunStation;
case AstroObject.Name.MapSatellite:
if (_mapSatellite == null) _mapSatellite = GameObject.Find("HearthianMapSatellite_Body")?.gameObject?.GetComponent<AstroObject>();
return _mapSatellite;
case AstroObject.Name.CustomString:
return _customAstroObjectDictionary[customName];
}
return null;
}
public static void RegisterCustomAstroObject(AstroObject ao)
{
if (ao.GetAstroObjectName() != AstroObject.Name.CustomString)
{
Logger.Log($"Can't register {ao.name} as it's AstroObject.Name isn't CustomString.");
return;
}
var name = ao.GetCustomName();
if (_customAstroObjectDictionary.Keys.Contains(name))
_customAstroObjectDictionary[name] = ao;
else
_customAstroObjectDictionary.Add(name, ao);
}
public static void DeregisterCustomAstroObject(AstroObject ao)
{
if (ao.GetAstroObjectName() != AstroObject.Name.CustomString) return;
_customAstroObjectDictionary.Remove(ao.GetCustomName());
}
public static AstroObject[] GetAllAstroObjects()
{
return _list.ToArray();
}
public static void AddAstroObject(AstroObject ao)
{
_list.Add(ao);
}
public static void RemoveAstroObject(AstroObject ao)
{
_list.Remove(ao);
}
public static GameObject[] GetMoons(AstroObject primary)
{
return _list.Where(x => x._primaryBody == primary).Select(x => x.gameObject).ToArray();
}
public static GameObject[] GetChildren(AstroObject primary)
{
var otherChildren = new List<GameObject>();
switch(primary.GetAstroObjectName())
{ {
case AstroObject.Name.TowerTwin: RegisterCustomAstroObject(ao);
otherChildren.Add(GameObject.Find("TimeLoopRing_Body")); }
break; }
case AstroObject.Name.ProbeCannon:
otherChildren.Add(GameObject.Find("NomaiProbe_Body")); public static AstroObject GetAstroObject(string name, bool flag = false)
otherChildren.Add(GameObject.Find("CannonMuzzle_Body")); {
otherChildren.Add(GameObject.Find("FakeCannonMuzzle_Body (1)")); if (_customAstroObjectDictionary.ContainsKey(name))
otherChildren.Add(GameObject.Find("CannonBarrel_Body")); {
otherChildren.Add(GameObject.Find("FakeCannonBarrel_Body (1)")); return _customAstroObjectDictionary[name];
otherChildren.Add(GameObject.Find("Debris_Body (1)"));
break;
case AstroObject.Name.SunStation:
otherChildren.Add(GameObject.Find("SS_Debris_Body"));
break;
case AstroObject.Name.GiantsDeep:
otherChildren.Add(GameObject.Find("BrambleIsland_Body"));
otherChildren.Add(GameObject.Find("GabbroIsland_Body"));
otherChildren.Add(GameObject.Find("QuantumIsland_Body"));
otherChildren.Add(GameObject.Find("StatueIsland_Body"));
otherChildren.Add(GameObject.Find("ConstructionYardIsland_Body"));
otherChildren.Add(GameObject.Find("GabbroShip_Body"));
break;
case AstroObject.Name.WhiteHole:
otherChildren.Add(GameObject.Find("WhiteholeStation_Body"));
otherChildren.Add(GameObject.Find("WhiteholeStationSuperstructure_Body"));
break;
case AstroObject.Name.TimberHearth:
otherChildren.Add(GameObject.Find("MiningRig_Body"));
break;
case AstroObject.Name.DreamWorld:
otherChildren.Add(GameObject.Find("BackRaft_Body"));
otherChildren.Add(GameObject.Find("SealRaft_Body"));
break;
default:
break;
} }
return otherChildren.ToArray(); // Else check stock names
var stringID = name.ToUpper().Replace(" ", "_").Replace("'", "");
if (stringID.Equals("ATTLEROCK")) stringID = "TIMBER_MOON";
if (stringID.Equals("HOLLOWS_LANTERN")) stringID = "VOLCANIC_MOON";
if (stringID.Equals("ASH_TWIN")) stringID = "TOWER_TWIN";
if (stringID.Equals("EMBER_TWIN")) stringID = "CAVE_TWIN";
if (stringID.Equals("INTERLOPER")) stringID = "COMET";
string key;
if (stringID.ToUpper().Replace("_", "").Equals("MAPSATELLITE"))
{
key = AstroObject.Name.MapSatellite.ToString();
}
else
{
key = AstroObject.StringIDToAstroObjectName(stringID).ToString();
}
if (_customAstroObjectDictionary.ContainsKey(key))
{
return _customAstroObjectDictionary[key];
}
// Try again
if (!flag) return GetAstroObject(name.Replace(" ", ""), true);
return null;
} }
}
public static void RegisterCustomAstroObject(AstroObject ao)
{
var key = ao._name == AstroObject.Name.CustomString ? ao.GetCustomName() : ao._name.ToString();
if (_customAstroObjectDictionary.Keys.Contains(key))
{
Logger.Log($"Registering duplicate [{ao.name}] as [{key}]");
_customAstroObjectDictionary[key] = ao;
}
else
{
Logger.Log($"Registering [{ao.name}] as [{key}]");
_customAstroObjectDictionary.Add(key, ao);
}
}
public static void DeregisterCustomAstroObject(AstroObject ao)
{
var key = ao._name == AstroObject.Name.CustomString ? ao.GetCustomName() : ao._name.ToString();
_customAstroObjectDictionary.Remove(key);
}
public static AstroObject[] GetAllAstroObjects()
{
return _customAstroObjectDictionary.Values.ToArray();
}
public static GameObject[] GetMoons(AstroObject primary)
{
return _customAstroObjectDictionary.Values.Where(x => x._primaryBody == primary).Select(x => x.gameObject).ToArray();
}
public static GameObject[] GetChildren(AstroObject primary)
{
var otherChildren = new List<GameObject>();
switch (primary.GetAstroObjectName())
{
case AstroObject.Name.TowerTwin:
otherChildren.Add(GameObject.Find("TimeLoopRing_Body"));
break;
case AstroObject.Name.ProbeCannon:
otherChildren.Add(GameObject.Find("NomaiProbe_Body"));
otherChildren.Add(GameObject.Find("CannonMuzzle_Body"));
otherChildren.Add(GameObject.Find("FakeCannonMuzzle_Body (1)"));
otherChildren.Add(GameObject.Find("CannonBarrel_Body"));
otherChildren.Add(GameObject.Find("FakeCannonBarrel_Body (1)"));
otherChildren.Add(GameObject.Find("Debris_Body (1)"));
break;
case AstroObject.Name.SunStation:
otherChildren.Add(GameObject.Find("SS_Debris_Body"));
break;
case AstroObject.Name.GiantsDeep:
otherChildren.Add(GameObject.Find("BrambleIsland_Body"));
otherChildren.Add(GameObject.Find("GabbroIsland_Body"));
otherChildren.Add(GameObject.Find("QuantumIsland_Body"));
otherChildren.Add(GameObject.Find("StatueIsland_Body"));
otherChildren.Add(GameObject.Find("ConstructionYardIsland_Body"));
otherChildren.Add(GameObject.Find("GabbroShip_Body"));
break;
case AstroObject.Name.WhiteHole:
otherChildren.Add(GameObject.Find("WhiteholeStation_Body"));
otherChildren.Add(GameObject.Find("WhiteholeStationSuperstructure_Body"));
break;
case AstroObject.Name.TimberHearth:
otherChildren.Add(GameObject.Find("MiningRig_Body"));
otherChildren.Add(GameObject.Find("Ship_Body"));
break;
case AstroObject.Name.DreamWorld:
otherChildren.Add(GameObject.Find("BackRaft_Body"));
otherChildren.Add(GameObject.Find("SealRaft_Body"));
break;
default:
break;
}
return otherChildren.ToArray();
}
}
} }