## Minor features
- Allow setting hazard type and damage per second, as well as first
contact damage, for tornados and hurricanes. Resolves #496

## Improvements
- Throw errors when attempting to make a signal without a frequency or
name. Resolves #660.

## Bug fixes
- Supernovae are no longer silent. Fixes #522.
- Supernovae proxies will no longer explode on top of you.
- Lightning now appears properly on top of basic clouds. Fixes #321.
- Bramble music won't play if in another audio volume. Fixes #651.
- Fix QM clouds defaulting to GD fog when not given a tint. Fixes #182.
- Makes creating empty details actually work
- Fixed suit up again #333
This commit is contained in:
Nick 2023-07-22 01:49:34 -04:00 committed by GitHub
commit 8399142648
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 270 additions and 96 deletions

View File

@ -8,6 +8,7 @@ using NewHorizons.Utility.OWML;
using OWML.Common; using OWML.Common;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Tessellation; using Tessellation;
using UnityEngine; using UnityEngine;
@ -15,11 +16,12 @@ namespace NewHorizons.Builder.Atmosphere
{ {
public static class CloudsBuilder public static class CloudsBuilder
{ {
private static Material[] _gdCloudMaterials; private static Material[] _gdCloudMaterials, _gdBottomMaterials;
private static Material[] _qmCloudMaterials;
private static Material[] _qmBottomMaterials;
private static Mesh _gdTopCloudMesh; private static Mesh _gdTopCloudMesh;
private static Tessellation.MeshGroup _qmBottomMeshGroup;
private static Material[] _qmCloudMaterials, _qmBottomMaterials;
private static MeshGroup _qmBottomMeshGroup;
private static Material _transparentCloud; private static Material _transparentCloud;
private static GameObject _lightningPrefab; private static GameObject _lightningPrefab;
private static Texture2D _colorRamp; private static Texture2D _colorRamp;
@ -41,10 +43,14 @@ namespace NewHorizons.Builder.Atmosphere
_isInit = true; _isInit = true;
if (_lightningPrefab == null) _lightningPrefab = SearchUtilities.Find("GiantsDeep_Body/Sector_GD/Clouds_GD/LightningGenerator_GD").InstantiateInactive().Rename("LightningGenerator").DontDestroyOnLoad(); if (_lightningPrefab == null) _lightningPrefab = SearchUtilities.Find("GiantsDeep_Body/Sector_GD/Clouds_GD/LightningGenerator_GD").InstantiateInactive().Rename("LightningGenerator").DontDestroyOnLoad();
if (_gdTopCloudMesh == null) _gdTopCloudMesh = SearchUtilities.Find("CloudsTopLayer_GD").GetComponent<MeshFilter>().mesh.DontDestroyOnLoad(); if (_gdTopCloudMesh == null) _gdTopCloudMesh = SearchUtilities.Find("CloudsTopLayer_GD").GetComponent<MeshFilter>().mesh.DontDestroyOnLoad();
if (_gdCloudMaterials == null) _gdCloudMaterials = SearchUtilities.Find("CloudsTopLayer_GD").GetComponent<MeshRenderer>().sharedMaterials.MakePrefabMaterials(); if (_gdCloudMaterials == null) _gdCloudMaterials = SearchUtilities.Find("CloudsTopLayer_GD").GetComponent<MeshRenderer>().sharedMaterials.MakePrefabMaterials();
if (_gdBottomMaterials == null) _gdBottomMaterials = SearchUtilities.Find("CloudsBottomLayer_GD").GetComponent<TessellatedSphereRenderer>().sharedMaterials.MakePrefabMaterials();
if (_qmCloudMaterials == null) _qmCloudMaterials = SearchUtilities.Find("CloudsTopLayer_QM").GetComponent<MeshRenderer>().sharedMaterials.MakePrefabMaterials(); if (_qmCloudMaterials == null) _qmCloudMaterials = SearchUtilities.Find("CloudsTopLayer_QM").GetComponent<MeshRenderer>().sharedMaterials.MakePrefabMaterials();
if (_qmBottomMaterials == null) _qmBottomMaterials = SearchUtilities.Find("CloudsBottomLayer_QM").GetComponent<TessellatedSphereRenderer>().sharedMaterials.MakePrefabMaterials(); if (_qmBottomMaterials == null) _qmBottomMaterials = SearchUtilities.Find("CloudsBottomLayer_QM").GetComponent<TessellatedSphereRenderer>().sharedMaterials.MakePrefabMaterials();
if (_qmBottomMeshGroup == null) if (_qmBottomMeshGroup == null)
{ {
var originalMeshGroup = SearchUtilities.Find("CloudsBottomLayer_QM").GetComponent<TessellatedSphereRenderer>().tessellationMeshGroup; var originalMeshGroup = SearchUtilities.Find("CloudsBottomLayer_QM").GetComponent<TessellatedSphereRenderer>().tessellationMeshGroup;
@ -67,7 +73,7 @@ namespace NewHorizons.Builder.Atmosphere
{ {
InitPrefabs(); InitPrefabs();
GameObject cloudsMainGO = new GameObject("Clouds"); var cloudsMainGO = new GameObject("Clouds");
cloudsMainGO.SetActive(false); cloudsMainGO.SetActive(false);
cloudsMainGO.transform.parent = sector?.transform ?? planetGO.transform; cloudsMainGO.transform.parent = sector?.transform ?? planetGO.transform;
@ -81,20 +87,24 @@ namespace NewHorizons.Builder.Atmosphere
return; return;
} }
GameObject cloudsBottomGO = new GameObject("BottomClouds"); var cloudsBottomGO = new GameObject("BottomClouds");
cloudsBottomGO.SetActive(false); cloudsBottomGO.SetActive(false);
cloudsBottomGO.transform.parent = cloudsMainGO.transform; cloudsBottomGO.transform.parent = cloudsMainGO.transform;
cloudsBottomGO.transform.localScale = Vector3.one * atmo.clouds.innerCloudRadius; cloudsBottomGO.transform.localScale = Vector3.one * atmo.clouds.innerCloudRadius;
TessellatedSphereRenderer bottomTSR = cloudsBottomGO.AddComponent<TessellatedSphereRenderer>(); var bottomTSR = cloudsBottomGO.AddComponent<TessellatedSphereRenderer>();
bottomTSR.tessellationMeshGroup = _qmBottomMeshGroup; bottomTSR.tessellationMeshGroup = _qmBottomMeshGroup;
var bottomTSRMaterials = _qmBottomMaterials;
// If they set a colour apply it to all the materials else keep the default QM one var bottomTSRMaterials = atmo.clouds.cloudsPrefab == CloudPrefabType.GiantsDeep ? _gdBottomMaterials : _qmBottomMaterials;
if (atmo.clouds.tint != null)
// If they set a colour apply it to all the materials else keep the defaults
if (atmo.clouds.tint == null)
{
bottomTSR.sharedMaterials = bottomTSRMaterials.Select(x => new Material(x)).ToArray();
}
else
{ {
var bottomColor = atmo.clouds.tint.ToColor(); var bottomColor = atmo.clouds.tint.ToColor();
var bottomTSRTempArray = new Material[2]; var bottomTSRTempArray = new Material[2];
bottomTSRTempArray[0] = new Material(bottomTSRMaterials[0]); bottomTSRTempArray[0] = new Material(bottomTSRMaterials[0]);
@ -105,34 +115,34 @@ namespace NewHorizons.Builder.Atmosphere
bottomTSR.sharedMaterials = bottomTSRTempArray; bottomTSR.sharedMaterials = bottomTSRTempArray;
} }
else
{
bottomTSR.sharedMaterials = bottomTSRMaterials;
}
bottomTSR.maxLOD = 6; bottomTSR.maxLOD = 6;
bottomTSR.LODBias = 0; bottomTSR.LODBias = 0;
bottomTSR.LODRadius = 1f; bottomTSR.LODRadius = 1f;
if (cloaked) if (cloaked)
{
cloudsBottomGO.AddComponent<CloakedTessSphereSectorToggle>()._sector = sector; cloudsBottomGO.AddComponent<CloakedTessSphereSectorToggle>()._sector = sector;
}
else else
{
cloudsBottomGO.AddComponent<TessSphereSectorToggle>()._sector = sector; cloudsBottomGO.AddComponent<TessSphereSectorToggle>()._sector = sector;
}
GameObject cloudsFluidGO = new GameObject("CloudsFluid"); var cloudsFluidGO = new GameObject("CloudsFluid");
cloudsFluidGO.SetActive(false); cloudsFluidGO.SetActive(false);
cloudsFluidGO.layer = Layer.BasicEffectVolume; cloudsFluidGO.layer = Layer.BasicEffectVolume;
cloudsFluidGO.transform.parent = cloudsMainGO.transform; cloudsFluidGO.transform.parent = cloudsMainGO.transform;
SphereCollider fluidSC = cloudsFluidGO.AddComponent<SphereCollider>(); var fluidSC = cloudsFluidGO.AddComponent<SphereCollider>();
fluidSC.isTrigger = true; fluidSC.isTrigger = true;
fluidSC.radius = atmo.clouds.outerCloudRadius; fluidSC.radius = atmo.clouds.outerCloudRadius;
OWShellCollider fluidOWSC = cloudsFluidGO.AddComponent<OWShellCollider>(); var fluidOWSC = cloudsFluidGO.AddComponent<OWShellCollider>();
fluidOWSC._innerRadius = atmo.clouds.innerCloudRadius; fluidOWSC._innerRadius = atmo.clouds.innerCloudRadius;
// copied from gd // copied from gd
CloudLayerFluidVolume fluidCLFV = cloudsFluidGO.AddComponent<CloudLayerFluidVolume>(); var fluidCLFV = cloudsFluidGO.AddComponent<CloudLayerFluidVolume>();
fluidCLFV._layer = 5; fluidCLFV._layer = 5;
fluidCLFV._priority = 1; fluidCLFV._priority = 1;
fluidCLFV._density = 1.2f; fluidCLFV._density = 1.2f;
@ -168,12 +178,19 @@ namespace NewHorizons.Builder.Atmosphere
lightning.transform.localPosition = Vector3.zero; lightning.transform.localPosition = Vector3.zero;
var lightningGenerator = lightning.GetComponent<CloudLightningGenerator>(); var lightningGenerator = lightning.GetComponent<CloudLightningGenerator>();
lightningGenerator._altitude = atmo.clouds.cloudsPrefab != CloudPrefabType.Transparent ? (atmo.clouds.outerCloudRadius + atmo.clouds.innerCloudRadius) / 2f : atmo.clouds.outerCloudRadius;
lightningGenerator._altitude = atmo.clouds.cloudsPrefab switch
{
CloudPrefabType.GiantsDeep or CloudPrefabType.QuantumMoon => (atmo.clouds.outerCloudRadius + atmo.clouds.innerCloudRadius) / 2f,
_ => atmo.clouds.outerCloudRadius,
};
if (noAudio) if (noAudio)
{ {
lightningGenerator._audioPrefab = null; lightningGenerator._audioPrefab = null;
lightningGenerator._audioSourcePool = null; lightningGenerator._audioSourcePool = null;
} }
lightningGenerator._audioSector = sector; lightningGenerator._audioSector = sector;
if (atmo.clouds.lightningGradient != null) if (atmo.clouds.lightningGradient != null)
{ {
@ -188,6 +205,7 @@ namespace NewHorizons.Builder.Atmosphere
lightningGenerator._lightColor.colorKeys = gradient; lightningGenerator._lightColor.colorKeys = gradient;
} }
lightning.SetActive(true); lightning.SetActive(true);
return lightningGenerator; return lightningGenerator;
} }
@ -204,6 +222,7 @@ namespace NewHorizons.Builder.Atmosphere
if (atmo.clouds.capPath == null) cap = ImageUtilities.ClearTexture(128, 128, wrap: true); if (atmo.clouds.capPath == null) cap = ImageUtilities.ClearTexture(128, 128, wrap: true);
else cap = ImageUtilities.GetTexture(mod, atmo.clouds.capPath, wrap: true); else cap = ImageUtilities.GetTexture(mod, atmo.clouds.capPath, wrap: true);
if (atmo.clouds.rampPath == null) ramp = ImageUtilities.CanvasScaled(image, 1, image.height); if (atmo.clouds.rampPath == null) ramp = ImageUtilities.CanvasScaled(image, 1, image.height);
else ramp = ImageUtilities.GetTexture(mod, atmo.clouds.rampPath); else ramp = ImageUtilities.GetTexture(mod, atmo.clouds.rampPath);
} }
@ -213,17 +232,17 @@ namespace NewHorizons.Builder.Atmosphere
return null; return null;
} }
GameObject cloudsTopGO = new GameObject("TopClouds"); var cloudsTopGO = new GameObject("TopClouds");
cloudsTopGO.SetActive(false); cloudsTopGO.SetActive(false);
cloudsTopGO.transform.parent = rootObject.transform; cloudsTopGO.transform.parent = rootObject.transform;
cloudsTopGO.transform.localScale = Vector3.one * atmo.clouds.outerCloudRadius; cloudsTopGO.transform.localScale = Vector3.one * atmo.clouds.outerCloudRadius;
MeshFilter topMF = cloudsTopGO.AddComponent<MeshFilter>(); var topMF = cloudsTopGO.AddComponent<MeshFilter>();
topMF.mesh = _gdTopCloudMesh; topMF.mesh = _gdTopCloudMesh;
MeshRenderer topMR = cloudsTopGO.AddComponent<MeshRenderer>(); var topMR = cloudsTopGO.AddComponent<MeshRenderer>();
Material[] prefabMaterials = atmo.clouds.cloudsPrefab == CloudPrefabType.GiantsDeep ? _gdCloudMaterials : _qmCloudMaterials; var prefabMaterials = atmo.clouds.cloudsPrefab == CloudPrefabType.GiantsDeep ? _gdCloudMaterials : _qmCloudMaterials;
var tempArray = new Material[2]; var tempArray = new Material[2];
if (atmo.clouds.cloudsPrefab == CloudPrefabType.Basic) if (atmo.clouds.cloudsPrefab == CloudPrefabType.Basic)
@ -289,7 +308,7 @@ namespace NewHorizons.Builder.Atmosphere
return null; return null;
} }
GameObject cloudsTransparentGO = new GameObject("TransparentClouds"); var cloudsTransparentGO = new GameObject("TransparentClouds");
cloudsTransparentGO.SetActive(false); cloudsTransparentGO.SetActive(false);
cloudsTransparentGO.transform.parent = rootObject.transform; cloudsTransparentGO.transform.parent = rootObject.transform;
cloudsTransparentGO.transform.localScale = Vector3.one * atmo.clouds.outerCloudRadius; cloudsTransparentGO.transform.localScale = Vector3.one * atmo.clouds.outerCloudRadius;
@ -297,7 +316,7 @@ namespace NewHorizons.Builder.Atmosphere
MeshFilter filter = cloudsTransparentGO.AddComponent<MeshFilter>(); MeshFilter filter = cloudsTransparentGO.AddComponent<MeshFilter>();
filter.mesh = _gdTopCloudMesh; filter.mesh = _gdTopCloudMesh;
MeshRenderer renderer = cloudsTransparentGO.AddComponent<MeshRenderer>(); var renderer = cloudsTransparentGO.AddComponent<MeshRenderer>();
var material = new Material(_transparentCloud); var material = new Material(_transparentCloud);
material.name = "TransparentClouds_" + image.name; material.name = "TransparentClouds_" + image.name;
material.SetTexture(MainTex, image); material.SetTexture(MainTex, image);
@ -305,7 +324,7 @@ namespace NewHorizons.Builder.Atmosphere
if (!isProxy) if (!isProxy)
{ {
GameObject tcrqcGO = new GameObject("TransparentCloudRenderQueueController"); var tcrqcGO = new GameObject("TransparentCloudRenderQueueController");
tcrqcGO.transform.SetParent(cloudsTransparentGO.transform, false); tcrqcGO.transform.SetParent(cloudsTransparentGO.transform, false);
tcrqcGO.layer = Layer.BasicEffectVolume; tcrqcGO.layer = Layer.BasicEffectVolume;
@ -315,7 +334,7 @@ namespace NewHorizons.Builder.Atmosphere
var owTriggerVolume = tcrqcGO.AddComponent<OWTriggerVolume>(); var owTriggerVolume = tcrqcGO.AddComponent<OWTriggerVolume>();
owTriggerVolume._shape = shape; owTriggerVolume._shape = shape;
TransparentCloudRenderQueueController tcrqc = tcrqcGO.AddComponent<TransparentCloudRenderQueueController>(); var tcrqc = tcrqcGO.AddComponent<TransparentCloudRenderQueueController>();
tcrqc.renderer = renderer; tcrqc.renderer = renderer;
} }

