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(); 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"); GameObject atmoGO = new GameObject("Atmosphere");
atmoGO.SetActive(false); atmoGO.SetActive(false);
@ -26,19 +26,19 @@ namespace NewHorizons.Builder.Atmosphere
if (atmosphereModule.useAtmosphereShader) if (atmosphereModule.useAtmosphereShader)
{ {
var atmoSphere = SearchUtilities.Find("TimberHearth_Body/Atmosphere_TH/AtmoSphere"); if (proxy)
if (atmoSphere != null)
{ {
GameObject atmo = GameObject.Instantiate(atmoSphere, atmoGO.transform, true); 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.position = planetGO.transform.TransformPoint(Vector3.zero);
atmo.transform.localScale = Vector3.one * atmosphereModule.size * 1.2f; atmo.transform.localScale = Vector3.one * atmosphereModule.size * 1.2f * 2f;
var renderers = atmo.GetComponentsInChildren<MeshRenderer>(); var renderer = atmo.GetComponent<MeshRenderer>();
var material = renderers[0].material; // makes a new material var material = renderer.material; // makes a new material
foreach (var renderer in renderers)
{
renderer.sharedMaterial = material; renderer.sharedMaterial = material;
}
material.SetFloat(InnerRadius, atmosphereModule.clouds != null ? atmosphereModule.size : surfaceSize); material.SetFloat(InnerRadius, atmosphereModule.clouds != null ? atmosphereModule.size : surfaceSize);
material.SetFloat(OuterRadius, atmosphereModule.size * 1.2f); material.SetFloat(OuterRadius, atmosphereModule.size * 1.2f);
if (atmosphereModule.atmosphereTint != null) material.SetColor(SkyColor, atmosphereModule.atmosphereTint.ToColor()); if (atmosphereModule.atmosphereTint != null) material.SetColor(SkyColor, atmosphereModule.atmosphereTint.ToColor());
@ -57,9 +57,45 @@ namespace NewHorizons.Builder.Atmosphere
} }
} }
} }
else
{
var atmoSphere = SearchUtilities.Find("TimberHearth_Body/Atmosphere_TH/AtmoSphere");
if (atmoSphere != null)
{
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.transform.position = planetGO.transform.TransformPoint(Vector3.zero);
atmoGO.SetActive(true); atmoGO.SetActive(true);
return atmoGO;
} }
} }
} }

View File

@ -109,26 +109,7 @@ namespace NewHorizons.Builder.Atmosphere
// Lightning // Lightning
if (atmo.clouds.hasLightning) if (atmo.clouds.hasLightning)
{ {
var lightning = _lightningPrefab.InstantiateInactive(); MakeLightning(cloudsMainGO, sector, atmo);
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);
} }
cloudsMainGO.transform.position = planetGO.transform.TransformPoint(Vector3.zero); cloudsMainGO.transform.position = planetGO.transform.TransformPoint(Vector3.zero);
@ -140,6 +121,37 @@ namespace NewHorizons.Builder.Atmosphere
cloudsMainGO.SetActive(true); 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) public static GameObject MakeTopClouds(GameObject rootObject, AtmosphereModule atmo, IModBehaviour mod)
{ {
Color cloudTint = atmo.clouds.tint?.ToColor() ?? UnityEngine.Color.white; Color cloudTint = atmo.clouds.tint?.ToColor() ?? UnityEngine.Color.white;
@ -210,11 +222,14 @@ namespace NewHorizons.Builder.Atmosphere
cloudsTopGO.layer = LayerMask.NameToLayer("IgnoreSun"); cloudsTopGO.layer = LayerMask.NameToLayer("IgnoreSun");
} }
if (atmo.clouds.rotationSpeed != 0f)
{
RotateTransform topRT = cloudsTopGO.AddComponent<RotateTransform>(); RotateTransform topRT = cloudsTopGO.AddComponent<RotateTransform>();
// Idk why but the axis is weird // Idk why but the axis is weird
topRT._localAxis = atmo.clouds.cloudsPrefab == CloudPrefabType.Basic ? Vector3.forward : Vector3.up; topRT._localAxis = atmo.clouds.cloudsPrefab == CloudPrefabType.Basic ? Vector3.forward : Vector3.up;
topRT._degreesPerSecond = atmo.clouds.rotationSpeed; topRT._degreesPerSecond = atmo.clouds.rotationSpeed;
topRT._randomizeRotationRate = false; topRT._randomizeRotationRate = false;
}
cloudsTopGO.transform.localPosition = Vector3.zero; cloudsTopGO.transform.localPosition = Vector3.zero;

View File

@ -23,6 +23,7 @@ namespace NewHorizons.Builder.Atmosphere
if (config.Atmosphere.hasRain) if (config.Atmosphere.hasRain)
{ {
var rainGO = GameObject.Instantiate(SearchUtilities.Find("GiantsDeep_Body/Sector_GD/Sector_GDInterior/Effects_GDInterior/Effects_GD_Rain"), effectsGO.transform); 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; rainGO.transform.position = planetGO.transform.position;
var pvc = rainGO.GetComponent<PlanetaryVectionController>(); 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 DensityExponent = Shader.PropertyToID("_DensityExp");
private static readonly int ColorRampTexture = Shader.PropertyToID("_ColorRampTex"); 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"); 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 // Going to copy from dark bramble
var dbFog = SearchUtilities.Find("DarkBramble_Body/Atmosphere_DB/FogLOD"); 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>(); 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>(); MeshFilter MF = fogGO.AddComponent<MeshFilter>();
MF.mesh = dbFog.GetComponent<MeshFilter>().mesh; MF.mesh = dbFog.GetComponent<MeshFilter>().mesh;
@ -60,6 +60,41 @@ namespace NewHorizons.Builder.Atmosphere
fogGO.transform.position = planetGO.transform.position; fogGO.transform.position = planetGO.transform.position;
fogGO.SetActive(true); 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() config.ProcGen = new ProcGenModule()
{ {
scale = size, scale = size,
color = new MColor(126, 94, 73, 255) color = new MColor(126, 94, 73)
}; };
} }
else else

