diff --git a/NewHorizons/Builder/Props/EchoesOfTheEye/DreamSimulationBuilder.cs b/NewHorizons/Builder/Body/DreamDimensionBuilder.cs similarity index 74% rename from NewHorizons/Builder/Props/EchoesOfTheEye/DreamSimulationBuilder.cs rename to NewHorizons/Builder/Body/DreamDimensionBuilder.cs index e51165f9..9bd5c69c 100644 --- a/NewHorizons/Builder/Props/EchoesOfTheEye/DreamSimulationBuilder.cs +++ b/NewHorizons/Builder/Body/DreamDimensionBuilder.cs @@ -1,6 +1,10 @@ +using NewHorizons.Components.EOTE; using NewHorizons.Components.Props; +using NewHorizons.External; +using NewHorizons.External.Configs; using NewHorizons.Utility; using NewHorizons.Utility.OuterWilds; +using NewHorizons.Utility.OWML; using System; using System.Collections.Generic; using System.Linq; @@ -8,9 +12,9 @@ using System.Text; using System.Threading.Tasks; using UnityEngine; -namespace NewHorizons.Builder.Props.EchoesOfTheEye +namespace NewHorizons.Builder.Body { - public static class DreamSimulationBuilder + public static class DreamDimensionBuilder { private static Material gridMaterial; private static Material waterMaterial; @@ -30,6 +34,26 @@ namespace NewHorizons.Builder.Props.EchoesOfTheEye "Flame", }; + public static void Make(GameObject planetGO, Sector sector, NewHorizonsBody body) + { + var bodyWantsSimMeshes = body.Config.Dream?.generateSimulationMeshes ?? false; + var propsWantSimMeshes = body.Config.Props?.dreamArrivalPoints?.Any(p => p.generateSimulationMeshes) ?? false; + if (bodyWantsSimMeshes || propsWantSimMeshes) + { + MakeDreamSimulationMeshes(sector ? sector.gameObject : planetGO); + } + + if (body.Config?.Dream?.inDreamWorld ?? false) + { + var dreamDimension = planetGO.AddComponent(); + Delay.FireInNUpdates(() => + { + dreamDimension.Initialize(); + }, 4); + } + + } + public static void MakeDreamSimulationMeshes(GameObject go) { if (gridMaterial == null) gridMaterial = SearchUtilities.FindResourceOfTypeAndName("Terrain_IP_DreamGrid_mat"); diff --git a/NewHorizons/Builder/Props/PropBuildManager.cs b/NewHorizons/Builder/Props/PropBuildManager.cs index 3b5b2e8f..8cff2939 100644 --- a/NewHorizons/Builder/Props/PropBuildManager.cs +++ b/NewHorizons/Builder/Props/PropBuildManager.cs @@ -181,11 +181,6 @@ namespace NewHorizons.Builder.Props } } } - - if (Main.HasDLC && config.Props.dreamArrivalPoints != null && config.Props.dreamArrivalPoints.Any(p => p.generateSimulationMeshes)) - { - DreamSimulationBuilder.MakeDreamSimulationMeshes(sector ? sector.gameObject : go); - } } private static bool _ignoreParent; diff --git a/NewHorizons/Components/EOTE/DreamDimension.cs b/NewHorizons/Components/EOTE/DreamDimension.cs new file mode 100644 index 00000000..00c3389b --- /dev/null +++ b/NewHorizons/Components/EOTE/DreamDimension.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.Components.EOTE +{ + public class DreamDimension : MonoBehaviour + { + private bool initialized; + private bool active; + private List toggledObjects = []; + + public void Initialize() + { + foreach (Transform child in transform) + { + if (child.gameObject.name == "FieldDetector") continue; + toggledObjects.Add(child.gameObject); + } + + initialized = true; + UpdateState(); + } + + public void SetActive(bool active) + { + if (this.active != active) + { + this.active = active; + UpdateState(); + } + } + + void UpdateState() + { + foreach (var obj in toggledObjects) obj.SetActive(active); + } + + public void Update() + { + if (!initialized) return; + SetActive(PlayerState.InDreamWorld()); + } + } +} diff --git a/NewHorizons/External/Configs/PlanetConfig.cs b/NewHorizons/External/Configs/PlanetConfig.cs index 28f00318..2e23410b 100644 --- a/NewHorizons/External/Configs/PlanetConfig.cs +++ b/NewHorizons/External/Configs/PlanetConfig.cs @@ -93,6 +93,11 @@ namespace NewHorizons.External.Configs /// public CloakModule Cloak; + /// + /// Make this planet part of the dream world + /// + public DreamModule Dream; + /// /// Make this body into a focal point (barycenter) /// @@ -282,6 +287,9 @@ namespace NewHorizons.External.Configs // Stars and focal points shouldnt be destroyed by stars if (Star != null || FocalPoint != null) Base.invulnerableToSun = true; + + // Disable map marker for dream dimensions + if (Dream != null && Dream.inDreamWorld) MapMarker.enabled = false; } public void Migrate() diff --git a/NewHorizons/External/Modules/DreamModule.cs b/NewHorizons/External/Modules/DreamModule.cs new file mode 100644 index 00000000..1d422689 --- /dev/null +++ b/NewHorizons/External/Modules/DreamModule.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NewHorizons.External.Modules +{ + [JsonObject] + public class DreamModule + { + /// + /// Setting this value will make this body a dream world style dimension where its contents are only activated while entering it from a dream campfire. Disables the body's map marker. + /// + public bool inDreamWorld; + /// + /// Whether to generate simulation meshes (the models used in the "tronworld" or "matrix" view) for most objects on this planet by cloning the existing meshes and applying the simulation materials. Leave this off if you are building your own simulation meshes or using existing objects which have them. + /// + public bool generateSimulationMeshes; + } +} diff --git a/NewHorizons/External/NewHorizonBody.cs b/NewHorizons/External/NewHorizonBody.cs index 6779e526..b2ed22fc 100644 --- a/NewHorizons/External/NewHorizonBody.cs +++ b/NewHorizons/External/NewHorizonBody.cs @@ -32,8 +32,11 @@ namespace NewHorizons.External { var detailPaths = Config?.Props?.details?.Select(x => x.path) ?? Array.Empty(); return Config?.Cloak != null + || Config?.Dream != null || Config?.Props?.rafts != null || Config?.Props?.slideShows != null + || Config?.Props?.dreamArrivalPoints != null + || Config?.Props?.dreamCampfires != null || detailPaths.Any(x => x.StartsWith("RingWorld_Body") || x.StartsWith("DreamWorld_Body")); } catch diff --git a/NewHorizons/Handlers/PlanetCreationHandler.cs b/NewHorizons/Handlers/PlanetCreationHandler.cs index fda247e7..5f5a0587 100644 --- a/NewHorizons/Handlers/PlanetCreationHandler.cs +++ b/NewHorizons/Handlers/PlanetCreationHandler.cs @@ -1,3 +1,4 @@ +using Epic.OnlineServices; using NewHorizons.Builder.Atmosphere; using NewHorizons.Builder.Body; using NewHorizons.Builder.General; @@ -724,6 +725,11 @@ namespace NewHorizons.Handlers } } + if (Main.HasDLC) + { + DreamDimensionBuilder.Make(go, sector, body); + } + // Has to go last probably if (willHaveCloak) { diff --git a/NewHorizons/Patches/EchoesOfTheEyePatches/DreamworldControllerPatches.cs b/NewHorizons/Patches/EchoesOfTheEyePatches/DreamworldControllerPatches.cs index 6ee7e21f..ede68948 100644 --- a/NewHorizons/Patches/EchoesOfTheEyePatches/DreamworldControllerPatches.cs +++ b/NewHorizons/Patches/EchoesOfTheEyePatches/DreamworldControllerPatches.cs @@ -1,4 +1,5 @@ using HarmonyLib; +using NewHorizons.Components.EOTE; using System.Collections.Generic; using System.Reflection.Emit; using UnityEngine; @@ -31,6 +32,13 @@ namespace NewHorizons.Patches.EchoesOfTheEyePatches [HarmonyPatch(nameof(DreamWorldController.EnterDreamWorld))] public static void DreamWorldController_EnterDreamWorld(DreamWorldController __instance, DreamCampfire dreamCampfire, DreamArrivalPoint arrivalPoint) { + // If we are arriving in a custom dream dimension, activate it immediately + var dimension = arrivalPoint.GetAttachedOWRigidbody().GetComponent(); + if (dimension != null) + { + dimension.SetActive(true); + } + // Make the body/sector/volume where the player 'wakes up' in the dream match the body where the arrival point is located if it isn't the vanilla DreamWorld, or reset it if it is var dreamWorldAO = Locator.GetAstroObject(AstroObject.Name.DreamWorld); if (arrivalPoint.GetAttachedOWRigidbody() == dreamWorldAO.GetOWRigidbody())