View File

@ -7,8 +7,7 @@ namespace NewHorizons.Builder.Atmosphere
{ {
private static readonly int FogColor = Shader.PropertyToID("_FogColor"); private static readonly int FogColor = Shader.PropertyToID("_FogColor");
private static Material _gdMaterial; private static Material _gdMaterial, _gdCloudMaterial;
private static Material _gdCloudMaterial;
private static bool _isInit; private static bool _isInit;
@ -59,12 +58,23 @@ namespace NewHorizons.Builder.Atmosphere
ER._material = _gdMaterial; ER._material = _gdMaterial;
if (config.Atmosphere?.clouds != null)
{
var cloudMaterial = new Material(_gdCloudMaterial); var cloudMaterial = new Material(_gdCloudMaterial);
if (config.Atmosphere?.clouds?.tint != null) if (config.Atmosphere?.clouds?.tint != null)
{ {
cloudMaterial.SetColor(FogColor, config.Atmosphere.clouds.tint.ToColor()); cloudMaterial.SetColor(FogColor, config.Atmosphere.clouds.tint.ToColor());
} }
// For all prefabs but GD we want grey fog between clouds
// I can't find an EffectsRuleset on the QM so I don't know how it works
else if (config.Atmosphere.clouds.cloudsPrefab != External.Modules.CloudPrefabType.GiantsDeep)
{
cloudMaterial.SetColor(FogColor, new Color(43f/255f, 51f/255f, 57f/255f));
}
ER._cloudMaterial = cloudMaterial; ER._cloudMaterial = cloudMaterial;
}
volumesGO.transform.position = planetGO.transform.position; volumesGO.transform.position = planetGO.transform.position;
rulesetGO.SetActive(true); rulesetGO.SetActive(true);

View File

@ -4,6 +4,7 @@ using NewHorizons.Utility;
using NewHorizons.Utility.OuterWilds; using NewHorizons.Utility.OuterWilds;
using NewHorizons.Utility.OWML; using NewHorizons.Utility.OWML;
using System; using System;
using System.Linq;
using System.Reflection; using System.Reflection;
using UnityEngine; using UnityEngine;
@ -102,6 +103,7 @@ namespace NewHorizons.Builder.General
{ {
handler.Method.Invoke(handler.Target, new object[] { command }); handler.Method.Invoke(handler.Target, new object[] { command });
} }
spv._interactVolume._listInteractions.First(x => x.promptText == UITextType.SuitUpPrompt).interactionEnabled = true;
} }
} }
} }