View File

@ -4,7 +4,7 @@ namespace NewHorizons.Builder.Body
{ {
public static class GeometryBuilder 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); GameObject groundGO = GameObject.CreatePrimitive(PrimitiveType.Sphere);
groundGO.transform.name = "GroundSphere"; groundGO.transform.name = "GroundSphere";
@ -23,6 +23,8 @@ namespace NewHorizons.Builder.Body
groundGO.transform.localScale *= 2; groundGO.transform.localScale *= 2;
} }
groundGO.SetActive(true); groundGO.SetActive(true);
return groundGO;
} }
} }
} }

View File

@ -14,7 +14,7 @@ namespace NewHorizons.Builder.Body
{ {
public static Shader PlanetShader; 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; var deleteHeightmapFlag = false;
@ -60,7 +60,7 @@ namespace NewHorizons.Builder.Body
catch (Exception e) catch (Exception e)
{ {
Logger.LogError($"Couldn't load HeightMap textures:\n{e}"); Logger.LogError($"Couldn't load HeightMap textures:\n{e}");
return; return null;
} }
GameObject cubeSphere = new GameObject("CubeSphere"); 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 // Now that we've made the mesh we can delete the heightmap texture
if (deleteHeightmapFlag) ImageUtilities.DeleteTexture(mod, module.heightMap, heightMap); 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) 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); sectorProxy.SetSector(sector);
var destructionVolume = GameObject.Instantiate(SearchUtilities.Find("VolcanicMoon_Body/MoltenCore_VM/DestructionVolume"), moltenCore.transform); var destructionVolume = GameObject.Instantiate(SearchUtilities.Find("VolcanicMoon_Body/MoltenCore_VM/DestructionVolume"), moltenCore.transform);
destructionVolume.name = "DestructionVolume";
destructionVolume.GetComponent<SphereCollider>().radius = 1; destructionVolume.GetComponent<SphereCollider>().radius = 1;
destructionVolume.SetActive(true); destructionVolume.SetActive(true);

View File

@ -9,7 +9,7 @@ namespace NewHorizons.Builder.Body
private static Material quantumMaterial; private static Material quantumMaterial;
private static Material iceMaterial; 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 (quantumMaterial == null) quantumMaterial = SearchUtilities.FindResourceOfTypeAndName<Material>("Rock_QM_EyeRock_mat");
if (iceMaterial == null) iceMaterial = SearchUtilities.FindResourceOfTypeAndName<Material>("Rock_BH_IceSpike_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; if (superGroup != null) icosphere.AddComponent<ProxyShadowCaster>()._superGroup = superGroup;
icosphere.SetActive(true); icosphere.SetActive(true);
return icosphere;
} }
} }
} }

View File

