using NewHorizons.External; using NewHorizons.Utility; using OWML.Utils; using System; using System.Reflection; using UnityEngine; using NewHorizons.External.Configs; using Logger = NewHorizons.Utility.Logger; namespace NewHorizons.Builder.General { public static class GravityBuilder { public static GravityVolume Make(GameObject planetGO, AstroObject ao, IPlanetConfig config) { var exponent = config.Base.GravityFallOff.Equals("linear") ? 1f : 2f; var GM = config.Base.SurfaceGravity * Mathf.Pow(config.Base.SurfaceSize, exponent); // Gravity limit will be when the acceleration it would cause is less than 0.1 m/s^2 var gravityRadius = GM / 0.1f; if (exponent == 2f) gravityRadius = Mathf.Sqrt(gravityRadius); // To let you actually orbit things the way you would expect we cap this at 4x the diameter if its not a star or black hole (this is what giants deep has) if (config.Star == null && config.Singularity == null) gravityRadius = Mathf.Min(gravityRadius, 4 * config.Base.SurfaceSize); else gravityRadius = Mathf.Min(gravityRadius, 15 * config.Base.SurfaceSize); if (config.Base.SphereOfInfluence != 0f) gravityRadius = config.Base.SphereOfInfluence; GameObject gravityGO = new GameObject("GravityWell"); gravityGO.transform.parent = planetGO.transform; gravityGO.transform.localPosition = Vector3.zero; gravityGO.layer = 17; gravityGO.SetActive(false); SphereCollider SC = gravityGO.AddComponent(); SC.isTrigger = true; SC.radius = gravityRadius; OWCollider OWC = gravityGO.AddComponent(); OWC.SetLODActivationMask(DynamicOccupant.Player); OWTriggerVolume OWTV = gravityGO.AddComponent(); GravityVolume GV = gravityGO.AddComponent(); GV._cutoffAcceleration = 0.1f; GravityVolume.FalloffType falloff = GravityVolume.FalloffType.linear; if (config.Base.GravityFallOff.ToUpper().Equals("LINEAR")) falloff = GravityVolume.FalloffType.linear; else if (config.Base.GravityFallOff.ToUpper().Equals("INVERSESQUARED")) falloff = GravityVolume.FalloffType.inverseSquared; else Logger.LogError($"Couldn't set gravity type {config.Base.GravityFallOff}. Must be either \"linear\" or \"inverseSquared\". Defaulting to linear."); GV._falloffType = falloff; GV._alignmentRadius = config.Base.SurfaceGravity != 0 ? 1.5f * config.Base.SurfaceSize : 0f; GV._upperSurfaceRadius = config.Base.SurfaceSize; GV._lowerSurfaceRadius = 0; GV._layer = 3; GV._priority = 0; GV._alignmentPriority = 0; GV._surfaceAcceleration = config.Base.SurfaceGravity; GV._inheritable = false; GV._isPlanetGravityVolume = true; GV._cutoffRadius = 0f; gravityGO.SetActive(true); ao._gravityVolume = GV; return GV; } } }