View File

@ -5,6 +5,7 @@ using NewHorizons.Utility.OWML;
using OWML.Common; using OWML.Common;
using OWML.Utils; using OWML.Utils;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using UnityEngine; using UnityEngine;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
@ -134,6 +135,9 @@ namespace NewHorizons.Builder.Props.Audio
public static GameObject Make(GameObject planetGO, Sector sector, SignalInfo info, IModBehaviour mod) public static GameObject Make(GameObject planetGO, Sector sector, SignalInfo info, IModBehaviour mod)
{ {
if (string.IsNullOrEmpty(info.frequency)) throw new System.Exception("Cannot make a signal without a frequency");
if (string.IsNullOrEmpty(info.name)) throw new System.Exception("Cannot make a signal without a name");
var owAudioSource = GeneralAudioBuilder.Make(planetGO, sector, info, mod); var owAudioSource = GeneralAudioBuilder.Make(planetGO, sector, info, mod);
var signalGO = owAudioSource.gameObject; var signalGO = owAudioSource.gameObject;

View File

@ -70,7 +70,7 @@ namespace NewHorizons.Builder.Props
/// </summary> /// </summary>
public static GameObject Make(GameObject planetGO, Sector sector, DetailInfo info) public static GameObject Make(GameObject planetGO, Sector sector, DetailInfo info)
{ {
_emptyPrefab ??= new GameObject("Empty"); if (_emptyPrefab == null) _emptyPrefab = new GameObject("Empty");
// Allow for empty game objects so you can set up conditional activation on them and parent other props to them // Allow for empty game objects so you can set up conditional activation on them and parent other props to them
var prefab = string.IsNullOrEmpty(info.path) ? _emptyPrefab : SearchUtilities.Find(info.path); var prefab = string.IsNullOrEmpty(info.path) ? _emptyPrefab : SearchUtilities.Find(info.path);

View File

@ -224,9 +224,16 @@ namespace NewHorizons.Builder.Props
if (config.Props.signals != null) if (config.Props.signals != null)
{ {
foreach (var signal in config.Props.signals) foreach (var signal in config.Props.signals)
{
try
{ {
SignalBuilder.Make(go, sector, signal, mod); SignalBuilder.Make(go, sector, signal, mod);
} }
catch (Exception ex)
{
NHLogger.LogError($"Couldn't make signal on planet [{config.name}] - {ex}");
}
}
} }
if (config.Props.remotes != null) if (config.Props.remotes != null)
{ {

View File

@ -1,3 +1,4 @@
using NewHorizons.Builder.Volumes;
using NewHorizons.Components.Props; using NewHorizons.Components.Props;
using NewHorizons.External.Modules.Props; using NewHorizons.External.Modules.Props;
using NewHorizons.Handlers; using NewHorizons.Handlers;
@ -169,6 +170,11 @@ namespace NewHorizons.Builder.Props
ApplyWanderer(tornadoGO, planetGO, info); ApplyWanderer(tornadoGO, planetGO, info);
} }
if (info.hazardType != null || info.firstContactDamageType != null)
{
HazardVolumeBuilder.AddHazardVolume(fluidGO.gameObject, sector, planetGO.GetComponent<OWRigidbody>(), info.hazardType, info.firstContactDamageType, info.firstContactDamage, info.damagePerSecond);
}
soundGO.SetActive(true); soundGO.SetActive(true);
tornadoGO.SetActive(true); tornadoGO.SetActive(true);
} }
@ -196,10 +202,6 @@ namespace NewHorizons.Builder.Props
child.localPosition = new Vector3(0, 60, 0); child.localPosition = new Vector3(0, 60, 0);
child.localScale = Vector3.one * 1.1f; child.localScale = Vector3.one * 1.1f;
} }
if (child.name.Equals("Effects_GD_HurricaneCycloneExterior"))
{
child.localScale = new Vector3(0.88f, 1f, 0.88f);
}
} }
} }
@ -228,6 +230,11 @@ namespace NewHorizons.Builder.Props
ApplyWanderer(hurricaneGO, planetGO, info); ApplyWanderer(hurricaneGO, planetGO, info);
} }
if (info.hazardType != null || info.firstContactDamageType != null)
{
HazardVolumeBuilder.AddHazardVolume(fluidVolume.gameObject, sector, planetGO.GetComponent<OWRigidbody>(), info.hazardType, info.firstContactDamageType, info.firstContactDamage, info.damagePerSecond);
}
hurricaneGO.SetActive(true); hurricaneGO.SetActive(true);
} }