@ -34,9 +34,13 @@ namespace NewHorizons.Builder.Body
var proxyName = $"{body.Config.name}_Proxy"; var proxyName = $"{body.Config.name}_Proxy";
var newProxy = new GameObject(proxyName); var newProxy = new GameObject(proxyName);
newProxy.SetActive(false);
try try
{ {
var proxyController = newProxy.AddComponent<NHProxy>();
proxyController.astroName = body.Config.name;
// We want to take the largest size I think // We want to take the largest size I think
var realSize = body.Config.Base.surfaceSize; var realSize = body.Config.Base.surfaceSize;
@ -45,32 +49,57 @@ namespace NewHorizons.Builder.Body
HeightMapBuilder.Make(newProxy, null, body.Config.HeightMap, body.Mod, 20); HeightMapBuilder.Make(newProxy, null, body.Config.HeightMap, body.Mod, 20);
if (realSize < body.Config.HeightMap.maxHeight) realSize = body.Config.HeightMap.maxHeight; if (realSize < body.Config.HeightMap.maxHeight) realSize = body.Config.HeightMap.maxHeight;
} }
if (body.Config.Base.groundSize != 0) if (body.Config.Base.groundSize != 0)
{ {
GeometryBuilder.Make(newProxy, null, body.Config.Base.groundSize); GeometryBuilder.Make(newProxy, null, body.Config.Base.groundSize);
if (realSize < body.Config.Base.groundSize) realSize = 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); 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 (realSize < body.Config.Atmosphere.size) realSize = body.Config.Atmosphere.size;
} }
}
if (body.Config.Ring != null) if (body.Config.Ring != null)
{ {
RingBuilder.MakeRingGraphics(newProxy, null, body.Config.Ring, body.Mod); RingBuilder.MakeRingGraphics(newProxy, null, body.Config.Ring, body.Mod);
if (realSize < body.Config.Ring.outerRadius) realSize = body.Config.Ring.outerRadius; if (realSize < body.Config.Ring.outerRadius) realSize = body.Config.Ring.outerRadius;
} }
if (body.Config.Star != null) if (body.Config.Star != null)
{ {
var starGO = StarBuilder.MakeStarProxy(planetGO, newProxy, body.Config.Star, body.Mod); var starGO = StarBuilder.MakeStarProxy(planetGO, newProxy, body.Config.Star, body.Mod);
if (realSize < body.Config.Star.size) realSize = body.Config.Star.size; if (realSize < body.Config.Star.size) realSize = body.Config.Star.size;
} }
GameObject procGen = null;
if (body.Config.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 (realSize < body.Config.ProcGen.scale) realSize = body.Config.ProcGen.scale;
} }
if (body.Config.Lava != null) if (body.Config.Lava != null)
{ {
var sphere = AddColouredSphere(newProxy, body.Config.Lava.size, body.Config.Lava.curve, Color.black); 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()); if (body.Config.Lava.tint != null) material.SetColor(EmissionColor, body.Config.Lava.tint.ToColor());
sphere.GetComponent<MeshRenderer>().material = material; sphere.GetComponent<MeshRenderer>().material = material;
} }
if (body.Config.Water != null) if (body.Config.Water != null)
{ {
var colour = body.Config.Water.tint?.ToColor() ?? Color.blue; var colour = body.Config.Water.tint?.ToColor() ?? Color.blue;
AddColouredSphere(newProxy, body.Config.Water.size, body.Config.Water.curve, colour); AddColouredSphere(newProxy, body.Config.Water.size, body.Config.Water.curve, colour);
if (realSize < body.Config.Water.size) realSize = body.Config.Water.size; if (realSize < body.Config.Water.size) realSize = body.Config.Water.size;
} }
if (body.Config.Sand != null) if (body.Config.Sand != null)
{ {
var colour = body.Config.Sand.tint?.ToColor() ?? Color.yellow; var colour = body.Config.Sand.tint?.ToColor() ?? Color.yellow;
AddColouredSphere(newProxy, body.Config.Sand.size, body.Config.Sand.curve, colour); AddColouredSphere(newProxy, body.Config.Sand.size, body.Config.Sand.curve, colour);
if (realSize < body.Config.Sand.size) realSize = body.Config.Sand.size; if (realSize < body.Config.Sand.size) realSize = body.Config.Sand.size;
} }
// Could improve this to actually use the proper renders and materials // Could improve this to actually use the proper renders and materials
if (body.Config.Props?.singularities != null) if (body.Config.Props?.singularities != null)
{ {
@ -109,10 +141,12 @@ namespace NewHorizons.Builder.Body
if (realSize < singularity.size) realSize = singularity.size; if (realSize < singularity.size) realSize = singularity.size;
} }
} }
if (body.Config.Base.hasCometTail) if (body.Config.Base.hasCometTail)
{ {
CometTailBuilder.Make(newProxy, null, body.Config); CometTailBuilder.Make(newProxy, null, body.Config);
} }
if (body.Config.Props?.proxyDetails != null) if (body.Config.Props?.proxyDetails != null)
{ {
foreach (var detailInfo in body.Config.Props.proxyDetails) 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 // Remove all collisions if there are any
foreach (var col in newProxy.GetComponentsInChildren<Collider>()) foreach (var col in newProxy.GetComponentsInChildren<Collider>())
{ {
@ -138,8 +177,6 @@ namespace NewHorizons.Builder.Body
tessellatedRenderer.enabled = true; tessellatedRenderer.enabled = true;
} }
var proxyController = newProxy.AddComponent<NHProxy>();
proxyController.astroName = body.Config.name;
proxyController._realObjectDiameter = realSize; proxyController._realObjectDiameter = realSize;
} }
catch (Exception ex) catch (Exception ex)
@ -147,6 +184,8 @@ namespace NewHorizons.Builder.Body
Logger.LogError($"Exception thrown when generating proxy for [{body.Config.name}]:\n{ex}"); Logger.LogError($"Exception thrown when generating proxy for [{body.Config.name}]:\n{ex}");
GameObject.Destroy(newProxy); GameObject.Destroy(newProxy);
} }
newProxy.SetActive(true);
} }
private static GameObject AddColouredSphere(GameObject rootObj, float size, VariableSizeModule.TimeValuePair[] curve, Color color) 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; if (sizeController != null) sizeController.audioSource = blackHoleAudioSource;
var blackHoleOneShot = GameObject.Instantiate(SearchUtilities.Find("BrittleHollow_Body/BlackHole_BH/BlackHoleEmissionOneShot"), blackHole.transform); var blackHoleOneShot = GameObject.Instantiate(SearchUtilities.Find("BrittleHollow_Body/BlackHole_BH/BlackHoleEmissionOneShot"), blackHole.transform);
blackHoleOneShot.name = "BlackHoleEmissionOneShot";
var oneShotAudioSource = blackHoleOneShot.GetComponent<AudioSource>(); var oneShotAudioSource = blackHoleOneShot.GetComponent<AudioSource>();
oneShotAudioSource.maxDistance = size * 3f; oneShotAudioSource.maxDistance = size * 3f;
oneShotAudioSource.minDistance = size * 0.4f; oneShotAudioSource.minDistance = size * 0.4f;

View File

