Merge branch 'dev' into eye-of-the-universe

This commit is contained in:
Noah Pilarski 2022-08-18 00:54:40 -04:00
commit 49e53af910
37 changed files with 1344 additions and 106 deletions

View File

@ -0,0 +1,19 @@
{
"credits": [
"xen#Mod Director\n#Programmer",
"Bwc9876#Mod Manager\n#Programmer\n#Dev Ops",
"FreezeDriedMangos#Programmer\n#Dev Tool Creator",
"MegaPiggy#Programmer",
"JohnCorby#Programmer",
"Hawkbat#Programmer",
"Trifid#Tester\n#Programmer",
"Nageld#Programmer",
"Ernesto#Fish",
"With help from#Raicuparta\n#dgarroDC\n#jtsalomo\n#and the modding community",
" ",
"Based off Marshmallow made by#Mister_Nebula",
"With help from#AmazingAlek\n#Raicuparta\n#and the Outer Wilds discord server",
" ",
"This work is unofficial Fan Content and is not affiliated with Mobius Digital"
]
}

View File

@ -18,7 +18,7 @@ namespace NewHorizons.Builder.Atmosphere
Skys.Clear();
}
public static void Make(GameObject planetGO, Sector sector, AtmosphereModule atmosphereModule, float surfaceSize)
public static GameObject Make(GameObject planetGO, Sector sector, AtmosphereModule atmosphereModule, float surfaceSize, bool proxy = false)
{
GameObject atmoGO = new GameObject("Atmosphere");
atmoGO.SetActive(false);
@ -26,40 +26,76 @@ namespace NewHorizons.Builder.Atmosphere
if (atmosphereModule.useAtmosphereShader)
{
var atmoSphere = SearchUtilities.Find("TimberHearth_Body/Atmosphere_TH/AtmoSphere");
if (atmoSphere != null)
if (proxy)
{
GameObject atmo = GameObject.Instantiate(atmoSphere, atmoGO.transform, true);
atmo.transform.position = planetGO.transform.TransformPoint(Vector3.zero);
atmo.transform.localScale = Vector3.one * atmosphereModule.size * 1.2f;
var renderers = atmo.GetComponentsInChildren<MeshRenderer>();
var material = renderers[0].material; // makes a new material
foreach (var renderer in renderers)
var distantProxy = (SearchUtilities.Find("TimberHearth_DistantProxy", false) ?? SearchUtilities.Find("TimberHearth_DistantProxy(Clone)", false))?.FindChild("Atmosphere_TH/Atmosphere_LOD3");
if (distantProxy != null)
{
GameObject atmo = GameObject.Instantiate(distantProxy, atmoGO.transform, true);
atmo.name = "Atmosphere_LOD3";
atmo.transform.position = planetGO.transform.TransformPoint(Vector3.zero);
atmo.transform.localScale = Vector3.one * atmosphereModule.size * 1.2f * 2f;
var renderer = atmo.GetComponent<MeshRenderer>();
var material = renderer.material; // makes a new material
renderer.sharedMaterial = material;
}
material.SetFloat(InnerRadius, atmosphereModule.clouds != null ? atmosphereModule.size : surfaceSize);
material.SetFloat(OuterRadius, atmosphereModule.size * 1.2f);
if (atmosphereModule.atmosphereTint != null) material.SetColor(SkyColor, atmosphereModule.atmosphereTint.ToColor());
material.SetFloat(InnerRadius, atmosphereModule.clouds != null ? atmosphereModule.size : surfaceSize);
material.SetFloat(OuterRadius, atmosphereModule.size * 1.2f);
if (atmosphereModule.atmosphereTint != null) material.SetColor(SkyColor, atmosphereModule.atmosphereTint.ToColor());
atmo.SetActive(true);
atmo.SetActive(true);
if (atmosphereModule.atmosphereSunIntensity == 0)
{
// do it based on distance
Skys.Add((planetGO, material));
if (atmosphereModule.atmosphereSunIntensity == 0)
{
// do it based on distance
Skys.Add((planetGO, material));
}
else
{
// use the override instead
material.SetFloat(SunIntensity, atmosphereModule.atmosphereSunIntensity);
}
}
else
}
else
{
var atmoSphere = SearchUtilities.Find("TimberHearth_Body/Atmosphere_TH/AtmoSphere");
if (atmoSphere != null)
{
// use the override instead
material.SetFloat(SunIntensity, atmosphereModule.atmosphereSunIntensity);
GameObject atmo = GameObject.Instantiate(atmoSphere, atmoGO.transform, true);
atmo.name = "AtmoSphere";
atmo.transform.position = planetGO.transform.TransformPoint(Vector3.zero);
atmo.transform.localScale = Vector3.one * atmosphereModule.size * 1.2f;
var renderers = atmo.GetComponentsInChildren<MeshRenderer>();
var material = renderers[0].material; // makes a new material
foreach (var renderer in renderers)
{
renderer.sharedMaterial = material;
}
material.SetFloat(InnerRadius, atmosphereModule.clouds != null ? atmosphereModule.size : surfaceSize);
material.SetFloat(OuterRadius, atmosphereModule.size * 1.2f);
if (atmosphereModule.atmosphereTint != null) material.SetColor(SkyColor, atmosphereModule.atmosphereTint.ToColor());
atmo.SetActive(true);
if (atmosphereModule.atmosphereSunIntensity == 0)
{
// do it based on distance
Skys.Add((planetGO, material));
}
else
{
// use the override instead
material.SetFloat(SunIntensity, atmosphereModule.atmosphereSunIntensity);
}
}
}
}
atmoGO.transform.position = planetGO.transform.TransformPoint(Vector3.zero);
atmoGO.SetActive(true);
return atmoGO;
}
}
}

View File

@ -109,26 +109,7 @@ namespace NewHorizons.Builder.Atmosphere
// Lightning
if (atmo.clouds.hasLightning)
{
var lightning = _lightningPrefab.InstantiateInactive();
lightning.transform.parent = cloudsMainGO.transform;
lightning.transform.localPosition = Vector3.zero;
var lightningGenerator = lightning.GetComponent<CloudLightningGenerator>();
lightningGenerator._altitude = (atmo.clouds.outerCloudRadius + atmo.clouds.innerCloudRadius) / 2f;
lightningGenerator._audioSector = sector;
if (atmo.clouds.lightningGradient != null)
{
var gradient = new GradientColorKey[atmo.clouds.lightningGradient.Length];
for(int i = 0; i < atmo.clouds.lightningGradient.Length; i++)
{
var pair = atmo.clouds.lightningGradient[i];
gradient[i] = new GradientColorKey(pair.tint.ToColor(), pair.time);
}
lightningGenerator._lightColor.colorKeys = gradient;
}
lightning.SetActive(true);
MakeLightning(cloudsMainGO, sector, atmo);
}
cloudsMainGO.transform.position = planetGO.transform.TransformPoint(Vector3.zero);
@ -140,6 +121,37 @@ namespace NewHorizons.Builder.Atmosphere
cloudsMainGO.SetActive(true);
}
public static CloudLightningGenerator MakeLightning(GameObject rootObject, Sector sector, AtmosphereModule atmo, bool noAudio = false)
{
var lightning = _lightningPrefab.InstantiateInactive();
lightning.name = "LightningGenerator";
lightning.transform.parent = rootObject.transform;
lightning.transform.localPosition = Vector3.zero;
var lightningGenerator = lightning.GetComponent<CloudLightningGenerator>();
lightningGenerator._altitude = (atmo.clouds.outerCloudRadius + atmo.clouds.innerCloudRadius) / 2f;
if (noAudio)
{
lightningGenerator._audioPrefab = null;
lightningGenerator._audioSourcePool = null;
}
lightningGenerator._audioSector = sector;
if (atmo.clouds.lightningGradient != null)
{
var gradient = new GradientColorKey[atmo.clouds.lightningGradient.Length];
for (int i = 0; i < atmo.clouds.lightningGradient.Length; i++)
{
var pair = atmo.clouds.lightningGradient[i];
gradient[i] = new GradientColorKey(pair.tint.ToColor(), pair.time);
}
lightningGenerator._lightColor.colorKeys = gradient;
}
lightning.SetActive(true);
return lightningGenerator;
}
public static GameObject MakeTopClouds(GameObject rootObject, AtmosphereModule atmo, IModBehaviour mod)
{
Color cloudTint = atmo.clouds.tint?.ToColor() ?? UnityEngine.Color.white;
@ -210,11 +222,14 @@ namespace NewHorizons.Builder.Atmosphere
cloudsTopGO.layer = LayerMask.NameToLayer("IgnoreSun");
}
RotateTransform topRT = cloudsTopGO.AddComponent<RotateTransform>();
// Idk why but the axis is weird
topRT._localAxis = atmo.clouds.cloudsPrefab == CloudPrefabType.Basic ? Vector3.forward : Vector3.up;
topRT._degreesPerSecond = atmo.clouds.rotationSpeed;
topRT._randomizeRotationRate = false;
if (atmo.clouds.rotationSpeed != 0f)
{
RotateTransform topRT = cloudsTopGO.AddComponent<RotateTransform>();
// Idk why but the axis is weird
topRT._localAxis = atmo.clouds.cloudsPrefab == CloudPrefabType.Basic ? Vector3.forward : Vector3.up;
topRT._degreesPerSecond = atmo.clouds.rotationSpeed;
topRT._randomizeRotationRate = false;
}
cloudsTopGO.transform.localPosition = Vector3.zero;

View File