View File

@ -21,23 +21,32 @@ namespace NewHorizons.Builder.Volumes
var owTriggerVolume = go.AddComponent<OWTriggerVolume>(); var owTriggerVolume = go.AddComponent<OWTriggerVolume>();
owTriggerVolume._shape = shape; owTriggerVolume._shape = shape;
var volume = AddHazardVolume(go, sector, owrb, info.type, info.firstContactDamageType, info.firstContactDamage, info.damagePerSecond);
go.SetActive(true);
return volume;
}
public static HazardVolume AddHazardVolume(GameObject go, Sector sector, OWRigidbody owrb, HazardVolumeInfo.HazardType? type, HazardVolumeInfo.InstantDamageType? firstContactDamageType, float firstContactDamage, float damagePerSecond)
{
HazardVolume hazardVolume = null; HazardVolume hazardVolume = null;
if (info.type == HazardVolumeInfo.HazardType.RIVERHEAT) if (type == HazardVolumeInfo.HazardType.RIVERHEAT)
{ {
hazardVolume = go.AddComponent<RiverHeatHazardVolume>(); hazardVolume = go.AddComponent<RiverHeatHazardVolume>();
} }
else if (info.type == HazardVolumeInfo.HazardType.HEAT) else if (type == HazardVolumeInfo.HazardType.HEAT)
{ {
hazardVolume = go.AddComponent<HeatHazardVolume>(); hazardVolume = go.AddComponent<HeatHazardVolume>();
} }
else if (info.type == HazardVolumeInfo.HazardType.DARKMATTER) else if (type == HazardVolumeInfo.HazardType.DARKMATTER)
{ {
hazardVolume = go.AddComponent<DarkMatterVolume>(); hazardVolume = go.AddComponent<DarkMatterVolume>();
var visorFrostEffectVolume = go.AddComponent<VisorFrostEffectVolume>(); var visorFrostEffectVolume = go.AddComponent<VisorFrostEffectVolume>();
visorFrostEffectVolume._frostRate = 0.5f; visorFrostEffectVolume._frostRate = 0.5f;
visorFrostEffectVolume._maxFrost = 0.91f; visorFrostEffectVolume._maxFrost = 0.91f;
var water = planetGO.GetComponentsInChildren<RadialFluidVolume>().FirstOrDefault(x => x._fluidType == FluidVolume.Type.WATER); var water = owrb.GetComponentsInChildren<RadialFluidVolume>().FirstOrDefault(x => x._fluidType == FluidVolume.Type.WATER);
if (water != null) if (water != null)
{ {
var submerge = go.AddComponent<DarkMatterSubmergeController>(); var submerge = go.AddComponent<DarkMatterSubmergeController>();
@ -58,7 +67,7 @@ namespace NewHorizons.Builder.Volumes
submerge._fluidDetector = detector; submerge._fluidDetector = detector;
} }
} }
else if (info.type == HazardVolumeInfo.HazardType.ELECTRICITY) else if (type == HazardVolumeInfo.HazardType.ELECTRICITY)
{ {
var electricityVolume = go.AddComponent<ElectricityVolume>(); var electricityVolume = go.AddComponent<ElectricityVolume>();
electricityVolume._shockAudioPool = new OWAudioSource[0]; electricityVolume._shockAudioPool = new OWAudioSource[0];
@ -67,15 +76,17 @@ namespace NewHorizons.Builder.Volumes
else else
{ {
var simpleHazardVolume = go.AddComponent<SimpleHazardVolume>(); var simpleHazardVolume = go.AddComponent<SimpleHazardVolume>();
simpleHazardVolume._type = EnumUtils.Parse<HazardVolume.HazardType>(info.type.ToString(), HazardVolume.HazardType.GENERAL); simpleHazardVolume._type = EnumUtils.Parse(type.ToString(), HazardVolume.HazardType.GENERAL);
hazardVolume = simpleHazardVolume; hazardVolume = simpleHazardVolume;
} }
hazardVolume._attachedBody = owrb; hazardVolume._attachedBody = owrb;
hazardVolume._damagePerSecond = info.damagePerSecond; hazardVolume._damagePerSecond = type == null ? 0f : damagePerSecond;
hazardVolume._firstContactDamageType = EnumUtils.Parse<InstantDamageType>(info.firstContactDamageType.ToString(), InstantDamageType.Impact);
hazardVolume._firstContactDamage = info.firstContactDamage;
go.SetActive(true); if (firstContactDamageType != null)
{
hazardVolume._firstContactDamageType = EnumUtils.Parse(firstContactDamageType.ToString(), InstantDamageType.Impact);
hazardVolume._firstContactDamage = firstContactDamage;
}
return hazardVolume; return hazardVolume;
} }

View File

@ -5,6 +5,7 @@ using NewHorizons.Utility.OuterWilds;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityEngine; using UnityEngine;
namespace NewHorizons.Components namespace NewHorizons.Components
{ {
public class NHProxy : ProxyPlanet public class NHProxy : ProxyPlanet

View File

@ -364,7 +364,10 @@ namespace NewHorizons.Components.SizeControllers
_surface._materials[0].CopyPropertiesFromMaterial(_collapseStartSurfaceMaterial); _surface._materials[0].CopyPropertiesFromMaterial(_collapseStartSurfaceMaterial);
if (oneShotSource != null && !PlayerState.IsSleepingAtCampfire() && !PlayerState.InDreamWorld()) oneShotSource.PlayOneShot(AudioType.Sun_Collapse); if (oneShotSource != null && !PlayerState.IsSleepingAtCampfire() && !PlayerState.InDreamWorld()) oneShotSource.PlayOneShot(AudioType.Sun_Collapse);
if (_proxy != null) _proxy.StartCollapse(); if (_proxy != null)
{
_proxy.StartCollapse();
}
} }
public void StopCollapse() public void StopCollapse()
@ -396,7 +399,14 @@ namespace NewHorizons.Components.SizeControllers
if (planetDestructionVolume != null) planetDestructionVolume._deathType = DeathType.Supernova; if (planetDestructionVolume != null) planetDestructionVolume._deathType = DeathType.Supernova;
if (oneShotSource != null && !PlayerState.IsSleepingAtCampfire() && !PlayerState.InDreamWorld()) oneShotSource.PlayOneShot(AudioType.Sun_Explosion); if (oneShotSource != null && !PlayerState.IsSleepingAtCampfire() && !PlayerState.InDreamWorld()) oneShotSource.PlayOneShot(AudioType.Sun_Explosion);
if (_proxy != null) _proxy.StartSupernova(); if (_proxy != null)
{
_proxy.StartSupernova();
// When the supernova starts some effects start on, we have to refresh their states
var nhproxy = _proxy.GetComponentInParent<NHProxy>();
nhproxy.ToggleRendering(!nhproxy._outOfRange);
}
} }
public void StopSupernova() public void StopSupernova()