@ -142,11 +142,14 @@ namespace NewHorizons.Builder.Body
controller.supernova = supernova; controller.supernova = supernova;
controller.StartColour = starModule.tint; controller.StartColour = starModule.tint;
controller.EndColour = starModule.endTint; controller.EndColour = starModule.endTint;
controller.SupernovaColour = starModule.supernovaTint;
controller.WillExplode = starModule.goSupernova; controller.WillExplode = starModule.goSupernova;
controller.lifespan = starModule.lifespan; controller.lifespan = starModule.lifespan;
controller.normalRamp = !string.IsNullOrEmpty(starModule.starRampTexture) ? ImageUtilities.GetTexture(mod, starModule.starRampTexture) : ramp; controller.normalRamp = !string.IsNullOrEmpty(starModule.starRampTexture) ? ImageUtilities.GetTexture(mod, starModule.starRampTexture) : ramp;
controller._destructionVolume = deathVolume.GetComponent<DestructionVolume>(); controller._destructionVolume = deathVolume.GetComponent<DestructionVolume>();
controller._planetDestructionVolume = planetDestructionVolume.GetComponent<DestructionVolume>(); controller._planetDestructionVolume = planetDestructionVolume.GetComponent<DestructionVolume>();
controller._destructionFluidVolume = planetDestructionVolume.GetComponent<SimpleFluidVolume>();
controller._planetDestructionFluidVolume = planetDestructionVolume.GetComponent<SimpleFluidVolume>();
if (!string.IsNullOrEmpty(starModule.starCollapseRampTexture)) if (!string.IsNullOrEmpty(starModule.starCollapseRampTexture))
{ {
controller.collapseRamp = ImageUtilities.GetTexture(mod, starModule.starCollapseRampTexture); controller.collapseRamp = ImageUtilities.GetTexture(mod, starModule.starCollapseRampTexture);
@ -192,6 +195,7 @@ namespace NewHorizons.Builder.Body
controller.supernova = supernova; controller.supernova = supernova;
controller.StartColour = starModule.tint; controller.StartColour = starModule.tint;
controller.EndColour = starModule.endTint; controller.EndColour = starModule.endTint;
controller.SupernovaColour = starModule.supernovaTint;
controller.WillExplode = starModule.goSupernova; controller.WillExplode = starModule.goSupernova;
controller.lifespan = starModule.lifespan; controller.lifespan = starModule.lifespan;
controller.normalRamp = !string.IsNullOrEmpty(starModule.starRampTexture) ? ImageUtilities.GetTexture(mod, starModule.starRampTexture) : ramp; 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) private static SupernovaEffectController MakeSupernova(GameObject starGO, StarModule starModule)
{ {
var supernovaGO = SearchUtilities.Find("Sun_Body/Sector_SUN/Effects_SUN/Supernova").InstantiateInactive(); var supernovaGO = SearchUtilities.Find("Sun_Body/Sector_SUN/Effects_SUN/Supernova").InstantiateInactive();
supernovaGO.name = "Supernova";
supernovaGO.transform.SetParent(starGO.transform); supernovaGO.transform.SetParent(starGO.transform);
supernovaGO.transform.localPosition = Vector3.zero; supernovaGO.transform.localPosition = Vector3.zero;
var supernova = supernovaGO.GetComponent<SupernovaEffectController>(); var supernova = supernovaGO.GetComponent<SupernovaEffectController>();
supernova._surface = starGO.GetComponentInChildren<TessellatedSphereRenderer>(); 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; supernova._supernovaVolume = null;
if (starModule.supernovaTint != 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 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"); 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; if (ambientLight == null) return null;
GameObject lightGO = GameObject.Instantiate(ambientLight, sector?.transform ?? planetGO.transform); GameObject lightGO = GameObject.Instantiate(ambientLight, sector?.transform ?? planetGO.transform);
lightGO.transform.position = planetGO.transform.position; 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 * 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.range = scale;
light.intensity = intensity; 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.Components.Orbital;
using NewHorizons.External.Configs; using NewHorizons.External.Configs;
using NewHorizons.Utility;
using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using Logger = NewHorizons.Utility.Logger; using Logger = NewHorizons.Utility.Logger;
namespace NewHorizons.Builder.General namespace NewHorizons.Builder.General
@ -33,10 +35,61 @@ namespace NewHorizons.Builder.General
OWRB.RegisterAttachedFluidDetector(fluidDetector); 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
});
}
} }
SetDetector(primaryBody, astroObject, forceDetector); 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);
detectorGO.SetActive(true); detectorGO.SetActive(true);
return detectorGO; return detectorGO;

View File