@ -23,6 +23,7 @@ namespace NewHorizons.Builder.Atmosphere
if (config.Atmosphere.hasRain)
{
var rainGO = GameObject.Instantiate(SearchUtilities.Find("GiantsDeep_Body/Sector_GD/Sector_GDInterior/Effects_GDInterior/Effects_GD_Rain"), effectsGO.transform);
rainGO.name = "RainEmitter";
rainGO.transform.position = planetGO.transform.position;
var pvc = rainGO.GetComponent<PlanetaryVectionController>();

View File

@ -14,7 +14,7 @@ namespace NewHorizons.Builder.Atmosphere
private static readonly int DensityExponent = Shader.PropertyToID("_DensityExp");
private static readonly int ColorRampTexture = Shader.PropertyToID("_ColorRampTex");
public static void Make(GameObject planetGO, Sector sector, AtmosphereModule atmo)
public static PlanetaryFogController Make(GameObject planetGO, Sector sector, AtmosphereModule atmo)
{
if (_ramp == null) _ramp = ImageUtilities.GetTexture(Main.Instance, "Assets/textures/FogColorRamp.png");
@ -25,9 +25,9 @@ namespace NewHorizons.Builder.Atmosphere
// Going to copy from dark bramble
var dbFog = SearchUtilities.Find("DarkBramble_Body/Atmosphere_DB/FogLOD");
if (dbFog == null) return;
if (dbFog == null) return null;
var dbPlanetaryFogController = SearchUtilities.Find("DarkBramble_Body/Atmosphere_DB/FogSphere_DB")?.GetComponent<PlanetaryFogController>();
if (dbPlanetaryFogController == null) return;
if (dbPlanetaryFogController == null) return null;
MeshFilter MF = fogGO.AddComponent<MeshFilter>();
MF.mesh = dbFog.GetComponent<MeshFilter>().mesh;
@ -60,6 +60,41 @@ namespace NewHorizons.Builder.Atmosphere
fogGO.transform.position = planetGO.transform.position;
fogGO.SetActive(true);
return PFC;
}
public static Renderer MakeProxy(GameObject proxyGO, AtmosphereModule atmo)
{
if (_ramp == null) _ramp = ImageUtilities.GetTexture(Main.Instance, "Assets/textures/FogColorRamp.png");
GameObject fogGO = new GameObject("FogSphere");
fogGO.SetActive(false);
fogGO.transform.parent = proxyGO.transform;
fogGO.transform.localScale = Vector3.one * atmo.fogSize;
var fog = (SearchUtilities.Find("TimberHearth_DistantProxy", false) ?? SearchUtilities.Find("TimberHearth_DistantProxy(Clone)", false))?.FindChild("Atmosphere_TH/FogSphere");
MeshFilter MF = fogGO.AddComponent<MeshFilter>();
MF.mesh = fog.GetComponent<MeshFilter>().mesh;
MeshRenderer MR = fogGO.AddComponent<MeshRenderer>();
MR.materials = fog.GetComponent<MeshRenderer>().materials;
MR.allowOcclusionWhenDynamic = true;
var colorRampTexture = atmo.fogTint == null ? _ramp : ImageUtilities.TintImage(_ramp, atmo.fogTint.ToColor());
if (atmo.fogTint != null)
{
MR.material.SetColor(Tint, atmo.fogTint.ToColor());
}
MR.material.SetFloat(Radius, atmo.fogSize);
MR.material.SetFloat(Density, atmo.fogDensity);
MR.material.SetFloat(DensityExponent, 1);
MR.material.SetTexture(ColorRampTexture, colorRampTexture);
fogGO.transform.position = proxyGO.transform.position;
fogGO.SetActive(true);
return MR;
}
}
}

View File

@ -62,7 +62,7 @@ namespace NewHorizons.Builder.Body
config.ProcGen = new ProcGenModule()
{
scale = size,
color = new MColor(126, 94, 73, 255)
color = new MColor(126, 94, 73)
};
}
else

View File

@ -4,7 +4,7 @@ namespace NewHorizons.Builder.Body
{
public static class GeometryBuilder
{
public static void Make(GameObject planetGO, Sector sector, float groundScale)
public static GameObject Make(GameObject planetGO, Sector sector, float groundScale)
{
GameObject groundGO = GameObject.CreatePrimitive(PrimitiveType.Sphere);
groundGO.transform.name = "GroundSphere";
@ -23,6 +23,8 @@ namespace NewHorizons.Builder.Body
groundGO.transform.localScale *= 2;
}
groundGO.SetActive(true);
return groundGO;
}
}
}

View File

@ -14,7 +14,7 @@ namespace NewHorizons.Builder.Body
{
public static Shader PlanetShader;
public static void Make(GameObject planetGO, Sector sector, HeightMapModule module, IModBehaviour mod, int resolution, bool useLOD = false)
public static GameObject Make(GameObject planetGO, Sector sector, HeightMapModule module, IModBehaviour mod, int resolution, bool useLOD = false)
{
var deleteHeightmapFlag = false;
@ -60,7 +60,7 @@ namespace NewHorizons.Builder.Body
catch (Exception e)
{
Logger.LogError($"Couldn't load HeightMap textures:\n{e}");
return;
return null;
}
GameObject cubeSphere = new GameObject("CubeSphere");
@ -111,6 +111,8 @@ namespace NewHorizons.Builder.Body
// Now that we've made the mesh we can delete the heightmap texture
if (deleteHeightmapFlag) ImageUtilities.DeleteTexture(mod, module.heightMap, heightMap);
return cubeSphere;
}
public static MeshRenderer MakeLODTerrain(GameObject root, Texture2D heightMap, Texture2D textureMap, float minHeight, float maxHeight, int resolution, Vector3 stretch)

View File

@ -52,6 +52,7 @@ namespace NewHorizons.Builder.Body
sectorProxy.SetSector(sector);
var destructionVolume = GameObject.Instantiate(SearchUtilities.Find("VolcanicMoon_Body/MoltenCore_VM/DestructionVolume"), moltenCore.transform);
destructionVolume.name = "DestructionVolume";
destructionVolume.GetComponent<SphereCollider>().radius = 1;
destructionVolume.SetActive(true);

View File

@ -9,7 +9,7 @@ namespace NewHorizons.Builder.Body
private static Material quantumMaterial;
private static Material iceMaterial;
public static void Make(GameObject planetGO, Sector sector, ProcGenModule module)
public static GameObject Make(GameObject planetGO, Sector sector, ProcGenModule module)
{
if (quantumMaterial == null) quantumMaterial = SearchUtilities.FindResourceOfTypeAndName<Material>("Rock_QM_EyeRock_mat");
if (iceMaterial == null) iceMaterial = SearchUtilities.FindResourceOfTypeAndName<Material>("Rock_BH_IceSpike_mat");
@ -40,6 +40,7 @@ namespace NewHorizons.Builder.Body
if (superGroup != null) icosphere.AddComponent<ProxyShadowCaster>()._superGroup = superGroup;
icosphere.SetActive(true);
return icosphere;
}
}
}

View File

@ -34,9 +34,13 @@ namespace NewHorizons.Builder.Body
var proxyName = $"{body.Config.name}_Proxy";
var newProxy = new GameObject(proxyName);
newProxy.SetActive(false);
try
{
var proxyController = newProxy.AddComponent<NHProxy>();
proxyController.astroName = body.Config.name;
// We want to take the largest size I think
var realSize = body.Config.Base.surfaceSize;
@ -45,32 +49,57 @@ namespace NewHorizons.Builder.Body
HeightMapBuilder.Make(newProxy, null, body.Config.HeightMap, body.Mod, 20);
if (realSize < body.Config.HeightMap.maxHeight) realSize = body.Config.HeightMap.maxHeight;
}
if (body.Config.Base.groundSize != 0)
{
GeometryBuilder.Make(newProxy, null, body.Config.Base.groundSize);
if (realSize < body.Config.Base.groundSize) realSize = body.Config.Base.groundSize;
}
if (body.Config.Atmosphere?.clouds != null)
if (body.Config.Atmosphere != null)
{
CloudsBuilder.MakeTopClouds(newProxy, body.Config.Atmosphere, body.Mod);
if (realSize < body.Config.Atmosphere.size) realSize = body.Config.Atmosphere.size;
proxyController._atmosphere = AtmosphereBuilder.Make(newProxy, null, body.Config.Atmosphere, body.Config.Base.surfaceSize, true).GetComponentInChildren<MeshRenderer>();
proxyController._mieCurveMaxVal = 0.1f;
proxyController._mieCurve = AnimationCurve.EaseInOut(0.0011f, 1, 1, 0);
if (body.Config.Atmosphere.fogSize != 0)
{
proxyController._fog = FogBuilder.MakeProxy(newProxy, body.Config.Atmosphere);
proxyController._fogCurveMaxVal = body.Config.Atmosphere.fogDensity;
proxyController._fogCurve = AnimationCurve.Linear(0, 1, 1, 0);
}
if (body.Config.Atmosphere.clouds != null)
{
proxyController._mainBody = CloudsBuilder.MakeTopClouds(newProxy, body.Config.Atmosphere, body.Mod).GetComponent<MeshRenderer>();
if (body.Config.Atmosphere.clouds.hasLightning)
{
proxyController._lightningGenerator = CloudsBuilder.MakeLightning(newProxy, null, body.Config.Atmosphere, true);
}
if (realSize < body.Config.Atmosphere.size) realSize = body.Config.Atmosphere.size;
}
}
if (body.Config.Ring != null)
{
RingBuilder.MakeRingGraphics(newProxy, null, body.Config.Ring, body.Mod);
if (realSize < body.Config.Ring.outerRadius) realSize = body.Config.Ring.outerRadius;
}
if (body.Config.Star != null)
{
var starGO = StarBuilder.MakeStarProxy(planetGO, newProxy, body.Config.Star, body.Mod);
if (realSize < body.Config.Star.size) realSize = body.Config.Star.size;
}
GameObject procGen = null;
if (body.Config.ProcGen != null)
{
ProcGenBuilder.Make(newProxy, null, body.Config.ProcGen);
procGen = ProcGenBuilder.Make(newProxy, null, body.Config.ProcGen);
if (realSize < body.Config.ProcGen.scale) realSize = body.Config.ProcGen.scale;
}
if (body.Config.Lava != null)
{
var sphere = AddColouredSphere(newProxy, body.Config.Lava.size, body.Config.Lava.curve, Color.black);
@ -80,18 +109,21 @@ namespace NewHorizons.Builder.Body
if (body.Config.Lava.tint != null) material.SetColor(EmissionColor, body.Config.Lava.tint.ToColor());
sphere.GetComponent<MeshRenderer>().material = material;
}
if (body.Config.Water != null)
{
var colour = body.Config.Water.tint?.ToColor() ?? Color.blue;
AddColouredSphere(newProxy, body.Config.Water.size, body.Config.Water.curve, colour);
if (realSize < body.Config.Water.size) realSize = body.Config.Water.size;
}
if (body.Config.Sand != null)
{
var colour = body.Config.Sand.tint?.ToColor() ?? Color.yellow;
AddColouredSphere(newProxy, body.Config.Sand.size, body.Config.Sand.curve, colour);
if (realSize < body.Config.Sand.size) realSize = body.Config.Sand.size;
}
// Could improve this to actually use the proper renders and materials
if (body.Config.Props?.singularities != null)
{
@ -109,10 +141,12 @@ namespace NewHorizons.Builder.Body
if (realSize < singularity.size) realSize = singularity.size;
}
}
if (body.Config.Base.hasCometTail)
{
CometTailBuilder.Make(newProxy, null, body.Config);
}
if (body.Config.Props?.proxyDetails != null)
{
foreach (var detailInfo in body.Config.Props.proxyDetails)
@ -121,6 +155,11 @@ namespace NewHorizons.Builder.Body
}
}
if (body.Config.Base.hasSupernovaShockEffect && body.Config.Star == null && body.Config.name != "Sun" && body.Config.FocalPoint == null)
{
proxyController._supernovaPlanetEffectController = SupernovaEffectBuilder.Make(newProxy, null, body.Config, procGen, null, null, null, proxyController._atmosphere, proxyController._fog);
}
// Remove all collisions if there are any
foreach (var col in newProxy.GetComponentsInChildren<Collider>())
{
@ -138,8 +177,6 @@ namespace NewHorizons.Builder.Body
tessellatedRenderer.enabled = true;
}
var proxyController = newProxy.AddComponent<NHProxy>();
proxyController.astroName = body.Config.name;
proxyController._realObjectDiameter = realSize;
}
catch (Exception ex)
@ -147,6 +184,8 @@ namespace NewHorizons.Builder.Body
Logger.LogError($"Exception thrown when generating proxy for [{body.Config.name}]:\n{ex}");
GameObject.Destroy(newProxy);
}
newProxy.SetActive(true);
}
private static GameObject AddColouredSphere(GameObject rootObj, float size, VariableSizeModule.TimeValuePair[] curve, Color color)