View File

@ -84,6 +84,7 @@ namespace NewHorizons.Components.Stars
{ {
float dt = Mathf.InverseLerp(12000f, 0.0f, distanceToPlayer); float dt = Mathf.InverseLerp(12000f, 0.0f, distanceToPlayer);
audioSource.SetLocalVolume(Mathf.Lerp(0.0f, 1f, dt * dt) * Mathf.InverseLerp(0.0f, 5f, _time)); audioSource.SetLocalVolume(Mathf.Lerp(0.0f, 1f, dt * dt) * Mathf.InverseLerp(0.0f, 5f, _time));
audioSource.maxDistance = shockwaveScale.Evaluate(shockwaveTime);
} }
RumbleManager.UpdateSupernova(distanceToPlayer); RumbleManager.UpdateSupernova(distanceToPlayer);
@ -97,7 +98,10 @@ namespace NewHorizons.Components.Stars
public void SetParticlesVisibility(bool visible) public void SetParticlesVisibility(bool visible)
{ {
foreach (var particleRenderer in _cachedParticleRenderers) particleRenderer.enabled = visible; foreach (var particleRenderer in _cachedParticleRenderers)
{
particleRenderer.enabled = visible;
}
} }
public void SetRenderingEnabled(bool renderingEnabled) public void SetRenderingEnabled(bool renderingEnabled)

