diff --git a/NewHorizons/AssetBundle/StarColorOverTime.png b/NewHorizons/AssetBundle/StarColorOverTime.png new file mode 100644 index 00000000..7ec04697 Binary files /dev/null and b/NewHorizons/AssetBundle/StarColorOverTime.png differ diff --git a/NewHorizons/Body/AsteroidBeltBuilder.cs b/NewHorizons/Body/AsteroidBeltBuilder.cs index 3a872b18..29eb7668 100644 --- a/NewHorizons/Body/AsteroidBeltBuilder.cs +++ b/NewHorizons/Body/AsteroidBeltBuilder.cs @@ -60,7 +60,7 @@ namespace NewHorizons.Body Logger.Log($"{config}"); var asteroid = new NewHorizonsBody(new PlanetConfig(config), assets); - Main.AdditionalBodies.Add(asteroid); + Main.NextPassBodies.Add(asteroid); } } } diff --git a/NewHorizons/Body/StarBuilder.cs b/NewHorizons/Body/StarBuilder.cs index dbbae741..d2051d1a 100644 --- a/NewHorizons/Body/StarBuilder.cs +++ b/NewHorizons/Body/StarBuilder.cs @@ -1,17 +1,22 @@ using NewHorizons.External; +using OWML.Utils; 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.Body { static class StarBuilder { + private static Texture2D _colorOverTime; public static void Make(GameObject body, Sector sector, StarModule starModule) { + if (_colorOverTime == null) _colorOverTime = Main.Instance.ModHelper.Assets.GetTexture("AssetBundle/StarColorOverTime.png"); + var sunGO = new GameObject("Star"); sunGO.transform.parent = body.transform; @@ -21,33 +26,68 @@ namespace NewHorizons.Body sunSurface.name = "Surface"; var sunLight = GameObject.Instantiate(GameObject.Find("Sun_Body/Sector_SUN/Effects_SUN/SunLight"), sunGO.transform); - sunSurface.transform.localPosition = Vector3.zero; - sunSurface.transform.localScale = Vector3.one; + sunLight.transform.localPosition = Vector3.zero; + sunLight.transform.localScale = Vector3.one; sunLight.name = "StarLight"; var solarFlareEmitter = GameObject.Instantiate(GameObject.Find("Sun_Body/Sector_SUN/Effects_SUN/SolarFlareEmitter"), sunGO.transform); - sunSurface.transform.localPosition = Vector3.zero; - sunSurface.transform.localScale = Vector3.one; + solarFlareEmitter.transform.localPosition = Vector3.zero; + solarFlareEmitter.transform.localScale = Vector3.one; solarFlareEmitter.name = "SolarFlareEmitter"; var sunAudio = GameObject.Instantiate(GameObject.Find("Sun_Body/Sector_SUN/Audio_SUN"), sunGO.transform); - sunSurface.transform.localPosition = Vector3.zero; - sunSurface.transform.localScale = Vector3.one; + sunAudio.transform.localPosition = Vector3.zero; + sunAudio.transform.localScale = Vector3.one; sunAudio.transform.Find("SurfaceAudio_Sun").GetComponent().maxDistance = starModule.Size * 2f; sunAudio.name = "Audio_Star"; var sunAtmosphere = GameObject.Instantiate(GameObject.Find("Sun_Body/Atmosphere_SUN"), sunGO.transform); - sunSurface.transform.localPosition = Vector3.zero; - sunSurface.transform.localScale = Vector3.one * 1.5f; + sunAtmosphere.transform.localPosition = Vector3.zero; + sunAtmosphere.transform.localScale = Vector3.one; sunAtmosphere.name = "Atmosphere_Star"; var ambientLightGO = GameObject.Instantiate(GameObject.Find("Sun_Body/AmbientLight_SUN"), sunGO.transform); ambientLightGO.transform.localPosition = Vector3.zero; ambientLightGO.name = "AmbientLight_Star"; + var heatVolume = GameObject.Instantiate(GameObject.Find("Sun_Body/Sector_SUN/Volumes_SUN/HeatVolume"), sunGO.transform); + heatVolume.transform.localPosition = Vector3.zero; + heatVolume.transform.localScale = Vector3.one; + heatVolume.GetComponent().radius = 1f; + heatVolume.name = "HeatVolume"; + PlanetaryFogController fog = sunAtmosphere.transform.Find("FogSphere").GetComponent(); TessellatedSphereRenderer surface = sunSurface.GetComponent(); Light ambientLight = ambientLightGO.GetComponent(); + SunLightController sunLightController = sunLight.GetComponent(); + GameObject.Destroy(sunLight.GetComponent()); + + if(starModule.Tint != null) + { + var colour = starModule.Tint.ToColor32(); + //sunLightController.sunColor = colour; + //ambientLight.color = colour; + fog.fogTint = colour; + + var sun = GameObject.Find("Sun_Body"); + var mainSequenceMaterial = sun.GetComponent().GetValue("_startSurfaceMaterial"); + var giantMaterial = sun.GetComponent().GetValue("_endSurfaceMaterial"); + + surface.sharedMaterial = new Material(starModule.Size >= 3000 ? giantMaterial : mainSequenceMaterial); + surface.sharedMaterial.color = new Color(colour.r * 4f / 255f, colour.g * 4f / 255f, colour.b * 4f / 255f); + surface.sharedMaterial.SetTexture("_ColorRamp", Utility.ImageUtilities.TintImage(_colorOverTime, colour)); + + sunAtmosphere.transform.Find("AtmoSphere").transform.localScale = Vector3.one * 2f; + foreach (var lod in sunAtmosphere.transform.Find("AtmoSphere").GetComponentsInChildren()) + { + lod.material.SetColor("_SkyColor", colour); + lod.material.SetFloat("_InnerRadius", starModule.Size); + lod.material.SetFloat("_OuterRadius", starModule.Size + 1000); + } + } + + if(starModule.SolarFlareTint != null) + solarFlareEmitter.GetComponent().tint = starModule.SolarFlareTint.ToColor32(); sunGO.transform.localPosition = Vector3.zero; sunGO.transform.localScale = starModule.Size * Vector3.one; diff --git a/NewHorizons/External/StarModule.cs b/NewHorizons/External/StarModule.cs index 23511f17..75c52122 100644 --- a/NewHorizons/External/StarModule.cs +++ b/NewHorizons/External/StarModule.cs @@ -11,5 +11,6 @@ namespace NewHorizons.External { public float Size { get; set; } public MColor32 Tint { get; set; } + public MColor32 SolarFlareTint { get; set; } } } diff --git a/NewHorizons/General/MarkerBuilder.cs b/NewHorizons/General/MarkerBuilder.cs index 8a5dbb00..7c03fe8a 100644 --- a/NewHorizons/General/MarkerBuilder.cs +++ b/NewHorizons/General/MarkerBuilder.cs @@ -8,7 +8,7 @@ namespace NewHorizons.General { static class MarkerBuilder { - public static void Make(GameObject body, string name, bool isMoon) + public static void Make(GameObject body, string name, bool isMoon, bool isStar) { MapMarker MM = body.AddComponent(); MM.SetValue("_labelID", (UITextType)Utility.AddToUITable.Add(name.ToUpper())); @@ -17,7 +17,10 @@ namespace NewHorizons.General { MM.SetValue("_markerType", MM.GetType().GetNestedType("MarkerType", BindingFlags.NonPublic).GetField("Moon").GetValue(MM)); } - else + else if(isStar) + { + MM.SetValue("_markerType", MM.GetType().GetNestedType("MarkerType", BindingFlags.NonPublic).GetField("Sun").GetValue(MM)); + } { MM.SetValue("_markerType", MM.GetType().GetNestedType("MarkerType", BindingFlags.NonPublic).GetField("Planet").GetValue(MM)); } diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index c96b4c6e..0f86dbe6 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -25,7 +25,9 @@ namespace NewHorizons public static Main Instance { get; private set; } public static List BodyList = new List(); - public static List AdditionalBodies = new List(); + public static List NextPassBodies = new List(); + + public static float FurthestOrbit = 50000f; public override object GetApi() { @@ -75,18 +77,35 @@ namespace NewHorizons (b.Config.Orbit.IsMoon ? 2 : 1) )).ToList(); + var flagNoneLoadedThisPass = true; while(BodyList.Count != 0) { foreach (var body in BodyList) { - LoadBody(body); + if (LoadBody(body)) + flagNoneLoadedThisPass = false; } - BodyList = AdditionalBodies; - AdditionalBodies = new List(); + if (flagNoneLoadedThisPass) + { + // Try again but default to sun + foreach(var body in BodyList) + { + if (LoadBody(body, true)) + flagNoneLoadedThisPass = false; + } + if(flagNoneLoadedThisPass) + { + // Give up + Logger.Log($"Couldn't finish adding bodies."); + return; + } + } + BodyList = NextPassBodies; + NextPassBodies = new List(); } } - private void LoadBody(NewHorizonsBody body) + private bool LoadBody(NewHorizonsBody body, bool defaultPrimaryToSun = false) { var stringID = body.Config.Name.ToUpper().Replace(" ", "_").Replace("'", ""); if (stringID.Equals("ATTLEROCK")) stringID = "TIMBER_MOON"; @@ -119,28 +138,31 @@ namespace NewHorizons catch (Exception e) { Logger.LogError($"Couldn't update body {body.Config?.Name}: {e.Message}, {e.StackTrace}"); + return false; } } else { try { - GameObject planetObject; - planetObject = GenerateBody(body); + GameObject planetObject = GenerateBody(body); + if (planetObject == null) return false; planetObject.SetActive(true); } catch (Exception e) { Logger.LogError($"Couldn't generate body {body.Config?.Name}: {e.Message}, {e.StackTrace}"); + return false; } } + return true; } public void LoadConfigs(IModBehaviour mod) { var folder = mod.ModHelper.Manifest.ModFolderPath; - foreach (var file in Directory.GetFiles(folder + @"planets\")) + foreach (var file in Directory.GetFiles(folder + @"planets\", "*.json", SearchOption.AllDirectories)) { try { @@ -168,8 +190,23 @@ namespace NewHorizons return SharedGenerateBody(body, go, sector, rb); } - public static GameObject GenerateBody(NewHorizonsBody body) + public static GameObject GenerateBody(NewHorizonsBody body, bool defaultPrimaryToSun = false) { + AstroObject primaryBody = AstroObjectLocator.GetAstroObject(body.Config.Orbit.PrimaryBody); + if (primaryBody == null) + { + if(defaultPrimaryToSun) + { + Logger.Log($"Couldn't find {body.Config.Orbit.PrimaryBody}, defaulting to Sun"); + primaryBody = AstroObjectLocator.GetAstroObject("Sun"); + } + else + { + NextPassBodies.Add(body); + return null; + } + } + Logger.Log("Begin generation sequence of [" + body.Config.Name + "] ...", Logger.LogType.Log); var go = new GameObject(body.Config.Name.Replace(" ", "").Replace("'", "") + "_Body"); @@ -177,13 +214,6 @@ namespace NewHorizons if(body.Config.Base.GroundSize != 0) GeometryBuilder.Make(go, body.Config.Base.GroundSize); - AstroObject primaryBody = AstroObjectLocator.GetAstroObject(body.Config.Orbit.PrimaryBody); - if(primaryBody == null) - { - Logger.LogError($"Could not find AstroObject {body.Config.Orbit.PrimaryBody}, defaulting to SUN"); - primaryBody = AstroObjectLocator.GetAstroObject(AstroObject.Name.Sun); - } - var atmoSize = body.Config.Atmosphere != null ? body.Config.Atmosphere.Size : 0f; float sphereOfInfluence = Mathf.Max(atmoSize, body.Config.Base.SurfaceSize * 2f); @@ -228,7 +258,7 @@ namespace NewHorizons RFVolumeBuilder.Make(go, rb, sphereOfInfluence); if (body.Config.Base.HasMapMarker) - MarkerBuilder.Make(go, body.Config.Name, body.Config.Orbit.IsMoon); + MarkerBuilder.Make(go, body.Config.Name, body.Config.Orbit.IsMoon, body.Config.Star != null); if (body.Config.Base.HasAmbientLight) AmbientLightBuilder.Make(go, sphereOfInfluence); @@ -246,10 +276,8 @@ namespace NewHorizons if (body.Config.Base.BlackHoleSize != 0) BlackHoleBuilder.Make(go, body.Config.Base, sector); - /* if (body.Config.Star != null) StarBuilder.Make(go, sector, body.Config.Star); - */ // Do stuff that's shared between generating new planets and updating old ones go = SharedGenerateBody(body, go, sector, rb); @@ -264,6 +292,11 @@ namespace NewHorizons go.transform.parent = Locator.GetRootTransform(); go.transform.position = positionVector + primaryBody.transform.position; + if (go.transform.position.magnitude > FurthestOrbit) + { + FurthestOrbit = go.transform.position.magnitude + 30000f; + } + // Have to do this after setting position InitialMotionBuilder.Make(go, primaryBody, rb, body.Config.Orbit); diff --git a/NewHorizons/Utility/ImageUtilities.cs b/NewHorizons/Utility/ImageUtilities.cs index 2a885efe..6264a1b3 100644 --- a/NewHorizons/Utility/ImageUtilities.cs +++ b/NewHorizons/Utility/ImageUtilities.cs @@ -17,6 +17,7 @@ namespace NewHorizons.Utility var newImage = new Texture2D(image.width, image.height); newImage.SetPixels(pixels); + newImage.Apply(); return newImage; } diff --git a/NewHorizons/Utility/Patches.cs b/NewHorizons/Utility/Patches.cs index 32cfcbd9..c6cfda4a 100644 --- a/NewHorizons/Utility/Patches.cs +++ b/NewHorizons/Utility/Patches.cs @@ -15,6 +15,8 @@ namespace NewHorizons.Utility Main.Instance.ModHelper.HarmonyHelper.AddPrefix("GetHUDDisplayName", typeof(Patches), nameof(Patches.GetHUDDisplayName)); Main.Instance.ModHelper.HarmonyHelper.AddPrefix("CheckShipOutsideSolarSystem", typeof(Patches), nameof(Patches.CheckShipOutersideSolarSystem)); Main.Instance.ModHelper.HarmonyHelper.AddPostfix("Start", typeof(Patches), nameof(Patches.OnEllipticOrbitLineStart)); + Main.Instance.ModHelper.HarmonyHelper.AddPostfix("Awake", typeof(Patches), nameof(Patches.OnMapControllerAwake)); + Main.Instance.ModHelper.HarmonyHelper.AddPostfix("Awake", typeof(Patches), nameof(Patches.OnOWCameraAwake)); } public static bool GetHUDDisplayName(ReferenceFrame __instance, ref string __result) @@ -41,5 +43,17 @@ namespace NewHorizons.Utility // For some reason other planets do this idk ____upAxisDir *= -1f; } + + public static void OnMapControllerAwake(MapController __instance, ref float ____maxPanDistance, ref float ____maxZoomDistance, ref float ____minPitchAngle) + { + ____maxPanDistance *= 4f; + ____maxZoomDistance *= 6f; + ____minPitchAngle = -90f; + } + + public static void OnOWCameraAwake(OWCamera __instance) + { + __instance.farClipPlane *= 4f; + } } }