mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
Decluttered logs and added asteroid belts
Also includes some basic proc gen
This commit is contained in:
parent
66b099c594
commit
c977cb5333
BIN
NewHorizons/AssetBundle/shader
Normal file
BIN
NewHorizons/AssetBundle/shader
Normal file
Binary file not shown.
@ -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: []
|
||||
@ -60,7 +60,6 @@ namespace NewHorizons.Atmosphere
|
||||
}
|
||||
|
||||
airGO.SetActive(true);
|
||||
Logger.Log("Finished building air.", Logger.LogType.Log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,7 +77,6 @@ namespace NewHorizons.Atmosphere
|
||||
}
|
||||
|
||||
atmoGO.SetActive(true);
|
||||
Logger.Log("Finished building atmosphere.", Logger.LogType.Log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,8 +51,6 @@ namespace NewHorizons.Atmosphere
|
||||
}
|
||||
|
||||
effectsGO.SetActive(true);
|
||||
|
||||
Logger.Log("Finished building effects", Logger.LogType.Log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,7 +21,6 @@ namespace NewHorizons.Atmosphere
|
||||
GDSOV.SetValue("_waterInnerRadius", 0f);
|
||||
|
||||
overrideGO.SetActive(true);
|
||||
Logger.Log("Finished building sun override.", Logger.LogType.Log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +38,6 @@ namespace NewHorizons.Atmosphere
|
||||
|
||||
rulesetGO.SetActive(true);
|
||||
volumesGO.SetActive(true);
|
||||
Logger.Log("Finished building volumes", Logger.LogType.Log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
64
NewHorizons/Body/AsteroidBeltBuilder.cs
Normal file
64
NewHorizons/Body/AsteroidBeltBuilder.cs
Normal file
@ -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<string, object>()
|
||||
{
|
||||
{"Name", $"{bodyName} Asteroid {i}"},
|
||||
{"Base", new Dictionary<string, object>()
|
||||
{
|
||||
{"HasMapMarker", false },
|
||||
{"SurfaceGravity", 1 },
|
||||
{"SurfaceSize", size },
|
||||
{"HideOrbitLine", true }
|
||||
}
|
||||
},
|
||||
{"Orbit", new Dictionary<string, object>()
|
||||
{
|
||||
{"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<string, object>()
|
||||
{
|
||||
{"Scale", size },
|
||||
{"Color", new MColor32(126, 94, 73, 255) }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Logger.Log($"{config}");
|
||||
|
||||
var asteroid = new NewHorizonsBody(new PlanetConfig(config));
|
||||
Main.AdditionalBodies.Add(asteroid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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]}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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<float, int> seamVertices = new Dictionary<float, int>();
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
176
NewHorizons/Body/Geometry/Perlin.cs
Normal file
176
NewHorizons/Body/Geometry/Perlin.cs
Normal file
@ -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
|
||||
}
|
||||
}
|
||||
@ -49,7 +49,6 @@ namespace NewHorizons.Body
|
||||
geo.SetActive(true);
|
||||
|
||||
*/
|
||||
Logger.Log("Finished building geometry", Logger.LogType.Log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<MeshFilter>();
|
||||
cubeSphere.GetComponent<MeshFilter>().mesh = mesh;
|
||||
|
||||
if(ShaderBundle == null) ShaderBundle = Main.Instance.ModHelper.Assets.LoadBundle("assets/shader");
|
||||
if(PlanetShader == null) PlanetShader = ShaderBundle.LoadAsset<Shader>("Assets/SphereTextureWrapper.shader");
|
||||
if(PlanetShader == null) PlanetShader = Main.ShaderBundle.LoadAsset<Shader>("Assets/SphereTextureWrapper.shader");
|
||||
|
||||
var cubeSphereMR = cubeSphere.AddComponent<MeshRenderer>();
|
||||
cubeSphereMR.material = new Material(PlanetShader);
|
||||
@ -48,7 +45,9 @@ namespace NewHorizons.Body
|
||||
|
||||
var cubeSphereMC = cubeSphere.AddComponent<MeshCollider>();
|
||||
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<MeshCollider>();
|
||||
cubeSphereMC.sharedMesh = mesh;
|
||||
icosphere.transform.localRotation = Quaternion.Euler(90, 0, 0);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
34
NewHorizons/Body/ProcGenBuilder.cs
Normal file
34
NewHorizons/Body/ProcGenBuilder.cs
Normal file
@ -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<MeshFilter>();
|
||||
icosphere.GetComponent<MeshFilter>().mesh = mesh;
|
||||
|
||||
var cubeSphereMR = icosphere.AddComponent<MeshRenderer>();
|
||||
cubeSphereMR.material = new Material(Shader.Find("Standard"));
|
||||
cubeSphereMR.material.color = module.Color.ToColor32();
|
||||
|
||||
var cubeSphereMC = icosphere.AddComponent<MeshCollider>();
|
||||
cubeSphereMC.sharedMesh = mesh;
|
||||
icosphere.transform.localRotation = Quaternion.Euler(90, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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<MeshRenderer>();
|
||||
var texture = ringTexture;
|
||||
|
||||
var mat = new Material(Shader.Find("Legacy Shaders/Particles/Alpha Blended Premultiply"));
|
||||
if (RingShader == null) RingShader = Main.ShaderBundle.LoadAsset<Shader>("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
|
||||
|
||||
16
NewHorizons/Body/SunBuilder.cs
Normal file
16
NewHorizons/Body/SunBuilder.cs
Normal file
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -80,8 +80,6 @@ namespace NewHorizons.Body
|
||||
*/
|
||||
|
||||
waterGO.SetActive(true);
|
||||
|
||||
Logger.Log("Finished building water", Logger.LogType.Log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
16
NewHorizons/External/AsteroidBeltModule.cs
vendored
Normal file
16
NewHorizons/External/AsteroidBeltModule.cs
vendored
Normal file
@ -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; }
|
||||
}
|
||||
}
|
||||
1
NewHorizons/External/BaseModule.cs
vendored
1
NewHorizons/External/BaseModule.cs
vendored
@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
2
NewHorizons/External/IPlanetConfig.cs
vendored
2
NewHorizons/External/IPlanetConfig.cs
vendored
@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
6
NewHorizons/External/Module.cs
vendored
6
NewHorizons/External/Module.cs
vendored
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1
NewHorizons/External/OrbitModule.cs
vendored
1
NewHorizons/External/OrbitModule.cs
vendored
@ -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; }
|
||||
|
||||
42
NewHorizons/External/PlanetConfig.cs
vendored
42
NewHorizons/External/PlanetConfig.cs
vendored
@ -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<string, object> 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<string, object>);
|
||||
break;
|
||||
case "Orbit":
|
||||
Orbit.Build(item.Value as Dictionary<string, object>);
|
||||
break;
|
||||
case "Atmosphere":
|
||||
Atmosphere = new AtmosphereModule();
|
||||
Atmosphere.Build(item.Value as Dictionary<string, object>);
|
||||
break;
|
||||
case "Orbit":
|
||||
Orbit = new OrbitModule();
|
||||
Orbit.Build(item.Value as Dictionary<string, object>);
|
||||
break;
|
||||
case "Ring":
|
||||
Ring = new RingModule();
|
||||
Ring.Build(item.Value as Dictionary<string, object>);
|
||||
@ -49,23 +48,24 @@ namespace NewHorizons.External
|
||||
HeightMap = new HeightMapModule();
|
||||
HeightMap.Build(item.Value as Dictionary<string, object>);
|
||||
break;
|
||||
case "ProcGen":
|
||||
ProcGen = new ProcGenModule();
|
||||
ProcGen.Build(item.Value as Dictionary<string, object>);
|
||||
break;
|
||||
case "AsteroidBelt":
|
||||
AsteroidBelt = new AsteroidBeltModule();
|
||||
AsteroidBelt.Build(item.Value as Dictionary<string, object>);
|
||||
break;
|
||||
case "Spawn":
|
||||
Spawn = new SpawnModule();
|
||||
Spawn.Build(item.Value as Dictionary<string, object>);
|
||||
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));
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
NewHorizons/External/ProcGenModule.cs
vendored
Normal file
15
NewHorizons/External/ProcGenModule.cs
vendored
Normal file
@ -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; }
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,18 +26,6 @@ namespace NewHorizons.General
|
||||
OWRB.SetValue("_maintainOriginalCenterOfMass", true);
|
||||
OWRB.SetValue("_rigidbody", RB);
|
||||
|
||||
InitialMotion IM = body.AddComponent<InitialMotion>();
|
||||
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<AstroObject>();
|
||||
@ -55,7 +43,6 @@ namespace NewHorizons.General
|
||||
*/
|
||||
}
|
||||
|
||||
Logger.Log("Finished building base", Logger.LogType.Log);
|
||||
return new MTuple(AO, OWRB);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<ConstantForceDetector>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,8 +40,6 @@ namespace NewHorizons.General
|
||||
gravityGO.SetActive(true);
|
||||
|
||||
ao.SetValue("_gravityVolume", GV);
|
||||
|
||||
Logger.Log("Finished building gravity", Logger.LogType.Log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
54
NewHorizons/General/InitialMotionBuilder.cs
Normal file
54
NewHorizons/General/InitialMotionBuilder.cs
Normal file
@ -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<InitialMotion>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<LineRenderer>();
|
||||
var LR = orbitGO.AddComponent<LineRenderer>();
|
||||
|
||||
var thLR = GameObject.Find("OrbitLine_TH").GetComponent<LineRenderer>();
|
||||
var thLR = GameObject.Find("OrbitLine_CO").GetComponent<LineRenderer>();
|
||||
|
||||
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>();
|
||||
OrbitLine ol = orbit.Eccentricity != 0 ? orbitGO.AddComponent<EllipticOrbitLine>() : orbitGO.AddComponent<OrbitLine>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
118
NewHorizons/General/PlanetDestroyer.cs
Normal file
118
NewHorizons/General/PlanetDestroyer.cs
Normal file
@ -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<AstroObject> toDestroy = null)
|
||||
{
|
||||
Logger.Log($"Removing {ao.name}");
|
||||
|
||||
if (ao.gameObject == null || !ao.gameObject.activeInHierarchy) return;
|
||||
|
||||
if (toDestroy == null) toDestroy = new List<AstroObject>();
|
||||
|
||||
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<ProxyOrbiter>())
|
||||
{
|
||||
if (p.GetValue<AstroObject>("_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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<SphereCollider>();
|
||||
SC.isTrigger = true;
|
||||
SC.radius = atmoEndSize * 2;
|
||||
SC.radius = sphereOfInfluence * 2;
|
||||
|
||||
ReferenceFrameVolume RFV = rfGO.AddComponent<ReferenceFrameVolume>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,7 +31,6 @@ namespace NewHorizons.Body
|
||||
|
||||
sectorGO.SetActive(true);
|
||||
|
||||
Logger.Log("Finished building sector", Logger.LogType.Log);
|
||||
return S;
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,9 +18,12 @@ namespace NewHorizons
|
||||
{
|
||||
public class Main : ModBehaviour
|
||||
{
|
||||
|
||||
public static AssetBundle ShaderBundle;
|
||||
public static Main Instance { get; private set; }
|
||||
|
||||
public static List<NewHorizonsBody> BodyList = new List<NewHorizonsBody>();
|
||||
public static List<NewHorizonsBody> AdditionalBodies = new List<NewHorizonsBody>();
|
||||
|
||||
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<DebugRaycaster>());
|
||||
|
||||
@ -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<NewHorizonsBody>();
|
||||
}
|
||||
}
|
||||
|
||||
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<Sector>();
|
||||
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<AstroObject> toDestroy = null)
|
||||
{
|
||||
Logger.Log($"Removing {ao.name}");
|
||||
|
||||
if (ao.gameObject == null || !ao.gameObject.activeInHierarchy) return;
|
||||
|
||||
if (toDestroy == null) toDestroy = new List<AstroObject>();
|
||||
|
||||
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<ProxyOrbiter>())
|
||||
{
|
||||
if(p.GetValue<AstroObject>("_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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,14 +230,20 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Atmosphere\FogBuilder.cs" />
|
||||
<Compile Include="Body\AsteroidBeltBuilder.cs" />
|
||||
<Compile Include="Body\Geometry\CubeSphere.cs" />
|
||||
<Compile Include="Body\Geometry\Icosphere.cs" />
|
||||
<Compile Include="Body\Geometry\Perlin.cs" />
|
||||
<Compile Include="Body\HeightMapBuilder.cs" />
|
||||
<Compile Include="Body\ProcGenBuilder.cs" />
|
||||
<Compile Include="Body\SunBuilder.cs" />
|
||||
<Compile Include="External\AsteroidBeltModule.cs" />
|
||||
<Compile Include="External\AtmosphereModule.cs" />
|
||||
<Compile Include="External\BaseModule.cs" />
|
||||
<Compile Include="External\HeightMapModule.cs" />
|
||||
<Compile Include="External\Module.cs" />
|
||||
<Compile Include="External\OrbitModule.cs" />
|
||||
<Compile Include="External\ProcGenModule.cs" />
|
||||
<Compile Include="External\RingModule.cs" />
|
||||
<Compile Include="External\SpawnModule.cs" />
|
||||
<Compile Include="General\BaseBuilder.cs" />
|
||||
@ -245,12 +251,15 @@
|
||||
<Compile Include="General\DetectorBuilder.cs" />
|
||||
<Compile Include="General\GravityBuilder.cs" />
|
||||
<Compile Include="Body\LavaBuilder.cs" />
|
||||
<Compile Include="General\InitialMotionBuilder.cs" />
|
||||
<Compile Include="General\MarkerBuilder.cs" />
|
||||
<Compile Include="General\OrbitlineBuilder.cs" />
|
||||
<Compile Include="General\PlanetDestroyer.cs" />
|
||||
<Compile Include="General\RFVolumeBuilder.cs" />
|
||||
<Compile Include="Body\RingBuilder.cs" />
|
||||
<Compile Include="General\SectorBuilder.cs" />
|
||||
<Compile Include="General\SpawnPointBuilder.cs" />
|
||||
<Compile Include="Physics\OrbitalHelper.cs" />
|
||||
<Compile Include="Utility\AddDebugShape.cs" />
|
||||
<Compile Include="General\AmbientLightBuilder.cs" />
|
||||
<Compile Include="External\IPlanetConfig.cs" />
|
||||
@ -269,6 +278,7 @@
|
||||
<Compile Include="Utility\AstroObjectLocator.cs" />
|
||||
<Compile Include="Utility\DebugRaycaster.cs" />
|
||||
<Compile Include="Utility\ImageUtilities.cs" />
|
||||
<Compile Include="Physics\ParameterizedOrbitLine.cs" />
|
||||
<Compile Include="Utility\Logger.cs" />
|
||||
<Compile Include="Utility\MakeMeshDoubleFaced.cs" />
|
||||
<Compile Include="Utility\NewHorizonBody.cs" />
|
||||
@ -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"
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
99
NewHorizons/Physics/OrbitalHelper.cs
Normal file
99
NewHorizons/Physics/OrbitalHelper.cs
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
125
NewHorizons/Physics/ParameterizedOrbitLine.cs
Normal file
125
NewHorizons/Physics/ParameterizedOrbitLine.cs
Normal file
@ -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<LineRenderer>().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<LineRenderer>().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<InitialMotion>() : 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;
|
||||
}
|
||||
}
|
||||
@ -15,16 +15,10 @@ namespace NewHorizons.Utility
|
||||
try
|
||||
{
|
||||
KeyValuePair<int, string> pair = instance.theUITable.First(x => x.Value.Equals(text));
|
||||
if (pair.Equals(default(KeyValuePair<int, string>)))
|
||||
{
|
||||
Logger.Log($"UI table already contains [{text}] with key [{pair.Key}]");
|
||||
return pair.Key;
|
||||
}
|
||||
if (pair.Equals(default(KeyValuePair<int, string>))) 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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<string, AstroObject>();
|
||||
_list = new List<AstroObject>();
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user