View File

@ -192,6 +192,9 @@ namespace NewHorizons.Components.Stars
// For the param thing to work it wants this to be on the star idk // For the param thing to work it wants this to be on the star idk
transform.parent = star.transform; transform.parent = star.transform;
transform.localPosition = Vector3.zero; transform.localPosition = Vector3.zero;
// Some effects use Locator.GetSunTransform so hopefully its fine to change it
Locator._sunTransform = transform;
} }
} }
} }

View File

@ -1,3 +1,4 @@
using NewHorizons.External.Modules.Volumes.VolumeInfos;
using NewHorizons.External.SerializableData; using NewHorizons.External.SerializableData;
using NewHorizons.External.SerializableEnums; using NewHorizons.External.SerializableEnums;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -69,6 +70,26 @@ namespace NewHorizons.External.Modules.Props
/// Fluid type for sounds/effects when colliding with this tornado. /// Fluid type for sounds/effects when colliding with this tornado.
/// </summary> /// </summary>
[DefaultValue("cloud")] public NHFluidType fluidType = NHFluidType.CLOUD; [DefaultValue("cloud")] public NHFluidType fluidType = NHFluidType.CLOUD;
/// <summary>
/// The type of hazard for this volume. Leave empty for this tornado to not be hazardous.
/// </summary>
public HazardVolumeInfo.HazardType? hazardType;
/// <summary>
/// The amount of damage you will take per second while inside this tornado. Only used it hazardType is set.
/// </summary>
[DefaultValue(10f)] public float damagePerSecond = 10f;
/// <summary>
/// The type of damage you will take when you first touch this volume. Leave empty for this tornado to not cause damage on first contact.
/// </summary>
public HazardVolumeInfo.InstantDamageType? firstContactDamageType;
/// <summary>
/// The amount of damage you will take when you first touch this volume. Only relevant if firstContactDamageType is set.
/// </summary>
[DefaultValue(10f)] public float firstContactDamage = 10f;
} }
} }

