diff --git a/NewHorizons/Builder/Atmosphere/CloudsBuilder.cs b/NewHorizons/Builder/Atmosphere/CloudsBuilder.cs index fce3ada5..da11d9a0 100644 --- a/NewHorizons/Builder/Atmosphere/CloudsBuilder.cs +++ b/NewHorizons/Builder/Atmosphere/CloudsBuilder.cs @@ -1,4 +1,5 @@ using NewHorizons.External.Modules; +using NewHorizons.Components; using NewHorizons.Utility; using OWML.Common; using System; @@ -20,7 +21,7 @@ namespace NewHorizons.Builder.Atmosphere private static readonly int CapTex = Shader.PropertyToID("_CapTex"); private static readonly int ColorRamp = Shader.PropertyToID("_ColorRamp"); - public static void Make(GameObject planetGO, Sector sector, AtmosphereModule atmo, IModBehaviour mod) + public static void Make(GameObject planetGO, Sector sector, AtmosphereModule atmo, bool cloaked, IModBehaviour mod) { if (_lightningPrefab == null) _lightningPrefab = SearchUtilities.Find("GiantsDeep_Body/Sector_GD/Clouds_GD/LightningGenerator_GD"); if (_colorRamp == null) _colorRamp = ImageUtilities.GetTexture(Main.Instance, "Assets/textures/Clouds_Bottom_ramp.png"); @@ -65,8 +66,10 @@ namespace NewHorizons.Builder.Atmosphere bottomTSR.LODBias = 0; bottomTSR.LODRadius = 1f; - TessSphereSectorToggle bottomTSST = cloudsBottomGO.AddComponent(); - bottomTSST._sector = sector; + if (cloaked) + cloudsBottomGO.AddComponent()._sector = sector; + else + cloudsBottomGO.AddComponent()._sector = sector; GameObject cloudsFluidGO = new GameObject("CloudsFluid"); cloudsFluidGO.SetActive(false); diff --git a/NewHorizons/Builder/General/DetectorBuilder.cs b/NewHorizons/Builder/General/DetectorBuilder.cs index 3f47e8bb..82671951 100644 --- a/NewHorizons/Builder/General/DetectorBuilder.cs +++ b/NewHorizons/Builder/General/DetectorBuilder.cs @@ -44,45 +44,41 @@ namespace NewHorizons.Builder.General public static void SetDetector(AstroObject primaryBody, AstroObject astroObject, ConstantForceDetector forceDetector) { - GravityVolume parentGravityVolume = primaryBody?.GetAttachedOWRigidbody()?.GetAttachedGravityVolume(); - if (parentGravityVolume != null) + var binaryFocalPoint = primaryBody?.gameObject?.GetComponent(); + var parentGravityVolume = primaryBody?.GetAttachedOWRigidbody()?.GetAttachedGravityVolume(); + + if (binaryFocalPoint != null) { - forceDetector._detectableFields = new ForceVolume[] { parentGravityVolume }; - } - else if (astroObject != null) - { - // It's probably a focal point (or its just broken) - var binaryFocalPoint = primaryBody?.gameObject?.GetComponent(); - if (binaryFocalPoint != null) + if (astroObject.GetCustomName().Equals(binaryFocalPoint.PrimaryName)) { - if (astroObject.GetCustomName().Equals(binaryFocalPoint.PrimaryName)) + binaryFocalPoint.Primary = astroObject; + if (binaryFocalPoint.Secondary != null) { - binaryFocalPoint.Primary = astroObject; - if (binaryFocalPoint.Secondary != null) - { - var secondaryRB = binaryFocalPoint.Secondary.GetAttachedOWRigidbody(); - SetBinaryForceDetectableFields(binaryFocalPoint, forceDetector, (ConstantForceDetector)secondaryRB.GetAttachedForceDetector()); - } - } - else if (astroObject.GetCustomName().Equals(binaryFocalPoint.SecondaryName)) - { - binaryFocalPoint.Secondary = astroObject; - if (binaryFocalPoint.Primary != null) - { - var primaryRB = binaryFocalPoint.Primary.GetAttachedOWRigidbody(); - SetBinaryForceDetectableFields(binaryFocalPoint, (ConstantForceDetector)primaryRB.GetAttachedForceDetector(), forceDetector); - } - } - else - { - // It's a planet - if (binaryFocalPoint.Primary != null && binaryFocalPoint.Secondary != null) - { - var fakeBarycenterGravityVolume = binaryFocalPoint.FakeMassBody.GetComponent().GetGravityVolume(); - forceDetector._detectableFields = new ForceVolume[] { fakeBarycenterGravityVolume }; - } + var secondaryRB = binaryFocalPoint.Secondary.GetAttachedOWRigidbody(); + SetBinaryForceDetectableFields(binaryFocalPoint, forceDetector, (ConstantForceDetector)secondaryRB.GetAttachedForceDetector()); } } + else if (astroObject.GetCustomName().Equals(binaryFocalPoint.SecondaryName)) + { + binaryFocalPoint.Secondary = astroObject; + if (binaryFocalPoint.Primary != null) + { + var primaryRB = binaryFocalPoint.Primary.GetAttachedOWRigidbody(); + SetBinaryForceDetectableFields(binaryFocalPoint, (ConstantForceDetector)primaryRB.GetAttachedForceDetector(), forceDetector); + } + } + else + { + // It's a planet + if (binaryFocalPoint.Primary != null && binaryFocalPoint.Secondary != null) + { + forceDetector._detectableFields = new ForceVolume[] { parentGravityVolume }; + } + } + } + else + { + forceDetector._detectableFields = new ForceVolume[] { parentGravityVolume }; } } diff --git a/NewHorizons/Builder/Orbital/FocalPointBuilder.cs b/NewHorizons/Builder/Orbital/FocalPointBuilder.cs index a9810eda..6c939658 100644 --- a/NewHorizons/Builder/Orbital/FocalPointBuilder.cs +++ b/NewHorizons/Builder/Orbital/FocalPointBuilder.cs @@ -4,6 +4,7 @@ using NewHorizons.External.Modules; using NewHorizons.Handlers; using NewHorizons.Utility; using OWML.Common; +using System.Linq; using UnityEngine; using Logger = NewHorizons.Utility.Logger; namespace NewHorizons.Builder.Orbital @@ -18,12 +19,10 @@ namespace NewHorizons.Builder.Orbital binary.PrimaryName = module.primary; binary.SecondaryName = module.secondary; - // Below is the stupid fix for making circumbinary planets or wtv - // Grab the bodies from the main dictionary NewHorizonsBody primary = null; NewHorizonsBody secondary = null; - foreach (var body in Main.BodyDict[Main.Instance.CurrentStarSystem]) + foreach (var body in Main.BodyDict[config.starSystem]) { if (body.Config.name == module.primary) { @@ -44,28 +43,26 @@ namespace NewHorizons.Builder.Orbital Logger.LogError($"Couldn't make focal point between [{module.primary} = {primary}] and [{module.secondary} = {secondary}]"); return; } + } + + public static void ValidateConfig(PlanetConfig config) + { + var primary = Main.BodyDict[config.starSystem].Where(x => x.Config.name == config.FocalPoint.primary).FirstOrDefault(); + var secondary = Main.BodyDict[config.starSystem].Where(x => x.Config.name == config.FocalPoint.secondary).FirstOrDefault(); var gravitationalMass = GetGravitationalMass(primary.Config) + GetGravitationalMass(secondary.Config); - // Copying it because I don't want to modify the actual config - var fakeMassConfig = new PlanetConfig(); - // Now need to fake the 3 values to make it return this mass - fakeMassConfig.Base.surfaceSize = 1; - fakeMassConfig.Base.surfaceGravity = gravitationalMass * GravityVolume.GRAVITATIONAL_CONSTANT; - fakeMassConfig.Base.gravityFallOff = primary.Config.Base.gravityFallOff; + config.Base.surfaceSize = 1; + config.Base.surfaceGravity = gravitationalMass * GravityVolume.GRAVITATIONAL_CONSTANT; + config.Base.gravityFallOff = primary.Config.Base.gravityFallOff; - // Other stuff to make the fake barycenter not interact with anything in any way - fakeMassConfig.name = config.name + "_FakeBarycenterMass"; - fakeMassConfig.Base.soiOverride = 0; - fakeMassConfig.Base.hasMapMarker = false; - fakeMassConfig.ReferenceFrame.enabled = false; - fakeMassConfig.ReferenceFrame.hideInMap = true; + // Other stuff to make the barycenter not interact with anything in any way + config.Base.soiOverride = 0; - fakeMassConfig.Orbit = new OrbitModule(); - fakeMassConfig.Orbit.CopyPropertiesFrom(config.Orbit); - - binary.FakeMassBody = PlanetCreationHandler.GenerateBody(new NewHorizonsBody(fakeMassConfig, mod)); + var separation = primary.Config.Orbit.semiMajorAxis + secondary.Config.Orbit.semiMajorAxis; + config.ReferenceFrame.bracketRadius = separation; + config.ReferenceFrame.targetColliderRadius = separation; } private static float GetGravitationalMass(PlanetConfig config) diff --git a/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs b/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs index d204e79f..36ece316 100644 --- a/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs +++ b/NewHorizons/Builder/Orbital/InitialMotionBuilder.cs @@ -70,8 +70,8 @@ namespace NewHorizons.Builder.Orbital else { // It's a circumbinary moon/planet - var fakePrimaryBody = focalPoint.FakeMassBody.GetComponent(); - SetMotionFromPrimary(fakePrimaryBody, secondaryBody, secondaryBody as NHAstroObject, initialMotion); + var focalPointAO = focalPoint.GetComponent(); + SetMotionFromPrimary(focalPointAO, secondaryBody, secondaryBody as NHAstroObject, initialMotion); } } else if (primaryBody.GetGravityVolume()) @@ -107,11 +107,11 @@ namespace NewHorizons.Builder.Orbital // Might make binaries with binaries with binaries work if (primaryBody.GetGravityVolume() == null) { - primaryGravity = new Gravity(primaryBody.GetComponent()?.FakeMassBody?.GetComponent()?.GetGravityVolume()); + primaryGravity = new Gravity(primaryBody.GetGravityVolume()); } if (secondaryBody.GetGravityVolume() == null) { - secondaryGravity = new Gravity(secondaryBody.GetComponent()?.FakeMassBody?.GetComponent()?.GetGravityVolume()); + secondaryGravity = new Gravity(secondaryBody.GetGravityVolume()); } // Update the positions diff --git a/NewHorizons/Components/CloakSectorController.cs b/NewHorizons/Components/CloakSectorController.cs index 09f50776..7d0bbf7b 100644 --- a/NewHorizons/Components/CloakSectorController.cs +++ b/NewHorizons/Components/CloakSectorController.cs @@ -11,6 +11,8 @@ namespace NewHorizons.Components private bool _isInitialized; private List _renderers = null; + private List _tessellatedRenderers = null; + private List _tessSphereToggles = null; public static bool isPlayerInside = false; public static bool isProbeInside = false; @@ -51,6 +53,8 @@ namespace NewHorizons.Components private void SetUpList() { _renderers = _root.GetComponentsInChildren().ToList(); + _tessellatedRenderers = _root.GetComponentsInChildren().ToList(); + _tessSphereToggles = _root.GetComponentsInChildren().ToList(); } public void OnPlayerEnter() @@ -62,6 +66,16 @@ namespace NewHorizons.Components renderer.forceRenderingOff = false; } + foreach (var tessellatedRenderer in _tessellatedRenderers) + { + tessellatedRenderer.enabled = true; + } + + foreach (var tessSphereSectorToggle in _tessSphereToggles) + { + tessSphereSectorToggle.OnEnterCloakField(); + } + isPlayerInside = true; GlobalMessenger.FireEvent("PlayerEnterCloakField"); } @@ -75,6 +89,16 @@ namespace NewHorizons.Components renderer.forceRenderingOff = true; } + foreach (var tessellatedRenderer in _tessellatedRenderers) + { + tessellatedRenderer.enabled = false; + } + + foreach (var tessSphereSectorToggle in _tessSphereToggles) + { + tessSphereSectorToggle.OnExitCloakField(); + } + isPlayerInside = false; GlobalMessenger.FireEvent("PlayerExitCloakField"); } diff --git a/NewHorizons/Components/CloakedTessSphereSectorToggle.cs b/NewHorizons/Components/CloakedTessSphereSectorToggle.cs new file mode 100644 index 00000000..b5232720 --- /dev/null +++ b/NewHorizons/Components/CloakedTessSphereSectorToggle.cs @@ -0,0 +1,74 @@ +using UnityEngine; + +namespace NewHorizons.Components +{ + [RequireComponent(typeof(TessellatedSphereRenderer))] + public class CloakedTessSphereSectorToggle : SectoredMonoBehaviour + { + protected TessellatedSphereRenderer _renderer; + protected bool _inMapView; + protected bool _inCloakField; + + public override void Awake() + { + _renderer = GetComponent(); + GlobalMessenger.AddListener("EnterMapView", OnEnterMapView); + GlobalMessenger.AddListener("ExitMapView", OnExitMapView); + } + + public override void OnDestroy() + { + GlobalMessenger.RemoveListener("EnterMapView", OnEnterMapView); + GlobalMessenger.RemoveListener("ExitMapView", OnExitMapView); + } + + public override void OnChangeSector(Sector oldSector, Sector newSector) => OnSectorOccupantsUpdated(); + + public override void OnSectorOccupantsUpdated() + { + if (_inMapView || !_inCloakField) + return; + if (_sector != null) + { + if (_sector.ContainsAnyOccupants(DynamicOccupant.Player | DynamicOccupant.Probe) && !_renderer.enabled) + { + _renderer.enabled = true; + } + else + { + if (_sector.ContainsAnyOccupants(DynamicOccupant.Player | DynamicOccupant.Probe) || !_renderer.enabled) + return; + _renderer.enabled = false; + } + } + else + _renderer.enabled = true; + } + + public virtual void OnEnterMapView() + { + _inMapView = true; + if (_renderer.enabled) + _renderer.enabled = false; + } + + public virtual void OnExitMapView() + { + _inMapView = false; + OnSectorOccupantsUpdated(); + } + + public virtual void OnEnterCloakField() + { + _inCloakField = true; + OnSectorOccupantsUpdated(); + } + + public virtual void OnExitCloakField() + { + _inCloakField = false; + if (_renderer.enabled) + _renderer.enabled = false; + } + } +} diff --git a/NewHorizons/Components/Orbital/BinaryFocalPoint.cs b/NewHorizons/Components/Orbital/BinaryFocalPoint.cs index 6738a690..c67fd568 100644 --- a/NewHorizons/Components/Orbital/BinaryFocalPoint.cs +++ b/NewHorizons/Components/Orbital/BinaryFocalPoint.cs @@ -1,4 +1,4 @@ -using UnityEngine; +using UnityEngine; namespace NewHorizons.Components.Orbital { public class BinaryFocalPoint : MonoBehaviour @@ -9,14 +9,6 @@ namespace NewHorizons.Components.Orbital public AstroObject Primary { get; set; } public AstroObject Secondary { get; set; } - public GameObject FakeMassBody { get; set; } - - void Start() - { - // Make sure its active but maybe it hasn't been set yet - if (FakeMassBody) FakeMassBody.SetActive(true); - } - void Update() { if (Primary == null || Secondary == null) @@ -48,8 +40,6 @@ namespace NewHorizons.Components.Orbital { component2.DisableMarker(); } - - FakeMassBody.SetActive(false); } } } diff --git a/NewHorizons/External/Configs/PlanetConfig.cs b/NewHorizons/External/Configs/PlanetConfig.cs index c595fc26..e571e431 100644 --- a/NewHorizons/External/Configs/PlanetConfig.cs +++ b/NewHorizons/External/Configs/PlanetConfig.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; +using NewHorizons.Builder.Orbital; using NewHorizons.External.Modules; using NewHorizons.External.Modules.VariableSize; using Newtonsoft.Json; diff --git a/NewHorizons/Handlers/PlanetCreationHandler.cs b/NewHorizons/Handlers/PlanetCreationHandler.cs index af0f1a51..1da8e099 100644 --- a/NewHorizons/Handlers/PlanetCreationHandler.cs +++ b/NewHorizons/Handlers/PlanetCreationHandler.cs @@ -326,6 +326,9 @@ namespace NewHorizons.Handlers public static GameObject GenerateStandardBody(NewHorizonsBody body, bool defaultPrimaryToSun = false) { + // Focal points are weird + if (body.Config.FocalPoint != null) FocalPointBuilder.ValidateConfig(body.Config); + AstroObject primaryBody; if (body.Config.Orbit.primaryBody != null) { @@ -508,6 +511,8 @@ namespace NewHorizons.Handlers SandBuilder.Make(go, sector, rb, body.Config.Sand); } + var willHaveCloak = body.Config.Cloak != null && body.Config.Cloak.radius != 0f; + if (body.Config.Atmosphere != null) { var airInfo = new AtmosphereModule.AirInfo() @@ -524,7 +529,7 @@ namespace NewHorizons.Handlers if (!string.IsNullOrEmpty(body.Config.Atmosphere?.clouds?.texturePath)) { - CloudsBuilder.Make(go, sector, body.Config.Atmosphere, body.Mod); + CloudsBuilder.Make(go, sector, body.Config.Atmosphere, willHaveCloak, body.Mod); SunOverrideBuilder.Make(go, sector, body.Config.Atmosphere, body.Config.Water, surfaceSize); } @@ -553,7 +558,7 @@ namespace NewHorizons.Handlers } // Has to go last probably - if (body.Config.Cloak != null && body.Config.Cloak.radius != 0f) + if (willHaveCloak) { CloakBuilder.Make(go, sector, rb, body.Config.Cloak, !body.Config.ReferenceFrame.hideInMap, body.Mod); } diff --git a/docs/content/pages/tutorials/details.md b/docs/content/pages/tutorials/details.md index d4517922..93390d5c 100644 --- a/docs/content/pages/tutorials/details.md +++ b/docs/content/pages/tutorials/details.md @@ -1,6 +1,6 @@ --- Title: Detailing -Sort_Priority: 90 +Sort_Priority: 85 --- # Details/Scatterer diff --git a/docs/content/pages/tutorials/star_system.md b/docs/content/pages/tutorials/star_system.md new file mode 100644 index 00000000..734a9b61 --- /dev/null +++ b/docs/content/pages/tutorials/star_system.md @@ -0,0 +1,46 @@ +--- +Title: Star System +Description: A guide to editing a custom star system in New Horizons +Sort_Priority: 90 +--- + +# Intro + +Welcome! This page outlines how to edit a custom star system. + +## Getting Started + +Star Systems are placed in a folder called systems within your mod folder. + +The name of your star system config must be the same as the unique id used in the `starSystem` field of your planet configs. Example: `xen.RealSolarSystem.json`. + +A star system config file will look something like this: + +```json +{ + "$schema": "https://raw.githubusercontent.com/xen-42/outer-wilds-new-horizons/main/NewHorizons/Schemas/star_system_schema.json", + "coords": { + "x": [ 4, 0, 3, 1 ], + "y": [ 0, 5, 4 ], + "z": [ 5, 4, 0, 3, 1 ] + }, + "vesselPosition": { + "x": 0, + "y": 0, + "z": 8000 + } +} +``` + +To see all the different things you can put into a config file check out the [Star System Schema]({{ 'Star System Schema'|route}}). + +## Vessel Coordinates + +You can warp to custom star systems via the Nomai vessel. Each coordinate has to be 2-6 points long. +These are the points for each coordinate node. When making your unique coordinate you should only use each point once. +![nomaiCoordinateIndexes]({{ "images/star_system/nomai_coordinate_indexes.webp"|static }}) + +### Hearthian Solar System Vessel Coordinates + +You can use these coordinates to warp back to the hearthian solar system. +![hearthianSolarSystemCoordinates]({{ "images/star_system/hearthian_solar_system_coordinates.webp"|static }}) \ No newline at end of file diff --git a/docs/content/static/images/star_system/hearthian_solar_system_coordinates.webp b/docs/content/static/images/star_system/hearthian_solar_system_coordinates.webp new file mode 100644 index 00000000..17730df0 Binary files /dev/null and b/docs/content/static/images/star_system/hearthian_solar_system_coordinates.webp differ diff --git a/docs/content/static/images/star_system/nomai_coordinate_indexes.webp b/docs/content/static/images/star_system/nomai_coordinate_indexes.webp new file mode 100644 index 00000000..5bc128dd Binary files /dev/null and b/docs/content/static/images/star_system/nomai_coordinate_indexes.webp differ