View File

@ -140,6 +140,7 @@ namespace NewHorizons.Builder.Body
if (sizeController != null) sizeController.audioSource = blackHoleAudioSource;
var blackHoleOneShot = GameObject.Instantiate(SearchUtilities.Find("BrittleHollow_Body/BlackHole_BH/BlackHoleEmissionOneShot"), blackHole.transform);
blackHoleOneShot.name = "BlackHoleEmissionOneShot";
var oneShotAudioSource = blackHoleOneShot.GetComponent<AudioSource>();
oneShotAudioSource.maxDistance = size * 3f;
oneShotAudioSource.minDistance = size * 0.4f;

View File

@ -142,11 +142,14 @@ namespace NewHorizons.Builder.Body
controller.supernova = supernova;
controller.StartColour = starModule.tint;
controller.EndColour = starModule.endTint;
controller.SupernovaColour = starModule.supernovaTint;
controller.WillExplode = starModule.goSupernova;
controller.lifespan = starModule.lifespan;
controller.normalRamp = !string.IsNullOrEmpty(starModule.starRampTexture) ? ImageUtilities.GetTexture(mod, starModule.starRampTexture) : ramp;
controller._destructionVolume = deathVolume.GetComponent<DestructionVolume>();
controller._planetDestructionVolume = planetDestructionVolume.GetComponent<DestructionVolume>();
controller._destructionFluidVolume = planetDestructionVolume.GetComponent<SimpleFluidVolume>();
controller._planetDestructionFluidVolume = planetDestructionVolume.GetComponent<SimpleFluidVolume>();
if (!string.IsNullOrEmpty(starModule.starCollapseRampTexture))
{
controller.collapseRamp = ImageUtilities.GetTexture(mod, starModule.starCollapseRampTexture);
@ -192,6 +195,7 @@ namespace NewHorizons.Builder.Body
controller.supernova = supernova;
controller.StartColour = starModule.tint;
controller.EndColour = starModule.endTint;
controller.SupernovaColour = starModule.supernovaTint;
controller.WillExplode = starModule.goSupernova;
controller.lifespan = starModule.lifespan;
controller.normalRamp = !string.IsNullOrEmpty(starModule.starRampTexture) ? ImageUtilities.GetTexture(mod, starModule.starRampTexture) : ramp;
@ -283,12 +287,13 @@ namespace NewHorizons.Builder.Body
private static SupernovaEffectController MakeSupernova(GameObject starGO, StarModule starModule)
{
var supernovaGO = SearchUtilities.Find("Sun_Body/Sector_SUN/Effects_SUN/Supernova").InstantiateInactive();
supernovaGO.name = "Supernova";
supernovaGO.transform.SetParent(starGO.transform);
supernovaGO.transform.localPosition = Vector3.zero;
var supernova = supernovaGO.GetComponent<SupernovaEffectController>();
supernova._surface = starGO.GetComponentInChildren<TessellatedSphereRenderer>();
supernova._supernovaScale = AnimationCurve.Linear(5, 0, 15, starModule.supernovaSize);
supernova._supernovaScale = new AnimationCurve(new Keyframe(0, 200, 0, 0, 1f / 3f, 1f / 3f), new Keyframe(45, starModule.supernovaSize, 1758.508f, 1758.508f, 1f / 3f, 1f / 3f));
supernova._supernovaVolume = null;
if (starModule.supernovaTint != null)

View File

@ -0,0 +1,163 @@
using UnityEngine;
using NewHorizons.Utility;
using NewHorizons.External.Configs;
using NewHorizons.Components;
using System.Linq;
using NewHorizons.Handlers;
namespace NewHorizons.Builder.Body
{
public static class SupernovaEffectBuilder
{
public static NHSupernovaPlanetEffectController Make(GameObject planetGO, Sector sector, PlanetConfig config, GameObject procGen, Light ambientLight, PlanetaryFogController fog, LODGroup atmosphere, Renderer atmosphereRenderer, Renderer fogImpostor)
{
var vanillaController = planetGO.GetComponentInChildren<SupernovaPlanetEffectController>();
if (vanillaController != null)
{
ReplaceVanillaWithNH(vanillaController);
}
var currentController = planetGO.GetComponentInChildren<NHSupernovaPlanetEffectController>();
if (currentController != null)
{
if (currentController._ambientLight == null && ambientLight != null)
{
currentController._ambientLight = ambientLight;
currentController._ambientLightOrigIntensity = config.Base.ambientLight;
}
if (currentController._atmosphere == null && atmosphere != null) currentController._atmosphere = atmosphere;
if (currentController._fog == null && fog != null) currentController._fog = fog;
return currentController;
}
else
{
var supernovaController = new GameObject("SupernovaController");
supernovaController.transform.SetParent(sector?.transform ?? planetGO.transform, false);
var supernovaEffectController = supernovaController.AddComponent<NHSupernovaPlanetEffectController>();
supernovaEffectController._ambientLight = ambientLight;
supernovaEffectController._ambientLightOrigIntensity = config.Base.ambientLight;
supernovaEffectController._atmosphere = atmosphere;
supernovaEffectController._atmosphereRenderer = atmosphereRenderer;
supernovaEffectController._fog = fog;
supernovaEffectController._fogImpostor = fogImpostor;
var shockLayerGD = SearchUtilities.Find("GiantsDeep_Body/Shocklayer_GD");
var shockLayer = new GameObject("ShockLayer");
shockLayer.transform.SetParent(sector?.transform ?? planetGO.transform, false);
shockLayer.AddComponent<MeshFilter>().sharedMesh = shockLayerGD.GetComponent<MeshFilter>().sharedMesh;
var shockLayerMaterial = new Material(shockLayerGD.GetComponent<MeshRenderer>().sharedMaterial);
shockLayerMaterial.name = "ShockLayer_mat";
var shockLayerRenderer = shockLayer.AddComponent<MeshRenderer>();
shockLayerRenderer.sharedMaterial = shockLayerMaterial;
supernovaEffectController._shockLayer = shockLayerRenderer;
var biggestSize = config.Base.surfaceSize;
var noMeshChange = false;
if (config.Atmosphere != null)
{
if (config.Atmosphere.size > biggestSize) biggestSize = config.Atmosphere.size;
if (config.Atmosphere.fogSize > biggestSize) biggestSize = config.Atmosphere.fogSize;
if (config.Atmosphere.clouds != null)
{
noMeshChange = true;
if (config.Atmosphere.clouds.innerCloudRadius > biggestSize) biggestSize = config.Atmosphere.clouds.innerCloudRadius;
if (config.Atmosphere.clouds.outerCloudRadius > biggestSize) biggestSize = config.Atmosphere.clouds.outerCloudRadius;
}
}
if (config.Base.groundSize > biggestSize)
{
noMeshChange = true;
biggestSize = config.Base.groundSize;
}
if (config.HeightMap != null)
{
if (config.HeightMap.minHeight > biggestSize) biggestSize = config.HeightMap.minHeight;
if (config.HeightMap.maxHeight > biggestSize) biggestSize = config.HeightMap.maxHeight;
}
if (config.ProcGen != null)
{
if (config.ProcGen.scale > biggestSize) biggestSize = config.ProcGen.scale;
}
if (config.Lava != null)
{
noMeshChange = true;
var lavaSize = config.Lava.size;
if (config.Lava.curve != null) lavaSize *= config.Lava.curve.Max(tvp => tvp.value);
if (lavaSize > biggestSize) biggestSize = lavaSize;
}
if (config.Water != null)
{
noMeshChange = true;
var waterSize = config.Water.size;
if (config.Water.curve != null) waterSize *= config.Water.curve.Max(tvp => tvp.value);
if (waterSize > biggestSize) biggestSize = waterSize;
}
if (config.Sand != null)
{
noMeshChange = true;
var sandSize = config.Sand.size;
if (config.Sand.curve != null) sandSize *= config.Sand.curve.Max(tvp => tvp.value);
if (sandSize > biggestSize) biggestSize = sandSize;
}
if (config.Props?.singularities != null)
{
noMeshChange = true;
foreach (var singularity in config.Props.singularities)
{
if (singularity.size > biggestSize) biggestSize = singularity.size;
}
}
supernovaEffectController._shockLayerStartRadius = biggestSize;
supernovaEffectController._shockLayerFullRadius = biggestSize * 10f;
supernovaEffectController._shockLayerTrailFlare = 100;
supernovaEffectController._shockLayerTrailLength = biggestSize < 600 ? 300 : 600;
shockLayer.transform.position = planetGO.transform.position;
shockLayer.transform.localScale = Vector3.one * biggestSize * 1.1f;
if (!noMeshChange && procGen != null)
{
shockLayer.GetComponent<MeshFilter>().sharedMesh = procGen.GetComponent<MeshFilter>().sharedMesh;
shockLayer.transform.localScale = Vector3.one * 1.1f;
shockLayer.transform.rotation = Quaternion.Euler(90, 0, 0);
}
return supernovaEffectController;
}
}
public static void ReplaceVanillaWithNH(SupernovaPlanetEffectController vanillaController)
{
if (vanillaController._shockLayer != null) vanillaController._shockLayer.gameObject.SetActive(true);
var supernovaEffectController = vanillaController.gameObject.GetAddComponent<NHSupernovaPlanetEffectController>();
supernovaEffectController._atmosphere = vanillaController._atmosphere;
supernovaEffectController._ambientLight = vanillaController._ambientLight;
supernovaEffectController._ambientLightOrigIntensity = vanillaController._ambientLightOrigIntensity;
supernovaEffectController._atmosphere = vanillaController._atmosphere;
supernovaEffectController._fog = vanillaController._fog;
supernovaEffectController._fogOrigTint = vanillaController._fogOrigTint;
supernovaEffectController._shockLayer = vanillaController._shockLayer;
supernovaEffectController._shockLayerColor = vanillaController._shockLayerColor;
supernovaEffectController._shockLayerFullRadius = vanillaController._shockLayerFullRadius;
supernovaEffectController._shockLayerStartRadius = vanillaController._shockLayerStartRadius;
supernovaEffectController._shockLayerTrailFlare = vanillaController._shockLayerTrailFlare;
supernovaEffectController._shockLayerTrailLength = vanillaController._shockLayerTrailLength;
supernovaEffectController._sunController = SearchUtilities.Find("Sun_Body").GetComponent<SunController>();
Object.Destroy(vanillaController);
}
}
}

View File

@ -4,10 +4,10 @@ namespace NewHorizons.Builder.General
{
public static class AmbientLightBuilder
{
public static void Make(GameObject planetGO, Sector sector, float scale, float intensity)
public static Light Make(GameObject planetGO, Sector sector, float scale, float intensity)
{
var ambientLight = Main.Instance.CurrentStarSystem == "EyeOfTheUniverse" ? SearchUtilities.Find("EyeOfTheUniverse_Body/Sector_EyeOfTheUniverse/SixthPlanet_Root/QuantumMoonProxy_Pivot/QuantumMoonProxy_Root/MoonState_Root/AmbientLight_QM") : SearchUtilities.Find("BrittleHollow_Body/AmbientLight_BH_Surface");
if (ambientLight == null) return;
var ambientLight = Main.Instance.CurrentStarSystem == "EyeOfTheUniverse" ? SearchUtilities.Find("EyeOfTheUniverse_Body/Sector_EyeOfTheUniverse/SixthPlanet_Root/QuantumMoonProxy_Pivot/QuantumMoonProxy_Root/MoonState_Root/AmbientLight_QM") : SearchUtilities.Find("QuantumMoon_Body/AmbientLight_QM");
if (ambientLight == null) return null;
GameObject lightGO = GameObject.Instantiate(ambientLight, sector?.transform ?? planetGO.transform);
lightGO.transform.position = planetGO.transform.position;
@ -20,9 +20,17 @@ namespace NewHorizons.Builder.General
* A is the intensity and its like square rooted and squared and idgi
*/
light.color = new Color(0.0f, 0.0f, 0.8f, 0.0225f);
light.color = new Color(0.5f, 0.0f, 0.8f, 0.0225f);
light.range = scale;
light.intensity = intensity;
/*if (tint != null)
{
var cubemap = ImageUtilities.TintImage(ImageUtilities.GetTexture(Main.Instance, "Assets/textures/AmbientLight_QM.png"), tint.ToColor());
light.cookie = cubemap;
}*/
return light;
}
}
}

View File

@ -1,5 +1,7 @@
using NewHorizons.Components.Orbital;
using NewHorizons.External.Configs;
using NewHorizons.Utility;
using System.Collections.Generic;
using UnityEngine;
using Logger = NewHorizons.Utility.Logger;
namespace NewHorizons.Builder.General
@ -33,10 +35,61 @@ namespace NewHorizons.Builder.General
OWRB.RegisterAttachedFluidDetector(fluidDetector);
// Could copy the splash from the interloper as well some day
var splashEffects = new List<SplashEffect>();
var cometDetector = SearchUtilities.Find("Comet_Body/Detector_CO")?.GetComponent<FluidDetector>();
if (cometDetector != null)
{
foreach (var splashEffect in cometDetector._splashEffects)
{
splashEffects.Add(new SplashEffect
{
fluidType = splashEffect.fluidType,
ignoreSphereAligment = splashEffect.ignoreSphereAligment,
triggerEvent = splashEffect.triggerEvent,
minImpactSpeed = 15,
splashPrefab = splashEffect.splashPrefab
});
}
}
var islandDetector = SearchUtilities.Find("GabbroIsland_Body/Detector_GabbroIsland")?.GetComponent<FluidDetector>();
if (islandDetector != null)
{
foreach (var splashEffect in islandDetector._splashEffects)
{
splashEffects.Add(new SplashEffect
{
fluidType = splashEffect.fluidType,
ignoreSphereAligment = splashEffect.ignoreSphereAligment,
triggerEvent = splashEffect.triggerEvent,
minImpactSpeed = 15,
splashPrefab = splashEffect.splashPrefab
});
}
}
var shipDetector = SearchUtilities.Find("Ship_Body/ShipDetector")?.GetComponent<FluidDetector>();
if (shipDetector != null)
{
foreach (var splashEffect in shipDetector._splashEffects)
{
if (splashEffect.fluidType == FluidVolume.Type.SAND)
splashEffects.Add(new SplashEffect
{
fluidType = splashEffect.fluidType,
ignoreSphereAligment = splashEffect.ignoreSphereAligment,
triggerEvent = splashEffect.triggerEvent,
minImpactSpeed = 15,
splashPrefab = splashEffect.splashPrefab
});
}
}
fluidDetector._splashEffects = splashEffects.ToArray();
}
SetDetector(primaryBody, astroObject, forceDetector);
if (!config.Orbit.isStatic) SetDetector(primaryBody, astroObject, forceDetector);
detectorGO.SetActive(true);
return detectorGO;

View File

@ -36,7 +36,8 @@ namespace NewHorizons.Builder.Props
}
if (_hurricanePrefab == null)
{
_hurricanePrefab = SearchUtilities.Find("GiantsDeep_Body/Sector_GD/Sector_GDInterior/Tornadoes_GDInterior/Hurricane/").InstantiateInactive();
_hurricanePrefab = SearchUtilities.Find("GiantsDeep_Body/Sector_GD/Sector_GDInterior/Tornadoes_GDInterior/Hurricane").InstantiateInactive();
_hurricanePrefab.name = "Hurricane_Prefab";
// For some reason they put the hurricane at the origin and offset all its children (450)
// Increasing by 40 will keep the bottom above the ground
foreach (Transform child in _hurricanePrefab.transform)
@ -84,6 +85,7 @@ namespace NewHorizons.Builder.Props
private static void MakeTornado(GameObject planetGO, Sector sector, PropModule.TornadoInfo info, Vector3 position, bool downwards)
{
var tornadoGO = downwards ? _downPrefab.InstantiateInactive() : _upPrefab.InstantiateInactive();
tornadoGO.name = downwards ? "Tornado_Down" : "Tornado_Up";
tornadoGO.transform.parent = sector.transform;
tornadoGO.transform.position = planetGO.transform.TransformPoint(position);
tornadoGO.transform.rotation = Quaternion.FromToRotation(Vector3.up, sector.transform.TransformDirection(position.normalized));
@ -168,6 +170,7 @@ namespace NewHorizons.Builder.Props
private static void MakeHurricane(GameObject planetGO, Sector sector, PropModule.TornadoInfo info, Vector3 position, bool hasClouds)
{
var hurricaneGO = _hurricanePrefab.InstantiateInactive();
hurricaneGO.name = "Hurricane";
hurricaneGO.transform.parent = sector.transform;
hurricaneGO.transform.position = planetGO.transform.TransformPoint(position);
hurricaneGO.transform.rotation = Quaternion.FromToRotation(Vector3.up, sector.transform.TransformDirection(position.normalized));

View File

@ -1,4 +1,4 @@
using NewHorizons.Components.SizeControllers;
using NewHorizons.Components.SizeControllers;
using NewHorizons.Utility;
using System.Collections.Generic;
using UnityEngine;
@ -13,6 +13,9 @@ namespace NewHorizons.Components
private TessellatedRenderer[] _starTessellatedRenderers;
private ParticleSystemRenderer[] _starParticleRenderers;
private SolarFlareEmitter _solarFlareEmitter;
public CloudLightningGenerator _lightningGenerator;
public MeshRenderer _mainBody;
public NHSupernovaPlanetEffectController _supernovaPlanetEffectController;
public override void Awake()
{
@ -30,6 +33,10 @@ namespace NewHorizons.Components
_solarFlareEmitter = _star.GetComponentInChildren<SolarFlareEmitter>();
}
if (_lightningGenerator == null) _lightningGenerator = GetComponentInChildren<CloudLightningGenerator>();
if (_supernovaPlanetEffectController == null) _supernovaPlanetEffectController = GetComponentInChildren<NHSupernovaPlanetEffectController>();
// Start off
_outOfRange = false;
ToggleRendering(false);
@ -39,9 +46,9 @@ namespace NewHorizons.Components
{
AstroObject astroObject = AstroObjectLocator.GetAstroObject(astroName);
_realObjectTransform = astroObject.transform;
_hasAtmosphere = _atmosphere != null;
if (_hasAtmosphere)
if (_atmosphere != null)
{
_hasAtmosphere = true;
_atmosphereMaterial = new Material(_atmosphere.sharedMaterial);
_baseAtmoMatShellInnerRadius = _atmosphereMaterial.GetFloat(propID_AtmoInnerRadius);
_baseAtmoMatShellOuterRadius = _atmosphereMaterial.GetFloat(propID_AtmoOuterRadius);
@ -73,6 +80,22 @@ namespace NewHorizons.Components
_solarFlareEmitter.gameObject.SetActive(on);
}
if (_mainBody != null)
{
_mainBody.enabled = on;
}
if (_lightningGenerator != null)
{
_lightningGenerator.enabled = on;
}
if (_supernovaPlanetEffectController != null)
{
if (on) _supernovaPlanetEffectController.Enable();
else _supernovaPlanetEffectController.Disable();
}
foreach (var renderer in _starRenderers)
{
renderer.enabled = on;

View File

@ -0,0 +1,196 @@
using NewHorizons.Components.SizeControllers;
using NewHorizons.Handlers;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using static SupernovaPlanetEffectController;
namespace NewHorizons.Components
{
public class NHSupernovaPlanetEffectController : MonoBehaviour
{
public Light _ambientLight;
public float _ambientLightOrigIntensity;
public LODGroup _atmosphere;
public Renderer _atmosphereRenderer;
public PlanetaryFogController _fog;
public Renderer _fogImpostor;
public Color _fogOrigTint;
[Space]
public MeshRenderer _shockLayer;
public static readonly Color _shockLayerDefaultColor = new Color(0.3569f, 0.7843f, 1f, 1f);
[ColorUsage(true, true)]
public Color _shockLayerColor = _shockLayerDefaultColor;
public float _shockLayerStartRadius = 1000f;
public float _shockLayerFullRadius = 10000f;
public float _shockLayerTrailLength = 300f;
public float _shockLayerTrailFlare = 100f;
private LOD[] _atmosphereLODs;
public StarEvolutionController _starEvolutionController;
public SunController _sunController;
public void Awake()
{
if (s_matPropBlock_Atmosphere == null)
{
s_matPropBlock_Atmosphere = new MaterialPropertyBlock();
s_propID_SunIntensity = Shader.PropertyToID("_SunIntensity");
s_propID_Tint = Shader.PropertyToID("_Tint");
s_matPropBlock_ShockLayer = new MaterialPropertyBlock();
s_propID_Color = Shader.PropertyToID("_Color");
s_propID_WorldToLocalShockMatrix = Shader.PropertyToID("_WorldToShockLocalMatrix");
s_propID_Dir = Shader.PropertyToID("_Dir");
s_propID_Length = Shader.PropertyToID("_Length");
s_propID_Flare = Shader.PropertyToID("_Flare");
s_propID_TrailFade = Shader.PropertyToID("_TrailFade");
s_propID_GradientLerp = Shader.PropertyToID("_GradientLerp");
s_propID_MainTex_ST = Shader.PropertyToID("_MainTex_ST");
}
}
public void Start()
{
SupernovaEffectHandler.RegisterPlanetEffect(this);
if (_atmosphere != null) _atmosphereLODs = _atmosphere.GetLODs();
if (_fog != null)
{
_fogOrigTint = _fog.fogTint;
_fogImpostor = _fog.fogImpostor;
}
else if (_fogImpostor != null)
{
_fogOrigTint = _fogImpostor.material.GetColor(s_propID_Tint);
}
if (_shockLayer != null) _shockLayer.enabled = false;
}
public void OnDestroy()
{
SupernovaEffectHandler.UnregisterPlanetEffect(this);
}
public void Enable()
{
enabled = true;
}
public void Disable()
{
enabled = false;
if (_shockLayer != null) _shockLayer.enabled = false;
}
public void Update()
{
SupernovaEffectHandler.GetNearestStarSupernova(this);
if (_starEvolutionController != null)
{
if (_starEvolutionController.HasSupernovaStarted())
{
if (_shockLayer != null)
{
if (!_shockLayer.enabled) _shockLayer.enabled = true;
Vector3 dir = Vector3.Normalize(transform.position - _starEvolutionController.transform.position);
s_matPropBlock_ShockLayer.SetColor(s_propID_Color, _starEvolutionController.SupernovaColour != null ? _starEvolutionController.SupernovaColour.ToColor() : _shockLayerColor);
s_matPropBlock_ShockLayer.SetMatrix(s_propID_WorldToLocalShockMatrix, Matrix4x4.TRS(transform.position, Quaternion.LookRotation(dir, Vector3.up), Vector3.one).inverse);
s_matPropBlock_ShockLayer.SetVector(s_propID_Dir, dir);
s_matPropBlock_ShockLayer.SetFloat(s_propID_Length, _shockLayerTrailLength);
s_matPropBlock_ShockLayer.SetFloat(s_propID_Flare, _shockLayerTrailFlare);
s_matPropBlock_ShockLayer.SetFloat(s_propID_TrailFade, 1f - Mathf.InverseLerp(_shockLayerStartRadius, _shockLayerFullRadius, _starEvolutionController.GetSupernovaRadius()));
s_matPropBlock_ShockLayer.SetFloat(s_propID_GradientLerp, 0);
s_matPropBlock_ShockLayer.SetVector(s_propID_MainTex_ST, _shockLayer.sharedMaterial.GetVector(s_propID_MainTex_ST) with { w = -Time.timeSinceLevelLoad });
_shockLayer.SetPropertyBlock(s_matPropBlock_ShockLayer);
}
}
if (_starEvolutionController.IsCollapsing())
{
float collapseProgress = _starEvolutionController.GetCollapseProgress();
if (_ambientLight != null) _ambientLight.intensity = _ambientLightOrigIntensity * (1f - collapseProgress);
if (_atmosphere != null)
{
s_matPropBlock_Atmosphere.SetFloat(s_propID_SunIntensity, 1f - collapseProgress);
foreach (var lod in _atmosphereLODs)
foreach (var renderer in lod.renderers)
renderer.SetPropertyBlock(s_matPropBlock_Atmosphere);
}
if (_atmosphereRenderer != null)
{
s_matPropBlock_Atmosphere.SetFloat(s_propID_SunIntensity, 1f - collapseProgress);
_atmosphereRenderer.SetPropertyBlock(s_matPropBlock_Atmosphere);
}
if (_fog != null) _fog.fogTint = Color.Lerp(_fogOrigTint, Color.black, collapseProgress);
if (_fogImpostor != null) _fogImpostor.material.SetColor(s_propID_Tint, Color.Lerp(_fogOrigTint, Color.black, collapseProgress));
}
else
{
if (_shockLayer != null) _shockLayer.enabled = false;
}
}
else if (_sunController != null)
{
if (_sunController.HasSupernovaStarted())
{
if (_shockLayer != null)
{
if (!_shockLayer.enabled) _shockLayer.enabled = true;
Vector3 dir = Vector3.Normalize(transform.position - _sunController.transform.position);
s_matPropBlock_ShockLayer.SetColor(s_propID_Color, _shockLayerColor);
s_matPropBlock_ShockLayer.SetMatrix(s_propID_WorldToLocalShockMatrix, Matrix4x4.TRS(transform.position, Quaternion.LookRotation(dir, Vector3.up), Vector3.one).inverse);
s_matPropBlock_ShockLayer.SetVector(s_propID_Dir, dir);
s_matPropBlock_ShockLayer.SetFloat(s_propID_Length, _shockLayerTrailLength);
s_matPropBlock_ShockLayer.SetFloat(s_propID_Flare, _shockLayerTrailFlare);
s_matPropBlock_ShockLayer.SetFloat(s_propID_TrailFade, 1f - Mathf.InverseLerp(_shockLayerStartRadius, _shockLayerFullRadius, _sunController.GetSupernovaRadius()));
s_matPropBlock_ShockLayer.SetFloat(s_propID_GradientLerp, 0);
s_matPropBlock_ShockLayer.SetVector(s_propID_MainTex_ST, _shockLayer.sharedMaterial.GetVector(s_propID_MainTex_ST) with { w = -Time.timeSinceLevelLoad });
_shockLayer.SetPropertyBlock(s_matPropBlock_ShockLayer);
}
}
else if (_sunController._collapseStarted)
{
float collapseProgress = _sunController.GetCollapseProgress();
if (_ambientLight != null) _ambientLight.intensity = _ambientLightOrigIntensity * (1f - collapseProgress);
if (_atmosphere != null)
{
s_matPropBlock_Atmosphere.SetFloat(s_propID_SunIntensity, 1f - collapseProgress);
foreach (var lod in _atmosphereLODs)
foreach (var renderer in lod.renderers)
renderer.SetPropertyBlock(s_matPropBlock_Atmosphere);
}
if (_atmosphereRenderer != null)
{
s_matPropBlock_Atmosphere.SetFloat(s_propID_SunIntensity, 1f - collapseProgress);
_atmosphereRenderer.SetPropertyBlock(s_matPropBlock_Atmosphere);
}
if (_fog != null) _fog.fogTint = Color.Lerp(_fogOrigTint, Color.black, collapseProgress);
if (_fogImpostor != null) _fogImpostor.material.SetColor(s_propID_Tint, Color.Lerp(_fogOrigTint, Color.black, collapseProgress));
}
else
{
if (_shockLayer != null) _shockLayer.enabled = false;
}
}
else
{
if (_shockLayer != null) _shockLayer.enabled = false;
}
}
}
}

View File

@ -1,4 +1,5 @@
using NewHorizons.Builder.Body;
using NewHorizons.Handlers;
using NewHorizons.Utility;
using System;
using System.Collections.Generic;
@ -19,6 +20,7 @@ namespace NewHorizons.Components.SizeControllers
public bool WillExplode { get; set; }
public MColor StartColour { get; set; }
public MColor EndColour { get; set; }
public MColor SupernovaColour { get; set; }
public Texture normalRamp;
public Texture collapseRamp;
@ -30,6 +32,8 @@ namespace NewHorizons.Components.SizeControllers
private HeatHazardVolume _heatVolume;
public DestructionVolume _destructionVolume;
public DestructionVolume _planetDestructionVolume;
public SimpleFluidVolume _destructionFluidVolume;
public SimpleFluidVolume _planetDestructionFluidVolume;
private SolarFlareEmitter _flareEmitter;
private MapMarker _mapMarker;
private OWRigidbody _rigidbody;
@ -39,7 +43,9 @@ namespace NewHorizons.Components.SizeControllers
private float _collapseTimer;
public float collapseTime = 10f; // seconds
public float supernovaTime = 45f; // seconds
public float supernovaScaleStart = 45f; // seconds
public float supernovaScaleEnd = 50f; // seconds
public float supernovaTime = 50f; // seconds
public float lifespan = 22f; // minutes
public float supernovaSize = 50000f;
@ -56,7 +62,10 @@ namespace NewHorizons.Components.SizeControllers
private StarEvolutionController _proxy;
public UnityEvent CollapseStart = new UnityEvent();
public UnityEvent CollapseStop = new UnityEvent();
public UnityEvent SupernovaStart = new UnityEvent();
public UnityEvent SupernovaStop = new UnityEvent();
private float maxScale;
private float minScale;
@ -122,7 +131,7 @@ namespace NewHorizons.Components.SizeControllers
}
_heatVolume = GetComponentInChildren<HeatHazardVolume>();
if (_destructionVolume != null) _destructionVolume = GetComponentInChildren<DestructionVolume>();
if (_destructionVolume == null) _destructionVolume = GetComponentInChildren<DestructionVolume>();
if (atmosphere != null)
{
@ -146,6 +155,8 @@ namespace NewHorizons.Components.SizeControllers
_flareEmitter = GetComponentInChildren<SolarFlareEmitter>();
_surfaceMaterial = supernova._surface._materials[0];
SupernovaEffectHandler.RegisterStar(this);
var secondsElapsed = TimeLoop.GetSecondsElapsed();
var lifespanInSeconds = lifespan * 60;
if (secondsElapsed >= lifespanInSeconds)
@ -162,6 +173,7 @@ namespace NewHorizons.Components.SizeControllers
public void OnDestroy()
{
SupernovaEffectHandler.UnregisterStar(this);
}
public void SetProxy(StarEvolutionController proxy)
@ -228,6 +240,12 @@ namespace NewHorizons.Components.SizeControllers
if (_planetDestructionVolume != null) _planetDestructionVolume.transform.localScale = Vector3.one * supernova.GetSupernovaRadius() * 0.9f;
if (_heatVolume != null) _heatVolume.transform.localScale = Vector3.one * supernova.GetSupernovaRadius();
var t = Mathf.Clamp01((Time.time - (_supernovaStartTime + supernovaScaleStart)) / (supernovaScaleEnd - supernovaScaleStart));
if (t > 0)
{
_planetDestructionVolume.GetComponent<SphereCollider>().radius = Mathf.Lerp(0.8f, 1, t);
}
if (Time.time > _supernovaStartTime + supernovaTime)
{
DisableStar();
@ -281,6 +299,7 @@ namespace NewHorizons.Components.SizeControllers
Logger.LogVerbose($"{gameObject.transform.root.name} started collapse");
CollapseStart.Invoke();
_isCollapsing = true;
_collapseStartSize = CurrentScale;
_collapseTimer = 0f;
@ -295,6 +314,7 @@ namespace NewHorizons.Components.SizeControllers
Logger.LogVerbose($"{gameObject.transform.root.name} stopped collapse");
CollapseStop.Invoke();
_isCollapsing = false;
supernova._surface._materials[0].CopyPropertiesFromMaterial(_endSurfaceMaterial);
@ -314,6 +334,8 @@ namespace NewHorizons.Components.SizeControllers
if (atmosphere != null) atmosphere.SetActive(false);
if (_destructionVolume != null) _destructionVolume._deathType = DeathType.Supernova;
if (_planetDestructionVolume != null) _planetDestructionVolume._deathType = DeathType.Supernova;
if (_destructionFluidVolume != null) _destructionFluidVolume.enabled = false;
if (_planetDestructionFluidVolume != null) _planetDestructionFluidVolume.enabled = false;
if (_proxy != null) _proxy.StartSupernova();
}
@ -324,6 +346,7 @@ namespace NewHorizons.Components.SizeControllers
Logger.LogVerbose($"{gameObject.transform.root.name} stopped supernova");
SupernovaStop.Invoke();
supernova.enabled = false;
_isSupernova = false;
if (atmosphere != null) atmosphere.SetActive(true);
@ -337,6 +360,8 @@ namespace NewHorizons.Components.SizeControllers
_planetDestructionVolume._deathType = DeathType.Energy;
_planetDestructionVolume.transform.localScale = Vector3.one;
}
if (_destructionFluidVolume != null) _destructionFluidVolume.enabled = true;
if (_planetDestructionFluidVolume != null) _planetDestructionFluidVolume.enabled = true;
if (_heatVolume != null) _heatVolume.transform.localScale = Vector3.one;
gameObject.SetActive(true);
transform.localScale = Vector3.one;
@ -346,6 +371,24 @@ namespace NewHorizons.Components.SizeControllers
if (_proxy != null) _proxy.StopSupernova();
}
public bool IsCollapsing() => _isCollapsing;
public float GetCollapseProgress() => _collapseTimer / collapseTime;
public bool HasSupernovaStarted() => _isSupernova;
public bool IsPointInsideSupernova(Vector3 worldPosition) => _isSupernova && (worldPosition - transform.position).sqrMagnitude < (supernova.GetSupernovaRadius() * supernova.GetSupernovaRadius());
public bool IsPointInsideMaxSupernova(Vector3 worldPosition) => (worldPosition - transform.position).sqrMagnitude < (supernovaSize * supernovaSize);
public float GetDistanceToSupernova(Vector3 worldPosition) => Vector3.Distance(worldPosition, transform.position) - supernova.GetSupernovaRadius();
public float GetDistanceToMaxSupernova(Vector3 worldPosition) => Vector3.Distance(worldPosition, transform.position) - supernovaSize;
public float GetSupernovaRadius() => supernova.GetSupernovaRadius();
public float GetMaxSupernovaRadius() => supernovaSize;
protected new void FixedUpdate()
{
// If we've gone supernova and its been 45 seconds that means it has faded out and is gone

View File

@ -1,4 +1,4 @@
using UnityEngine;
using UnityEngine;
namespace NewHorizons.Components
{
public class TimeLoopController : MonoBehaviour
@ -14,8 +14,7 @@ namespace NewHorizons.Components
public void Update()
{
// Stock gives like 33 seconds after the sun collapses
// Gonna assume it takes like 7 seconds to collapse after the supernova trigger
if (_supernovaHappened && Time.time > _supernovaTime + 40f)
if (_supernovaHappened && Time.time > _supernovaTime + 50f)
{
Locator.GetDeathManager().KillPlayer(DeathType.TimeLoop);
}

View File

@ -24,5 +24,9 @@ namespace NewHorizons.External.Configs
/// </summary>
public AchievementInfo[] achievements;
/// <summary>
/// Credits info for this mod. A list of contributors and their roles separated by #. For example: xen#New Horizons dev.
/// </summary>
public string[] credits;
}
}

View File

@ -165,9 +165,9 @@ namespace NewHorizons.External.Modules
public bool unlit;
/// <summary>
/// How fast the clouds will rotate in degrees per second.
/// How fast the clouds will rotate relative to the planet in degrees per second.
/// </summary>
[DefaultValue(10f)] public float rotationSpeed = 10f;
[DefaultValue(0f)] public float rotationSpeed = 0f;
#region Obsolete

View File

@ -56,6 +56,11 @@ namespace NewHorizons.External.Modules
/// </summary>
public bool hasMapMarker;
/// <summary>
/// Does this planet have a shock effect when the nearest star goes supernova?
/// </summary>
[DefaultValue(true)] public bool hasSupernovaShockEffect = true;
/// <summary>
/// Can this planet survive entering a star?
/// </summary>

View File

@ -0,0 +1,218 @@
using System.Collections.Generic;
using System.Xml;
using UnityEngine;
using Logger = NewHorizons.Utility.Logger;
namespace NewHorizons.Handlers
{
public static class CreditsHandler
{
private static Dictionary<string, string[]> _creditsInfo;
public static void RegisterCredits(string sectionName, string[] entries)
{
if (_creditsInfo == null) _creditsInfo = new();
Logger.LogVerbose($"Registering credits for {sectionName}");
_creditsInfo[sectionName] = entries;
}
public static void AddCredits(Credits credits)
{
Logger.LogVerbose($"Adding to credits");
var creditsAsset = credits._creditsAsset;
var xml = new XmlDocument();
xml.LoadXml(creditsAsset.xml.text);
foreach (var pair in _creditsInfo)
{
AddCreditsSection(pair.Key, pair.Value, ref xml);
}
var outerXml = xml.OuterXml.Replace("/n", "&#xD;&#xA;");
creditsAsset.xml = new TextAsset(outerXml);
}
private static void AddCreditsSection(string sectionName, string[] entries, ref XmlDocument xml)
{
var finalCredits = xml.SelectSingleNode("Credits/section");
/*
* Looks bad, would need more customization, complicated, messes up music timing, wont do for now
var nodeFade = CreateFadeCreditsFromList(xml, sectionName, entries);
finalCredits.InsertAfter(nodeFade, finalCredits.ChildNodes[0]);
*/
var fastCredits = NodeWhere(finalCredits.ChildNodes, "MainScrollSection");
var nodeScroll = CreateScrollCreditsFromList(xml, sectionName, entries);
fastCredits.InsertBefore(nodeScroll, fastCredits.ChildNodes[0]);
}
private static XmlNode NodeWhere(XmlNodeList list, string name)
{
foreach(XmlNode node in list)
{
try
{
if (node.Attributes[0].Value == name) return node;
}
catch { }
}
return null;
}
// Looked bad so not used
/*
private static XmlNode CreateFadeCreditsFromList(XmlDocument doc, string title, string[] entries)
{
var rootSection = MakeNode(doc, "section", new Dictionary<string, string>()
{
{ "platform", "All" },
{ "type", "Fade" },
{ "fadeInTime", "1.3" },
{ "displayTime", "10" },
{ "fadeOutTime", "1.4" },
{ "waitTime", "0.5" },
{ "padding-bottom", "-8" },
{ "spacing", "16" }
});
var titleLayout = MakeNode(doc, "layout", new Dictionary<string, string>()
{
{ "type", "SingleColumnFadeCentered" }
});
var titleNode = MakeNode(doc, "title", new Dictionary<string, string>()
{
{"text-align", "UpperCenter" },
{"height", "122" }
});
titleNode.InnerText = title;
titleLayout.AppendChild(titleNode);
var type = "SingleColumnFadeCentered";
var xmlText = $"<layout type=\"{type}\" spacer-base-height=\"10\">\n";
for (int i = 0; i < entries.Length; i++)
{
var entry = entries[i];
if (entry.Contains("#"))
{
// Replace first one with a space
entry = RemoveExcessSpaces(entry);
var indexOfColon = entry.IndexOf(":");
var firstPart = entry.Substring(0, Math.Min(entry.IndexOf("#"), indexOfColon == -1 ? int.MaxValue : indexOfColon));
entry = firstPart + ": " + entry.Substring(entry.IndexOf("#") + 1);
}
entry = entry.Replace("#", ", ").Replace("/n", "");
xmlText += $"{entry}\n";
xmlText += "<spacer />\n";
}
xmlText += "<spacer height = \"295\" />\n";
xmlText += "</layout>";
rootSection.AppendChild(titleLayout);
foreach (var node in StringToNodes(doc, xmlText)) rootSection.AppendChild(node);
return rootSection;
}
private static string RemoveExcessSpaces(string s)
{
var options = RegexOptions.None;
Regex regex = new Regex("[ ]{2,}", options);
return regex.Replace(s, " ");
}
*/
private static XmlNode CreateScrollCreditsFromList(XmlDocument doc, string title, string[] entries)
{
var rootSection = MakeNode(doc, "section", new Dictionary<string, string>()
{
{ "platform", "All" },
{ "type", "Scroll" },
{ "scrollDuration", "214" },
{ "spacing", "12" },
{ "width", "1590" }
});
var titleLayout = MakeNode(doc, "layout", new Dictionary<string, string>()
{
{ "type", "SingleColumnScrollCentered" }
});
var titleNode = MakeNode(doc, "title", new Dictionary<string, string>()
{
{"text-align", "UpperCenter" },
{"height", "122" }
});
titleNode.InnerText = title;
titleLayout.AppendChild(titleNode);
var xmlText = "";
bool? flag = null;
for (int i = 0; i < entries.Length; i++)
{
var entry = entries[i];
var twoColumn = entry.Contains("#");
if (flag != twoColumn)
{
if (i != 0) xmlText += "</layout>";
var type = twoColumn ? "TwoColumnScrollAlignRightLeft" : "SingleColumnScrollCentered";
xmlText += $"<layout type=\"{type}\" spacer-base-height=\"10\">\n";
flag = twoColumn;
}
xmlText += $"{entry}\n";
xmlText += "<spacer/>";
}
xmlText += "<spacer height = \"295\" />\n";
xmlText += "</layout>";
rootSection.AppendChild(titleLayout);
foreach(var node in StringToNodes(doc, xmlText)) rootSection.AppendChild(node);
return rootSection;
}
private static XmlNode[] StringToNodes(XmlDocument docContext, string text)
{
var doc = new XmlDocument();
// Doing this funny thing so that theres a single parent root thing
doc.LoadXml("<root>" + text + "</root>");
// ArgumentException: The node to be inserted is from a different document context.
var nodes = new List<XmlNode>();
foreach (XmlNode node in doc.DocumentElement.ChildNodes)
{
nodes.Add(docContext.ImportNode(node, true));
}
return nodes.ToArray();
}
private static XmlNode MakeNode(XmlDocument doc, string nodeType, Dictionary<string, string> attributes)
{
var xmlNode = doc.CreateElement(nodeType);
if (attributes != null)
{
foreach (var pair in attributes)
{
var attribute = doc.CreateAttribute(pair.Key);
attribute.Value = pair.Value;
xmlNode.Attributes.Append(attribute);
}
}
return xmlNode;
}
}
}

View File

@ -37,6 +37,7 @@ namespace NewHorizons.Handlers
// Set up stars
// Need to manage this when there are multiple stars
var sun = SearchUtilities.Find("Sun_Body");
SupernovaEffectHandler.RegisterSun(sun.GetComponent<SunController>());
var starController = sun.AddComponent<StarController>();
starController.Light = SearchUtilities.Find("Sun_Body/Sector_SUN/Effects_SUN/SunLight").GetComponent<Light>();
starController.AmbientLight = SearchUtilities.Find("Sun_Body/AmbientLight_SUN").GetComponent<Light>();
@ -448,10 +449,7 @@ namespace NewHorizons.Handlers
Delay.FireOnNextUpdate(() => OrbitlineBuilder.Make(body.Object, ao as NHAstroObject, body.Config.Orbit.isMoon, body.Config));
}
if (!body.Config.Orbit.isStatic)
{
DetectorBuilder.Make(go, owRigidBody, primaryBody, ao, body.Config);
}
DetectorBuilder.Make(go, owRigidBody, primaryBody, ao, body.Config);
AstroObjectLocator.RegisterCustomAstroObject(ao);
@ -482,9 +480,10 @@ namespace NewHorizons.Handlers
{
var sphereOfInfluence = GetSphereOfInfluence(body);
Light ambientLight = null;
if (body.Config.Base.ambientLight != 0)
{
AmbientLightBuilder.Make(go, sector, sphereOfInfluence, body.Config.Base.ambientLight);
ambientLight = AmbientLightBuilder.Make(go, sector, sphereOfInfluence, body.Config.Base.ambientLight);
}
if (body.Config.Base.groundSize != 0)
@ -500,9 +499,10 @@ namespace NewHorizons.Handlers
HeightMapBuilder.Make(go, sector, body.Config.HeightMap, body.Mod, res, true);
}
GameObject procGen = null;
if (body.Config.ProcGen != null)
{
ProcGenBuilder.Make(go, sector, body.Config.ProcGen);
procGen = ProcGenBuilder.Make(go, sector, body.Config.ProcGen);
}
if (body.Config.Star != null)
@ -554,7 +554,8 @@ namespace NewHorizons.Handlers
}
var willHaveCloak = body.Config.Cloak != null && body.Config.Cloak.radius != 0f;
PlanetaryFogController fog = null;
LODGroup atmosphere = null;
if (body.Config.Atmosphere != null)
{
var surfaceSize = body.Config.Base.surfaceSize;
@ -571,9 +572,11 @@ namespace NewHorizons.Handlers
EffectsBuilder.Make(go, sector, body.Config, surfaceSize);
if (body.Config.Atmosphere.fogSize != 0)
FogBuilder.Make(go, sector, body.Config.Atmosphere);
{
fog = FogBuilder.Make(go, sector, body.Config.Atmosphere);
}
AtmosphereBuilder.Make(go, sector, body.Config.Atmosphere, surfaceSize);
atmosphere = AtmosphereBuilder.Make(go, sector, body.Config.Atmosphere, surfaceSize).GetComponentInChildren<LODGroup>();
}
if (body.Config.Props != null)
@ -592,6 +595,11 @@ namespace NewHorizons.Handlers
CloakBuilder.Make(go, sector, rb, body.Config.Cloak, !body.Config.ReferenceFrame.hideInMap, body.Mod);
}
if (body.Config.Base.hasSupernovaShockEffect && body.Config.Star == null && body.Config.name != "Sun" && body.Config.FocalPoint == null)
{
SupernovaEffectBuilder.Make(go, sector, body.Config, procGen, ambientLight, fog, atmosphere, null, fog?._fogImpostor);
}
return go;
}