View File

@ -644,7 +644,10 @@ namespace NewHorizons.Handlers
if (!string.IsNullOrEmpty(body.Config.Atmosphere?.clouds?.texturePath)) if (!string.IsNullOrEmpty(body.Config.Atmosphere?.clouds?.texturePath))
{ {
CloudsBuilder.Make(go, sector, body.Config.Atmosphere, willHaveCloak, body.Mod); CloudsBuilder.Make(go, sector, body.Config.Atmosphere, willHaveCloak, body.Mod);
if (body.Config.Atmosphere.clouds.cloudsPrefab != External.Modules.CloudPrefabType.Transparent) SunOverrideBuilder.Make(go, sector, body.Config.Atmosphere, body.Config.Water, surfaceSize); if (body.Config.Atmosphere.clouds.cloudsPrefab != External.Modules.CloudPrefabType.Transparent)
{
SunOverrideBuilder.Make(go, sector, body.Config.Atmosphere, body.Config.Water, surfaceSize);
}
} }
if (body.Config.Atmosphere.hasRain || body.Config.Atmosphere.hasSnow) if (body.Config.Atmosphere.hasRain || body.Config.Atmosphere.hasSnow)

View File

@ -0,0 +1,38 @@
using HarmonyLib;
using UnityEngine;
namespace NewHorizons.Patches;
[HarmonyPatch(typeof(GlobalMusicController))]
public class GlobalMusicControllerPatches
{
private static AudioDetector _audioDetector;
[HarmonyPrefix]
[HarmonyPatch(nameof(GlobalMusicController.UpdateBrambleMusic))]
public static bool GlobalMusicController_UpdateBrambleMusic(GlobalMusicController __instance)
{
// is this too hacky?
if (_audioDetector == null) _audioDetector = Object.FindObjectOfType<AudioDetector>();
var shouldBePlaying = Locator.GetPlayerSectorDetector().InBrambleDimension() &&
!Locator.GetPlayerSectorDetector().InVesselDimension() &&
PlayerState.AtFlightConsole() &&
!PlayerState.IsHullBreached() &&
!__instance._playingFinalEndTimes &&
_audioDetector._activeVolumes.Count == 0; // change - don't play if in another audio volume
var playing = __instance._darkBrambleSource.isPlaying &&
!__instance._darkBrambleSource.IsFadingOut();
if (shouldBePlaying && !playing)
{
__instance._darkBrambleSource.FadeIn(5f);
}
else if (!shouldBePlaying && playing)
{
__instance._darkBrambleSource.FadeOut(5f);
}
return false;
}
}

