Supernova Planet Effect, Proxy Atmosphere, Proxy Fog, Proxy Lightning, and etc. (#267)

Yay
This commit is contained in:
Nick 2022-08-18 00:17:03 -04:00 committed by GitHub
commit 0c7c54992a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 1033 additions and 78 deletions

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,36 +26,73 @@ namespace NewHorizons.Builder.Atmosphere
if (atmosphereModule.useAtmosphereShader)
{
GameObject atmo = GameObject.Instantiate(SearchUtilities.Find("TimberHearth_Body/Atmosphere_TH/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)
if (proxy)
{
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());
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;
atmo.SetActive(true);
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());
if (atmosphereModule.atmosphereSunIntensity == 0)
{
// do it based on distance
Skys.Add((planetGO, material));
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);
}
}
}
else
{
// use the override instead
material.SetFloat(SunIntensity, atmosphereModule.atmosphereSunIntensity);
GameObject atmo = GameObject.Instantiate(SearchUtilities.Find("TimberHearth_Body/Atmosphere_TH/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;

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");
@ -58,6 +58,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";
@ -15,6 +15,8 @@ namespace NewHorizons.Builder.Body
groundGO.GetComponent<MeshFilter>().mesh = SearchUtilities.Find("CloudsTopLayer_GD").GetComponent<MeshFilter>().mesh;
groundGO.GetComponent<SphereCollider>().radius = 1f;
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,7 +4,7 @@ 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)
{
GameObject lightGO = GameObject.Instantiate(SearchUtilities.Find("QuantumMoon_Body/AmbientLight_QM"), sector?.transform ?? planetGO.transform);
lightGO.transform.position = planetGO.transform.position;
@ -20,12 +20,14 @@ namespace NewHorizons.Builder.General
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,7 +35,58 @@ 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();
}
if (!config.Orbit.isStatic) SetDetector(primaryBody, astroObject, forceDetector);
@ -113,4 +166,4 @@ namespace NewHorizons.Builder.General
secondaryCFD._inheritElement0 = false;
}
}
}
}

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

@ -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

@ -31,11 +31,12 @@ namespace NewHorizons.Handlers
_existingBodyDict = new();
_customBodyDict = new();
// Set up stars
// Need to manage this when there are multiple stars
var sun = SearchUtilities.Find("Sun_Body");
var starController = sun.AddComponent<StarController>();
SupernovaEffectHandler.RegisterSun(sun.GetComponent<SunController>());
starController.Light = SearchUtilities.Find("Sun_Body/Sector_SUN/Effects_SUN/SunLight").GetComponent<Light>();
starController.AmbientLight = SearchUtilities.Find("Sun_Body/AmbientLight_SUN").GetComponent<Light>();
starController.FaceActiveCamera = SearchUtilities.Find("Sun_Body/Sector_SUN/Effects_SUN/SunLight").GetComponent<FaceActiveCamera>();
@ -464,9 +465,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)
@ -482,9 +484,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)
@ -536,7 +539,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;
@ -553,9 +557,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)
@ -574,6 +580,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

@ -304,6 +304,11 @@ namespace NewHorizons
if (isSolarSystem)
{
foreach (var supernovaPlanetEffectController in GameObject.FindObjectsOfType<SupernovaPlanetEffectController>())
{
SupernovaEffectBuilder.ReplaceVanillaWithNH(supernovaPlanetEffectController);
}
PlanetCreationHandler.Init(BodyDict[CurrentStarSystem]);
VesselWarpHandler.LoadVessel();
@ -313,6 +318,7 @@ namespace NewHorizons
LoadTranslations(ModHelper.Manifest.ModFolderPath + "Assets/", this);
StarChartHandler.Init(SystemDict.Values.ToArray());
if (isSolarSystem)
{
// Warp drive
@ -398,7 +404,17 @@ namespace NewHorizons
ssrLight.spotAngle = 179;
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}]");

View File

@ -1,9 +1,18 @@
using HarmonyLib;
using NewHorizons.Utility;
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))]
public static bool Locator_RegisterCloakFieldController()
@ -31,5 +40,96 @@ 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)
{
switch (astroObjectName)
{
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;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Locator), nameof(Locator.RegisterAstroObject))]
public static bool Locator_RegisterAstroObject(AstroObject astroObject)
{
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"))
{
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;
}
[HarmonyPostfix]
[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 HarmonyLib;
using NewHorizons.Utility;
using System;
using System.Runtime.CompilerServices;
using UnityEngine;
namespace NewHorizons.Patches
{
[HarmonyPatch]
@ -46,5 +51,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

@ -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

@ -89,6 +89,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];
@ -142,7 +152,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);
}
}