View File

@ -0,0 +1,90 @@
using NewHorizons.Components;
using NewHorizons.Components.SizeControllers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NewHorizons.Handlers
{
public class SupernovaEffectHandler
{
private static List<NHSupernovaPlanetEffectController> _supernovaPlanetEffectControllers = new List<NHSupernovaPlanetEffectController>();
private static List<StarEvolutionController> _starEvolutionControllers = new List<StarEvolutionController>();
private static SunController _sunController;
public static void RegisterStar(StarEvolutionController starEvolutionController)
{
_starEvolutionControllers.SafeAdd(starEvolutionController);
}
public static void UnregisterStar(StarEvolutionController starEvolutionController)
{
_starEvolutionControllers.Remove(starEvolutionController);
}
public static void RegisterSun(SunController sunController)
{
_sunController = sunController;
}
public static void UnregisterSun()
{
_sunController = null;
}
public static void RegisterPlanetEffect(NHSupernovaPlanetEffectController supernovaPlanetEffectController)
{
_supernovaPlanetEffectControllers.SafeAdd(supernovaPlanetEffectController);
}
public static void UnregisterPlanetEffect(NHSupernovaPlanetEffectController supernovaPlanetEffectController)
{
_supernovaPlanetEffectControllers.Remove(supernovaPlanetEffectController);
}
public static void GetNearestStarSupernova(NHSupernovaPlanetEffectController supernovaPlanetEffectController)
{
if (supernovaPlanetEffectController == null) return;
StarEvolutionController nearestStarEvolutionController = null;
float nearestDistance = float.MaxValue;
foreach (StarEvolutionController starEvolutionController in _starEvolutionControllers)
{
if (starEvolutionController == null) continue;
if (!(starEvolutionController.gameObject.activeSelf && starEvolutionController.gameObject.activeInHierarchy)) continue;
float distance = (supernovaPlanetEffectController.transform.position - starEvolutionController.transform.position).sqrMagnitude;
if (distance < (starEvolutionController.supernovaSize * starEvolutionController.supernovaSize) && distance < nearestDistance)
{
nearestDistance = distance;
nearestStarEvolutionController = starEvolutionController;
}
}
if (_sunController != null && _sunController.gameObject.activeSelf)
{
float distance = (supernovaPlanetEffectController.transform.position - _sunController.transform.position).sqrMagnitude;
if (distance < 2500000000f && distance < nearestDistance)
{
supernovaPlanetEffectController._sunController = _sunController;
supernovaPlanetEffectController._starEvolutionController = null;
}
else
{
supernovaPlanetEffectController._sunController = null;
supernovaPlanetEffectController._starEvolutionController = nearestStarEvolutionController;
}
}
else
{
supernovaPlanetEffectController._sunController = null;
supernovaPlanetEffectController._starEvolutionController = nearestStarEvolutionController;
}
}
public static SunController GetSunController() => _sunController;
public static bool InPointInsideSunSupernova(NHSupernovaPlanetEffectController supernovaPlanetEffectController) => _sunController != null && (supernovaPlanetEffectController.transform.position - _sunController.transform.position).sqrMagnitude < 2500000000f;//(50000f*50000f);
}
}