View File

@ -2132,6 +2132,40 @@
"description": "Fluid type for sounds/effects when colliding with this tornado.", "description": "Fluid type for sounds/effects when colliding with this tornado.",
"default": "cloud", "default": "cloud",
"$ref": "#/definitions/NHFluidType" "$ref": "#/definitions/NHFluidType"
},
"hazardType": {
"description": "The type of hazard for this volume. Leave empty for this tornado to not be hazardous.",
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/definitions/HazardType"
}
]
},
"damagePerSecond": {
"type": "number",
"description": "The amount of damage you will take per second while inside this tornado. Only used it hazardType is set.",
"format": "float",
"default": 10.0
},
"firstContactDamageType": {
"description": "The type of damage you will take when you first touch this volume. Leave empty for this tornado to not cause damage on first contact.",
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/definitions/InstantDamageType"
}
]
},
"firstContactDamage": {
"type": "number",
"description": "The amount of damage you will take when you first touch this volume. Only relevant if firstContactDamageType is set.",
"format": "float",
"default": 10.0
} }
} }
}, },
@ -2149,6 +2183,46 @@
"hurricane" "hurricane"
] ]
}, },
"HazardType": {
"type": "string",
"description": "",
"x-enumNames": [
"NONE",
"GENERAL",
"DARKMATTER",
"HEAT",
"FIRE",
"SANDFALL",
"ELECTRICITY",
"RAPIDS",
"RIVERHEAT"
],
"enum": [
"none",
"general",
"ghostMatter",
"heat",
"fire",
"sandfall",
"electricity",
"rapids",
"riverHeat"
]
},
"InstantDamageType": {
"type": "string",
"description": "",
"x-enumNames": [
"Impact",
"Puncture",
"Electrical"
],
"enum": [
"impact",
"puncture",
"electrical"
]
},
"VolcanoInfo": { "VolcanoInfo": {
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
@ -3846,46 +3920,6 @@
} }
} }
}, },
"HazardType": {
"type": "string",
"description": "",
"x-enumNames": [
"NONE",
"GENERAL",
"DARKMATTER",
"HEAT",
"FIRE",
"SANDFALL",
"ELECTRICITY",
"RAPIDS",
"RIVERHEAT"
],
"enum": [
"none",
"general",
"ghostMatter",
"heat",
"fire",
"sandfall",
"electricity",
"rapids",
"riverHeat"
]
},
"InstantDamageType": {
"type": "string",
"description": "",
"x-enumNames": [
"Impact",
"Puncture",
"Electrical"
],
"enum": [
"impact",
"puncture",
"electrical"
]
},
"VolumeInfo": { "VolumeInfo": {
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,

View File

@ -4,7 +4,7 @@
"author": "xen, Bwc9876, clay, MegaPiggy, John, Trifid, Hawkbar, Book", "author": "xen, Bwc9876, clay, MegaPiggy, John, Trifid, Hawkbar, Book",
"name": "New Horizons", "name": "New Horizons",
"uniqueName": "xen.NewHorizons", "uniqueName": "xen.NewHorizons",
"version": "1.12.6", "version": "1.12.7",
"owmlVersion": "2.9.3", "owmlVersion": "2.9.3",
"dependencies": [ "JohnCorby.VanillaFix", "_nebula.MenuFramework", "xen.CommonCameraUtility", "dgarro.CustomShipLogModes" ], "dependencies": [ "JohnCorby.VanillaFix", "_nebula.MenuFramework", "xen.CommonCameraUtility", "dgarro.CustomShipLogModes" ],
"conflicts": [ "Raicuparta.QuantumSpaceBuddies", "PacificEngine.OW_CommonResources" ], "conflicts": [ "Raicuparta.QuantumSpaceBuddies", "PacificEngine.OW_CommonResources" ],