mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
Merge branch 'master' into common-resources
This commit is contained in:
commit
e5ced93768
Binary file not shown.
@ -1,9 +1,9 @@
|
||||
ManifestFileVersion: 0
|
||||
CRC: 3840241390
|
||||
CRC: 3597037522
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: 1c2c90716d1ed7c9cbf5f785e41eace6
|
||||
Hash: 33678ea445c06b269454371064cc3a5c
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: 6370d3f9de9eca57f523bce048404a46
|
||||
@ -12,6 +12,7 @@ ClassTypes:
|
||||
- Class: 48
|
||||
Script: {instanceID: 0}
|
||||
Assets:
|
||||
- Assets/SphereTextureWrapper.shader
|
||||
- Assets/UnlitTransparent.shader
|
||||
- Assets/Shaders/SphereTextureWrapper.shader
|
||||
- Assets/Shaders/Ring.shader
|
||||
- Assets/Shaders/UnlitTransparent.shader
|
||||
Dependencies: []
|
||||
|
||||
@ -20,8 +20,6 @@ namespace NewHorizons.Atmosphere
|
||||
|
||||
if (atmo.CloudCap == null) cap = ImageUtilities.ClearTexture(128, 128);
|
||||
else cap = assets.GetTexture(atmo.CloudCap);
|
||||
|
||||
//if(atmo.CloudRamp == null) ramp = ImageUtilities.Scaled(image, 1, 128);
|
||||
if(atmo.CloudRamp == null) ramp = ImageUtilities.CanvasScaled(image, 1, image.height);
|
||||
else ramp = assets.GetTexture(atmo.CloudRamp);
|
||||
}
|
||||
@ -31,6 +29,8 @@ namespace NewHorizons.Atmosphere
|
||||
return;
|
||||
}
|
||||
|
||||
Color cloudTint = atmo.CloudTint == null ? Color.white : (Color)atmo.CloudTint.ToColor32();
|
||||
|
||||
GameObject cloudsMainGO = new GameObject();
|
||||
cloudsMainGO.SetActive(false);
|
||||
cloudsMainGO.transform.parent = body.transform;
|
||||
@ -56,8 +56,8 @@ namespace NewHorizons.Atmosphere
|
||||
|
||||
foreach (var material in topMR.sharedMaterials)
|
||||
{
|
||||
material.SetColor("_Color", atmo.CloudTint.ToColor32());
|
||||
material.SetColor("_TintColor", atmo.CloudTint.ToColor32());
|
||||
material.SetColor("_Color", cloudTint);
|
||||
material.SetColor("_TintColor", cloudTint);
|
||||
|
||||
material.SetTexture("_MainTex", image);
|
||||
material.SetTexture("_RampTex", ramp);
|
||||
@ -84,7 +84,7 @@ namespace NewHorizons.Atmosphere
|
||||
bottomTSR.LODRadius = 1f;
|
||||
|
||||
// It's always more green than expected
|
||||
var bottomCloudTint = atmo.CloudTint.ToColor32();
|
||||
var bottomCloudTint = cloudTint;
|
||||
bottomCloudTint.g = (byte)(bottomCloudTint.g * 0.8f);
|
||||
foreach (Material material in bottomTSR.sharedMaterials)
|
||||
{
|
||||
|
||||
@ -14,8 +14,10 @@ namespace NewHorizons.Builder.Body
|
||||
{
|
||||
static class AsteroidBeltBuilder
|
||||
{
|
||||
public static void Make(string bodyName, AsteroidBeltModule belt, IModAssets assets)
|
||||
public static void Make(string bodyName, IPlanetConfig parentConfig, IModAssets assets, string uniqueName)
|
||||
{
|
||||
var belt = parentConfig.AsteroidBelt;
|
||||
|
||||
var minSize = 20;
|
||||
var maxSize = 50;
|
||||
int count = (int)(2f * Mathf.PI * belt.InnerRadius / (10f * maxSize));
|
||||
@ -28,7 +30,8 @@ namespace NewHorizons.Builder.Body
|
||||
var size = Random.Range(minSize, maxSize);
|
||||
var config = new Dictionary<string, object>()
|
||||
{
|
||||
{"Name", $"{bodyName} Asteroid {i+1}"},
|
||||
{"Name", $"{bodyName} Asteroid {i}"},
|
||||
{"StarSystem", parentConfig.StarSystem },
|
||||
{"Base", new Dictionary<string, object>()
|
||||
{
|
||||
{"HasMapMarker", false },
|
||||
@ -57,7 +60,9 @@ namespace NewHorizons.Builder.Body
|
||||
}
|
||||
};
|
||||
|
||||
var asteroid = new NewHorizonsBody(new PlanetConfig(config), assets);
|
||||
var asteroidConfig = new PlanetConfig(config);
|
||||
if (belt.ProcGen != null) asteroidConfig.ProcGen = belt.ProcGen;
|
||||
var asteroid = new NewHorizonsBody(new PlanetConfig(config), assets, uniqueName);
|
||||
Main.NextPassBodies.Add(asteroid);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
using NewHorizons.External;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NewHorizons.Builder.Body
|
||||
{
|
||||
static class BlackHoleBuilder
|
||||
{
|
||||
public static void Make(GameObject body, BaseModule module, Sector sector)
|
||||
{
|
||||
var blackHole = GameObject.Instantiate(GameObject.Find("BrittleHollow_Body/BlackHole_BH"), body.transform);
|
||||
blackHole.name = "BlackHole";
|
||||
blackHole.transform.localPosition = Vector3.zero;
|
||||
//blackHole.transform.localScale = Vector3.one; //* module.BlackHoleSize;
|
||||
|
||||
var blackHoleRenderer = blackHole.transform.Find("BlackHoleRenderer");
|
||||
//blackHoleRenderer.transform.localScale = Vector3.one;
|
||||
|
||||
var singularityLOD = blackHoleRenderer.GetComponent<SingularityLOD>();
|
||||
singularityLOD.SetSector(sector);
|
||||
|
||||
/*
|
||||
var meshRenderer = blackHoleRenderer.GetComponent<MeshRenderer>();
|
||||
meshRenderer.material.SetFloat("_Radius", module.BlackHoleSize * 0.4f);
|
||||
|
||||
var owRenderer = blackHoleRenderer.gameObject.AddComponent<OWRenderer>();
|
||||
var propID_Radius = Shader.PropertyToID("_Radius");
|
||||
owRenderer.SetMaterialProperty(propID_Radius, module.BlackHoleSize * 0.4f);
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -97,8 +97,8 @@ namespace NewHorizons.Body
|
||||
|
||||
float latitude = (Mathf.Rad2Deg * Mathf.Acos(v.z / Mathf.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z)));
|
||||
float longitude = 180f;
|
||||
if(v.x > 0) longitude = Mathf.Rad2Deg * Mathf.Atan(v.y / v.x) + 90f;
|
||||
if(v.x < 0) longitude = Mathf.Rad2Deg * (Mathf.Atan(v.y / v.x) + Mathf.PI) + 90f;
|
||||
if(v.x > 0) longitude = Mathf.Rad2Deg * Mathf.Atan(v.y / v.x);
|
||||
if(v.x < 0) longitude = Mathf.Rad2Deg * (Mathf.Atan(v.y / v.x) + Mathf.PI);
|
||||
|
||||
float sampleX = heightMap.width * longitude / 360f;
|
||||
float sampleY = heightMap.height * latitude / 180f;
|
||||
|
||||
@ -33,6 +33,7 @@ namespace NewHorizons.Builder.Body
|
||||
}
|
||||
|
||||
GameObject cubeSphere = new GameObject("CubeSphere");
|
||||
cubeSphere.SetActive(false);
|
||||
cubeSphere.transform.parent = go.transform;
|
||||
cubeSphere.transform.rotation = Quaternion.Euler(90, 0, 0);
|
||||
|
||||
@ -41,7 +42,7 @@ namespace NewHorizons.Builder.Body
|
||||
cubeSphere.AddComponent<MeshFilter>();
|
||||
cubeSphere.GetComponent<MeshFilter>().mesh = mesh;
|
||||
|
||||
if(PlanetShader == null) PlanetShader = Main.ShaderBundle.LoadAsset<Shader>("Assets/SphereTextureWrapper.shader");
|
||||
if(PlanetShader == null) PlanetShader = Main.ShaderBundle.LoadAsset<Shader>("Assets/Shaders/SphereTextureWrapper.shader");
|
||||
|
||||
var cubeSphereMR = cubeSphere.AddComponent<MeshRenderer>();
|
||||
cubeSphereMR.material = new Material(PlanetShader);
|
||||
@ -50,9 +51,13 @@ namespace NewHorizons.Builder.Body
|
||||
var cubeSphereMC = cubeSphere.AddComponent<MeshCollider>();
|
||||
cubeSphereMC.sharedMesh = mesh;
|
||||
|
||||
if(go.GetComponent<ProxyShadowCasterSuperGroup>() != null) cubeSphere.AddComponent<ProxyShadowCaster>();
|
||||
|
||||
// Fix rotation in the end
|
||||
cubeSphere.transform.localRotation = Quaternion.Euler(90, 0, 0);
|
||||
cubeSphere.transform.localPosition = Vector3.zero;
|
||||
|
||||
cubeSphere.SetActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,6 +30,8 @@ namespace NewHorizons.Builder.Body
|
||||
var cubeSphereMC = icosphere.AddComponent<MeshCollider>();
|
||||
cubeSphereMC.sharedMesh = mesh;
|
||||
icosphere.transform.localRotation = Quaternion.Euler(90, 0, 0);
|
||||
|
||||
icosphere.AddComponent<ProxyShadowCaster>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ namespace NewHorizons.Builder.Body
|
||||
static class RingBuilder
|
||||
{
|
||||
public static Shader RingShader;
|
||||
public static Shader UnlitShader;
|
||||
|
||||
public static void Make(GameObject body, RingModule ring, IModAssets assets)
|
||||
{
|
||||
@ -39,15 +40,16 @@ namespace NewHorizons.Builder.Body
|
||||
var ringMR = ringGO.AddComponent<MeshRenderer>();
|
||||
var texture = ringTexture;
|
||||
|
||||
if (RingShader == null) RingShader = Main.ShaderBundle.LoadAsset<Shader>("Assets/UnlitTransparent.shader");
|
||||
if (RingShader == null) RingShader = Main.ShaderBundle.LoadAsset<Shader>("Assets/Shaders/Ring.shader");
|
||||
if (UnlitShader == null) UnlitShader = Main.ShaderBundle.LoadAsset<Shader>("Assets/Shaders/UnlitTransparent.shader");
|
||||
|
||||
var mat = new Material(RingShader);
|
||||
var mat = new Material(ring.Unlit ? UnlitShader : RingShader);
|
||||
mat.mainTexture = texture;
|
||||
mat.renderQueue = 3000;
|
||||
mat.renderQueue = 2895;
|
||||
ringMR.material = mat;
|
||||
|
||||
// Make mesh
|
||||
var segments = (int)Math.Max(20, ring.OuterRadius);
|
||||
var segments = (int)Mathf.Clamp(ring.OuterRadius, 20, 2000);
|
||||
BuildRingMesh(ringMesh, segments, ring.InnerRadius, ring.OuterRadius);
|
||||
}
|
||||
|
||||
|
||||
234
NewHorizons/Builder/Body/SingularityBuilder.cs
Normal file
234
NewHorizons/Builder/Body/SingularityBuilder.cs
Normal file
@ -0,0 +1,234 @@
|
||||
using NewHorizons.Components;
|
||||
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;
|
||||
|
||||
namespace NewHorizons.Builder.Body
|
||||
{
|
||||
static class SingularityBuilder
|
||||
{
|
||||
enum Polarity
|
||||
{
|
||||
BlackHole,
|
||||
WhiteHole
|
||||
}
|
||||
|
||||
private static Shader blackHoleShader = null;
|
||||
private static Shader whiteHoleShader = null;
|
||||
|
||||
public static void Make(GameObject body, Sector sector, OWRigidbody OWRB, IPlanetConfig config)
|
||||
{
|
||||
|
||||
var size = config.Base.BlackHoleSize;
|
||||
string pairedSingularity = null;
|
||||
var polarity = Polarity.BlackHole;
|
||||
|
||||
if (config.Singularity != null)
|
||||
{
|
||||
size = config.Singularity.Size;
|
||||
pairedSingularity = config.Singularity.PairedSingularity;
|
||||
if(config.Singularity.Type != null && config.Singularity.Type.ToUpper().Equals("WHITEHOLE"))
|
||||
{
|
||||
polarity = Polarity.WhiteHole;
|
||||
}
|
||||
}
|
||||
bool isWormHole = config.Singularity.TargetStarSystem != null;
|
||||
bool hasHazardVolume = !isWormHole && (pairedSingularity == null);
|
||||
|
||||
Vector3 localPosition = config.Singularity.Position == null ? Vector3.zero : (Vector3)config.Singularity.Position;
|
||||
|
||||
GameObject newSingularity = null;
|
||||
switch (polarity)
|
||||
{
|
||||
case Polarity.BlackHole:
|
||||
newSingularity = MakeBlackHole(body, sector, localPosition, size, hasHazardVolume, config.Singularity.TargetStarSystem);
|
||||
break;
|
||||
case Polarity.WhiteHole:
|
||||
newSingularity = MakeWhiteHole(body, sector, OWRB, localPosition, size);
|
||||
break;
|
||||
}
|
||||
|
||||
// Try to pair them
|
||||
if(pairedSingularity != null && newSingularity != null)
|
||||
{
|
||||
var pairedSingularityAO = AstroObjectLocator.GetAstroObject(pairedSingularity);
|
||||
if(pairedSingularityAO != null)
|
||||
{
|
||||
switch (polarity)
|
||||
{
|
||||
case Polarity.BlackHole:
|
||||
PairSingularities(newSingularity, pairedSingularityAO.gameObject);
|
||||
break;
|
||||
case Polarity.WhiteHole:
|
||||
PairSingularities(pairedSingularityAO.gameObject, newSingularity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void PairSingularities(GameObject blackHole, GameObject whiteHole)
|
||||
{
|
||||
Logger.Log($"Pairing singularities {blackHole?.name}, {whiteHole?.name}");
|
||||
try
|
||||
{
|
||||
blackHole.GetComponentInChildren<BlackHoleVolume>()._whiteHole = whiteHole.GetComponentInChildren<WhiteHoleVolume>();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Logger.LogError($"Couldn't pair singularities");
|
||||
}
|
||||
}
|
||||
|
||||
public static GameObject MakeBlackHole(GameObject body, Sector sector, Vector3 localPosition, float size, bool hasDestructionVolume, string targetSolarSystem, bool makeAudio = true)
|
||||
{
|
||||
var blackHole = new GameObject("BlackHole");
|
||||
blackHole.SetActive(false);
|
||||
blackHole.transform.parent = body.transform;
|
||||
blackHole.transform.localPosition = localPosition;
|
||||
|
||||
var blackHoleRender = new GameObject("BlackHoleRender");
|
||||
blackHoleRender.transform.parent = blackHole.transform;
|
||||
blackHoleRender.transform.localPosition = Vector3.zero;
|
||||
blackHoleRender.transform.localScale = Vector3.one * size;
|
||||
|
||||
var meshFilter = blackHoleRender.AddComponent<MeshFilter>();
|
||||
meshFilter.mesh = GameObject.Find("BrittleHollow_Body/BlackHole_BH/BlackHoleRenderer").GetComponent<MeshFilter>().mesh;
|
||||
|
||||
var meshRenderer = blackHoleRender.AddComponent<MeshRenderer>();
|
||||
if (blackHoleShader == null) blackHoleShader = GameObject.Find("BrittleHollow_Body/BlackHole_BH/BlackHoleRenderer").GetComponent<MeshRenderer>().sharedMaterial.shader;
|
||||
meshRenderer.material = new Material(blackHoleShader);
|
||||
meshRenderer.material.SetFloat("_Radius", size * 0.4f);
|
||||
meshRenderer.material.SetFloat("_MaxDistortRadius", size * 0.95f);
|
||||
meshRenderer.material.SetFloat("_MassScale", 1);
|
||||
meshRenderer.material.SetFloat("_DistortFadeDist", size * 0.55f);
|
||||
|
||||
if(makeAudio)
|
||||
{
|
||||
var blackHoleAmbience = GameObject.Instantiate(GameObject.Find("BrittleHollow_Body/BlackHole_BH/BlackHoleAmbience"), blackHole.transform);
|
||||
blackHoleAmbience.name = "BlackHoleAmbience";
|
||||
blackHoleAmbience.GetComponent<SectorAudioGroup>().SetSector(sector);
|
||||
|
||||
var blackHoleAudioSource = blackHoleAmbience.GetComponent<AudioSource>();
|
||||
blackHoleAudioSource.maxDistance = size * 2.5f;
|
||||
blackHoleAudioSource.minDistance = size * 0.4f;
|
||||
blackHoleAmbience.transform.localPosition = Vector3.zero;
|
||||
|
||||
var blackHoleOneShot = GameObject.Instantiate(GameObject.Find("BrittleHollow_Body/BlackHole_BH/BlackHoleEmissionOneShot"), blackHole.transform);
|
||||
var oneShotAudioSource = blackHoleOneShot.GetComponent<AudioSource>();
|
||||
oneShotAudioSource.maxDistance = size * 3f;
|
||||
oneShotAudioSource.minDistance = size * 0.4f;
|
||||
}
|
||||
|
||||
|
||||
if (hasDestructionVolume || targetSolarSystem != null)
|
||||
{
|
||||
var destructionVolumeGO = new GameObject("DestructionVolume");
|
||||
destructionVolumeGO.layer = LayerMask.NameToLayer("BasicEffectVolume");
|
||||
destructionVolumeGO.transform.parent = blackHole.transform;
|
||||
destructionVolumeGO.transform.localScale = Vector3.one;
|
||||
destructionVolumeGO.transform.localPosition = Vector3.zero;
|
||||
|
||||
var sphereCollider = destructionVolumeGO.AddComponent<SphereCollider>();
|
||||
sphereCollider.radius = size * 0.4f;
|
||||
sphereCollider.isTrigger = true;
|
||||
|
||||
if (hasDestructionVolume) destructionVolumeGO.AddComponent<BlackHoleDestructionVolume>();
|
||||
else if (targetSolarSystem != null)
|
||||
{
|
||||
var wormholeVolume = destructionVolumeGO.AddComponent<ChangeStarSystemVolume>();
|
||||
wormholeVolume.TargetSolarSystem = targetSolarSystem;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var blackHoleVolume = GameObject.Instantiate(GameObject.Find("BrittleHollow_Body/BlackHole_BH/BlackHoleVolume"), blackHole.transform);
|
||||
blackHoleVolume.name = "BlackHoleVolume";
|
||||
blackHoleVolume.GetComponent<SphereCollider>().radius = size * 0.4f;
|
||||
}
|
||||
|
||||
blackHole.SetActive(true);
|
||||
return blackHole;
|
||||
}
|
||||
|
||||
public static GameObject MakeWhiteHole(GameObject body, Sector sector, OWRigidbody OWRB, Vector3 localPosition, float size, bool makeZeroGVolume = true)
|
||||
{
|
||||
var whiteHole = new GameObject("WhiteHole");
|
||||
whiteHole.SetActive(false);
|
||||
whiteHole.transform.parent = body.transform;
|
||||
whiteHole.transform.localPosition = localPosition;
|
||||
|
||||
var whiteHoleRenderer = new GameObject("WhiteHoleRenderer");
|
||||
whiteHoleRenderer.transform.parent = whiteHole.transform;
|
||||
whiteHoleRenderer.transform.localPosition = Vector3.zero;
|
||||
whiteHoleRenderer.transform.localScale = Vector3.one * size * 2.8f;
|
||||
|
||||
var meshFilter = whiteHoleRenderer.AddComponent<MeshFilter>();
|
||||
meshFilter.mesh = GameObject.Find("WhiteHole_Body/WhiteHoleVisuals/Singularity").GetComponent<MeshFilter>().mesh;
|
||||
|
||||
var meshRenderer = whiteHoleRenderer.AddComponent<MeshRenderer>();
|
||||
if (whiteHoleShader == null) whiteHoleShader = GameObject.Find("WhiteHole_Body/WhiteHoleVisuals/Singularity").GetComponent<MeshRenderer>().sharedMaterial.shader;
|
||||
meshRenderer.material = new Material(whiteHoleShader);
|
||||
meshRenderer.sharedMaterial.SetFloat("_Radius", size * 0.4f);
|
||||
meshRenderer.sharedMaterial.SetFloat("_DistortFadeDist", size);
|
||||
meshRenderer.sharedMaterial.SetFloat("_MaxDistortRadius", size * 2.8f);
|
||||
meshRenderer.sharedMaterial.SetColor("_Color", new Color(1.88f, 1.88f, 1.88f, 1f));
|
||||
|
||||
var ambientLight = GameObject.Instantiate(GameObject.Find("WhiteHole_Body/WhiteHoleVisuals/AmbientLight_WH"));
|
||||
ambientLight.transform.parent = whiteHole.transform;
|
||||
ambientLight.transform.localScale = Vector3.one;
|
||||
ambientLight.transform.localPosition = Vector3.zero;
|
||||
ambientLight.name = "AmbientLight";
|
||||
ambientLight.GetComponent<Light>().range = size * 7f;
|
||||
|
||||
GameObject whiteHoleVolumeGO = GameObject.Instantiate(GameObject.Find("WhiteHole_Body/WhiteHoleVolume"));
|
||||
whiteHoleVolumeGO.transform.parent = whiteHole.transform;
|
||||
whiteHoleVolumeGO.transform.localPosition = Vector3.zero;
|
||||
whiteHoleVolumeGO.transform.localScale = Vector3.one;
|
||||
whiteHoleVolumeGO.GetComponent<SphereCollider>().radius = size;
|
||||
whiteHoleVolumeGO.name = "WhiteHoleVolume";
|
||||
|
||||
var whiteHoleFluidVolume = whiteHoleVolumeGO.GetComponent<WhiteHoleFluidVolume>();
|
||||
whiteHoleFluidVolume._innerRadius = size * 0.5f;
|
||||
whiteHoleFluidVolume._outerRadius = size;
|
||||
whiteHoleFluidVolume._attachedBody = OWRB;
|
||||
|
||||
var whiteHoleVolume = whiteHoleVolumeGO.GetComponent<WhiteHoleVolume>();
|
||||
whiteHoleVolume._debrisDistMax = size * 6.5f;
|
||||
whiteHoleVolume._debrisDistMin = size * 2f;
|
||||
whiteHoleVolume._whiteHoleSector = sector;
|
||||
whiteHoleVolume._fluidVolume = whiteHoleFluidVolume;
|
||||
whiteHoleVolume._whiteHoleBody = OWRB;
|
||||
whiteHoleVolume._whiteHoleProxyShadowSuperGroup = body.GetComponent<ProxyShadowCasterSuperGroup>();
|
||||
|
||||
whiteHoleVolumeGO.GetComponent<SphereCollider>().radius = size;
|
||||
|
||||
whiteHoleVolume.enabled = true;
|
||||
whiteHoleFluidVolume.enabled = true;
|
||||
|
||||
if(makeZeroGVolume)
|
||||
{
|
||||
var zeroGVolume = GameObject.Instantiate(GameObject.Find("WhiteHole_Body/ZeroGVolume"), whiteHole.transform);
|
||||
zeroGVolume.name = "ZeroGVolume";
|
||||
zeroGVolume.transform.localPosition = Vector3.zero;
|
||||
zeroGVolume.GetComponent<SphereCollider>().radius = size * 10f;
|
||||
zeroGVolume.GetComponent<ZeroGVolume>()._attachedBody = OWRB;
|
||||
|
||||
var rulesetVolume = GameObject.Instantiate(GameObject.Find("WhiteHole_Body/Sector_WhiteHole/RulesetVolumes_WhiteHole"), body.transform);
|
||||
rulesetVolume.name = "RulesetVolume";
|
||||
rulesetVolume.transform.localPosition = Vector3.zero;
|
||||
rulesetVolume.transform.localScale = Vector3.one * size / 100f;
|
||||
rulesetVolume.GetComponent<SphereShape>().enabled = true;
|
||||
}
|
||||
|
||||
whiteHole.SetActive(true);
|
||||
return whiteHole;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12,6 +12,8 @@ namespace NewHorizons.Builder.General
|
||||
{
|
||||
public static Tuple<AstroObject, OWRigidbody> Make(GameObject body, AstroObject primaryBody, IPlanetConfig config)
|
||||
{
|
||||
body.AddComponent<ProxyShadowCasterSuperGroup>();
|
||||
|
||||
Rigidbody rigidBody = body.AddComponent<Rigidbody>();
|
||||
rigidBody.mass = 10000;
|
||||
rigidBody.drag = 0f;
|
||||
@ -38,6 +40,7 @@ namespace NewHorizons.Builder.General
|
||||
|
||||
var type = AstroObject.Type.Planet;
|
||||
if (config.Orbit.IsMoon) type = AstroObject.Type.Moon;
|
||||
else if (config.Base.IsSatellite) type = AstroObject.Type.Satellite;
|
||||
else if (config.Base.HasCometTail) type = AstroObject.Type.Comet;
|
||||
else if (config.Star != null) type = AstroObject.Type.Star;
|
||||
else if (config.FocalPoint != null) type = AstroObject.Type.None;
|
||||
|
||||
@ -13,22 +13,26 @@ namespace NewHorizons.Builder.General
|
||||
MapMarker mapMarker = body.AddComponent<MapMarker>();
|
||||
mapMarker.SetValue("_labelID", (UITextType)Utility.AddToUITable.Add(name.ToUpper()));
|
||||
|
||||
var markerType = "Planet";
|
||||
var markerType = MapMarker.MarkerType.Planet;
|
||||
|
||||
if (config.Orbit.IsMoon)
|
||||
{
|
||||
markerType = "Moon";
|
||||
markerType = MapMarker.MarkerType.Moon;
|
||||
}
|
||||
else if (config.Star != null)
|
||||
{
|
||||
markerType = "Sun";
|
||||
markerType = MapMarker.MarkerType.Sun;
|
||||
}
|
||||
else if (config.FocalPoint != null)
|
||||
{
|
||||
markerType = "HourglassTwins";
|
||||
markerType = MapMarker.MarkerType.HourglassTwins;
|
||||
}
|
||||
else if(config.Base.IsSatellite)
|
||||
{
|
||||
markerType = MapMarker.MarkerType.Probe;
|
||||
}
|
||||
|
||||
mapMarker.SetValue("_markerType", mapMarker.GetType().GetNestedType("MarkerType", BindingFlags.NonPublic).GetField(markerType).GetValue(mapMarker));
|
||||
mapMarker._markerType = markerType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
40
NewHorizons/Builder/General/ShipLogBuilder.cs
Normal file
40
NewHorizons/Builder/General/ShipLogBuilder.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NewHorizons.Builder.General
|
||||
{
|
||||
public static class ShipLogBuilder
|
||||
{
|
||||
public static ShipLogDetectiveMode StarChartMode;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
/*
|
||||
var shipLogRoot = GameObject.Find("Ship_Body/Module_Cabin/Systems_Cabin/ShipLogPivot/ShipLog/ShipLogPivot/ShipLogCanvas");
|
||||
var starChartLog = GameObject.Instantiate(shipLogRoot.transform.Find("DetectiveMode"), shipLogRoot.transform);
|
||||
starChartLog.transform.name = "StarChartMode";
|
||||
|
||||
var cardRoot = starChartLog.transform.Find("ScaleRoot").Find("PanRoot");
|
||||
foreach(Transform child in cardRoot)
|
||||
{
|
||||
GameObject.Destroy(child.gameObject);
|
||||
}
|
||||
|
||||
var cardPrefab = GameObject.Find("Ship_Body/Module_Cabin/Systems_Cabin/ShipLogPivot/ShipLog/ShipLogPivot/ShipLogCanvas/DetectiveMode/ScaleRoot/PanRoot/TH_VILLAGE");
|
||||
|
||||
var detectiveMode = GameObject.Find("Ship_Body/Module_Cabin/Systems_Cabin/ShipLogPivot/ShipLog/ShipLogPivot/ShipLogCanvas/DetectiveMode/");
|
||||
var mapMode = GameObject.Find("Ship_Body/Module_Cabin/Systems_Cabin/ShipLogPivot/ShipLog/ShipLogPivot/ShipLogCanvas/MapMode/");
|
||||
|
||||
StarChartMode = starChartLog.GetComponent<ShipLogDetectiveMode>();
|
||||
|
||||
StarChartMode._cardDict = new Dictionary<string, ShipLogEntryCard>();
|
||||
StarChartMode._cardList = new List<ShipLogEntryCard>();
|
||||
StarChartMode._centerPromptList = detectiveMode.GetComponent<ShipLogDetectiveMode>()._centerPromptList;
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -32,13 +32,24 @@ namespace NewHorizons.Builder.Orbital
|
||||
if (config.Orbit.Tint != null) color = config.Orbit.Tint.ToColor32();
|
||||
else if (config.Star != null) color = config.Star.Tint.ToColor32();
|
||||
else if (config.Atmosphere != null && config.Atmosphere.CloudTint != null) color = config.Atmosphere.CloudTint.ToColor32();
|
||||
else if (config.Base.BlackHoleSize != 0) color = new Color(1f, 0.5f, 1f);
|
||||
else if (config.Base.BlackHoleSize != 0 || config.Singularity != null) color = new Color(1f, 0.5f, 1f);
|
||||
else if (config.Base.WaterSize != 0) color = new Color(0.5f, 0.5f, 1f);
|
||||
else if (config.Base.LavaSize != 0) color = new Color(1f, 0.5f, 0.5f);
|
||||
else if (config.Atmosphere != null && config.Atmosphere.FogTint != null) color = config.Atmosphere.FogTint.ToColor32();
|
||||
|
||||
var fade = isMoon;
|
||||
if (config.Base.IsSatellite)
|
||||
{
|
||||
if(config.Orbit.Tint != null) color = new Color(0.4082f, 0.516f, 0.4469f, 1f);
|
||||
fade = true;
|
||||
orbitLine._fadeEndDist = 5000;
|
||||
orbitLine._fadeStartDist = 3000;
|
||||
}
|
||||
|
||||
orbitLine.SetValue("_color", color);
|
||||
|
||||
orbitLine.SetValue("_astroObject", astroobject);
|
||||
orbitLine.SetValue("_fade", isMoon);
|
||||
orbitLine.SetValue("_fade", fade);
|
||||
orbitLine.SetValue("_lineWidth", 2f);
|
||||
|
||||
Main.Instance.ModHelper.Events.Unity.FireOnNextUpdate(() =>
|
||||
|
||||
@ -9,39 +9,60 @@ using Random = UnityEngine.Random;
|
||||
using Logger = NewHorizons.Utility.Logger;
|
||||
using System.Reflection;
|
||||
using NewHorizons.Utility;
|
||||
using OWML.Common;
|
||||
|
||||
namespace NewHorizons.Builder.Props
|
||||
{
|
||||
public static class PropBuilder
|
||||
{
|
||||
public static void Make(GameObject go, Sector sector, IPlanetConfig config)
|
||||
public static void Make(GameObject go, Sector sector, IPlanetConfig config, IModAssets assets, string uniqueModName)
|
||||
{
|
||||
if (config.Props.Scatter != null) PropBuilder.Scatter(go, config.Props.Scatter, config.Base.SurfaceSize, sector);
|
||||
if (config.Props.Scatter != null)
|
||||
{
|
||||
PropBuilder.MakeScatter(go, config.Props.Scatter, config.Base.SurfaceSize, sector, assets, uniqueModName);
|
||||
}
|
||||
if(config.Props.Details != null)
|
||||
{
|
||||
foreach(var detail in config.Props.Details)
|
||||
{
|
||||
MakeDetail(go, sector, detail.path, detail.position, detail.rotation, detail.scale);
|
||||
if(detail.assetBundle != null)
|
||||
{
|
||||
var prefab = LoadPrefab(detail.assetBundle, detail.path, uniqueModName, assets);
|
||||
MakeDetail(go, sector, prefab, detail.position, detail.rotation, detail.scale, detail.alignToNormal);
|
||||
}
|
||||
else if(detail.objFilePath != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var prefab = assets.Get3DObject(detail.objFilePath, detail.mtlFilePath);
|
||||
prefab.SetActive(false);
|
||||
MakeDetail(go, sector, prefab, detail.position, detail.rotation, detail.scale, detail.alignToNormal);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logger.LogError($"Could not load 3d object {detail.objFilePath} with texture {detail.mtlFilePath} : {e.Message}");
|
||||
}
|
||||
}
|
||||
else MakeDetail(go, sector, detail.path, detail.position, detail.rotation, detail.scale, detail.alignToNormal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static GameObject MakeDetail(GameObject go, Sector sector, string propToClone, MVector3 position, MVector3 rotation, float scale)
|
||||
public static GameObject MakeDetail(GameObject go, Sector sector, string propToClone, MVector3 position, MVector3 rotation, float scale, bool alignWithNormal)
|
||||
{
|
||||
var prefab = GameObject.Find(propToClone);
|
||||
return MakeDetail(go, sector, prefab, position, rotation, scale);
|
||||
|
||||
//TODO: this is super costly
|
||||
if (prefab == null) prefab = SearchUtilities.FindObjectOfTypeAndName<GameObject>(propToClone.Split(new char[] { '\\', '/' }).Last());
|
||||
if (prefab == null) Logger.LogError($"Couldn't find detail {propToClone}");
|
||||
return MakeDetail(go, sector, prefab, position, rotation, scale, alignWithNormal);
|
||||
}
|
||||
|
||||
public static GameObject MakeDetail(GameObject go, Sector sector, GameObject prefab, MVector3 position, MVector3 rotation, float scale, bool alignWithNormal = false)
|
||||
public static GameObject MakeDetail(GameObject go, Sector sector, GameObject prefab, MVector3 position, MVector3 rotation, float scale, bool alignWithNormal, bool snapToSurface = false)
|
||||
{
|
||||
if (prefab == null) return null;
|
||||
|
||||
GameObject prop = GameObject.Instantiate(prefab, sector.transform);
|
||||
prop.transform.localPosition = position == null ? prefab.transform.localPosition : (Vector3)position;
|
||||
Quaternion rot = rotation == null ? prefab.transform.localRotation : Quaternion.Euler((Vector3)rotation);
|
||||
if (alignWithNormal) rot = Quaternion.FromToRotation(prop.transform.TransformDirection(Vector3.up), ((Vector3)position).normalized);
|
||||
prop.transform.rotation = rot;
|
||||
prop.transform.localScale = scale != 0 ? Vector3.one * scale : prefab.transform.localScale;
|
||||
prop.SetActive(false);
|
||||
|
||||
List<string> assetBundles = new List<string>();
|
||||
@ -59,45 +80,54 @@ namespace NewHorizons.Builder.Props
|
||||
sector.OnOccupantEnterSector += ((SectorDetector sd) => StreamingManager.LoadStreamingAssets(assetBundle));
|
||||
}
|
||||
|
||||
foreach(var component in prop.GetComponentsInChildren<Component>())
|
||||
foreach (var component in prop.GetComponentsInChildren<Component>())
|
||||
{
|
||||
try
|
||||
{
|
||||
var setSectorMethod = component.GetType().GetMethod("SetSector");
|
||||
var sectorField = component.GetType().GetField("_sector");
|
||||
// TODO: Make this work or smthng
|
||||
if (component is GhostIK) (component as GhostIK).enabled = false;
|
||||
if(component is GhostEffects) (component as GhostEffects).enabled = false;
|
||||
|
||||
|
||||
if (setSectorMethod != null)
|
||||
{
|
||||
Logger.Log($"Found a SetSector method in {prop}.{component}");
|
||||
setSectorMethod.Invoke(component, new object[] { sector });
|
||||
}
|
||||
else if (sectorField != null)
|
||||
{
|
||||
Logger.Log($"Found a _sector field in {component}");
|
||||
sectorField.SetValue(component, sector);
|
||||
}
|
||||
}
|
||||
catch (Exception e) { Logger.Log($"{e.Message}, {e.StackTrace}"); }
|
||||
var enabledField = component.GetType().GetField("enabled");
|
||||
if(enabledField != null && enabledField.FieldType == typeof(bool)) enabledField.SetValue(component, true);
|
||||
}
|
||||
|
||||
prop.transform.parent = go.transform;
|
||||
prop.transform.localPosition = position == null ? Vector3.zero : (Vector3)position;
|
||||
|
||||
Quaternion rot = rotation == null ? prefab.transform.rotation : Quaternion.Euler((Vector3)rotation);
|
||||
prop.transform.rotation = rot;
|
||||
if (alignWithNormal)
|
||||
{
|
||||
var up = prop.transform.localPosition.normalized;
|
||||
var front = Vector3.Cross(up, Vector3.left);
|
||||
if (front.sqrMagnitude == 0f) front = Vector3.Cross(up, Vector3.forward);
|
||||
if (front.sqrMagnitude == 0f) front = Vector3.Cross(up, Vector3.up);
|
||||
|
||||
prop.transform.LookAt(prop.transform.position + front, up);
|
||||
}
|
||||
|
||||
prop.transform.localScale = scale != 0 ? Vector3.one * scale : prefab.transform.localScale;
|
||||
|
||||
prop.SetActive(true);
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
private static void Scatter(GameObject go, PropModule.ScatterInfo[] scatterInfo, float radius, Sector sector)
|
||||
private static void MakeScatter(GameObject go, PropModule.ScatterInfo[] scatterInfo, float radius, Sector sector, IModAssets assets, string uniqueModName)
|
||||
{
|
||||
var area = 4f * Mathf.PI * radius * radius;
|
||||
var points = FibonacciSphere((int)area);
|
||||
|
||||
foreach (var propInfo in scatterInfo)
|
||||
{
|
||||
var prefab = GameObject.Find(propInfo.path);
|
||||
GameObject prefab;
|
||||
if (propInfo.assetBundle != null) prefab = LoadPrefab(propInfo.assetBundle, propInfo.path, uniqueModName, assets);
|
||||
else prefab = GameObject.Find(propInfo.path);
|
||||
for(int i = 0; i < propInfo.count; i++)
|
||||
{
|
||||
var randomInd = (int)Random.Range(0, points.Count);
|
||||
var point = points[randomInd];
|
||||
var prop = MakeDetail(go, sector, prefab, (MVector3)(point.normalized * radius), null, 0f, true);
|
||||
var prop = MakeDetail(go, sector, prefab, (MVector3)(point.normalized * radius), null, propInfo.scale, true, true);
|
||||
if(propInfo.offset != null) prop.transform.localPosition += prop.transform.TransformVector(propInfo.offset);
|
||||
if(propInfo.rotation != null) prop.transform.rotation *= Quaternion.Euler(propInfo.rotation);
|
||||
points.RemoveAt(randomInd);
|
||||
@ -126,5 +156,40 @@ namespace NewHorizons.Builder.Props
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
private static GameObject LoadPrefab(string assetBundle, string path, string uniqueModName, IModAssets assets)
|
||||
{
|
||||
string key = uniqueModName + "." + assetBundle;
|
||||
AssetBundle bundle;
|
||||
GameObject prefab;
|
||||
|
||||
try
|
||||
{
|
||||
if (Main.AssetBundles.ContainsKey(key)) bundle = Main.AssetBundles[key];
|
||||
else
|
||||
{
|
||||
bundle = assets.LoadBundle(assetBundle);
|
||||
Main.AssetBundles[key] = bundle;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError($"Couldn't load AssetBundle {assetBundle} : {e.Message}");
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
prefab = bundle.LoadAsset<GameObject>(path);
|
||||
prefab.SetActive(false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log($"Couldn't load asset {path} from AssetBundle {assetBundle} : {e.Message}");
|
||||
return null;
|
||||
}
|
||||
|
||||
return prefab;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
using NewHorizons.Components;
|
||||
using NewHorizons.External;
|
||||
using NewHorizons.Utility;
|
||||
using OWML.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -83,20 +84,19 @@ namespace NewHorizons.Builder.Props
|
||||
|
||||
public static string GetCustomSignalName(SignalName signalName)
|
||||
{
|
||||
string name = null;
|
||||
_customSignalNames.TryGetValue(signalName, out name);
|
||||
_customSignalNames.TryGetValue(signalName, out string name);
|
||||
return name;
|
||||
}
|
||||
|
||||
public static void Make(GameObject body, Sector sector, SignalModule module)
|
||||
public static void Make(GameObject body, Sector sector, SignalModule module, IModAssets assets)
|
||||
{
|
||||
foreach(var info in module.Signals)
|
||||
{
|
||||
Make(body, sector, info);
|
||||
Make(body, sector, info, assets);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Make(GameObject body, Sector sector, SignalModule.SignalInfo info)
|
||||
public static void Make(GameObject body, Sector sector, SignalModule.SignalInfo info, IModAssets assets)
|
||||
{
|
||||
var signalGO = new GameObject($"Signal_{info.Name}");
|
||||
signalGO.SetActive(false);
|
||||
@ -107,15 +107,32 @@ namespace NewHorizons.Builder.Props
|
||||
var source = signalGO.AddComponent<AudioSource>();
|
||||
var owAudioSource = signalGO.AddComponent<OWAudioSource>();
|
||||
|
||||
AudioSignal audioSignal = null;
|
||||
AudioSignal audioSignal;
|
||||
if (info.InsideCloak) audioSignal = signalGO.AddComponent<CloakedAudioSignal>();
|
||||
else audioSignal = signalGO.AddComponent<AudioSignal>();
|
||||
|
||||
var frequency = StringToFrequency(info.Frequency);
|
||||
var name = StringToSignalName(info.Name);
|
||||
|
||||
AudioClip clip = SearchUtilities.FindResourceOfTypeAndName<AudioClip>(info.AudioClip);
|
||||
if (clip == null) return;
|
||||
AudioClip clip = null;
|
||||
if(info.AudioClip != null) clip = SearchUtilities.FindResourceOfTypeAndName<AudioClip>(info.AudioClip);
|
||||
else if (info.AudioFilePath != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
clip = assets.GetAudio(info.AudioFilePath);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logger.LogError($"Couldn't load audio file {info.AudioFilePath} : {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
if (clip == null)
|
||||
{
|
||||
Logger.LogError($"Couldn't find AudioClip {info.AudioClip} or AudioFile {info.AudioFilePath}");
|
||||
return;
|
||||
}
|
||||
|
||||
audioSignal.SetSector(sector);
|
||||
audioSignal._frequency = frequency;
|
||||
|
||||
28
NewHorizons/Components/BlackHoleDestructionVolume.cs
Normal file
28
NewHorizons/Components/BlackHoleDestructionVolume.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Logger = NewHorizons.Utility.Logger;
|
||||
|
||||
namespace NewHorizons.Components
|
||||
{
|
||||
public class BlackHoleDestructionVolume : DestructionVolume
|
||||
{
|
||||
public override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
_deathType = DeathType.BlackHole;
|
||||
}
|
||||
|
||||
public override void VanishProbe(OWRigidbody probeBody, RelativeLocationData entryLocation)
|
||||
{
|
||||
SurveyorProbe requiredComponent = probeBody.GetRequiredComponent<SurveyorProbe>();
|
||||
if (requiredComponent.IsLaunched())
|
||||
{
|
||||
UnityEngine.Object.Destroy(requiredComponent.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
18
NewHorizons/Components/ChangeStarSystemVolume.cs
Normal file
18
NewHorizons/Components/ChangeStarSystemVolume.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NewHorizons.Components
|
||||
{
|
||||
public class ChangeStarSystemVolume : BlackHoleDestructionVolume
|
||||
{
|
||||
public string TargetSolarSystem { get; set; }
|
||||
|
||||
public override void VanishPlayer(OWRigidbody playerBody, RelativeLocationData entryLocation)
|
||||
{
|
||||
Main.Instance.ChangeCurrentStarSystem(TargetSolarSystem);
|
||||
}
|
||||
}
|
||||
}
|
||||
1
NewHorizons/External/AsteroidBeltModule.cs
vendored
1
NewHorizons/External/AsteroidBeltModule.cs
vendored
@ -13,5 +13,6 @@ namespace NewHorizons.External
|
||||
public float Inclination { get; set; }
|
||||
public float LongitudeOfAscendingNode { get; set; }
|
||||
public int RandomSeed { get; set; }
|
||||
public ProcGenModule ProcGen { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
5
NewHorizons/External/BaseModule.cs
vendored
5
NewHorizons/External/BaseModule.cs
vendored
@ -16,10 +16,13 @@ namespace NewHorizons.External
|
||||
public float SurfaceSize { get; set; }
|
||||
public float WaterSize { get; set; }
|
||||
public float GroundSize { get; set; }
|
||||
public float BlackHoleSize { get; set; }
|
||||
public float LavaSize { get; set; }
|
||||
public bool HasCometTail { get; set; }
|
||||
public bool HasReferenceFrame { get; set; } = true;
|
||||
public bool CenterOfSolarSystem { get; set; } = false;
|
||||
public bool IsSatellite { get; set; }
|
||||
|
||||
// Old, see SingularityModule instead
|
||||
public float BlackHoleSize { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
2
NewHorizons/External/IPlanetConfig.cs
vendored
2
NewHorizons/External/IPlanetConfig.cs
vendored
@ -5,6 +5,7 @@ namespace NewHorizons.External
|
||||
public interface IPlanetConfig
|
||||
{
|
||||
string Name { get; }
|
||||
string StarSystem { get; }
|
||||
bool Destroy { get; }
|
||||
int BuildPriority { get; }
|
||||
BaseModule Base {get;}
|
||||
@ -19,5 +20,6 @@ namespace NewHorizons.External
|
||||
PropModule Props { get; }
|
||||
SpawnModule Spawn { get; }
|
||||
SignalModule Signal { get; }
|
||||
SingularityModule Singularity { get; }
|
||||
}
|
||||
}
|
||||
|
||||
2
NewHorizons/External/PlanetConfig.cs
vendored
2
NewHorizons/External/PlanetConfig.cs
vendored
@ -8,6 +8,7 @@ namespace NewHorizons.External
|
||||
public class PlanetConfig : IPlanetConfig
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string StarSystem { get; set; } = "SolarSystem";
|
||||
public bool Destroy { get; set; }
|
||||
public int BuildPriority { get; set; } = -1;
|
||||
public MVector3 SpawnPoint { get; set; }
|
||||
@ -23,6 +24,7 @@ namespace NewHorizons.External
|
||||
public PropModule Props { get; set; }
|
||||
public SpawnModule Spawn { get; set; }
|
||||
public SignalModule Signal { get; set; }
|
||||
public SingularityModule Singularity { get; set; }
|
||||
|
||||
public PlanetConfig(Dictionary<string, object> dict)
|
||||
{
|
||||
|
||||
10
NewHorizons/External/PropModule.cs
vendored
10
NewHorizons/External/PropModule.cs
vendored
@ -15,18 +15,24 @@ namespace NewHorizons.External
|
||||
|
||||
public class ScatterInfo
|
||||
{
|
||||
public string path;
|
||||
public int count;
|
||||
public string path;
|
||||
public string assetBundle;
|
||||
public MVector3 offset;
|
||||
public MVector3 rotation;
|
||||
public float scale { get; set; } = 1f;
|
||||
}
|
||||
|
||||
public class DetailInfo
|
||||
{
|
||||
public string path;
|
||||
public string objFilePath;
|
||||
public string mtlFilePath;
|
||||
public string assetBundle;
|
||||
public MVector3 position;
|
||||
public MVector3 rotation;
|
||||
public float scale;
|
||||
public float scale { get; set; } = 1f;
|
||||
public bool alignToNormal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1
NewHorizons/External/RingModule.cs
vendored
1
NewHorizons/External/RingModule.cs
vendored
@ -13,5 +13,6 @@ namespace NewHorizons.External
|
||||
public float Inclination { get; set; }
|
||||
public float LongitudeOfAscendingNode { get; set; }
|
||||
public string Texture { get; set; }
|
||||
public bool Unlit { get; set; } = true;
|
||||
}
|
||||
}
|
||||
|
||||
3
NewHorizons/External/SignalModule.cs
vendored
3
NewHorizons/External/SignalModule.cs
vendored
@ -16,7 +16,8 @@ namespace NewHorizons.External
|
||||
public MVector3 Position;
|
||||
public string Frequency;
|
||||
public string Name;
|
||||
public string AudioClip;
|
||||
public string AudioClip = null;
|
||||
public string AudioFilePath = null;
|
||||
public float SourceRadius = 1f;
|
||||
public float DetectionRadius = 0f;
|
||||
public float IdentificationRadius = 10f;
|
||||
|
||||
18
NewHorizons/External/SingularityModule.cs
vendored
Normal file
18
NewHorizons/External/SingularityModule.cs
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
using NewHorizons.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NewHorizons.External
|
||||
{
|
||||
public class SingularityModule : Module
|
||||
{
|
||||
public float Size;
|
||||
public string PairedSingularity;
|
||||
public string TargetStarSystem;
|
||||
public string Type; //BlackHole or WhiteHole
|
||||
public MVector3 Position;
|
||||
}
|
||||
}
|
||||
@ -17,6 +17,7 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UI;
|
||||
using Logger = NewHorizons.Utility.Logger;
|
||||
|
||||
namespace NewHorizons
|
||||
@ -29,11 +30,12 @@ namespace NewHorizons
|
||||
|
||||
public static List<NewHorizonsBody> BodyList = new List<NewHorizonsBody>();
|
||||
public static List<NewHorizonsBody> NextPassBodies = new List<NewHorizonsBody>();
|
||||
|
||||
public static Dictionary<string, AssetBundle> AssetBundles = new Dictionary<string, AssetBundle>();
|
||||
public static float FurthestOrbit { get; set; } = 50000f;
|
||||
|
||||
public StarLightController StarLightController { get; private set; }
|
||||
|
||||
private static string _currentStarSystem = "SolarSystem";
|
||||
|
||||
public override object GetApi()
|
||||
{
|
||||
return new NewHorizonsApi();
|
||||
@ -57,6 +59,9 @@ namespace NewHorizons
|
||||
{
|
||||
Logger.LogWarning("Couldn't find planets folder");
|
||||
}
|
||||
|
||||
//UnityEngine.Random.InitState();
|
||||
Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => OnSceneLoaded(SceneManager.GetActiveScene(), LoadSceneMode.Single));
|
||||
}
|
||||
|
||||
public void OnDestroy()
|
||||
@ -71,10 +76,14 @@ namespace NewHorizons
|
||||
|
||||
HeavenlyBodyBuilder.Reset();
|
||||
|
||||
if (scene.name != "SolarSystem") { return; }
|
||||
if (scene.name.Equals("TitleScreen")) DisplayBodyOnTitleScreen();
|
||||
|
||||
if (scene.name != "SolarSystem") return;
|
||||
|
||||
NewHorizonsData.Load();
|
||||
|
||||
Instance.ModHelper.Events.Unity.FireOnNextUpdate(() => ShipLogBuilder.Init());
|
||||
|
||||
// Need to manage this when there are multiple stars
|
||||
var sun = GameObject.Find("Sun_Body");
|
||||
var starController = sun.AddComponent<StarController>();
|
||||
@ -99,7 +108,7 @@ namespace NewHorizons
|
||||
|
||||
StarLightController = starLightGO.AddComponent<StarLightController>();
|
||||
StarLightController.AddStar(starController);
|
||||
|
||||
|
||||
starLightGO.SetActive(true);
|
||||
|
||||
// TODO: Make this configurable probably
|
||||
@ -115,8 +124,10 @@ namespace NewHorizons
|
||||
AstroObjectLocator.AddAstroObject(ao);
|
||||
}
|
||||
|
||||
// Stars then planets then moons (not necessary but probably speeds things up, maybe)
|
||||
var toLoad = BodyList.OrderBy(b =>
|
||||
// Order by stars then planets then moons (not necessary but probably speeds things up, maybe) ALSO only include current star system
|
||||
var toLoad = BodyList
|
||||
.Where(b => b.Config.StarSystem.Equals(_currentStarSystem))
|
||||
.OrderBy(b =>
|
||||
(b.Config.BuildPriority != -1 ? b.Config.BuildPriority :
|
||||
(b.Config.FocalPoint != null ? 0 :
|
||||
(b.Config.Star != null) ? 0 :
|
||||
@ -174,6 +185,65 @@ namespace NewHorizons
|
||||
*/
|
||||
}
|
||||
|
||||
public void DisplayBodyOnTitleScreen()
|
||||
{
|
||||
//Try loading one planet why not
|
||||
GameObject titleScreenGO = new GameObject("TitleScreenPlanet");
|
||||
var eligible = BodyList.Where(b => b.Config.Ring != null && (b.Config.HeightMap != null || (b.Config.Atmosphere?.Cloud != null))).ToArray();
|
||||
var body = eligible[UnityEngine.Random.Range(0, eligible.Count())];
|
||||
|
||||
Logger.Log($"Displaying {body.Config.Name} on the title screen");
|
||||
|
||||
var flag = false;
|
||||
HeightMapModule heightMap = new HeightMapModule();
|
||||
var minSize = 20;
|
||||
var maxSize = 35;
|
||||
float size = minSize;
|
||||
if (body.Config.HeightMap != null)
|
||||
{
|
||||
size = Mathf.Clamp(body.Config.HeightMap.MaxHeight / 10, minSize, maxSize);
|
||||
heightMap.TextureMap = body.Config.HeightMap.TextureMap;
|
||||
heightMap.HeightMap = body.Config.HeightMap.HeightMap;
|
||||
heightMap.MaxHeight = size;
|
||||
heightMap.MinHeight = body.Config.HeightMap.MinHeight * size / body.Config.HeightMap.MaxHeight;
|
||||
flag = true;
|
||||
}
|
||||
if (body.Config.Atmosphere != null && body.Config.Atmosphere.Cloud != null)
|
||||
{
|
||||
// Hacky but whatever I just want a sphere
|
||||
size = Mathf.Clamp(body.Config.Atmosphere.Size / 10, minSize, maxSize);
|
||||
heightMap.MaxHeight = heightMap.MinHeight = size+1;
|
||||
heightMap.TextureMap = body.Config.Atmosphere.Cloud;
|
||||
flag = true;
|
||||
}
|
||||
|
||||
if (flag)
|
||||
{
|
||||
HeightMapBuilder.Make(titleScreenGO, heightMap, body.Assets);
|
||||
if (body.Config.Ring != null)
|
||||
{
|
||||
RingModule newRing = new RingModule();
|
||||
newRing.InnerRadius = size * 1.2f;
|
||||
newRing.OuterRadius = size * 2f;
|
||||
newRing.Texture = body.Config.Ring.Texture;
|
||||
RingBuilder.Make(titleScreenGO, newRing, body.Assets);
|
||||
titleScreenGO.transform.localScale = Vector3.one * 0.8f;
|
||||
}
|
||||
GameObject.Find("Scene/Background/PlanetPivot/Prefab_HEA_Campfire").SetActive(false);
|
||||
GameObject.Find("Scene/Background/PlanetPivot/PlanetRoot").SetActive(false);
|
||||
titleScreenGO.transform.parent = GameObject.Find("Scene/Background/PlanetPivot/").transform;
|
||||
titleScreenGO.transform.localPosition = Vector3.zero;
|
||||
|
||||
var lightGO = new GameObject("Light");
|
||||
lightGO.transform.parent = titleScreenGO.transform.parent.parent;
|
||||
lightGO.transform.localPosition = new Vector3(-47.9203f, 145.7596f, 43.1802f);
|
||||
var light = lightGO.AddComponent<Light>();
|
||||
light.color = new Color(1f, 1f, 1f, 1f);
|
||||
light.range = 100;
|
||||
light.intensity = 0.8f;
|
||||
}
|
||||
}
|
||||
|
||||
private bool LoadBody(NewHorizonsBody body, bool defaultPrimaryToSun = false)
|
||||
{
|
||||
var stringID = body.Config.Name.ToUpper().Replace(" ", "_").Replace("'", "");
|
||||
@ -238,7 +308,7 @@ namespace NewHorizons
|
||||
{
|
||||
var config = mod.ModHelper.Storage.Load<PlanetConfig>(file.Replace(folder, ""));
|
||||
Logger.Log($"Loaded {config.Name}");
|
||||
BodyList.Add(new NewHorizonsBody(config, mod.ModHelper.Assets));
|
||||
BodyList.Add(new NewHorizonsBody(config, mod.ModHelper.Assets, mod.ModHelper.Manifest.UniqueName));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -291,7 +361,7 @@ namespace NewHorizons
|
||||
if (body.Config.Base.GroundSize != 0) GeometryBuilder.Make(go, body.Config.Base.GroundSize);
|
||||
|
||||
var atmoSize = body.Config.Atmosphere != null ? body.Config.Atmosphere.Size : 0f;
|
||||
float sphereOfInfluence = Mathf.Max(atmoSize, body.Config.Base.SurfaceSize * 2f);
|
||||
float sphereOfInfluence = Mathf.Max(Mathf.Max(atmoSize, 50), body.Config.Base.SurfaceSize * 2f);
|
||||
|
||||
var outputTuple = BaseBuilder.Make(go, primaryBody, body.Config);
|
||||
var ao = (AstroObject)outputTuple.Item1;
|
||||
@ -321,9 +391,6 @@ namespace NewHorizons
|
||||
if (body.Config.ProcGen != null)
|
||||
ProcGenBuilder.Make(go, body.Config.ProcGen);
|
||||
|
||||
if (body.Config.Base.BlackHoleSize != 0)
|
||||
BlackHoleBuilder.Make(go, body.Config.Base, sector);
|
||||
|
||||
if (body.Config.Star != null) StarLightController.AddStar(StarBuilder.Make(go, sector, body.Config.Star));
|
||||
|
||||
if (body.Config.FocalPoint != null)
|
||||
@ -369,7 +436,7 @@ namespace NewHorizons
|
||||
RingBuilder.Make(go, body.Config.Ring, body.Assets);
|
||||
|
||||
if (body.Config.AsteroidBelt != null)
|
||||
AsteroidBeltBuilder.Make(body.Config.Name, body.Config.AsteroidBelt, body.Assets);
|
||||
AsteroidBeltBuilder.Make(body.Config.Name, body.Config, body.Assets, body.ModUniqueName);
|
||||
|
||||
if (body.Config.Base.HasCometTail)
|
||||
CometTailBuilder.Make(go, body.Config.Base, go.GetComponent<AstroObject>().GetPrimaryBody());
|
||||
@ -399,13 +466,22 @@ namespace NewHorizons
|
||||
}
|
||||
|
||||
if (body.Config.Props != null)
|
||||
PropBuilder.Make(go, sector, body.Config);
|
||||
PropBuilder.Make(go, sector, body.Config, body.Assets, body.ModUniqueName);
|
||||
|
||||
if (body.Config.Signal != null)
|
||||
SignalBuilder.Make(go, sector, body.Config.Signal);
|
||||
SignalBuilder.Make(go, sector, body.Config.Signal, body.Assets);
|
||||
|
||||
if (body.Config.Base.BlackHoleSize != 0 || body.Config.Singularity != null)
|
||||
SingularityBuilder.Make(go, sector, rb, body.Config);
|
||||
|
||||
return go;
|
||||
}
|
||||
|
||||
public void ChangeCurrentStarSystem(string newStarSystem)
|
||||
{
|
||||
_currentStarSystem = newStarSystem;
|
||||
LoadManager.LoadSceneAsync(OWScene.SolarSystem, true, LoadManager.FadeType.ToBlack, 0.1f, true);
|
||||
}
|
||||
}
|
||||
|
||||
public class NewHorizonsApi
|
||||
@ -421,7 +497,7 @@ namespace NewHorizons
|
||||
Logger.Log("Recieved API request to create planet " + (string)config["Name"], Logger.LogType.Log);
|
||||
var planetConfig = new PlanetConfig(config);
|
||||
|
||||
var body = new NewHorizonsBody(planetConfig, mod != null ? mod.ModHelper.Assets : Main.Instance.ModHelper.Assets);
|
||||
var body = new NewHorizonsBody(planetConfig, mod != null ? mod.ModHelper.Assets : Main.Instance.ModHelper.Assets, mod.ModHelper.Manifest.UniqueName);
|
||||
|
||||
Main.BodyList.Add(body);
|
||||
}
|
||||
|
||||
@ -25,6 +25,9 @@
|
||||
</None>
|
||||
<None Include="manifest.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="AssetBundle\**">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using NewHorizons.Builder.Body;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -13,6 +14,9 @@ namespace NewHorizons.Utility
|
||||
{
|
||||
private OWRigidbody _rb;
|
||||
|
||||
private GameObject blackHole;
|
||||
private GameObject whiteHole;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_rb = this.GetRequiredComponent<OWRigidbody>();
|
||||
@ -34,6 +38,48 @@ namespace NewHorizons.Utility
|
||||
}
|
||||
_rb.EnableCollisionDetection();
|
||||
}
|
||||
|
||||
/*
|
||||
// Portal Gun:
|
||||
if (Keyboard.current == null) return;
|
||||
var fireBlackHole = Keyboard.current[Key.B].wasReleasedThisFrame;
|
||||
var fireWhiteHole = Keyboard.current[Key.N].wasReleasedThisFrame;
|
||||
if (fireBlackHole || fireWhiteHole)
|
||||
{
|
||||
// Raycast
|
||||
_rb.DisableCollisionDetection();
|
||||
int layerMask = OWLayerMask.physicalMask;
|
||||
var origin = Locator.GetActiveCamera().transform.position;
|
||||
var direction = Locator.GetActiveCamera().transform.TransformDirection(Vector3.forward);
|
||||
if (Physics.Raycast(origin, direction, out RaycastHit hitInfo, Mathf.Infinity, OWLayerMask.physicalMask))
|
||||
{
|
||||
var pos = hitInfo.transform.InverseTransformPoint(hitInfo.point + hitInfo.normal);
|
||||
var hitBody = hitInfo.transform.gameObject;
|
||||
var sector = hitBody.GetComponent<AstroObject>()?.GetRootSector();
|
||||
|
||||
if (hitBody == null || sector == null) return;
|
||||
Logger.Log($"{hitBody}");
|
||||
if (fireBlackHole)
|
||||
{
|
||||
if (blackHole != null) GameObject.Destroy(blackHole);
|
||||
blackHole = SingularityBuilder.MakeBlackHole(hitBody, sector, pos, 2, false, null, false);
|
||||
Logger.Log("Make black hole");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (whiteHole != null) GameObject.Destroy(whiteHole);
|
||||
whiteHole = SingularityBuilder.MakeWhiteHole(hitBody, sector, hitBody.GetAttachedOWRigidbody(), pos, 2, false);
|
||||
Logger.Log("Make white hole");
|
||||
}
|
||||
|
||||
if(blackHole && whiteHole)
|
||||
{
|
||||
SingularityBuilder.PairSingularities(blackHole, whiteHole);
|
||||
}
|
||||
}
|
||||
_rb.EnableCollisionDetection();
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,14 +6,16 @@ namespace NewHorizons.Utility
|
||||
{
|
||||
public class NewHorizonsBody
|
||||
{
|
||||
public NewHorizonsBody(IPlanetConfig config, IModAssets assets)
|
||||
public NewHorizonsBody(IPlanetConfig config, IModAssets assets, string modUniqueName)
|
||||
{
|
||||
Config = config;
|
||||
Assets = assets;
|
||||
ModUniqueName = modUniqueName;
|
||||
}
|
||||
|
||||
public IPlanetConfig Config;
|
||||
public IModAssets Assets;
|
||||
public string ModUniqueName;
|
||||
|
||||
public GameObject Object;
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using NewHorizons.Builder.Props;
|
||||
using NewHorizons.Builder.General;
|
||||
using NewHorizons.Builder.Props;
|
||||
using NewHorizons.Components;
|
||||
using NewHorizons.External;
|
||||
using OWML.Common;
|
||||
@ -43,6 +44,12 @@ namespace NewHorizons.Utility
|
||||
var playerDataResetGame = typeof(PlayerData).GetMethod("ResetGame");
|
||||
Main.Instance.ModHelper.HarmonyHelper.AddPostfix(playerDataResetGame, typeof(Patches), nameof(Patches.OnPlayerDataResetGame));
|
||||
|
||||
Main.Instance.ModHelper.HarmonyHelper.AddPrefix<BlackHoleVolume>("Start", typeof(Patches), nameof(Patches.OnBlackHoleVolumeStart));
|
||||
Main.Instance.ModHelper.HarmonyHelper.AddPrefix<WhiteHoleVolume>("Awake", typeof(Patches), nameof(Patches.OnWhiteHoleVolumeAwake));
|
||||
Main.Instance.ModHelper.HarmonyHelper.AddPrefix<ProbeLauncher>("UpdateOrbitalLaunchValues", typeof(Patches), nameof(Patches.OnProbeLauncherUpdateOrbitalLaunchValues));
|
||||
|
||||
Main.Instance.ModHelper.HarmonyHelper.AddPrefix<ShipLogController>("Update", typeof(Patches), nameof(Patches.OnShipLogControllerUpdate));
|
||||
|
||||
// Postfixes
|
||||
Main.Instance.ModHelper.HarmonyHelper.AddPostfix<MapController>("Awake", typeof(Patches), nameof(Patches.OnMapControllerAwake));
|
||||
Main.Instance.ModHelper.HarmonyHelper.AddPostfix<OWCamera>("Awake", typeof(Patches), nameof(Patches.OnOWCameraAwake));
|
||||
@ -306,5 +313,61 @@ namespace NewHorizons.Utility
|
||||
NewHorizonsData.Reset();
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static bool OnBlackHoleVolumeStart(BlackHoleVolume __instance)
|
||||
{
|
||||
return __instance._whiteHole == null;
|
||||
}
|
||||
|
||||
public static bool OnWhiteHoleVolumeAwake(WhiteHoleVolume __instance)
|
||||
{
|
||||
__instance._growQueue = new List<OWRigidbody>(8);
|
||||
__instance._growQueueLocationData = new List<RelativeLocationData>(8);
|
||||
__instance._ejectedBodyList = new List<OWRigidbody>(64);
|
||||
try
|
||||
{
|
||||
__instance._whiteHoleBody = __instance.gameObject.GetAttachedOWRigidbody(false);
|
||||
__instance._whiteHoleProxyShadowSuperGroup = __instance._whiteHoleBody.GetComponentInChildren<ProxyShadowCasterSuperGroup>();
|
||||
__instance._fluidVolume = __instance.gameObject.GetRequiredComponent<WhiteHoleFluidVolume>();
|
||||
}
|
||||
catch (Exception) { }
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool OnProbeLauncherUpdateOrbitalLaunchValues(ProbeLauncher __instance)
|
||||
{
|
||||
return (Locator.GetPlayerRulesetDetector()?.GetPlanetoidRuleset()?.GetGravityVolume() != null);
|
||||
}
|
||||
|
||||
public static bool OnShipLogControllerUpdate(ShipLogController __instance)
|
||||
{
|
||||
if (__instance._exiting
|
||||
|| OWInput.GetInputMode() != InputMode.ShipComputer
|
||||
|| __instance._currentMode.AllowCancelInput() && OWInput.IsNewlyPressed(InputLibrary.cancel, InputMode.All)
|
||||
|| ShipLogBuilder.StarChartMode == null)
|
||||
return true;
|
||||
|
||||
__instance._exitPrompt.SetVisibility(__instance._currentMode.AllowCancelInput());
|
||||
__instance._currentMode.UpdateMode();
|
||||
if (__instance._currentMode.AllowModeSwap() && OWInput.IsNewlyPressed(InputLibrary.swapShipLogMode, InputMode.All))
|
||||
{
|
||||
ShipLogMode currentMode = __instance._currentMode;
|
||||
string focusedEntryID = currentMode.GetFocusedEntryID();
|
||||
bool flag = currentMode.Equals(__instance._mapMode);
|
||||
__instance._currentMode = (flag ? __instance._detectiveMode : __instance._mapMode);
|
||||
|
||||
if (currentMode.Equals(__instance._mapMode))
|
||||
__instance._currentMode = ShipLogBuilder.StarChartMode;
|
||||
else if (currentMode.Equals(ShipLogBuilder.StarChartMode))
|
||||
__instance._currentMode = __instance._detectiveMode;
|
||||
else
|
||||
__instance._currentMode = __instance._mapMode;
|
||||
|
||||
currentMode.ExitMode();
|
||||
__instance._currentMode.EnterMode(focusedEntryID, null);
|
||||
__instance._oneShotSource.PlayOneShot(flag ? global::AudioType.ShipLogEnterDetectiveMode : global::AudioType.ShipLogEnterMapMode, 1f);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ namespace NewHorizons.Utility
|
||||
{
|
||||
public static class SearchUtilities
|
||||
{
|
||||
public static List<T> FindObjectsOfTypeAndName<T>(string name) where T : MonoBehaviour
|
||||
public static List<T> FindObjectsOfTypeAndName<T>(string name) where T : Object
|
||||
{
|
||||
T[] firstList = GameObject.FindObjectsOfType<T>();
|
||||
List<T> finalList = new List<T>();
|
||||
@ -26,6 +26,22 @@ namespace NewHorizons.Utility
|
||||
return finalList;
|
||||
}
|
||||
|
||||
public static T FindObjectOfTypeAndName<T>(string name) where T : Object
|
||||
{
|
||||
T[] firstList = GameObject.FindObjectsOfType<T>();
|
||||
List<T> finalList = new List<T>();
|
||||
|
||||
for (var i = 0; i < firstList.Length; i++)
|
||||
{
|
||||
if (firstList[i].name == name)
|
||||
{
|
||||
return firstList[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<T> FindResourcesOfTypeAndName<T>(string name) where T : Object
|
||||
{
|
||||
T[] firstList = Resources.FindObjectsOfTypeAll<T>();
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
"author": "xen",
|
||||
"name": "New Horizons",
|
||||
"uniqueName": "xen.NewHorizons",
|
||||
"version": "0.3.1",
|
||||
"version": "0.4.0",
|
||||
"owmlVersion": "2.1.0",
|
||||
"dependencies": [ "PacificEngine.OW_CommonResources" ]
|
||||
}
|
||||
|
||||
120
README.md
120
README.md
@ -1,8 +1,15 @@
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
A planet creator for Outer Wilds.
|
||||
|
||||
Planets are created using a JSON file format structure, and placed in the `planets` folder.
|
||||
You can view the addons creators have made [here](https://outerwildsmods.com/mods/newhorizons/addons/)!
|
||||
|
||||
Planets are created using a JSON file format structure, and placed in the `planets` folder (or in any sub-directory of it).
|
||||
|
||||
NOTE: Any mod that requires PacificEngine's CommonResources is not compatible with New Horizons currently. Both mods mess with planets and orbits and end up clashing. We're currently working on a solution.
|
||||
|
||||
<!-- TOC -->
|
||||
|
||||
@ -15,9 +22,14 @@ Planets are created using a JSON file format structure, and placed in the `plane
|
||||
- [AsteroidBelt](#asteroidbelt)
|
||||
- [FocalPoint](#focalpoint)
|
||||
- [Props](#props)
|
||||
- [Asset Bundles](#asset-bundles)
|
||||
- [Ring](#ring)
|
||||
- [Spawn](#spawn)
|
||||
- [Star](#star)
|
||||
- [Signal](#signal)
|
||||
- [Singularity](#singularity)
|
||||
- [How to destroy existing planets](#how-to-destroy-existing-planets)
|
||||
- [How to update existing planets](#how-to-update-existing-planets)
|
||||
- [How to use New Horizons in other mods](#how-to-use-new-horizons-in-other-mods)
|
||||
- [Credits](#credits)
|
||||
|
||||
@ -31,14 +43,14 @@ Planets are created using a JSON file format structure, and placed in the `plane
|
||||
- Comets (Done)
|
||||
- Signalscope signals (Done)
|
||||
- Asteroid belts (Done)
|
||||
- Support satellites (Done)
|
||||
- Surface scatter: rocks, trees, etc, using in-game models (done) or custom ones (done)
|
||||
- Load planet meshes from asset bundle (technically done)
|
||||
- Black hole / white hole pairs (done)
|
||||
- Procedurally terrain generation (started)
|
||||
- Support satellites (using custom models in the assets folder or in-game ones)
|
||||
- Surface scatter: rocks, trees, etc, using in-game models (done) or custom ones
|
||||
- Load planet meshes from asset bundle
|
||||
- "Quantum" planet parameters
|
||||
- Better terrain and water LOD
|
||||
- Edit existing planet orbits
|
||||
- Black hole / white hole pairs
|
||||
- Separate solar system scenes accessible via wormhole
|
||||
- Implement all planet features:
|
||||
- Tornados
|
||||
@ -177,7 +189,7 @@ Some of these I don't explain since they are just orbital parameters. If you don
|
||||
- "longitudeOfAscendingNode" : (decimal number)
|
||||
- "argumentOfPeriapsis" : (decimal number)
|
||||
- "eccentricity" : (decimal number from 0 to < 1) The closer to 1 it is, the more oval-shaped the orbit is.
|
||||
- "trueAnomaly" : (decimal number) Where the planet should start off in its orbit in terms of the central angle. From 0 to 360.
|
||||
- "trueAnomaly" : (decimal number) Where the planet should start off in its orbit in terms of the central angle. From 0 to 360. NOTE: This is currently broken for eccentric orbits which (for now) always start at periapsis. If you want to move the starting point, set argument of periapsis instead.
|
||||
- "axialTilt" : (decimal number)
|
||||
- "siderealPeriod" : (decimal number)
|
||||
- "isTidallyLocked" : (true/false)
|
||||
@ -282,9 +294,9 @@ and
|
||||
The positions of the binaries will be based off of their masses (as determined by the "surfaceGravity" parameter). However, one of them must have a non-zero semiMajorAxis field else the mod gets confused. This example uses stars, but it will also work for planets. If you want to have other planets orbiting the center of mass, just put the focal point body as the primary body.
|
||||
|
||||
### Props
|
||||
Lets you place items on the surface of the planet. Currently this is a very early release version.
|
||||
Lets you place items on the surface of the planet.
|
||||
|
||||
-scatter : (list) I'll just give an example.
|
||||
- "scatter" : (list) I'll just give an example.
|
||||
|
||||
```
|
||||
"scatter" : [
|
||||
@ -294,6 +306,49 @@ Lets you place items on the surface of the planet. Currently this is a very earl
|
||||
|
||||
The path is in the hierarchy of the solar system. Use the [Unity Explorer](https://outerwildsmods.com/mods/unityexplorer) mod to find an object you want to copy onto your new body. Some objects work better than others for this. Good luck.
|
||||
|
||||
- "details" : (list of detail info objects)
|
||||
|
||||
A detail info object can have the following parameters:
|
||||
- "path" : (string) either the location of it in the scene hierarchy or in the asset bundle provided
|
||||
- "assetBundle" : (string) the asset bundle containing the object
|
||||
- "objFilePath" : (string) the file path to a .obj 3d model
|
||||
- "mtlFilePath" : (string) the file path to the material for the .obj model
|
||||
- "position" : (x, y, z)
|
||||
- "rotation" : (x, y, z) the euler angle rotation from a 3d vector
|
||||
- "scale" : (decimal number)
|
||||
- "alignToNormal" : (true/false) If it should align with the normal vector of the surface its own (overwrites rotation)
|
||||
|
||||
You have three options: Load from the scene hierarchy by setting "path", load from an asset bundle by setting "path" and "assetBundle", or load an obj file by setting "objFilePath" and "mtlFilePath". Asset bundles give much better results than .obj's.
|
||||
|
||||
#### Asset Bundles
|
||||
1. Start up a Unity 2017 project (I use Unity 2017.4.40f1 (64-bit), so if you use something else I can't guarantee it will work).
|
||||
2. In the root directory create a folder called "Editor". In it create a file called "CreateAssetBundle.cs" with the following code in it:
|
||||
```
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
|
||||
public class CreateAssetBundles
|
||||
{
|
||||
[MenuItem("Assets/Build AssetBundles")]
|
||||
static void BuildAllAssetBundles()
|
||||
{
|
||||
string assetBundleDirectory = "Assets/StreamingAssets";
|
||||
if (!Directory.Exists(Application.streamingAssetsPath))
|
||||
{
|
||||
Directory.CreateDirectory(assetBundleDirectory);
|
||||
}
|
||||
BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
|
||||
}
|
||||
}
|
||||
```
|
||||
3. Create your object in the Unity scene and save it as a prefab.
|
||||
4. Add all files used (models, prefabs, textures, materials, etc) to an asset bundle by selecting them and using the drop down in the bottom right. Here I am adding a rover model to my "rss" asset bundle for the Real Solar System add-on.
|
||||

|
||||
|
||||
5. In the top left click the "Assets" drop-down and select "Build AssetBundles". This should create your asset bundle in a folder in the root directory called "StreamingAssets".
|
||||
6. Copy the asset bundle and asset bundle .manifest files from StreamingAssets into your mod's "planets" folder. If you did everything properly they should work in game. To double check everything is included, open the .manifest file in a text editor to see the files included and their paths.
|
||||
|
||||
### Ring
|
||||
- "innerRadius" : (decimal number)
|
||||
- "outerRadius" : (decimal number)
|
||||
@ -312,6 +367,47 @@ Use this if you are creating a star.
|
||||
- "tint" : (colour)
|
||||
- "solarFlareTint" : (colour) The flares are tinted weirdly so this won't make the actual colour of the star. You'll want to use trial and error to find something that matches.
|
||||
|
||||
### Signal
|
||||
- "signals" : (list of signal info objects)
|
||||
|
||||
Signal info objects can then have the following values set:
|
||||
- "position" : (position) To find a good value for this, fly to the planet, look directly at where you want the signal to come from, and press "P" to have the game log the position you're looking at.
|
||||
- "frequency" : (string) There are 7 acceptible values for this:
|
||||
- "Default" : appears in game as ???
|
||||
- "Traveler" : appears in game as "Outer Wilds Ventures"
|
||||
- "Quantum" : appears in game as "Quantum Fluctuations"
|
||||
- "EscapePod" : appears in game as "Distress Signal"
|
||||
- "Statue" : appears in game as "Nomai Statue"
|
||||
- "WarpCore" : appears in game as "Anti-Graviton Flux"
|
||||
- "HideAndSeek" : appears in game as "Hide and Seek"
|
||||
- "Radio" : appears in game as "Deep Space Radio"
|
||||
- "name" : (string) The name as it will appear in game
|
||||
- "audioClip" : (string) The audio clip from the game you want to use (can find these using Unity Explorer or by datamining)
|
||||
- "audioFilePath" : (string) The file path to a .wav you want to use as the audio clip
|
||||
- "sourceRadius" : (decimal number) The radius of the spherical volume the signal appears to come from
|
||||
- "detectionRadius" : (decimal number) How close you must be to get the "Unidentified signal detected" pop-up
|
||||
- "identiicationRadius" : (decimal number) How close you must get to identify the signal
|
||||
- "onlyAudibleToScope" : (true/false)
|
||||
- "insideCloak" : (true/false) You have to set this to true if the signal is inside a cloaking field
|
||||
|
||||
Here's an example of what all this looks like, for more check my [Signals+](https://github.com/xen-42/outer-wilds-signals-plus) add-on:
|
||||
```
|
||||
"Signal" :
|
||||
{
|
||||
"Signals" :
|
||||
[
|
||||
{ "Frequency" : "Statue", "Name" : "Museum Statue", "AudioClip" : "OW NM Flashback 082818 AP loop", "SourceRadius" : 1, "Position" : {"x": -76.35, "y": 12, "z": 214.7 } },
|
||||
{ "Frequency" : "WarpCore", "Name" : "Timber Hearth Receiver", "AudioClip" : "OW_NM_WhiteHoleAmbienceL", "SourceRadius" : 0.5, "Position" : {"x": -237.8, "y": -50.8, "z": -59.2 } }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Singularity
|
||||
This allows you to make black holes and white holes, and to pair them.
|
||||
- "size" : (decimal number)
|
||||
- "pairedSingularity" : (string) The singularity you want this one to pair to. Must be the opposite type. If you don't set this, the singularity will not transport you, and if it is a black hole it will kill you on entry.
|
||||
- "type" : (string) Put either "BlackHole" or "WhiteHole".
|
||||
|
||||
### How to destroy existing planets
|
||||
|
||||
You do this (but with the appropriate name) as it's own config.
|
||||
@ -322,7 +418,13 @@ You do this (but with the appropriate name) as it's own config.
|
||||
}
|
||||
```
|
||||
|
||||
Remember that if you destroy Timber Hearth you better put a [Spawn](#spawn) module on another planet. I haven't tried destroying the sun. Probably don't do that, it will break everything. Probably.
|
||||
Remember that if you destroy Timber Hearth you better put a [Spawn](#spawn) module on another planet. If you want to entirely replace the solar system you can restroy everything, including the sun. You can use the prefabs from my [Real Solar System](https://github.com/xen-42/outer-wilds-real-solar-system) addon, in the `planets/0 - original planets` folder. Also, deleting a planet destroys anything orbiting it, so if you want to replace the solar system you can just destroy the sun.
|
||||
|
||||
### How to update existing planets
|
||||
|
||||
Similar to above, make a config where "Name" is the name of the planet. The name should be able to just match their in-game english names, however if you encounter any issues with that here are the in-code names for planets that are guaranteed to work: `Sun`, `CaveTwin` (Ember Twin), `TowerTwin` (Ash Twin), `TimberHearth`, `BrittleHollow`, `GiantsDeep`, `DarkBramble`, `Comet` (Interloper), `WhiteHole`, `WhiteHoleTarget` (Whitehole station I believe), `QuantumMoon`, `ProbeCannon`, `TimberMoon` (Attlerock), `VolcanicMoon` (Hollow's Lantern), `DreamWorld`, `MapSatellite`, `RingWorld` (the Stranger).
|
||||
|
||||
Only some of the above modules are supported (currently) for existing planets. Things you cannot modify for existing planets include: heightmaps, procedural generation, gravity, or their orbits. You also can't make them into stars or binary focal points (but why would you want to, just delete them and replace them entirely). However this still means there are many things you can do: completely change their atmospheres, give them rings, asteroid belts, comet tails, lava, water, prop details, or signals.
|
||||
|
||||
## How to use New Horizons in other mods
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user