View File

@ -201,6 +201,8 @@ namespace NewHorizons
AchievementHandler.Init();
VoiceHandler.Init();
LoadAddonManifest("Assets/addon-manifest.json", this);
}
public void OnDestroy()
@ -377,6 +379,14 @@ namespace NewHorizons
AtmosphereBuilder.Init();
BrambleNodeBuilder.Init(BodyDict[CurrentStarSystem].Select(x => x.Config).Where(x => x.Bramble?.dimension != null).ToArray());
if (isSolarSystem)
{
foreach (var supernovaPlanetEffectController in GameObject.FindObjectsOfType<SupernovaPlanetEffectController>())
{
SupernovaEffectBuilder.ReplaceVanillaWithNH(supernovaPlanetEffectController);
}
}
PlanetCreationHandler.Init(BodyDict[CurrentStarSystem]);
VesselWarpHandler.LoadVessel();
SystemCreationHandler.LoadSystem(SystemDict[CurrentStarSystem]);
@ -384,6 +394,7 @@ namespace NewHorizons
LoadTranslations(ModHelper.Manifest.ModFolderPath + "Assets/", this);
StarChartHandler.Init(SystemDict.Values.ToArray());
if (isSolarSystem)
{
// Warp drive
@ -483,6 +494,16 @@ namespace NewHorizons
ssrLight.range = Main.FurthestOrbit * (4f/3f);
ssrLight.intensity = 0.001f;
var fluid = playerBody.FindChild("PlayerDetector").GetComponent<DynamicFluidDetector>();
fluid._splashEffects = fluid._splashEffects.AddToArray(new SplashEffect
{
fluidType = FluidVolume.Type.PLASMA,
ignoreSphereAligment = false,
minImpactSpeed = 15,
splashPrefab = SearchUtilities.Find("Probe_Body/ProbeDetector").GetComponent<FluidDetector>()._splashEffects.FirstOrDefault(sfx => sfx.fluidType == FluidVolume.Type.PLASMA).splashPrefab,
triggerEvent = SplashEffect.TriggerEvent.OnEntry
});
try
{
Logger.Log($"Star system finished loading [{Instance.CurrentStarSystem}]");
@ -601,9 +622,7 @@ namespace NewHorizons
// Has to go before translations for achievements
if (File.Exists(folder + "addon-manifest.json"))
{
var addonConfig = mod.ModHelper.Storage.Load<AddonConfig>("addon-manifest.json");
AchievementHandler.RegisterAddon(addonConfig, mod as ModBehaviour);
LoadAddonManifest("addon-manifest.json", mod);
}
if (Directory.Exists(folder + @"translations\"))
{
@ -617,6 +636,16 @@ namespace NewHorizons
}
}
private void LoadAddonManifest(string file, IModBehaviour mod)
{
Logger.LogVerbose($"Loading addon manifest for {mod.ModHelper.Manifest.Name}");
var addonConfig = mod.ModHelper.Storage.Load<AddonConfig>(file);
if (addonConfig.achievements != null) AchievementHandler.RegisterAddon(addonConfig, mod as ModBehaviour);
if (addonConfig.credits != null) CreditsHandler.RegisterCredits(mod.ModHelper.Manifest.Name, addonConfig.credits);
}
private void LoadTranslations(string folder, IModBehaviour mod)
{
var foundFile = false;

View File

@ -0,0 +1,33 @@
using HarmonyLib;
using NewHorizons.Utility;
using System;
namespace NewHorizons.Patches.CreditsScene
{
[HarmonyPatch]
public static class CreditsEntryPatches
{
[HarmonyPrefix]
[HarmonyPatch(typeof(CreditsEntry), nameof(CreditsEntry.SetContents))]
public static bool CreditsEntry_SetContents(CreditsEntry __instance, string[] __0)
{
var columnTexts = __0;
for (int i = 0; i < __instance._columns.Length; i++)
{
// Base method throws out of bounds exception sometimes (_columns length doesn't match columnTexts length)
// Trim also NREs sometimes because of the TrimHelper class Mobius has idk
try
{
__instance._columns[i].text = columnTexts[i].Trim();
}
catch
{
// Error occurs when column 2 is empty
__instance._columns[i].text = " ";
}
}
return false;
}
}
}

View File

@ -0,0 +1,17 @@
using HarmonyLib;
using NewHorizons.Handlers;
namespace NewHorizons.Patches.CreditsScene
{
[HarmonyPatch]
public static class CreditsPatches
{
[HarmonyPrefix]
[HarmonyPatch(typeof(Credits), nameof(Credits.Start))]
public static void Credits_Start(Credits __instance)
{
CreditsHandler.AddCredits(__instance);
}
}
}

View File

@ -1,12 +1,16 @@
using HarmonyLib;
using NewHorizons.Components;
namespace NewHorizons.Patches
{
[HarmonyPatch]
public static class LocatorPatches
{
public static AstroObject _attlerock;
public static AstroObject _eye;
public static AstroObject _focal;
public static AstroObject _hollowsLantern;
public static AstroObject _mapSatellite;
public static AstroObject _sunStation;
[HarmonyPrefix]
[HarmonyPatch(typeof(Locator), nameof(Locator.RegisterCloakFieldController))]
@ -36,14 +40,34 @@ namespace NewHorizons.Patches
__result = __result || Components.CloakSectorController.isShipInside;
}
// Locator Fixes
// Vanilla doesn't register these AstroObjects for some reason. So here is a fix.
[HarmonyPrefix]
[HarmonyPatch(typeof(Locator), nameof(Locator.GetAstroObject))]
public static bool Locator_GetAstroObject(AstroObject.Name astroObjectName, ref AstroObject __result)
{
if (astroObjectName == AstroObject.Name.Eye && _eye != null)
switch (astroObjectName)
{
__result = _eye;
return false;
case AstroObject.Name.Eye:
__result = _eye;
return false;
case AstroObject.Name.HourglassTwins:
__result = _focal;
return false;
case AstroObject.Name.MapSatellite:
__result = _mapSatellite;
return false;
case AstroObject.Name.SunStation:
__result = _sunStation;
return false;
case AstroObject.Name.TimberMoon:
__result = _attlerock;
return false;
case AstroObject.Name.VolcanicMoon:
__result = _hollowsLantern;
return false;
default:
break;
}
return true;
}
@ -52,10 +76,44 @@ namespace NewHorizons.Patches
[HarmonyPatch(typeof(Locator), nameof(Locator.RegisterAstroObject))]
public static bool Locator_RegisterAstroObject(AstroObject astroObject)
{
if (astroObject._name == AstroObject.Name.Eye)
if (astroObject.GetAstroObjectName() == AstroObject.Name.None) return false;
// Sun Station name change because for some dumb reason it doesn't use AstroObject.Name.SunStation
if (!string.IsNullOrEmpty(astroObject._customName) && astroObject._customName.Equals("Sun Station"))
{
_eye = astroObject;
return false;
if (astroObject.gameObject.name == "SunStation_Body")
{
astroObject._name = AstroObject.Name.SunStation;
_sunStation = astroObject;
return false;
}
// Debris uses same custom name because morbius, so let us change that.
else if (astroObject.gameObject.name == "SS_Debris_Body") astroObject._customName = "Sun Station Debris";
return true;
}
switch (astroObject.GetAstroObjectName())
{
case AstroObject.Name.Eye:
_eye = astroObject;
return false;
case AstroObject.Name.HourglassTwins:
_focal = astroObject;
return false;
case AstroObject.Name.MapSatellite:
_mapSatellite = astroObject;
return false;
case AstroObject.Name.SunStation:
_sunStation = astroObject;
return false;
case AstroObject.Name.TimberMoon:
_attlerock = astroObject;
return false;
case AstroObject.Name.VolcanicMoon:
_hollowsLantern = astroObject;
return false;
default:
break;
}
return true;
}
@ -64,7 +122,12 @@ namespace NewHorizons.Patches
[HarmonyPatch(typeof(Locator), nameof(Locator.ClearReferences))]
public static void Locator_ClearReferences()
{
_attlerock = null;
_eye = null;
_focal = null;
_hollowsLantern = null;
_mapSatellite = null;
_sunStation = null;
}
}
}

View File

@ -1,4 +1,9 @@
using HarmonyLib;
using NewHorizons.Utility;
using System;
using System.Runtime.CompilerServices;
using UnityEngine;
namespace NewHorizons.Patches
{
[HarmonyPatch]
@ -53,5 +58,72 @@ namespace NewHorizons.Patches
GlobalMessenger.RemoveListener("EnterMapView", __instance.OnEnterMapView);
GlobalMessenger.RemoveListener("ExitMapView", __instance.OnExitMapView);
}
[HarmonyReversePatch]
[HarmonyPatch(typeof(ProxyPlanet), nameof(ProxyPlanet.Initialize))]
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ProxyPlanet_Initialize(ProxyPlanet instance) { }
[HarmonyPrefix]
[HarmonyPatch(typeof(ProxyBrittleHollow), nameof(ProxyBrittleHollow.Initialize))]
public static bool ProxyBrittleHollow_Initialize(ProxyBrittleHollow __instance)
{
try
{
ProxyPlanet_Initialize(__instance);
__instance._moon.SetOriginalBodies(Locator.GetAstroObject(AstroObject.Name.VolcanicMoon).transform, Locator.GetAstroObject(AstroObject.Name.BrittleHollow).transform);
if (!__instance._fragmentsResolved) __instance.ResolveFragments();
__instance._blackHoleMaterial = new Material(__instance._blackHoleRenderer.sharedMaterial);
__instance._blackHoleRenderer.sharedMaterial = __instance._blackHoleMaterial;
}
catch (NullReferenceException ex)
{
__instance.PrintInitializeFailMessage(ex);
UnityEngine.Object.Destroy(__instance._moon.gameObject);
UnityEngine.Object.Destroy(__instance.gameObject);
}
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ProxyTimberHearth), nameof(ProxyTimberHearth.Initialize))]
public static bool ProxyTimberHearth_Initialize(ProxyTimberHearth __instance)
{
try
{
ProxyPlanet_Initialize(__instance);
__instance._moon.SetOriginalBodies(Locator.GetAstroObject(AstroObject.Name.TimberMoon).transform, Locator.GetAstroObject(AstroObject.Name.TimberHearth).transform);
}
catch (NullReferenceException ex)
{
__instance.PrintInitializeFailMessage(ex);
UnityEngine.Object.Destroy(__instance._moon.gameObject);
UnityEngine.Object.Destroy(__instance.gameObject);
}
return false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ProxyAshTwin), nameof(ProxyAshTwin.Initialize))]
public static bool ProxyAshTwin_Initialize(ProxyAshTwin __instance)
{
try
{
ProxyPlanet_Initialize(__instance);
__instance._realSandTransform = Locator.GetAstroObject(AstroObject.Name.TowerTwin).GetSandLevelController().transform;
SandFunnelController sandFunnelController = SearchUtilities.Find("SandFunnel_Body", false)?.GetComponent<SandFunnelController>();
if (sandFunnelController != null)
{
__instance._realSandColumnRoot = sandFunnelController.scaleRoot;
__instance._realSandColumnRenderObject = sandFunnelController.sandGeoObjects[0];
}
}
catch (NullReferenceException ex)
{
__instance.PrintInitializeFailMessage(ex);
UnityEngine.Object.Destroy(__instance.gameObject);
}
return false;
}
}
}