@ -36,7 +36,8 @@ namespace NewHorizons.Builder.Props
} }
if (_hurricanePrefab == null) 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) // 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 // Increasing by 40 will keep the bottom above the ground
foreach (Transform child in _hurricanePrefab.transform) 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) private static void MakeTornado(GameObject planetGO, Sector sector, PropModule.TornadoInfo info, Vector3 position, bool downwards)
{ {
var tornadoGO = downwards ? _downPrefab.InstantiateInactive() : _upPrefab.InstantiateInactive(); var tornadoGO = downwards ? _downPrefab.InstantiateInactive() : _upPrefab.InstantiateInactive();
tornadoGO.name = downwards ? "Tornado_Down" : "Tornado_Up";
tornadoGO.transform.parent = sector.transform; tornadoGO.transform.parent = sector.transform;
tornadoGO.transform.position = planetGO.transform.TransformPoint(position); tornadoGO.transform.position = planetGO.transform.TransformPoint(position);
tornadoGO.transform.rotation = Quaternion.FromToRotation(Vector3.up, sector.transform.TransformDirection(position.normalized)); 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) private static void MakeHurricane(GameObject planetGO, Sector sector, PropModule.TornadoInfo info, Vector3 position, bool hasClouds)
{ {
var hurricaneGO = _hurricanePrefab.InstantiateInactive(); var hurricaneGO = _hurricanePrefab.InstantiateInactive();
hurricaneGO.name = "Hurricane";
hurricaneGO.transform.parent = sector.transform; hurricaneGO.transform.parent = sector.transform;
hurricaneGO.transform.position = planetGO.transform.TransformPoint(position); hurricaneGO.transform.position = planetGO.transform.TransformPoint(position);
hurricaneGO.transform.rotation = Quaternion.FromToRotation(Vector3.up, sector.transform.TransformDirection(position.normalized)); 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 NewHorizons.Utility;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
@ -13,6 +13,9 @@ namespace NewHorizons.Components
private TessellatedRenderer[] _starTessellatedRenderers; private TessellatedRenderer[] _starTessellatedRenderers;
private ParticleSystemRenderer[] _starParticleRenderers; private ParticleSystemRenderer[] _starParticleRenderers;
private SolarFlareEmitter _solarFlareEmitter; private SolarFlareEmitter _solarFlareEmitter;
public CloudLightningGenerator _lightningGenerator;
public MeshRenderer _mainBody;
public NHSupernovaPlanetEffectController _supernovaPlanetEffectController;
public override void Awake() public override void Awake()
{ {
@ -30,6 +33,10 @@ namespace NewHorizons.Components
_solarFlareEmitter = _star.GetComponentInChildren<SolarFlareEmitter>(); _solarFlareEmitter = _star.GetComponentInChildren<SolarFlareEmitter>();
} }
if (_lightningGenerator == null) _lightningGenerator = GetComponentInChildren<CloudLightningGenerator>();
if (_supernovaPlanetEffectController == null) _supernovaPlanetEffectController = GetComponentInChildren<NHSupernovaPlanetEffectController>();
// Start off // Start off
_outOfRange = false; _outOfRange = false;
ToggleRendering(false); ToggleRendering(false);
@ -39,9 +46,9 @@ namespace NewHorizons.Components
{ {
AstroObject astroObject = AstroObjectLocator.GetAstroObject(astroName); AstroObject astroObject = AstroObjectLocator.GetAstroObject(astroName);
_realObjectTransform = astroObject.transform; _realObjectTransform = astroObject.transform;
_hasAtmosphere = _atmosphere != null; if (_atmosphere != null)
if (_hasAtmosphere)
{ {
_hasAtmosphere = true;
_atmosphereMaterial = new Material(_atmosphere.sharedMaterial); _atmosphereMaterial = new Material(_atmosphere.sharedMaterial);
_baseAtmoMatShellInnerRadius = _atmosphereMaterial.GetFloat(propID_AtmoInnerRadius); _baseAtmoMatShellInnerRadius = _atmosphereMaterial.GetFloat(propID_AtmoInnerRadius);
_baseAtmoMatShellOuterRadius = _atmosphereMaterial.GetFloat(propID_AtmoOuterRadius); _baseAtmoMatShellOuterRadius = _atmosphereMaterial.GetFloat(propID_AtmoOuterRadius);
@ -73,6 +80,22 @@ namespace NewHorizons.Components
_solarFlareEmitter.gameObject.SetActive(on); _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) foreach (var renderer in _starRenderers)
{ {
renderer.enabled = on; 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.Builder.Body;
using NewHorizons.Handlers;
using NewHorizons.Utility; using NewHorizons.Utility;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -19,6 +20,7 @@ namespace NewHorizons.Components.SizeControllers
public bool WillExplode { get; set; } public bool WillExplode { get; set; }
public MColor StartColour { get; set; } public MColor StartColour { get; set; }
public MColor EndColour { get; set; } public MColor EndColour { get; set; }
public MColor SupernovaColour { get; set; }
public Texture normalRamp; public Texture normalRamp;
public Texture collapseRamp; public Texture collapseRamp;
@ -30,6 +32,8 @@ namespace NewHorizons.Components.SizeControllers
private HeatHazardVolume _heatVolume; private HeatHazardVolume _heatVolume;
public DestructionVolume _destructionVolume; public DestructionVolume _destructionVolume;
public DestructionVolume _planetDestructionVolume; public DestructionVolume _planetDestructionVolume;
public SimpleFluidVolume _destructionFluidVolume;
public SimpleFluidVolume _planetDestructionFluidVolume;
private SolarFlareEmitter _flareEmitter; private SolarFlareEmitter _flareEmitter;
private MapMarker _mapMarker; private MapMarker _mapMarker;
private OWRigidbody _rigidbody; private OWRigidbody _rigidbody;
@ -39,7 +43,9 @@ namespace NewHorizons.Components.SizeControllers
private float _collapseTimer; private float _collapseTimer;
public float collapseTime = 10f; // seconds 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 lifespan = 22f; // minutes
public float supernovaSize = 50000f; public float supernovaSize = 50000f;
@ -56,7 +62,10 @@ namespace NewHorizons.Components.SizeControllers
private StarEvolutionController _proxy; private StarEvolutionController _proxy;
public UnityEvent CollapseStart = new UnityEvent();
public UnityEvent CollapseStop = new UnityEvent();
public UnityEvent SupernovaStart = new UnityEvent(); public UnityEvent SupernovaStart = new UnityEvent();
public UnityEvent SupernovaStop = new UnityEvent();
private float maxScale; private float maxScale;
private float minScale; private float minScale;
@ -122,7 +131,7 @@ namespace NewHorizons.Components.SizeControllers
} }
_heatVolume = GetComponentInChildren<HeatHazardVolume>(); _heatVolume = GetComponentInChildren<HeatHazardVolume>();
if (_destructionVolume != null) _destructionVolume = GetComponentInChildren<DestructionVolume>(); if (_destructionVolume == null) _destructionVolume = GetComponentInChildren<DestructionVolume>();
if (atmosphere != null) if (atmosphere != null)
{ {
@ -146,6 +155,8 @@ namespace NewHorizons.Components.SizeControllers
_flareEmitter = GetComponentInChildren<SolarFlareEmitter>(); _flareEmitter = GetComponentInChildren<SolarFlareEmitter>();
_surfaceMaterial = supernova._surface._materials[0]; _surfaceMaterial = supernova._surface._materials[0];
SupernovaEffectHandler.RegisterStar(this);
var secondsElapsed = TimeLoop.GetSecondsElapsed(); var secondsElapsed = TimeLoop.GetSecondsElapsed();
var lifespanInSeconds = lifespan * 60; var lifespanInSeconds = lifespan * 60;
if (secondsElapsed >= lifespanInSeconds) if (secondsElapsed >= lifespanInSeconds)
@ -162,6 +173,7 @@ namespace NewHorizons.Components.SizeControllers
public void OnDestroy() public void OnDestroy()
{ {
SupernovaEffectHandler.UnregisterStar(this);
} }
public void SetProxy(StarEvolutionController proxy) 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 (_planetDestructionVolume != null) _planetDestructionVolume.transform.localScale = Vector3.one * supernova.GetSupernovaRadius() * 0.9f;
if (_heatVolume != null) _heatVolume.transform.localScale = Vector3.one * supernova.GetSupernovaRadius(); 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) if (Time.time > _supernovaStartTime + supernovaTime)
{ {
DisableStar(); DisableStar();
@ -281,6 +299,7 @@ namespace NewHorizons.Components.SizeControllers
Logger.LogVerbose($"{gameObject.transform.root.name} started collapse"); Logger.LogVerbose($"{gameObject.transform.root.name} started collapse");
CollapseStart.Invoke();
_isCollapsing = true; _isCollapsing = true;
_collapseStartSize = CurrentScale; _collapseStartSize = CurrentScale;
_collapseTimer = 0f; _collapseTimer = 0f;
@ -295,6 +314,7 @@ namespace NewHorizons.Components.SizeControllers
Logger.LogVerbose($"{gameObject.transform.root.name} stopped collapse"); Logger.LogVerbose($"{gameObject.transform.root.name} stopped collapse");
CollapseStop.Invoke();
_isCollapsing = false; _isCollapsing = false;
supernova._surface._materials[0].CopyPropertiesFromMaterial(_endSurfaceMaterial); supernova._surface._materials[0].CopyPropertiesFromMaterial(_endSurfaceMaterial);
@ -314,6 +334,8 @@ namespace NewHorizons.Components.SizeControllers
if (atmosphere != null) atmosphere.SetActive(false); if (atmosphere != null) atmosphere.SetActive(false);
if (_destructionVolume != null) _destructionVolume._deathType = DeathType.Supernova; if (_destructionVolume != null) _destructionVolume._deathType = DeathType.Supernova;
if (_planetDestructionVolume != null) _planetDestructionVolume._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(); if (_proxy != null) _proxy.StartSupernova();
} }
@ -324,6 +346,7 @@ namespace NewHorizons.Components.SizeControllers
Logger.LogVerbose($"{gameObject.transform.root.name} stopped supernova"); Logger.LogVerbose($"{gameObject.transform.root.name} stopped supernova");
SupernovaStop.Invoke();
supernova.enabled = false; supernova.enabled = false;
_isSupernova = false; _isSupernova = false;
if (atmosphere != null) atmosphere.SetActive(true); if (atmosphere != null) atmosphere.SetActive(true);
@ -337,6 +360,8 @@ namespace NewHorizons.Components.SizeControllers
_planetDestructionVolume._deathType = DeathType.Energy; _planetDestructionVolume._deathType = DeathType.Energy;
_planetDestructionVolume.transform.localScale = Vector3.one; _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; if (_heatVolume != null) _heatVolume.transform.localScale = Vector3.one;
gameObject.SetActive(true); gameObject.SetActive(true);
transform.localScale = Vector3.one; transform.localScale = Vector3.one;
@ -346,6 +371,24 @@ namespace NewHorizons.Components.SizeControllers
if (_proxy != null) _proxy.StopSupernova(); 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() protected new void FixedUpdate()
{ {
// If we've gone supernova and its been 45 seconds that means it has faded out and is gone // 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 namespace NewHorizons.Components
{ {
public class TimeLoopController : MonoBehaviour public class TimeLoopController : MonoBehaviour
@ -14,8 +14,7 @@ namespace NewHorizons.Components
public void Update() public void Update()
{ {
// Stock gives like 33 seconds after the sun collapses // 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 + 50f)
if (_supernovaHappened && Time.time > _supernovaTime + 40f)
{ {
Locator.GetDeathManager().KillPlayer(DeathType.TimeLoop); Locator.GetDeathManager().KillPlayer(DeathType.TimeLoop);
} }

View File

@ -24,5 +24,9 @@ namespace NewHorizons.External.Configs
/// </summary> /// </summary>
public AchievementInfo[] achievements; 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; public bool unlit;
/// <summary> /// <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> /// </summary>
[DefaultValue(10f)] public float rotationSpeed = 10f; [DefaultValue(0f)] public float rotationSpeed = 0f;
#region Obsolete #region Obsolete

View File

@ -56,6 +56,11 @@ namespace NewHorizons.External.Modules
/// </summary> /// </summary>
public bool hasMapMarker; 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> /// <summary>
/// Can this planet survive entering a star? /// Can this planet survive entering a star?
/// </summary> /// </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 // Set up stars
// Need to manage this when there are multiple stars // Need to manage this when there are multiple stars
var sun = SearchUtilities.Find("Sun_Body"); var sun = SearchUtilities.Find("Sun_Body");
SupernovaEffectHandler.RegisterSun(sun.GetComponent<SunController>());
var starController = sun.AddComponent<StarController>(); var starController = sun.AddComponent<StarController>();
starController.Light = SearchUtilities.Find("Sun_Body/Sector_SUN/Effects_SUN/SunLight").GetComponent<Light>(); starController.Light = SearchUtilities.Find("Sun_Body/Sector_SUN/Effects_SUN/SunLight").GetComponent<Light>();
starController.AmbientLight = SearchUtilities.Find("Sun_Body/AmbientLight_SUN").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)); 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); AstroObjectLocator.RegisterCustomAstroObject(ao);
@ -482,9 +480,10 @@ namespace NewHorizons.Handlers
{ {
var sphereOfInfluence = GetSphereOfInfluence(body); var sphereOfInfluence = GetSphereOfInfluence(body);
Light ambientLight = null;
if (body.Config.Base.ambientLight != 0) 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) if (body.Config.Base.groundSize != 0)
@ -500,9 +499,10 @@ namespace NewHorizons.Handlers
HeightMapBuilder.Make(go, sector, body.Config.HeightMap, body.Mod, res, true); HeightMapBuilder.Make(go, sector, body.Config.HeightMap, body.Mod, res, true);
} }
GameObject procGen = null;
if (body.Config.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) if (body.Config.Star != null)
@ -554,7 +554,8 @@ namespace NewHorizons.Handlers
} }
var willHaveCloak = body.Config.Cloak != null && body.Config.Cloak.radius != 0f; var willHaveCloak = body.Config.Cloak != null && body.Config.Cloak.radius != 0f;
PlanetaryFogController fog = null;
LODGroup atmosphere = null;
if (body.Config.Atmosphere != null) if (body.Config.Atmosphere != null)
{ {
var surfaceSize = body.Config.Base.surfaceSize; var surfaceSize = body.Config.Base.surfaceSize;
@ -571,9 +572,11 @@ namespace NewHorizons.Handlers
EffectsBuilder.Make(go, sector, body.Config, surfaceSize); EffectsBuilder.Make(go, sector, body.Config, surfaceSize);
if (body.Config.Atmosphere.fogSize != 0) 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) 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); 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; 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(); AchievementHandler.Init();
VoiceHandler.Init(); VoiceHandler.Init();
LoadAddonManifest("Assets/addon-manifest.json", this);
} }
public void OnDestroy() public void OnDestroy()
@ -377,6 +379,14 @@ namespace NewHorizons
AtmosphereBuilder.Init(); AtmosphereBuilder.Init();
BrambleNodeBuilder.Init(BodyDict[CurrentStarSystem].Select(x => x.Config).Where(x => x.Bramble?.dimension != null).ToArray()); 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]); PlanetCreationHandler.Init(BodyDict[CurrentStarSystem]);
VesselWarpHandler.LoadVessel(); VesselWarpHandler.LoadVessel();
SystemCreationHandler.LoadSystem(SystemDict[CurrentStarSystem]); SystemCreationHandler.LoadSystem(SystemDict[CurrentStarSystem]);
@ -384,6 +394,7 @@ namespace NewHorizons
LoadTranslations(ModHelper.Manifest.ModFolderPath + "Assets/", this); LoadTranslations(ModHelper.Manifest.ModFolderPath + "Assets/", this);
StarChartHandler.Init(SystemDict.Values.ToArray()); StarChartHandler.Init(SystemDict.Values.ToArray());
if (isSolarSystem) if (isSolarSystem)
{ {
// Warp drive // Warp drive
@ -483,6 +494,16 @@ namespace NewHorizons
ssrLight.range = Main.FurthestOrbit * (4f/3f); ssrLight.range = Main.FurthestOrbit * (4f/3f);
ssrLight.intensity = 0.001f; 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 try
{ {
Logger.Log($"Star system finished loading [{Instance.CurrentStarSystem}]"); Logger.Log($"Star system finished loading [{Instance.CurrentStarSystem}]");
@ -601,9 +622,7 @@ namespace NewHorizons
// Has to go before translations for achievements // Has to go before translations for achievements
if (File.Exists(folder + "addon-manifest.json")) if (File.Exists(folder + "addon-manifest.json"))
{ {
var addonConfig = mod.ModHelper.Storage.Load<AddonConfig>("addon-manifest.json"); LoadAddonManifest("addon-manifest.json", mod);
AchievementHandler.RegisterAddon(addonConfig, mod as ModBehaviour);
} }
if (Directory.Exists(folder + @"translations\")) 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) private void LoadTranslations(string folder, IModBehaviour mod)
{ {
var foundFile = false; 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 HarmonyLib;
using NewHorizons.Components;
namespace NewHorizons.Patches namespace NewHorizons.Patches
{ {
[HarmonyPatch] [HarmonyPatch]
public static class LocatorPatches public static class LocatorPatches
{ {
public static AstroObject _attlerock;
public static AstroObject _eye; public static AstroObject _eye;
public static AstroObject _focal;
public static AstroObject _hollowsLantern;
public static AstroObject _mapSatellite;
public static AstroObject _sunStation;
[HarmonyPrefix] [HarmonyPrefix]
[HarmonyPatch(typeof(Locator), nameof(Locator.RegisterCloakFieldController))] [HarmonyPatch(typeof(Locator), nameof(Locator.RegisterCloakFieldController))]
@ -36,14 +40,34 @@ namespace NewHorizons.Patches
__result = __result || Components.CloakSectorController.isShipInside; __result = __result || Components.CloakSectorController.isShipInside;
} }
// Locator Fixes
// Vanilla doesn't register these AstroObjects for some reason. So here is a fix.
[HarmonyPrefix] [HarmonyPrefix]
[HarmonyPatch(typeof(Locator), nameof(Locator.GetAstroObject))] [HarmonyPatch(typeof(Locator), nameof(Locator.GetAstroObject))]
public static bool Locator_GetAstroObject(AstroObject.Name astroObjectName, ref AstroObject __result) public static bool Locator_GetAstroObject(AstroObject.Name astroObjectName, ref AstroObject __result)
{ {
if (astroObjectName == AstroObject.Name.Eye && _eye != null) switch (astroObjectName)
{ {
case AstroObject.Name.Eye:
__result = _eye; __result = _eye;
return false; 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; return true;
} }
@ -52,10 +76,44 @@ namespace NewHorizons.Patches
[HarmonyPatch(typeof(Locator), nameof(Locator.RegisterAstroObject))] [HarmonyPatch(typeof(Locator), nameof(Locator.RegisterAstroObject))]
public static bool Locator_RegisterAstroObject(AstroObject astroObject) 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"))
{ {
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; _eye = astroObject;
return false; 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; return true;
} }
@ -64,7 +122,12 @@ namespace NewHorizons.Patches
[HarmonyPatch(typeof(Locator), nameof(Locator.ClearReferences))] [HarmonyPatch(typeof(Locator), nameof(Locator.ClearReferences))]
public static void Locator_ClearReferences() public static void Locator_ClearReferences()
{ {
_attlerock = null;
_eye = 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 namespace NewHorizons.Patches
{ {
[HarmonyPatch] [HarmonyPatch]
@ -53,5 +58,72 @@ namespace NewHorizons.Patches
GlobalMessenger.RemoveListener("EnterMapView", __instance.OnEnterMapView); GlobalMessenger.RemoveListener("EnterMapView", __instance.OnEnterMapView);
GlobalMessenger.RemoveListener("ExitMapView", __instance.OnExitMapView); 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); base_DropItem(__instance, position, normal, parent, sector, customDropTarget);
} }
if (__instance._wasProjecting) __instance._mindProjectorTrigger.SetProjectorActive(false);
__instance.gameObject.GetComponent<Collider>().enabled = true;
return true; return true;
} }
} }

View File

@ -12,6 +12,13 @@
"$ref": "#/definitions/AchievementInfo" "$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": { "$schema": {
"type": "string", "type": "string",
"description": "The schema to validate with" "description": "The schema to validate with"

View File

@ -364,9 +364,9 @@
}, },
"rotationSpeed": { "rotationSpeed": {
"type": "number", "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", "format": "float",
"default": 10.0 "default": 0.0
} }
} }
}, },
@ -450,6 +450,11 @@
"type": "boolean", "type": "boolean",
"description": "If the body should have a marker on the map screen." "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": { "invulnerableToSun": {
"type": "boolean", "type": "boolean",
"description": "Can this planet survive entering a star?" "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(); 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) public static GameObject[] GetChildren(AstroObject primary)
{ {
if (primary == null) return new GameObject[0]; 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_SmallNest_Body"));
otherChildren.Add(SearchUtilities.Find("DB_Elsinore_Body")); otherChildren.Add(SearchUtilities.Find("DB_Elsinore_Body"));
break; 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: case AstroObject.Name.CustomString:
if (primary._customName.Equals("Sun Station")) if (primary._customName.Equals("Sun Station"))
{ {

View File

@ -1,4 +1,4 @@
using System.ComponentModel; using System.ComponentModel;
using Newtonsoft.Json; using Newtonsoft.Json;
using UnityEngine; using UnityEngine;
namespace NewHorizons.Utility namespace NewHorizons.Utility
@ -6,7 +6,7 @@ namespace NewHorizons.Utility
[JsonObject] [JsonObject]
public class MColor 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.r = r;
this.g = g; this.g = g;
@ -37,8 +37,30 @@ namespace NewHorizons.Utility
/// </summary> /// </summary>
[System.ComponentModel.DataAnnotations.Range(0, 255)] [System.ComponentModel.DataAnnotations.Range(0, 255)]
[DefaultValue(255)] [DefaultValue(255)]
public int a; public int a = 255;
public Color ToColor() => new Color(r / 255f, g / 255f, b / 255f, a / 255f); 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);
} }
} }