diff --git a/NewHorizons/AssetBundle/shader b/NewHorizons/AssetBundle/shader new file mode 100644 index 00000000..a6cf0246 Binary files /dev/null and b/NewHorizons/AssetBundle/shader differ diff --git a/NewHorizons/assets/shader.manifest b/NewHorizons/AssetBundle/shader.manifest similarity index 75% rename from NewHorizons/assets/shader.manifest rename to NewHorizons/AssetBundle/shader.manifest index b5c4697c..d8a544b8 100644 --- a/NewHorizons/assets/shader.manifest +++ b/NewHorizons/AssetBundle/shader.manifest @@ -1,9 +1,9 @@ ManifestFileVersion: 0 -CRC: 3655445632 +CRC: 3840241390 Hashes: AssetFileHash: serializedVersion: 2 - Hash: 160438a2f12bb2f4bd67ddfa0e6f2f3f + Hash: 1c2c90716d1ed7c9cbf5f785e41eace6 TypeTreeHash: serializedVersion: 2 Hash: 6370d3f9de9eca57f523bce048404a46 @@ -13,4 +13,5 @@ ClassTypes: Script: {instanceID: 0} Assets: - Assets/SphereTextureWrapper.shader +- Assets/UnlitTransparent.shader Dependencies: [] diff --git a/NewHorizons/Atmosphere/AirBuilder.cs b/NewHorizons/Atmosphere/AirBuilder.cs index 0c2b0900..414862f7 100644 --- a/NewHorizons/Atmosphere/AirBuilder.cs +++ b/NewHorizons/Atmosphere/AirBuilder.cs @@ -60,7 +60,6 @@ namespace NewHorizons.Atmosphere } airGO.SetActive(true); - Logger.Log("Finished building air.", Logger.LogType.Log); } } } diff --git a/NewHorizons/Atmosphere/AtmosphereBuilder.cs b/NewHorizons/Atmosphere/AtmosphereBuilder.cs index 522d4572..a5c878d8 100644 --- a/NewHorizons/Atmosphere/AtmosphereBuilder.cs +++ b/NewHorizons/Atmosphere/AtmosphereBuilder.cs @@ -77,7 +77,6 @@ namespace NewHorizons.Atmosphere } atmoGO.SetActive(true); - Logger.Log("Finished building atmosphere.", Logger.LogType.Log); } } } diff --git a/NewHorizons/Atmosphere/CloudsBuilder.cs b/NewHorizons/Atmosphere/CloudsBuilder.cs index 5296c087..4a5953c1 100644 --- a/NewHorizons/Atmosphere/CloudsBuilder.cs +++ b/NewHorizons/Atmosphere/CloudsBuilder.cs @@ -110,11 +110,13 @@ namespace NewHorizons.Atmosphere fluidCLFV.SetValue("_allowShipAutoroll", true); fluidCLFV.SetValue("_disableOnStart", false); + // Fix the rotations once the rest is done + cloudsMainGO.transform.localRotation = Quaternion.Euler(0, 0, 0); + cloudsTopGO.SetActive(true); cloudsBottomGO.SetActive(true); cloudsFluidGO.SetActive(true); cloudsMainGO.SetActive(true); - Logger.Log("Finished building clouds.", Logger.LogType.Log); } } } diff --git a/NewHorizons/Atmosphere/EffectsBuilder.cs b/NewHorizons/Atmosphere/EffectsBuilder.cs index 73a08868..36a6563e 100644 --- a/NewHorizons/Atmosphere/EffectsBuilder.cs +++ b/NewHorizons/Atmosphere/EffectsBuilder.cs @@ -51,8 +51,6 @@ namespace NewHorizons.Atmosphere } effectsGO.SetActive(true); - - Logger.Log("Finished building effects", Logger.LogType.Log); } } } diff --git a/NewHorizons/Atmosphere/SunOverrideBuilder.cs b/NewHorizons/Atmosphere/SunOverrideBuilder.cs index ce890886..073c609f 100644 --- a/NewHorizons/Atmosphere/SunOverrideBuilder.cs +++ b/NewHorizons/Atmosphere/SunOverrideBuilder.cs @@ -21,7 +21,6 @@ namespace NewHorizons.Atmosphere GDSOV.SetValue("_waterInnerRadius", 0f); overrideGO.SetActive(true); - Logger.Log("Finished building sun override.", Logger.LogType.Log); } } } diff --git a/NewHorizons/Atmosphere/VolumesBuilder.cs b/NewHorizons/Atmosphere/VolumesBuilder.cs index c6496345..96cda341 100644 --- a/NewHorizons/Atmosphere/VolumesBuilder.cs +++ b/NewHorizons/Atmosphere/VolumesBuilder.cs @@ -38,7 +38,6 @@ namespace NewHorizons.Atmosphere rulesetGO.SetActive(true); volumesGO.SetActive(true); - Logger.Log("Finished building volumes", Logger.LogType.Log); } } } diff --git a/NewHorizons/Body/AsteroidBeltBuilder.cs b/NewHorizons/Body/AsteroidBeltBuilder.cs new file mode 100644 index 00000000..d2392b2e --- /dev/null +++ b/NewHorizons/Body/AsteroidBeltBuilder.cs @@ -0,0 +1,64 @@ +using NewHorizons.External; +using NewHorizons.Utility; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Logger = NewHorizons.Utility.Logger; +using Random = UnityEngine.Random; + +namespace NewHorizons.Body +{ + static class AsteroidBeltBuilder + { + public static void Make(string bodyName, AsteroidBeltModule belt) + { + var minSize = 20; + var maxSize = 50; + int count = (int)(2f * Mathf.PI * belt.InnerRadius / (10f * maxSize)); + if (count > 400) count = 400; + + Logger.Log($"Making {count} asteroids around {bodyName}"); + + for (int i = 0; i < count; i++) + { + var size = Random.Range(minSize, maxSize); + var config = new Dictionary() + { + {"Name", $"{bodyName} Asteroid {i}"}, + {"Base", new Dictionary() + { + {"HasMapMarker", false }, + {"SurfaceGravity", 1 }, + {"SurfaceSize", size }, + {"HideOrbitLine", true } + } + }, + {"Orbit", new Dictionary() + { + {"IsMoon", true }, + {"Inclination", belt.Inclination + Random.Range(-2f, 2f) }, + {"LongitudeOfAscendingNode", belt.LongitudeOfAscendingNode }, + {"TrueAnomaly", 360f * (i + Random.Range(-0.2f, 0.2f)) / (float)count }, + {"PrimaryBody", bodyName }, + {"SemiMajorAxis", maxSize * Random.Range(belt.InnerRadius, belt.OuterRadius) } + } + }, + {"ProcGen", new Dictionary() + { + {"Scale", size }, + {"Color", new MColor32(126, 94, 73, 255) } + } + } + }; + + Logger.Log($"{config}"); + + var asteroid = new NewHorizonsBody(new PlanetConfig(config)); + Main.AdditionalBodies.Add(asteroid); + } + } + } +} diff --git a/NewHorizons/Body/Geometry/CubeSphere.cs b/NewHorizons/Body/Geometry/CubeSphere.cs index 05962a78..01653ee6 100644 --- a/NewHorizons/Body/Geometry/CubeSphere.cs +++ b/NewHorizons/Body/Geometry/CubeSphere.cs @@ -48,10 +48,6 @@ namespace NewHorizons.Body for (int x = 0; x <= resolution; x++) { SetVertex(vertices, normals, uvs, v++, x, y, 0, resolution, heightMap, minHeight, maxHeight); - if (x == resolution / 2 && y < resolution / 2) - { - Logger.Log($"{uvs[v - 1]}"); - } } for (int z = 1; z <= resolution; z++) { @@ -60,10 +56,6 @@ namespace NewHorizons.Body for (int x = resolution - 1; x >= 0; x--) { SetVertex(vertices, normals, uvs, v++, x, y, resolution, resolution, heightMap, minHeight, maxHeight); - if (x == resolution / 2 && y < resolution / 2) - { - Logger.Log($"{uvs[v - 1]}"); - } } for (int z = resolution - 1; z > 0; z--) { @@ -83,10 +75,6 @@ namespace NewHorizons.Body for (int x = 1; x < resolution; x++) { SetVertex(vertices, normals, uvs, v++, x, 0, z, resolution, heightMap, minHeight, maxHeight); - if (x == resolution / 2) - { - Logger.Log($"{uvs[v - 1]}"); - } } } diff --git a/NewHorizons/Body/Geometry/Icosphere.cs b/NewHorizons/Body/Geometry/Icosphere.cs index 5ea5cc2f..3020005a 100644 --- a/NewHorizons/Body/Geometry/Icosphere.cs +++ b/NewHorizons/Body/Geometry/Icosphere.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; +using Random = UnityEngine.Random; namespace NewHorizons.Body.Geometry { @@ -59,7 +60,7 @@ namespace NewHorizons.Body.Geometry } }; - public static Mesh Build(int subdivisions, Texture2D heightMap, float minHeight, float maxHeight) + public static Mesh Build(int subdivisions, float minHeight, float maxHeight) { Mesh mesh = new Mesh(); @@ -72,7 +73,7 @@ namespace NewHorizons.Body.Geometry Vector3[] normals = new Vector3[verticesToCopy.Length]; Vector2[] uvs = new Vector2[verticesToCopy.Length]; - Dictionary seamVertices = new Dictionary(); + var randomOffset = new Vector3(Random.Range(0, 10f), Random.Range(0, 10f), Random.Range(0, 10f)); for(int i = 0; i < verticesToCopy.Length; i++) { @@ -80,11 +81,8 @@ namespace NewHorizons.Body.Geometry float latitude = Mathf.Repeat(Mathf.Rad2Deg * Mathf.Acos(v.z / Mathf.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z)), 180f); float longitude = Mathf.Repeat(Mathf.Rad2Deg * (v.x > 0 ? Mathf.Atan(v.y / v.x) : Mathf.Atan(v.y / v.x) + Mathf.PI) + 90f, 360f); - - float sampleX = heightMap.width * longitude / 360f; - float sampleY = heightMap.height * latitude / 180f; - - float height = heightMap.GetPixel((int)sampleX, (int)sampleY).r * (maxHeight - minHeight) + minHeight; + + float height = Perlin.Noise(v + randomOffset) * (maxHeight - minHeight) + minHeight; newVertices[i] = verticesToCopy[i] * height; normals[i] = v.normalized; @@ -92,9 +90,6 @@ namespace NewHorizons.Body.Geometry var x = longitude / 360f; var y = latitude / 180f; - if (x == 0) seamVertices.Add(y, i); - - uvs[i] = new Vector2(x, y); } diff --git a/NewHorizons/Body/Geometry/Perlin.cs b/NewHorizons/Body/Geometry/Perlin.cs new file mode 100644 index 00000000..d3f22604 --- /dev/null +++ b/NewHorizons/Body/Geometry/Perlin.cs @@ -0,0 +1,176 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.Body.Geometry +{ + // Perlin noise generator for Unity + // Keijiro Takahashi, 2013, 2015 + // https://github.com/keijiro/PerlinNoise + public static class Perlin + { + #region Noise functions + + public static float Noise(float x) + { + var X = Mathf.FloorToInt(x) & 0xff; + x -= Mathf.Floor(x); + var u = Fade(x); + return Lerp(u, Grad(perm[X], x), Grad(perm[X + 1], x - 1)) * 2; + } + + public static float Noise(float x, float y) + { + var X = Mathf.FloorToInt(x) & 0xff; + var Y = Mathf.FloorToInt(y) & 0xff; + x -= Mathf.Floor(x); + y -= Mathf.Floor(y); + var u = Fade(x); + var v = Fade(y); + var A = (perm[X] + Y) & 0xff; + var B = (perm[X + 1] + Y) & 0xff; + return Lerp(v, Lerp(u, Grad(perm[A], x, y), Grad(perm[B], x - 1, y)), + Lerp(u, Grad(perm[A + 1], x, y - 1), Grad(perm[B + 1], x - 1, y - 1))); + } + + public static float Noise(Vector2 coord) + { + return Noise(coord.x, coord.y); + } + + public static float Noise(float x, float y, float z) + { + var X = Mathf.FloorToInt(x) & 0xff; + var Y = Mathf.FloorToInt(y) & 0xff; + var Z = Mathf.FloorToInt(z) & 0xff; + x -= Mathf.Floor(x); + y -= Mathf.Floor(y); + z -= Mathf.Floor(z); + var u = Fade(x); + var v = Fade(y); + var w = Fade(z); + var A = (perm[X] + Y) & 0xff; + var B = (perm[X + 1] + Y) & 0xff; + var AA = (perm[A] + Z) & 0xff; + var BA = (perm[B] + Z) & 0xff; + var AB = (perm[A + 1] + Z) & 0xff; + var BB = (perm[B + 1] + Z) & 0xff; + return Lerp(w, Lerp(v, Lerp(u, Grad(perm[AA], x, y, z), Grad(perm[BA], x - 1, y, z)), + Lerp(u, Grad(perm[AB], x, y - 1, z), Grad(perm[BB], x - 1, y - 1, z))), + Lerp(v, Lerp(u, Grad(perm[AA + 1], x, y, z - 1), Grad(perm[BA + 1], x - 1, y, z - 1)), + Lerp(u, Grad(perm[AB + 1], x, y - 1, z - 1), Grad(perm[BB + 1], x - 1, y - 1, z - 1)))); + } + + public static float Noise(Vector3 coord) + { + return Noise(coord.x, coord.y, coord.z); + } + + #endregion + + #region fBm functions + + public static float Fbm(float x, int octave) + { + var f = 0.0f; + var w = 0.5f; + for (var i = 0; i < octave; i++) + { + f += w * Noise(x); + x *= 2.0f; + w *= 0.5f; + } + return f; + } + + public static float Fbm(Vector2 coord, int octave) + { + var f = 0.0f; + var w = 0.5f; + for (var i = 0; i < octave; i++) + { + f += w * Noise(coord); + coord *= 2.0f; + w *= 0.5f; + } + return f; + } + + public static float Fbm(float x, float y, int octave) + { + return Fbm(new Vector2(x, y), octave); + } + + public static float Fbm(Vector3 coord, int octave) + { + var f = 0.0f; + var w = 0.5f; + for (var i = 0; i < octave; i++) + { + f += w * Noise(coord); + coord *= 2.0f; + w *= 0.5f; + } + return f; + } + + public static float Fbm(float x, float y, float z, int octave) + { + return Fbm(new Vector3(x, y, z), octave); + } + + #endregion + + #region Private functions + + static float Fade(float t) + { + return t * t * t * (t * (t * 6 - 15) + 10); + } + + static float Lerp(float t, float a, float b) + { + return a + t * (b - a); + } + + static float Grad(int hash, float x) + { + return (hash & 1) == 0 ? x : -x; + } + + static float Grad(int hash, float x, float y) + { + return ((hash & 1) == 0 ? x : -x) + ((hash & 2) == 0 ? y : -y); + } + + static float Grad(int hash, float x, float y, float z) + { + var h = hash & 15; + var u = h < 8 ? x : y; + var v = h < 4 ? y : (h == 12 || h == 14 ? x : z); + return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); + } + + static int[] perm = { + 151,160,137,91,90,15, + 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180, + 151 + }; + + #endregion + } +} diff --git a/NewHorizons/Body/GeometryBuilder.cs b/NewHorizons/Body/GeometryBuilder.cs index 3ceaaff4..a5c38ad9 100644 --- a/NewHorizons/Body/GeometryBuilder.cs +++ b/NewHorizons/Body/GeometryBuilder.cs @@ -49,7 +49,6 @@ namespace NewHorizons.Body geo.SetActive(true); */ - Logger.Log("Finished building geometry", Logger.LogType.Log); } } } diff --git a/NewHorizons/Body/HeightMapBuilder.cs b/NewHorizons/Body/HeightMapBuilder.cs index 246a1e42..5832df48 100644 --- a/NewHorizons/Body/HeightMapBuilder.cs +++ b/NewHorizons/Body/HeightMapBuilder.cs @@ -12,7 +12,6 @@ namespace NewHorizons.Body { static class HeightMapBuilder { - public static AssetBundle ShaderBundle; public static Shader PlanetShader; public static void Make(GameObject go, HeightMapModule module) @@ -29,7 +28,6 @@ namespace NewHorizons.Body return; } - GameObject cubeSphere = new GameObject("CubeSphere"); cubeSphere.transform.parent = go.transform; cubeSphere.transform.rotation = Quaternion.Euler(90, 0, 0); @@ -39,8 +37,7 @@ namespace NewHorizons.Body cubeSphere.AddComponent(); cubeSphere.GetComponent().mesh = mesh; - if(ShaderBundle == null) ShaderBundle = Main.Instance.ModHelper.Assets.LoadBundle("assets/shader"); - if(PlanetShader == null) PlanetShader = ShaderBundle.LoadAsset("Assets/SphereTextureWrapper.shader"); + if(PlanetShader == null) PlanetShader = Main.ShaderBundle.LoadAsset("Assets/SphereTextureWrapper.shader"); var cubeSphereMR = cubeSphere.AddComponent(); cubeSphereMR.material = new Material(PlanetShader); @@ -48,7 +45,9 @@ namespace NewHorizons.Body var cubeSphereMC = cubeSphere.AddComponent(); cubeSphereMC.sharedMesh = mesh; - + + // Fix rotation in the end + cubeSphere.transform.localRotation = Quaternion.Euler(90, 0, 0); /* GameObject icosphere = new GameObject("Icosphere"); @@ -66,6 +65,7 @@ namespace NewHorizons.Body var cubeSphereMC = icosphere.AddComponent(); cubeSphereMC.sharedMesh = mesh; + icosphere.transform.localRotation = Quaternion.Euler(90, 0, 0); */ } } diff --git a/NewHorizons/Body/ProcGenBuilder.cs b/NewHorizons/Body/ProcGenBuilder.cs new file mode 100644 index 00000000..3feb6aba --- /dev/null +++ b/NewHorizons/Body/ProcGenBuilder.cs @@ -0,0 +1,34 @@ +using NewHorizons.Body.Geometry; +using NewHorizons.External; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.Body +{ + static class ProcGenBuilder + { + public static void Make(GameObject go, ProcGenModule module) + { + GameObject icosphere = new GameObject("Icosphere"); + icosphere.transform.parent = go.transform; + icosphere.transform.rotation = Quaternion.Euler(90, 0, 0); + + Mesh mesh = Icosphere.Build(3, module.Scale, module.Scale * 1.2f); + + icosphere.AddComponent(); + icosphere.GetComponent().mesh = mesh; + + var cubeSphereMR = icosphere.AddComponent(); + cubeSphereMR.material = new Material(Shader.Find("Standard")); + cubeSphereMR.material.color = module.Color.ToColor32(); + + var cubeSphereMC = icosphere.AddComponent(); + cubeSphereMC.sharedMesh = mesh; + icosphere.transform.localRotation = Quaternion.Euler(90, 0, 0); + } + } +} diff --git a/NewHorizons/Body/RingBuilder.cs b/NewHorizons/Body/RingBuilder.cs index e47dd4f1..02b39a70 100644 --- a/NewHorizons/Body/RingBuilder.cs +++ b/NewHorizons/Body/RingBuilder.cs @@ -11,7 +11,9 @@ namespace NewHorizons.General { static class RingBuilder { - public static void Make(GameObject body, RingModule ring) + public static Shader RingShader; + + public static void Make(GameObject body, RingModule ring) { Texture2D ringTexture; try @@ -27,6 +29,7 @@ namespace NewHorizons.General var ringGO = new GameObject("Ring"); ringGO.transform.parent = body.transform; ringGO.transform.localPosition = Vector3.zero; + ringGO.transform.localRotation = Quaternion.Euler(0, 0, 0); ringGO.transform.Rotate(ringGO.transform.TransformDirection(Vector3.up), ring.LongitudeOfAscendingNode); ringGO.transform.Rotate(ringGO.transform.TransformDirection(Vector3.right), ring.Inclination); @@ -35,7 +38,9 @@ namespace NewHorizons.General var ringMR = ringGO.AddComponent(); var texture = ringTexture; - var mat = new Material(Shader.Find("Legacy Shaders/Particles/Alpha Blended Premultiply")); + if (RingShader == null) RingShader = Main.ShaderBundle.LoadAsset("Assets/UnlitTransparent.shader"); + + var mat = new Material(RingShader); mat.mainTexture = texture; mat.renderQueue = 3000; ringMR.material = mat; @@ -43,8 +48,6 @@ namespace NewHorizons.General // Make mesh var segments = (int)Math.Max(20, ring.OuterRadius); BuildRingMesh(ringMesh, segments, ring.InnerRadius, ring.OuterRadius); - - Logger.Log("Finished building rings", Logger.LogType.Log); } // Thank you https://github.com/boardtobits/planet-ring-mesh/blob/master/PlanetRing.cs diff --git a/NewHorizons/Body/SunBuilder.cs b/NewHorizons/Body/SunBuilder.cs new file mode 100644 index 00000000..79dab1bc --- /dev/null +++ b/NewHorizons/Body/SunBuilder.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.Body +{ + static class SunBuilder + { + public static void Make(GameObject body, Sector sector) + { + } + } +} diff --git a/NewHorizons/Body/WaterBuilder.cs b/NewHorizons/Body/WaterBuilder.cs index ade661de..b41d7fe1 100644 --- a/NewHorizons/Body/WaterBuilder.cs +++ b/NewHorizons/Body/WaterBuilder.cs @@ -80,8 +80,6 @@ namespace NewHorizons.Body */ waterGO.SetActive(true); - - Logger.Log("Finished building water", Logger.LogType.Log); } } } diff --git a/NewHorizons/External/AsteroidBeltModule.cs b/NewHorizons/External/AsteroidBeltModule.cs new file mode 100644 index 00000000..29db0f74 --- /dev/null +++ b/NewHorizons/External/AsteroidBeltModule.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NewHorizons.External +{ + public class AsteroidBeltModule : Module + { + public float InnerRadius { get; set; } + public float OuterRadius { get; set; } + public float Inclination { get; set; } + public float LongitudeOfAscendingNode { get; set; } + } +} diff --git a/NewHorizons/External/BaseModule.cs b/NewHorizons/External/BaseModule.cs index ae6d9f84..bd00e905 100644 --- a/NewHorizons/External/BaseModule.cs +++ b/NewHorizons/External/BaseModule.cs @@ -17,5 +17,6 @@ namespace NewHorizons.External public float GroundSize { get; set; } public float BlackHoleSize { get; set; } public float LavaSize { get; set; } + public bool HideOrbitLine { get; set; } } } diff --git a/NewHorizons/External/IPlanetConfig.cs b/NewHorizons/External/IPlanetConfig.cs index f94b78de..e16215a6 100644 --- a/NewHorizons/External/IPlanetConfig.cs +++ b/NewHorizons/External/IPlanetConfig.cs @@ -11,6 +11,8 @@ namespace NewHorizons.External OrbitModule Orbit { get; } RingModule Ring { get; } HeightMapModule HeightMap { get; } + ProcGenModule ProcGen { get; } + AsteroidBeltModule AsteroidBelt { get; } SpawnModule Spawn { get; } } } diff --git a/NewHorizons/External/Module.cs b/NewHorizons/External/Module.cs index 67de2cae..922ffcd7 100644 --- a/NewHorizons/External/Module.cs +++ b/NewHorizons/External/Module.cs @@ -17,10 +17,8 @@ namespace NewHorizons.External } foreach (var item in dict) { - Logger.Log($"{item.Key} : {item.Value}", Logger.LogType.Log); - - var field = GetType().GetField(item.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); - field.SetValue(this, Convert.ChangeType(item.Value, field.FieldType)); + var property = GetType().GetProperty(item.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); + property.SetValue(this, Convert.ChangeType(item.Value, property.PropertyType)); } } } diff --git a/NewHorizons/External/OrbitModule.cs b/NewHorizons/External/OrbitModule.cs index 3f4ab9fe..b4ef5ccb 100644 --- a/NewHorizons/External/OrbitModule.cs +++ b/NewHorizons/External/OrbitModule.cs @@ -15,6 +15,7 @@ namespace NewHorizons.External public float LongitudeOfAscendingNode { get; set; } public float Eccentricity { get; set; } public float ArgumentOfPeriapsis { get; set; } + public float TrueAnomaly { get; set; } public float AxialTilt { get; set; } public float SiderealPeriod { get; set; } public bool IsTidallyLocked { get; set; } diff --git a/NewHorizons/External/PlanetConfig.cs b/NewHorizons/External/PlanetConfig.cs index c8f28dfe..2ce82ac9 100644 --- a/NewHorizons/External/PlanetConfig.cs +++ b/NewHorizons/External/PlanetConfig.cs @@ -14,33 +14,32 @@ namespace NewHorizons.External public OrbitModule Orbit { get; set; } public RingModule Ring { get; set; } public HeightMapModule HeightMap { get; set; } + public ProcGenModule ProcGen { get; set; } + public AsteroidBeltModule AsteroidBelt { get; set; } public SpawnModule Spawn { get; set; } public PlanetConfig(Dictionary dict) { - // Always have to have a base module + // Always have to have a base module and orbit module Base = new BaseModule(); - if (dict == null) - { - return; - } + Orbit = new OrbitModule(); + + if (dict == null) return; + foreach (var item in dict) { - Logger.Log($"{item.Key} : {item.Value}", Logger.LogType.Log); - switch(item.Key) { case "Base": Base.Build(item.Value as Dictionary); break; + case "Orbit": + Orbit.Build(item.Value as Dictionary); + break; case "Atmosphere": Atmosphere = new AtmosphereModule(); Atmosphere.Build(item.Value as Dictionary); break; - case "Orbit": - Orbit = new OrbitModule(); - Orbit.Build(item.Value as Dictionary); - break; case "Ring": Ring = new RingModule(); Ring.Build(item.Value as Dictionary); @@ -49,23 +48,24 @@ namespace NewHorizons.External HeightMap = new HeightMapModule(); HeightMap.Build(item.Value as Dictionary); break; + case "ProcGen": + ProcGen = new ProcGenModule(); + ProcGen.Build(item.Value as Dictionary); + break; + case "AsteroidBelt": + AsteroidBelt = new AsteroidBeltModule(); + AsteroidBelt.Build(item.Value as Dictionary); + break; case "Spawn": Spawn = new SpawnModule(); Spawn.Build(item.Value as Dictionary); break; default: - var field = GetType().GetField(item.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); - if (field != null) - field.SetValue(this, Convert.ChangeType(item.Value, field.FieldType)); - else - Logger.LogError($"{item.Key} is not valid. Is your config file formatted correctly?"); + var property = typeof(PlanetConfig).GetProperty(item.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); + if (property != null) property.SetValue(this, Convert.ChangeType(item.Value, property.PropertyType)); + else Logger.LogError($"{item.Key} {item.Value} is not valid. Is your config formatted correctly?"); break; } - - /* - var field = GetType().GetField(item.Key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); - field.SetValue(this, Convert.ChangeType(item.Value, field.FieldType)); - */ } } } diff --git a/NewHorizons/External/ProcGenModule.cs b/NewHorizons/External/ProcGenModule.cs new file mode 100644 index 00000000..e4e738e5 --- /dev/null +++ b/NewHorizons/External/ProcGenModule.cs @@ -0,0 +1,15 @@ +using NewHorizons.Utility; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NewHorizons.External +{ + public class ProcGenModule : Module + { + public float Scale { get; set; } + public MColor32 Color { get; set; } + } +} diff --git a/NewHorizons/General/AmbientLightBuilder.cs b/NewHorizons/General/AmbientLightBuilder.cs index 0965800b..572c9c9e 100644 --- a/NewHorizons/General/AmbientLightBuilder.cs +++ b/NewHorizons/General/AmbientLightBuilder.cs @@ -19,8 +19,6 @@ namespace NewHorizons.General light.color = new Color(0.5f, 1f, 1f, 0.0225f); light.range = scale; light.intensity = 0.5f; - - Logger.Log("Finished building ambient light", Logger.LogType.Log); } } } diff --git a/NewHorizons/General/BaseBuilder.cs b/NewHorizons/General/BaseBuilder.cs index 75717f95..a6fb2fc1 100644 --- a/NewHorizons/General/BaseBuilder.cs +++ b/NewHorizons/General/BaseBuilder.cs @@ -26,18 +26,6 @@ namespace NewHorizons.General OWRB.SetValue("_maintainOriginalCenterOfMass", true); OWRB.SetValue("_rigidbody", RB); - InitialMotion IM = body.AddComponent(); - IM.SetPrimaryBody(primaryBody.GetAttachedOWRigidbody()); - IM.SetValue("_orbitAngle", config.Orbit.Inclination); - IM.SetValue("_isGlobalAxis", false); - IM.SetValue("_initAngularSpeed", config.Orbit.SiderealPeriod == 0 ? 0.02f : 1.0f / config.Orbit.SiderealPeriod); - var orbitVector = positionVector.normalized; - var rotationAxis = Quaternion.AngleAxis(config.Orbit.AxialTilt + config.Orbit.Inclination, orbitVector) * Vector3.up; - IM.SetValue("_rotationAxis", rotationAxis); - IM.SetValue("_initLinearSpeed", 0f); - - body.transform.rotation = Quaternion.FromToRotation(Vector3.up, rotationAxis); - DetectorBuilder.Make(body, primaryBody); AstroObject AO = body.AddComponent(); @@ -55,7 +43,6 @@ namespace NewHorizons.General */ } - Logger.Log("Finished building base", Logger.LogType.Log); return new MTuple(AO, OWRB); } } diff --git a/NewHorizons/General/DetectorBuilder.cs b/NewHorizons/General/DetectorBuilder.cs index 0b0bd7a8..52186f5f 100644 --- a/NewHorizons/General/DetectorBuilder.cs +++ b/NewHorizons/General/DetectorBuilder.cs @@ -1,4 +1,5 @@ using OWML.Utils; +using System; using UnityEngine; using Logger = NewHorizons.Utility.Logger; @@ -14,13 +15,13 @@ namespace NewHorizons.General detectorGO.layer = 20; ConstantForceDetector CFD = detectorGO.AddComponent(); - ForceVolume[] temp = new ForceVolume[1]; - temp[0] = primaryBody.GetAttachedOWRigidbody().GetAttachedGravityVolume(); - CFD.SetValue("_detectableFields", temp); + + GravityVolume parentGravityVolume = primaryBody.GetAttachedOWRigidbody().GetAttachedGravityVolume(); + + CFD.SetValue("_detectableFields", new ForceVolume[] { parentGravityVolume }); CFD.SetValue("_inheritElement0", true); detectorGO.SetActive(true); - Logger.Log("Finished building detector", Logger.LogType.Log); } } } diff --git a/NewHorizons/General/GravityBuilder.cs b/NewHorizons/General/GravityBuilder.cs index d00a5039..8f9a485f 100644 --- a/NewHorizons/General/GravityBuilder.cs +++ b/NewHorizons/General/GravityBuilder.cs @@ -40,8 +40,6 @@ namespace NewHorizons.General gravityGO.SetActive(true); ao.SetValue("_gravityVolume", GV); - - Logger.Log("Finished building gravity", Logger.LogType.Log); } } } diff --git a/NewHorizons/General/InitialMotionBuilder.cs b/NewHorizons/General/InitialMotionBuilder.cs new file mode 100644 index 00000000..8b0b755f --- /dev/null +++ b/NewHorizons/General/InitialMotionBuilder.cs @@ -0,0 +1,54 @@ +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.General +{ + static class InitialMotionBuilder + { + public static InitialMotion Make(GameObject body, AstroObject primaryBody, OWRigidbody OWRB, Vector3 positionVector, OrbitModule orbit) + { + InitialMotion IM = body.AddComponent(); + IM.SetPrimaryBody(primaryBody.GetAttachedOWRigidbody()); + IM.SetValue("_orbitAngle", orbit.Inclination); + IM.SetValue("_isGlobalAxis", false); + IM.SetValue("_initAngularSpeed", orbit.SiderealPeriod == 0 ? 0.02f : 1.0f / orbit.SiderealPeriod); + + // Initial velocity + var distance = positionVector - primaryBody.transform.position; + var speed = Kepler.OrbitalHelper.VisViva(primaryBody.GetGravityVolume().GetStandardGravitationalParameter(), distance, orbit.SemiMajorAxis); + var direction = Kepler.OrbitalHelper.EllipseTangent(orbit.Eccentricity, orbit.SemiMajorAxis, orbit.Inclination, orbit.LongitudeOfAscendingNode, orbit.ArgumentOfPeriapsis, orbit.TrueAnomaly); + var velocity = speed * direction; + + // Cancel out what the game does + if(orbit.Eccentricity != 0) + { + var oldVelocity = Kepler.OrbitalHelper.CalculateOrbitVelocity(primaryBody.GetAttachedOWRigidbody(), distance, orbit.Inclination); + if (!float.IsNaN(oldVelocity.magnitude)) velocity -= oldVelocity; + else Logger.LogError($"The original orbital velocity for {body.name} was calculated to be NaN?"); + + var trueSpeed = velocity.magnitude; + var trueDirection = velocity.normalized; + + Logger.Log($"Setting initial motion {velocity.magnitude} in direction {velocity.normalized}"); + if (!float.IsNaN(trueSpeed) && trueDirection != Vector3.zero) + { + IM.SetValue("_initLinearDirection", velocity.normalized); + IM.SetValue("_initLinearSpeed", velocity.magnitude); + } + else Logger.LogError($"Could not set velocity ({speed}, {direction}) -> ({trueSpeed}, {trueDirection}) for {body.name}"); + } + + var rotationAxis = Quaternion.AngleAxis(orbit.AxialTilt + orbit.Inclination, Vector3.right) * Vector3.up; + body.transform.rotation = Quaternion.FromToRotation(Vector3.up, rotationAxis); + + return IM; + } + } +} diff --git a/NewHorizons/General/MarkerBuilder.cs b/NewHorizons/General/MarkerBuilder.cs index 7943c7e7..8a5dbb00 100644 --- a/NewHorizons/General/MarkerBuilder.cs +++ b/NewHorizons/General/MarkerBuilder.cs @@ -21,7 +21,6 @@ namespace NewHorizons.General { MM.SetValue("_markerType", MM.GetType().GetNestedType("MarkerType", BindingFlags.NonPublic).GetField("Planet").GetValue(MM)); } - Logger.Log("Finished building map marker", Logger.LogType.Log); } } } diff --git a/NewHorizons/General/OrbitlineBuilder.cs b/NewHorizons/General/OrbitlineBuilder.cs index 47b63716..1e901654 100644 --- a/NewHorizons/General/OrbitlineBuilder.cs +++ b/NewHorizons/General/OrbitlineBuilder.cs @@ -1,4 +1,6 @@ -using OWML.Utils; +using NewHorizons.External; +using NewHorizons.Utility; +using OWML.Utils; using UnityEngine; using Logger = NewHorizons.Utility.Logger; @@ -6,28 +8,25 @@ namespace NewHorizons.General { static class OrbitlineBuilder { - public static void Make(GameObject body, AstroObject astroobject, bool isMoon) + public static void Make(GameObject body, AstroObject astroobject, bool isMoon, OrbitModule orbit) { - GameObject orbit = new GameObject("Orbit"); - orbit.transform.parent = body.transform; + GameObject orbitGO = new GameObject("Orbit"); + orbitGO.transform.parent = body.transform; - var LR = orbit.AddComponent(); + var LR = orbitGO.AddComponent(); - var thLR = GameObject.Find("OrbitLine_TH").GetComponent(); + var thLR = GameObject.Find("OrbitLine_CO").GetComponent(); LR.material = thLR.material; LR.useWorldSpace = false; LR.loop = false; - Logger.Log("AO primary body is " + astroobject.GetPrimaryBody().name, Logger.LogType.Log); - - var ol = orbit.AddComponent(); + OrbitLine ol = orbit.Eccentricity != 0 ? orbitGO.AddComponent() : orbitGO.AddComponent(); ol.SetValue("_astroObject", astroobject); ol.SetValue("_fade", isMoon); ol.SetValue("_lineWidth", 0.5f); + //ol.SetOrbitalParameters(orbit.Eccentricity, orbit.SemiMajorAxis, orbit.Inclination, orbit.LongitudeOfAscendingNode, orbit.ArgumentOfPeriapsis, orbit.TrueAnomaly); typeof(OrbitLine).GetMethod("InitializeLineRenderer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(ol, new object[] { }); - - Logger.Log("Finished building orbit line", Logger.LogType.Log); } } } diff --git a/NewHorizons/General/PlanetDestroyer.cs b/NewHorizons/General/PlanetDestroyer.cs new file mode 100644 index 00000000..7a520b9f --- /dev/null +++ b/NewHorizons/General/PlanetDestroyer.cs @@ -0,0 +1,118 @@ +using NewHorizons.Utility; +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.General +{ + static class PlanetDestroyer + { + public static void RemoveBody(AstroObject ao, List toDestroy = null) + { + Logger.Log($"Removing {ao.name}"); + + if (ao.gameObject == null || !ao.gameObject.activeInHierarchy) return; + + if (toDestroy == null) toDestroy = new List(); + + if (toDestroy.Contains(ao)) + { + Logger.LogError($"Possible infinite recursion in RemoveBody: {ao.name} might be it's own primary body?"); + return; + } + + toDestroy.Add(ao); + + if (ao.GetAstroObjectName() == AstroObject.Name.BrittleHollow) + RemoveBody(AstroObjectLocator.GetAstroObject(AstroObject.Name.WhiteHole), toDestroy); + + // Check if any other objects depend on it and remove them too + var aoArray = AstroObjectLocator.GetAllAstroObjects(); + foreach (AstroObject obj in aoArray) + { + if (obj?.gameObject == null || !obj.gameObject.activeInHierarchy) + { + AstroObjectLocator.RemoveAstroObject(obj); + continue; + } + if (ao.Equals(obj.GetPrimaryBody())) + { + AstroObjectLocator.RemoveAstroObject(obj); + RemoveBody(obj, toDestroy); + } + } + + if (ao.GetAstroObjectName() == AstroObject.Name.CaveTwin || ao.GetAstroObjectName() == AstroObject.Name.TowerTwin) + { + var focalBody = GameObject.Find("FocalBody"); + if (focalBody != null) focalBody.SetActive(false); + } + if (ao.GetAstroObjectName() == AstroObject.Name.MapSatellite) + { + var msb = GameObject.Find("MapSatellite_Body"); + if (msb != null) msb.SetActive(false); + } + if (ao.GetAstroObjectName() == AstroObject.Name.TowerTwin) + GameObject.Find("TimeLoopRing_Body").SetActive(false); + if (ao.GetAstroObjectName() == AstroObject.Name.ProbeCannon) + { + GameObject.Find("NomaiProbe_Body").SetActive(false); + GameObject.Find("CannonMuzzle_Body").SetActive(false); + GameObject.Find("FakeCannonMuzzle_Body (1)").SetActive(false); + GameObject.Find("CannonBarrel_Body").SetActive(false); + GameObject.Find("FakeCannonBarrel_Body (1)").SetActive(false); + GameObject.Find("Debris_Body (1)").SetActive(false); + } + if (ao.GetAstroObjectName() == AstroObject.Name.SunStation) + { + GameObject.Find("SS_Debris_Body").SetActive(false); + } + if (ao.GetAstroObjectName() == AstroObject.Name.GiantsDeep) + { + GameObject.Find("BrambleIsland_Body").SetActive(false); + GameObject.Find("GabbroIsland_Body").SetActive(false); + GameObject.Find("QuantumIsland_Body").SetActive(false); + GameObject.Find("StatueIsland_Body").SetActive(false); + GameObject.Find("ConstructionYardIsland_Body").SetActive(false); + } + if (ao.GetAstroObjectName() == AstroObject.Name.WhiteHole) + { + GameObject.Find("WhiteholeStation_Body").SetActive(false); + GameObject.Find("WhiteholeStationSuperstructure_Body").SetActive(false); + } + if (ao.GetAstroObjectName() == AstroObject.Name.TimberHearth) + { + GameObject.Find("MiningRig_Body").SetActive(false); + } + + // Deal with proxies + foreach (var p in GameObject.FindObjectsOfType()) + { + if (p.GetValue("_originalBody") == ao.gameObject) + { + p.gameObject.SetActive(false); + break; + } + } + Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => RemoveProxy(ao.name.Replace("_Body", ""))); + + ao.transform.root.gameObject.SetActive(false); + } + + private static void RemoveProxy(string name) + { + if (name.Equals("TowerTwin")) name = "AshTwin"; + if (name.Equals("CaveTwin")) name = "EmberTwin"; + var distantProxy = GameObject.Find(name + "_DistantProxy"); + var distantProxyClone = GameObject.Find(name + "_DistantProxy(Clone)"); + + if (distantProxy != null) GameObject.Destroy(distantProxy.gameObject); + if (distantProxyClone != null) GameObject.Destroy(distantProxyClone.gameObject); + } + } +} diff --git a/NewHorizons/General/RFVolumeBuilder.cs b/NewHorizons/General/RFVolumeBuilder.cs index 659f334b..f90545b2 100644 --- a/NewHorizons/General/RFVolumeBuilder.cs +++ b/NewHorizons/General/RFVolumeBuilder.cs @@ -7,7 +7,7 @@ namespace NewHorizons.General { static class RFVolumeBuilder { - public static void Make(GameObject body, OWRigidbody rigidbody, float atmoEndSize) + public static void Make(GameObject body, OWRigidbody rigidbody, float sphereOfInfluence) { GameObject rfGO = new GameObject("RFVolume"); rfGO.transform.parent = body.transform; @@ -16,30 +16,29 @@ namespace NewHorizons.General SphereCollider SC = rfGO.AddComponent(); SC.isTrigger = true; - SC.radius = atmoEndSize * 2; + SC.radius = sphereOfInfluence * 2; ReferenceFrameVolume RFV = rfGO.AddComponent(); ReferenceFrame RV = new ReferenceFrame(rigidbody); - RV.SetValue("_minSuitTargetDistance", 300); + RV.SetValue("_minSuitTargetDistance", sphereOfInfluence); RV.SetValue("_maxTargetDistance", 0); - RV.SetValue("_autopilotArrivalDistance", atmoEndSize * 2f); - RV.SetValue("_autoAlignmentDistance", atmoEndSize * 1.5f); - //Utility.AddDebugShape.AddSphere(rfGO, 1000, new Color32(0, 255, 0, 128)); + RV.SetValue("_autopilotArrivalDistance", sphereOfInfluence * 2f); + RV.SetValue("_autoAlignmentDistance", sphereOfInfluence * 1.5f); + RV.SetValue("_hideLandingModePrompt", false); RV.SetValue("_matchAngularVelocity", true); RV.SetValue("_minMatchAngularVelocityDistance", 70); RV.SetValue("_maxMatchAngularVelocityDistance", 400); - RV.SetValue("_bracketsRadius", 300); + RV.SetValue("_bracketsRadius", sphereOfInfluence); RFV.SetValue("_referenceFrame", RV); - RFV.SetValue("_minColliderRadius", 300); - RFV.SetValue("_maxColliderRadius", atmoEndSize * 2f); + RFV.SetValue("_minColliderRadius", sphereOfInfluence); + RFV.SetValue("_maxColliderRadius", sphereOfInfluence * 2f); RFV.SetValue("_isPrimaryVolume", true); RFV.SetValue("_isCloseRangeVolume", false); rfGO.SetActive(true); - Logger.Log("Finished building rfvolume", Logger.LogType.Log); } } } diff --git a/NewHorizons/General/SectorBuilder.cs b/NewHorizons/General/SectorBuilder.cs index e1be5c3c..714e89f3 100644 --- a/NewHorizons/General/SectorBuilder.cs +++ b/NewHorizons/General/SectorBuilder.cs @@ -31,7 +31,6 @@ namespace NewHorizons.Body sectorGO.SetActive(true); - Logger.Log("Finished building sector", Logger.LogType.Log); return S; } } diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index b3872d45..7b777ee9 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -18,9 +18,12 @@ namespace NewHorizons { public class Main : ModBehaviour { + + public static AssetBundle ShaderBundle; public static Main Instance { get; private set; } public static List BodyList = new List(); + public static List AdditionalBodies = new List(); public IModAssets CurrentAssets { get; private set; } @@ -33,6 +36,7 @@ namespace NewHorizons { SceneManager.sceneLoaded += OnSceneLoaded; Instance = this; + ShaderBundle = Main.Instance.ModHelper.Assets.LoadBundle("AssetBundle/shader"); Utility.Patches.Apply(); @@ -51,10 +55,7 @@ namespace NewHorizons void OnSceneLoaded(Scene scene, LoadSceneMode mode) { - if (scene.name != "SolarSystem") - { - return; - } + if (scene.name != "SolarSystem") return; Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => Locator.GetPlayerBody().gameObject.AddComponent()); @@ -64,60 +65,73 @@ namespace NewHorizons AstroObjectLocator.AddAstroObject(ao); } - foreach (var body in BodyList) - { - var stringID = body.Config.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"; + // Should make moons come after planets + BodyList = BodyList.OrderBy(b => (b.Config?.Orbit?.IsMoon)).ToList(); - Logger.Log($"Checking if [{stringID}] already exists"); - AstroObject existingPlanet = null; + while(BodyList.Count != 0) + { + foreach (var body in BodyList) + { + LoadBody(body); + } + BodyList = AdditionalBodies; + AdditionalBodies = new List(); + } + } + + private void LoadBody(NewHorizonsBody body) + { + var stringID = body.Config.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"; + + AstroObject existingPlanet = null; + try + { + existingPlanet = AstroObjectLocator.GetAstroObject(stringID); + if (existingPlanet == null) + existingPlanet = existingPlanet = AstroObjectLocator.GetAstroObject(body.Config.Name.Replace(" ", "")); + } + catch (Exception e) + { + Logger.LogWarning($"Error when looking for {body.Config.Name}: {e.Message}, {e.StackTrace}"); + } + + + if (existingPlanet != null) + { try { - existingPlanet = AstroObjectLocator.GetAstroObject(stringID); - if (existingPlanet == null) - existingPlanet = existingPlanet = AstroObjectLocator.GetAstroObject(body.Config.Name.Replace(" ", "")); + if (body.Config.Destroy) + { + Instance.ModHelper.Events.Unity.FireInNUpdates(() => PlanetDestroyer.RemoveBody(existingPlanet), 2); + } + else UpdateBody(body, existingPlanet); } - catch(Exception e) + catch (Exception e) { - Logger.LogWarning($"Error when looking for {body.Config.Name}: {e.Message}, {e.StackTrace}"); + Logger.LogError($"Couldn't update body {body.Config?.Name}: {e.Message}, {e.StackTrace}"); } - - - if (existingPlanet != null) + } + else + { + try { - try - { - if (body.Config.Destroy) - { - Instance.ModHelper.Events.Unity.FireInNUpdates(() => RemoveBody(existingPlanet), 2); - } - else UpdateBody(body, existingPlanet); - } - catch(Exception e) - { - Logger.LogError($"Couldn't update body {body.Config?.Name}: {e.Message}, {e.StackTrace}"); - } + GameObject planetObject; + planetObject = GenerateBody(body); + planetObject.SetActive(true); } - else + catch (Exception e) { - try - { - GameObject planetObject; - planetObject = GenerateBody(body); - planetObject.SetActive(true); - } - catch(Exception e) - { - Logger.LogError($"Couldn't generate body {body.Config?.Name}: {e.Message}, {e.StackTrace}"); - } + Logger.LogError($"Couldn't generate body {body.Config?.Name}: {e.Message}, {e.StackTrace}"); } } } + public void LoadConfigs(IModBehaviour mod) { CurrentAssets = mod.ModHelper.Assets; @@ -146,144 +160,8 @@ namespace NewHorizons var sector = go.GetComponentInChildren(); var rb = go.GetAttachedOWRigidbody(); - if (body.Config.Ring != null) - { - RingBuilder.Make(go, body.Config.Ring); - } - if (body.Config.Base.LavaSize != 0) - { - LavaBuilder.Make(go, sector, rb, body.Config.Base.LavaSize); - } - if (body.Config.Base.WaterSize != 0) - { - WaterBuilder.Make(go, sector, rb, body.Config.Base.WaterSize); - } - if(body.Config.Atmosphere != null) - { - AirBuilder.Make(go, body.Config.Atmosphere.Size, body.Config.Atmosphere.HasRain, body.Config.Atmosphere.HasOxygen); - - if (body.Config.Atmosphere.Cloud != null) - { - CloudsBuilder.Make(go, sector, body.Config.Atmosphere); - SunOverrideBuilder.Make(go, sector, body.Config.Base.SurfaceSize, body.Config.Atmosphere); - } - - if (body.Config.Atmosphere.HasRain || body.Config.Atmosphere.HasSnow) - EffectsBuilder.Make(go, sector, body.Config.Base.SurfaceSize, body.Config.Atmosphere.Size / 2f, body.Config.Atmosphere.HasRain, body.Config.Atmosphere.HasSnow); - - if (body.Config.Atmosphere.FogSize != 0) - FogBuilder.Make(go, sector, body.Config.Atmosphere); - - AtmosphereBuilder.Make(go, body.Config.Atmosphere); - } - - return go; - } - - private static void RemoveBody(AstroObject ao, List toDestroy = null) - { - Logger.Log($"Removing {ao.name}"); - - if (ao.gameObject == null || !ao.gameObject.activeInHierarchy) return; - - if (toDestroy == null) toDestroy = new List(); - - if(toDestroy.Contains(ao)) - { - Logger.LogError($"Possible infinite recursion in RemoveBody: {ao.name} might be it's own primary body?"); - return; - } - - toDestroy.Add(ao); - - if (ao.GetAstroObjectName() == AstroObject.Name.BrittleHollow) - RemoveBody(AstroObjectLocator.GetAstroObject(AstroObject.Name.WhiteHole), toDestroy); - - // Check if any other objects depend on it and remove them too - var aoArray = AstroObjectLocator.GetAllAstroObjects(); - foreach(AstroObject obj in aoArray) - { - if (obj?.gameObject == null || !obj.gameObject.activeInHierarchy) - { - AstroObjectLocator.RemoveAstroObject(obj); - continue; - } - if (ao.Equals(obj.GetPrimaryBody())) - { - AstroObjectLocator.RemoveAstroObject(obj); - RemoveBody(obj, toDestroy); - } - } - - if (ao.GetAstroObjectName() == AstroObject.Name.CaveTwin || ao.GetAstroObjectName() == AstroObject.Name.TowerTwin) - { - var focalBody = GameObject.Find("FocalBody"); - if(focalBody != null) focalBody.SetActive(false); - } - if (ao.GetAstroObjectName() == AstroObject.Name.MapSatellite) - { - var msb = GameObject.Find("MapSatellite_Body"); - if (msb != null) msb.SetActive(false); - } - if (ao.GetAstroObjectName() == AstroObject.Name.TowerTwin) - GameObject.Find("TimeLoopRing_Body").SetActive(false); - if (ao.GetAstroObjectName() == AstroObject.Name.ProbeCannon) - { - GameObject.Find("NomaiProbe_Body").SetActive(false); - GameObject.Find("CannonMuzzle_Body").SetActive(false); - GameObject.Find("FakeCannonMuzzle_Body (1)").SetActive(false); - GameObject.Find("CannonBarrel_Body").SetActive(false); - GameObject.Find("FakeCannonBarrel_Body (1)").SetActive(false); - GameObject.Find("Debris_Body (1)").SetActive(false); - } - if(ao.GetAstroObjectName() == AstroObject.Name.SunStation) - { - GameObject.Find("SS_Debris_Body").SetActive(false); - } - if(ao.GetAstroObjectName() == AstroObject.Name.GiantsDeep) - { - GameObject.Find("BrambleIsland_Body").SetActive(false); - GameObject.Find("GabbroIsland_Body").SetActive(false); - GameObject.Find("QuantumIsland_Body").SetActive(false); - GameObject.Find("StatueIsland_Body").SetActive(false); - GameObject.Find("ConstructionYardIsland_Body").SetActive(false); - } - if(ao.GetAstroObjectName() == AstroObject.Name.WhiteHole) - { - GameObject.Find("WhiteholeStation_Body").SetActive(false); - GameObject.Find("WhiteholeStationSuperstructure_Body").SetActive(false); - } - if(ao.GetAstroObjectName() == AstroObject.Name.TimberHearth) - { - GameObject.Find("MiningRig_Body").SetActive(false); - } - - // Deal with proxies - foreach(var p in GameObject.FindObjectsOfType()) - { - if(p.GetValue("_originalBody") == ao.gameObject) - { - p.gameObject.SetActive(false); - break; - } - } - Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => RemoveProxy(ao.name.Replace("_Body", ""))); - - ao.transform.root.gameObject.SetActive(false); - } - - private static void RemoveProxy(string name) - { - if (name.Equals("TowerTwin")) name = "AshTwin"; - if (name.Equals("CaveTwin")) name = "EmberTwin"; - var distantProxy = GameObject.Find(name + "_DistantProxy"); - var distantProxyClone = GameObject.Find(name + "_DistantProxy(Clone)"); - - - if (distantProxy != null) Destroy(distantProxy.gameObject); - else Logger.LogWarning($"Couldn't find distant proxy {name + "_DistantProxy"}"); - if (distantProxyClone != null) Destroy(distantProxyClone.gameObject); - else Logger.LogWarning($"Couldn't find distant proxy {name + "_DistantProxy(Clone)"}"); + // Do stuff that's shared between generating new planets and updating old ones + return SharedGenerateBody(body, go, sector, rb); } public static GameObject GenerateBody(NewHorizonsBody body) @@ -295,23 +173,22 @@ namespace NewHorizons if(body.Config.Base.GroundSize != 0) GeometryBuilder.Make(go, body.Config.Base.GroundSize); - AstroObject primaryBody = AstroObjectLocator.GetAstroObject(AstroObject.Name.Sun); - try - { - primaryBody = AstroObjectLocator.GetAstroObject(body.Config.Orbit.PrimaryBody); - } - catch(Exception) + 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); // Get initial position but set it at the end - var a = body.Config.Orbit.SemiMajorAxis; - var omega = Mathf.Deg2Rad * body.Config.Orbit.LongitudeOfAscendingNode; - var positionVector = primaryBody.gameObject.transform.position + new Vector3(a * Mathf.Sin(omega), 0, a * Mathf.Cos(omega)); + //var a = body.Config.Orbit.SemiMajorAxis; + //var omega = Mathf.Deg2Rad * body.Config.Orbit.LongitudeOfAscendingNode; + //var positionVector = primaryBody.gameObject.transform.position + new Vector3(a * Mathf.Sin(omega), 0, a * Mathf.Cos(omega)); + var positionVector = Kepler.OrbitalHelper.CartesianFromOrbitalElements(body.Config.Orbit.Eccentricity, body.Config.Orbit.SemiMajorAxis, body.Config.Orbit.Inclination, + body.Config.Orbit.LongitudeOfAscendingNode, body.Config.Orbit.ArgumentOfPeriapsis, body.Config.Orbit.TrueAnomaly); var outputTuple = BaseBuilder.Make(go, primaryBody, positionVector, body.Config); var ao = (AstroObject)outputTuple.Items[0]; @@ -333,7 +210,53 @@ namespace NewHorizons if (body.Config.HeightMap != null) HeightMapBuilder.Make(go, body.Config.HeightMap); - // These can be shared between creating new planets and updating planets + if (body.Config.ProcGen != null) + ProcGenBuilder.Make(go, body.Config.ProcGen); + + InitialMotionBuilder.Make(go, primaryBody, rb, positionVector, body.Config.Orbit); + + // Do stuff that's shared between generating new planets and updating old ones + go = SharedGenerateBody(body, go, sector, rb); + + body.Object = go; + + // Some things have to be done the second tick + if(body.Config.Orbit != null && !body.Config.Base.HideOrbitLine) + Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => OrbitlineBuilder.Make(body.Object, ao, body.Config.Orbit.IsMoon, body.Config.Orbit)); + + // Now that we're done move the planet into place + go.transform.parent = Locator.GetRootTransform(); + go.transform.position = positionVector + primaryBody.transform.position; + + // Spawning on other planets is a bit hacky so we do it last + if (body.Config.Spawn != null) + { + SpawnPointBuilder.Make(go, body.Config.Spawn, rb); + } + + if (ao.GetAstroObjectName() == AstroObject.Name.CustomString) AstroObjectLocator.RegisterCustomAstroObject(ao); + + Logger.Log("Generation of [" + body.Config.Name + "] completed.", Logger.LogType.Log); + + return go; + } + + private static GameObject SharedGenerateBody(NewHorizonsBody body, GameObject go, Sector sector, OWRigidbody rb) + { + if (body.Config.Ring != null) + RingBuilder.Make(go, body.Config.Ring); + + if (body.Config.AsteroidBelt != null) + AsteroidBeltBuilder.Make(body.Config.Name, body.Config.AsteroidBelt); + + if(body.Config.Base != null) + { + if (body.Config.Base.LavaSize != 0) + LavaBuilder.Make(go, sector, rb, body.Config.Base.LavaSize); + if (body.Config.Base.WaterSize != 0) + WaterBuilder.Make(go, sector, rb, body.Config.Base.WaterSize); + } + if (body.Config.Atmosphere != null) { AirBuilder.Make(go, body.Config.Atmosphere.Size, body.Config.Atmosphere.HasRain, body.Config.Atmosphere.HasOxygen); @@ -344,7 +267,7 @@ namespace NewHorizons SunOverrideBuilder.Make(go, sector, body.Config.Base.SurfaceSize, body.Config.Atmosphere); } - if(body.Config.Atmosphere.HasRain || body.Config.Atmosphere.HasSnow) + if (body.Config.Atmosphere.HasRain || body.Config.Atmosphere.HasSnow) EffectsBuilder.Make(go, sector, body.Config.Base.SurfaceSize, body.Config.Atmosphere.Size / 2f, body.Config.Atmosphere.HasRain, body.Config.Atmosphere.HasSnow); if (body.Config.Atmosphere.FogSize != 0) @@ -353,38 +276,6 @@ namespace NewHorizons AtmosphereBuilder.Make(go, body.Config.Atmosphere); } - if (body.Config.Ring != null) - RingBuilder.Make(go, body.Config.Ring); - - if (body.Config.Base.BlackHoleSize != 0) - BlackHoleBuilder.Make(go); - - if (body.Config.Base.LavaSize != 0) - LavaBuilder.Make(go, sector, rb, body.Config.Base.LavaSize); - - if (body.Config.Base.WaterSize != 0) - WaterBuilder.Make(go, sector, rb, body.Config.Base.WaterSize); - - if (body.Config.Base.HasAmbientLight) - AmbientLightBuilder.Make(go, sphereOfInfluence); - - Logger.Log("Generation of [" + body.Config.Name + "] completed.", Logger.LogType.Log); - - body.Object = go; - - // Some things have to be done the second tick - Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => OrbitlineBuilder.Make(body.Object, ao, body.Config.Orbit.IsMoon)); - - go.transform.parent = Locator.GetRootTransform(); - go.transform.localPosition = positionVector; - - if (body.Config.Spawn != null) - { - SpawnPointBuilder.Make(go, body.Config.Spawn, rb); - } - - if (ao.GetAstroObjectName() == AstroObject.Name.CustomString) AstroObjectLocator.RegisterCustomAstroObject(ao); - return go; } } diff --git a/NewHorizons/NewHorizons.csproj b/NewHorizons/NewHorizons.csproj index 80431b61..65b42e33 100644 --- a/NewHorizons/NewHorizons.csproj +++ b/NewHorizons/NewHorizons.csproj @@ -230,14 +230,20 @@ + + + + + + @@ -245,12 +251,15 @@ + + + @@ -269,6 +278,7 @@ + @@ -290,14 +300,14 @@ md "$(OwmlDir)\Mods\$(ModUniqueName)" md "$(OwmlDir)\Mods\$(ModUniqueName)\planets" md "$(OwmlDir)\Mods\$(ModUniqueName)\planets\assets" - md "$(OwmlDir)\Mods\$(ModUniqueName)\assets" + md "$(OwmlDir)\Mods\$(ModUniqueName)\AssetBundle" copy /y "$(TargetPath)" "$(OwmlDir)\Mods\$(ModUniqueName)" copy /y "$(ProjectDir)\default-config.json" "$(OwmlDir)\Mods\$(ModUniqueName)" copy /y "$(ProjectDir)\manifest.json" "$(OwmlDir)\Mods\$(ModUniqueName)" copy /y "$(ProjectDir)planets\" "$(OwmlDir)\Mods\$(ModUniqueName)\planets" copy /y "$(ProjectDir)planets\assets" "$(OwmlDir)\Mods\$(ModUniqueName)\planets\assets" - copy /y "$(ProjectDir)assets\" "$(OwmlDir)\Mods\$(ModUniqueName)\assets" + copy /y "$(ProjectDir)AssetBundle\" "$(OwmlDir)\Mods\$(ModUniqueName)\AssetBundle" \ No newline at end of file diff --git a/NewHorizons/Physics/OrbitalHelper.cs b/NewHorizons/Physics/OrbitalHelper.cs new file mode 100644 index 00000000..3643b259 --- /dev/null +++ b/NewHorizons/Physics/OrbitalHelper.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.Kepler +{ + public static class OrbitalHelper + { + public static Vector3 CartesianFromOrbitalElements(float e, float a, float inclination, float ascending, float periapsis, float angle) + { + float b = a * Mathf.Sqrt(1f - (e * e)); + + // Get point on ellipse + // Angle starts at apoapsis, shift by 90 degrees to get to periapsis and add true anomaly + float ellipseAngle = Mathf.Repeat(Mathf.PI / 4f + Mathf.Deg2Rad * angle, 2 * Mathf.PI); + + float tAngle = Mathf.Tan(ellipseAngle); + float x = (a * b) / Mathf.Sqrt(b * b + a * a * tAngle * tAngle); + if (ellipseAngle > Mathf.PI / 2f && ellipseAngle < 3f * Mathf.PI / 2f) x *= -1; + float y = x * tAngle; + + // Fix limits + if (float.IsNaN(x)) { + x = 0; + if (angle < 180) y = b; + else y = -b; + } + + var position = new Vector3(x, 0, y); + + return RotateToOrbitalPlane(position, ascending, periapsis, inclination); + } + + public static float VisViva(float standardGravitationalParameter, Vector3 relativePosition, float semiMajorAxis) + { + return Mathf.Sqrt(standardGravitationalParameter * (2f / relativePosition.magnitude - 1f / semiMajorAxis)); + } + + public static Vector3 EllipseTangent(float e, float a, float inclination, float ascending, float periapsis, float angle) + { + float b = a * Mathf.Sqrt(1f - (e * e)); + float ellipseAngle = Mathf.Repeat(Mathf.PI / 4f + Mathf.Deg2Rad * angle, 2 * Mathf.PI); + + var tan = Mathf.Tan(ellipseAngle); + + float x = (a * b) / Mathf.Sqrt(b * b + a * a * tan * tan); + + var sec2 = 1f / (tan * tan); + float dxdt = -a * a * a * b * sec2 * tan / Mathf.Pow(a * a * tan * tan + b * b, 3f / 2f); + + if (ellipseAngle > Mathf.PI / 2f && ellipseAngle < 3f * Mathf.PI / 2f) + { + dxdt *= -1; + x *= -1; + } + + // Product rule + var dydt = sec2 * x + dxdt * tan; + + // Fix limits + if(float.IsNaN(dxdt)) + { + dydt = 0; + if (angle == Mathf.PI / 2f) dxdt = -1; + else dxdt = 1; + } + + var vector = new Vector3(dxdt, 0, dydt).normalized; + return RotateToOrbitalPlane(vector, ascending, periapsis, inclination); + } + + private static Vector3 RotateToOrbitalPlane(Vector3 vector, float ascending, float periapsis, float inclination) + { + // Periapsis is at 90 degrees + vector = Quaternion.AngleAxis(Mathf.Deg2Rad * (ascending + periapsis) + Mathf.PI / 2f, Vector3.up) * vector; + + var inclinationAxis = Quaternion.AngleAxis(Mathf.Repeat(Mathf.Deg2Rad * ascending, 2f * Mathf.PI), Vector3.up) * new Vector3(1, 0, 0); + vector = Quaternion.AngleAxis(Mathf.Repeat(Mathf.Deg2Rad * inclination, 2f * Mathf.PI), inclinationAxis) * vector; + + return vector; + } + + public static Vector3 CalculateOrbitVelocity(OWRigidbody primaryBody, Vector3 relativePosition, float inclination = 0f) + { + GravityVolume attachedGravityVolume = primaryBody.GetAttachedGravityVolume(); + if (attachedGravityVolume == null) + { + return Vector3.zero; + } + Vector3 vector2 = Vector3.Cross(relativePosition, Vector3.up).normalized; + vector2 = Quaternion.AngleAxis(inclination, relativePosition) * vector2; + float d = Mathf.Sqrt(attachedGravityVolume.CalculateForceAccelerationAtPoint(relativePosition + primaryBody.transform.position).magnitude * relativePosition.magnitude); + return vector2 * d; + } + } +} diff --git a/NewHorizons/Physics/ParameterizedOrbitLine.cs b/NewHorizons/Physics/ParameterizedOrbitLine.cs new file mode 100644 index 00000000..4df18206 --- /dev/null +++ b/NewHorizons/Physics/ParameterizedOrbitLine.cs @@ -0,0 +1,125 @@ +using NewHorizons.Kepler; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.Utility +{ + public class ParameterizedOrbitLine : OrbitLine + { + protected override void InitializeLineRenderer() + { + base.GetComponent().positionCount = this._numVerts; + } + + protected override void OnValidate() + { + if (this._numVerts < 0 || this._numVerts > 4096) + { + this._numVerts = Mathf.Clamp(this._numVerts, 0, 4096); + } + if (base.GetComponent().positionCount != this._numVerts) + { + this.InitializeLineRenderer(); + } + } + + protected override void Start() + { + base.Start(); + this._verts = new Vector3[this._numVerts]; + base.enabled = false; + } + + public void SetOrbitalParameters(float eccentricity, float semiMajorAxis, float inclination, float longitudeOfAscendingNode, float argumentOfPeriapsis, float trueAnomaly) + { + _eccentricity = eccentricity; + _semiMajorAxis = semiMajorAxis; + _inclination = inclination; + _longitudeOfAscendingNode = longitudeOfAscendingNode; + _argumentOfPeriapsis = argumentOfPeriapsis; + _trueAnomaly = trueAnomaly; + + _initialMotion = (this._astroObject != null) ? this._astroObject.GetComponent() : null; + _primary = (this._astroObject != null) ? this._astroObject.GetPrimaryBody() : null; + + if (_initialMotion && _primary) + { + var periapsisAngle = longitudeOfAscendingNode + argumentOfPeriapsis; + var apoapsisAngle = periapsisAngle + 90f; + + _vSemiMinorAxis = OrbitalHelper.CartesianFromOrbitalElements(_eccentricity, _semiMajorAxis, _inclination, _longitudeOfAscendingNode, _argumentOfPeriapsis, periapsisAngle); + _vSemiMajorAxis = OrbitalHelper.CartesianFromOrbitalElements(_eccentricity, _semiMajorAxis, _inclination, _longitudeOfAscendingNode, _argumentOfPeriapsis, apoapsisAngle); + + Vector3 rhs = this._astroObject.transform.position - _primary.transform.position; + Vector3 initVelocity = _initialMotion.GetInitVelocity(); + Vector3 vector = Vector3.Cross(initVelocity, rhs); + this._upAxisDir = vector.normalized; + var semiMinorAxis = semiMajorAxis * Mathf.Sqrt(1 - (eccentricity * eccentricity)); + + _fociDistance = Mathf.Sqrt((semiMajorAxis * semiMajorAxis) - (semiMinorAxis * semiMinorAxis)); + + base.enabled = true; + } + else + { + Logger.LogError($"Couldn't set values for KeplerOrbitLine. InitialMotion = {_initialMotion}, AstroObject = {_primary}"); + } + } + + protected override void Update() + { + Vector3 vector = _primary.transform.position + _vSemiMajorAxis * _fociDistance; + float num = CalcProjectedAngleToCenter(vector, _vSemiMajorAxis, _vSemiMinorAxis, _astroObject.transform.position); + for (int i = 0; i < _numVerts; i++) + { + var angle = ((float)i / (float)(_numVerts - 1)) * 360f - Mathf.Rad2Deg * num; + _verts[i] = OrbitalHelper.CartesianFromOrbitalElements(_eccentricity, _semiMajorAxis, _inclination, _longitudeOfAscendingNode, _argumentOfPeriapsis, angle); + } + _lineRenderer.SetPositions(_verts); + + // From EllipticalOrbitLine + base.transform.position = vector; + base.transform.rotation = Quaternion.LookRotation(Quaternion.AngleAxis(-48f, Vector3.up) * _vSemiMajorAxis, -_upAxisDir); + float num2 = DistanceToEllipticalOrbitLine(vector, _vSemiMajorAxis, _vSemiMinorAxis, _upAxisDir, Locator.GetActiveCamera().transform.position); + float widthMultiplier = Mathf.Min(num2 * (_lineWidth / 1000f), _maxLineWidth); + float num3 = _fade ? (1f - Mathf.Clamp01((num2 - _fadeStartDist) / (_fadeEndDist - _fadeStartDist))) : 1f; + _lineRenderer.widthMultiplier = widthMultiplier; + _lineRenderer.startColor = new Color(_color.r, _color.g, _color.b, num3 * num3); + } + + private float CalcProjectedAngleToCenter(Vector3 foci, Vector3 semiMajorAxis, Vector3 semiMinorAxis, Vector3 point) + { + Vector3 lhs = point - foci; + Vector3 vector = new Vector3(Vector3.Dot(lhs, semiMajorAxis.normalized), 0f, Vector3.Dot(lhs, semiMinorAxis.normalized)); + vector.x *= semiMinorAxis.magnitude / semiMajorAxis.magnitude; + return Mathf.Atan2(vector.z, vector.x); + } + + private float DistanceToEllipticalOrbitLine(Vector3 foci, Vector3 semiMajorAxis, Vector3 semiMinorAxis, Vector3 upAxis, Vector3 point) + { + float f = this.CalcProjectedAngleToCenter(foci, semiMajorAxis, semiMinorAxis, point); + Vector3 b = foci + this._vSemiMajorAxis * Mathf.Cos(f) + this._vSemiMinorAxis * Mathf.Sin(f); + return Vector3.Distance(point, b); + } + + private Vector3 _vSemiMajorAxis; + private Vector3 _vSemiMinorAxis; + private Vector3 _upAxisDir; + private float _fociDistance; + + private float _eccentricity; + private float _semiMajorAxis; + private float _inclination; + private float _longitudeOfAscendingNode; + private float _argumentOfPeriapsis; + private float _trueAnomaly; + + private Vector3[] _verts; + private InitialMotion _initialMotion; + private AstroObject _primary; + } +} diff --git a/NewHorizons/Utility/AddToUITable.cs b/NewHorizons/Utility/AddToUITable.cs index 4d6f62bd..954b3d06 100644 --- a/NewHorizons/Utility/AddToUITable.cs +++ b/NewHorizons/Utility/AddToUITable.cs @@ -15,16 +15,10 @@ namespace NewHorizons.Utility try { KeyValuePair pair = instance.theUITable.First(x => x.Value.Equals(text)); - if (pair.Equals(default(KeyValuePair))) - { - Logger.Log($"UI table already contains [{text}] with key [{pair.Key}]"); - return pair.Key; - } + if (pair.Equals(default(KeyValuePair))) return pair.Key; } catch (Exception) { } - instance.Insert_UI(instance.theUITable.Keys.Max() + 1, text); - Logger.Log($"Added [{text}] to UI table with key [{instance.theUITable.Keys.Max()}]"); return instance.theUITable.Keys.Max(); } } diff --git a/NewHorizons/Utility/AstroObjectLocator.cs b/NewHorizons/Utility/AstroObjectLocator.cs index 2d5b5b88..349abe25 100644 --- a/NewHorizons/Utility/AstroObjectLocator.cs +++ b/NewHorizons/Utility/AstroObjectLocator.cs @@ -22,6 +22,7 @@ namespace NewHorizons.Utility if (name.Equals("MAP_SATELLITE")) return GetAstroObject(AstroObject.Name.MapSatellite); var aoName = AstroObject.StringIDToAstroObjectName(name); + if(aoName == AstroObject.Name.None) aoName = AstroObject.StringIDToAstroObjectName(name.ToUpper().Replace(" ", "_")); if (aoName != AstroObject.Name.None && aoName != AstroObject.Name.CustomString) return GetAstroObject(aoName); if (_customAstroObjectDictionary.ContainsKey(name)) @@ -75,23 +76,21 @@ namespace NewHorizons.Utility } var name = ao.GetCustomName(); - if (_customAstroObjectDictionary.Keys.Contains(name)) - Logger.Log($"Custom astro object dictionary already contains {name}. Replacing it.", Logger.LogType.Warning); - _customAstroObjectDictionary.Add(name, ao); + 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) - { - Logger.Log($"Can't deregister {ao.name} as it's AstroObject.Name isn't CustomString."); - return; - } + if (ao.GetAstroObjectName() != AstroObject.Name.CustomString) return; _customAstroObjectDictionary.Remove(ao.GetCustomName()); } public static void RefreshList() { + _customAstroObjectDictionary = new Dictionary(); _list = new List(); } diff --git a/NewHorizons/assets/shader b/NewHorizons/assets/shader deleted file mode 100644 index 2340d65c..00000000 Binary files a/NewHorizons/assets/shader and /dev/null differ