View File

@ -71,6 +71,10 @@ namespace NewHorizons.Patches
base_DropItem(__instance, position, normal, parent, sector, customDropTarget);
}
if (__instance._wasProjecting) __instance._mindProjectorTrigger.SetProjectorActive(false);
__instance.gameObject.GetComponent<Collider>().enabled = true;
return true;
}
}

View File

@ -12,6 +12,13 @@
"$ref": "#/definitions/AchievementInfo"
}
},
"credits": {
"type": "array",
"description": "Credits info for this mod. A list of contributors and their roles separated by #. For example: xen#New Horizons dev.",
"items": {
"type": "string"
}
},
"$schema": {
"type": "string",
"description": "The schema to validate with"

View File

@ -364,9 +364,9 @@
},
"rotationSpeed": {
"type": "number",
"description": "How fast the clouds will rotate in degrees per second.",
"description": "How fast the clouds will rotate relative to the planet in degrees per second.",
"format": "float",
"default": 10.0
"default": 0.0
}
}
},
@ -450,6 +450,11 @@
"type": "boolean",
"description": "If the body should have a marker on the map screen."
},
"hasSupernovaShockEffect": {
"type": "boolean",
"description": "Does this planet have a shock effect when the nearest star goes supernova?",
"default": true
},
"invulnerableToSun": {
"type": "boolean",
"description": "Can this planet survive entering a star?"

View File

@ -90,6 +90,16 @@ namespace NewHorizons.Utility
return _customAstroObjectDictionary.Values.Where(x => x._primaryBody == primary).Select(x => x.gameObject).ToArray();
}
public static AstroObject[] GetAncestors(AstroObject astroObject)
{
List<AstroObject> ancestors = new List<AstroObject>();
for (AstroObject primaryBody = astroObject._primaryBody; primaryBody != null && !ancestors.Contains(primaryBody); primaryBody = primaryBody._primaryBody)
{
ancestors.Add(primaryBody);
}
return ancestors.ToArray();
}
public static GameObject[] GetChildren(AstroObject primary)
{
if (primary == null) return new GameObject[0];
@ -143,7 +153,13 @@ namespace NewHorizons.Utility
otherChildren.Add(SearchUtilities.Find("DB_SmallNest_Body"));
otherChildren.Add(SearchUtilities.Find("DB_Elsinore_Body"));
break;
// For some dumb reason the sun station doesn't use AstroObject.Name.SunStation
case AstroObject.Name.SunStation:
// there are multiple debris with the same name
otherChildren.AddRange(Object.FindObjectsOfType<AstroObject>()
.Select(x => x.gameObject)
.Where(x => x.name == "SS_Debris_Body"));
break;
// Just in case GetChildren runs before sun station's name is changed
case AstroObject.Name.CustomString:
if (primary._customName.Equals("Sun Station"))
{

View File

@ -1,4 +1,4 @@
using System.ComponentModel;
using System.ComponentModel;
using Newtonsoft.Json;
using UnityEngine;
namespace NewHorizons.Utility
@ -6,7 +6,7 @@ namespace NewHorizons.Utility
[JsonObject]
public class MColor
{
public MColor(int r, int g, int b, int a)
public MColor(int r, int g, int b, int a = 255)
{
this.r = r;
this.g = g;
@ -37,8 +37,30 @@ namespace NewHorizons.Utility
/// </summary>
[System.ComponentModel.DataAnnotations.Range(0, 255)]
[DefaultValue(255)]
public int a;
public int a = 255;
public Color ToColor() => new Color(r / 255f, g / 255f, b / 255f, a / 255f);
public static MColor red => new MColor(255, 0, 0);
public static MColor green => new MColor(0, 255, 0);
public static MColor blue => new MColor(0, 0, 255);
public static MColor white => new MColor(255, 255, 255);
public static MColor black => new MColor(0, 0, 0);
public static MColor yellow => new MColor(255, 235, 4);
public static MColor cyan => new MColor(0, 255, 255);
public static MColor magenta => new MColor(255, 0, 255);
public static MColor gray => new MColor(127, 127, 127);
public static MColor grey => new MColor(127, 127, 127);
public static MColor clear => new MColor(0, 0, 0, 0);
}
}