mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
Particle/Vection Fields (#665)
<!-- A new module or something else important --> ## Major features - New `ParticleFields` module. Add particles to your planet (ex: leaves, rain, snow, fireflies, and more). Resolves #219 <!-- A new parameter added to a module, or API feature --> ## Minor features - <!-- Some improvement that requires no action on the part of add-on creators i.e., improved star graphics --> ## Improvements - <!-- Be sure to reference the existing issue if it exists --> ## Bug fixes -
This commit is contained in:
commit
d1072e10cb
@ -1,4 +1,5 @@
|
|||||||
using NewHorizons.External.Configs;
|
using NewHorizons.External.Configs;
|
||||||
|
using NewHorizons.External.Modules;
|
||||||
using NewHorizons.Utility;
|
using NewHorizons.Utility;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
namespace NewHorizons.Builder.Atmosphere
|
namespace NewHorizons.Builder.Atmosphere
|
||||||
@ -7,6 +8,21 @@ namespace NewHorizons.Builder.Atmosphere
|
|||||||
{
|
{
|
||||||
private static GameObject _rainEmitterPrefab;
|
private static GameObject _rainEmitterPrefab;
|
||||||
private static GameObject _snowEmitterPrefab;
|
private static GameObject _snowEmitterPrefab;
|
||||||
|
private static GameObject _snowLightEmitterPrefab;
|
||||||
|
private static GameObject _emberEmitterPrefab;
|
||||||
|
private static GameObject _leafEmitterPrefab;
|
||||||
|
private static GameObject _planktonEmitterPrefab;
|
||||||
|
private static GameObject _bubbleEmitterPrefab;
|
||||||
|
private static GameObject _currentEmitterPrefab;
|
||||||
|
private static GameObject _cloudEmitterPrefab;
|
||||||
|
private static GameObject _crawliesEmitterPrefab;
|
||||||
|
private static GameObject _firefliesEmitterPrefab;
|
||||||
|
private static GameObject _pollenEmitterPrefab;
|
||||||
|
private static GameObject _iceMoteEmitterPrefab;
|
||||||
|
private static GameObject _rockMoteEmitterPrefab;
|
||||||
|
private static GameObject _crystalMoteEmitterPrefab;
|
||||||
|
private static GameObject _sandMoteEmitterPrefab;
|
||||||
|
private static GameObject _fogEmitterPrefab;
|
||||||
|
|
||||||
private static bool _isInit;
|
private static bool _isInit;
|
||||||
|
|
||||||
@ -18,9 +34,24 @@ namespace NewHorizons.Builder.Atmosphere
|
|||||||
|
|
||||||
if (_rainEmitterPrefab == null) _rainEmitterPrefab = SearchUtilities.Find("GiantsDeep_Body/Sector_GD/Sector_GDInterior/Effects_GDInterior/Effects_GD_Rain").InstantiateInactive().Rename("Prefab_Effects_Rain").DontDestroyOnLoad();
|
if (_rainEmitterPrefab == null) _rainEmitterPrefab = SearchUtilities.Find("GiantsDeep_Body/Sector_GD/Sector_GDInterior/Effects_GDInterior/Effects_GD_Rain").InstantiateInactive().Rename("Prefab_Effects_Rain").DontDestroyOnLoad();
|
||||||
if (_snowEmitterPrefab == null) _snowEmitterPrefab = SearchUtilities.Find("BrittleHollow_Body/Sector_BH/Effects_BH/Effects_BH_Snowflakes").InstantiateInactive().Rename("Prefab_Effects_Snowflakes").DontDestroyOnLoad();
|
if (_snowEmitterPrefab == null) _snowEmitterPrefab = SearchUtilities.Find("BrittleHollow_Body/Sector_BH/Effects_BH/Effects_BH_Snowflakes").InstantiateInactive().Rename("Prefab_Effects_Snowflakes").DontDestroyOnLoad();
|
||||||
|
if (_snowLightEmitterPrefab == null) _snowLightEmitterPrefab = SearchUtilities.Find("TimberHearth_Body/Sector_TH/Effects_TH/Effects_TH_Snowflakes").InstantiateInactive().Rename("Prefab_Effects_SnowflakesLight").DontDestroyOnLoad();
|
||||||
|
if (_emberEmitterPrefab == null) _emberEmitterPrefab = SearchUtilities.Find("VolcanicMoon_Body/Sector_VM/Effects_VM/Effects_VM_Embers").InstantiateInactive().Rename("Prefab_Effects_Embers").DontDestroyOnLoad();
|
||||||
|
if (_leafEmitterPrefab == null) _leafEmitterPrefab = SearchUtilities.Find("GiantsDeep_Body/Sector_GD/Sector_GDInterior/Effects_GDInterior/Effects_GD_Leaves").InstantiateInactive().Rename("Prefab_Effects_Leaves").DontDestroyOnLoad();
|
||||||
|
if (_planktonEmitterPrefab == null) _planktonEmitterPrefab = SearchUtilities.Find("GiantsDeep_Body/Sector_GD/Sector_GDInterior/Effects_GDInterior/Effects_GD_Plankton").InstantiateInactive().Rename("Prefab_Effects_Plankton").DontDestroyOnLoad();
|
||||||
|
if (_bubbleEmitterPrefab == null) _bubbleEmitterPrefab = SearchUtilities.Find("GiantsDeep_Body/Sector_GD/Sector_GDInterior/Effects_GDInterior/Effects_GD_Bubbles").InstantiateInactive().Rename("Prefab_Effects_Bubbles").DontDestroyOnLoad();
|
||||||
|
if (_currentEmitterPrefab == null) _currentEmitterPrefab = SearchUtilities.Find("GiantsDeep_Body/Sector_GD/Sector_GDInterior/Effects_GDInterior/Effects_GD_RadialCurrent").InstantiateInactive().Rename("Prefab_Effects_Current").DontDestroyOnLoad();
|
||||||
|
if (_cloudEmitterPrefab == null) _cloudEmitterPrefab = SearchUtilities.Find("GiantsDeep_Body/Sector_GD/Effects_GD/Effects_GD_Clouds").InstantiateInactive().Rename("Prefab_Effects_Clouds").DontDestroyOnLoad();
|
||||||
|
if (_crawliesEmitterPrefab == null) _crawliesEmitterPrefab = SearchUtilities.Find("DB_EscapePodDimension_Body/Sector_EscapePodDimension/Effects_EscapePodDimension/Effects_DB_Crawlies (1)").InstantiateInactive().Rename("Prefab_Effects_Crawlies").DontDestroyOnLoad();
|
||||||
|
if (_firefliesEmitterPrefab == null) _firefliesEmitterPrefab = SearchUtilities.Find("TimberHearth_Body/Sector_TH/Effects_TH/Effects_TH_Fireflies").InstantiateInactive().Rename("Prefab_Effects_Fireflies").DontDestroyOnLoad();
|
||||||
|
if (_pollenEmitterPrefab == null) _pollenEmitterPrefab = SearchUtilities.Find("TimberHearth_Body/Sector_TH/Effects_TH/Effects_TH_SurfacePollen").InstantiateInactive().Rename("Prefab_Effects_Pollen").DontDestroyOnLoad();
|
||||||
|
if (_iceMoteEmitterPrefab == null) _iceMoteEmitterPrefab = SearchUtilities.Find("DarkBramble_Body/Effects_DB/Effects_DB_IceMotes").InstantiateInactive().Rename("Prefab_Effects_IceMotes").DontDestroyOnLoad();
|
||||||
|
if (_rockMoteEmitterPrefab == null) _rockMoteEmitterPrefab = SearchUtilities.Find("BrittleHollow_Body/Sector_BH/Effects_BH/Effects_BH_RockMotes").InstantiateInactive().Rename("Prefab_Effects_RockMotes").DontDestroyOnLoad();
|
||||||
|
if (_crystalMoteEmitterPrefab == null) _crystalMoteEmitterPrefab = SearchUtilities.Find("BrittleHollow_Body/Sector_BH/Effects_BH/Effects_BH_CrystalMotes").InstantiateInactive().Rename("Prefab_Effects_CrystalMotes").DontDestroyOnLoad();
|
||||||
|
if (_sandMoteEmitterPrefab == null) _sandMoteEmitterPrefab = SearchUtilities.Find("CaveTwin_Body/Sector_CaveTwin/Effects_CaveTwin/Effects_HGT_SandMotes").InstantiateInactive().Rename("Prefab_Effects_SandMotes").DontDestroyOnLoad();
|
||||||
|
if (_fogEmitterPrefab == null) _fogEmitterPrefab = SearchUtilities.Find("DB_EscapePodDimension_Body/Sector_EscapePodDimension/Effects_EscapePodDimension/Effects_DB_Fog (1)").InstantiateInactive().Rename("Prefab_Effects_Fog").DontDestroyOnLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Make(GameObject planetGO, Sector sector, PlanetConfig config, float surfaceSize)
|
public static void Make(GameObject planetGO, Sector sector, PlanetConfig config)
|
||||||
{
|
{
|
||||||
InitPrefabs();
|
InitPrefabs();
|
||||||
|
|
||||||
@ -36,7 +67,7 @@ namespace NewHorizons.Builder.Atmosphere
|
|||||||
SCG._dynamicCullingBounds = false;
|
SCG._dynamicCullingBounds = false;
|
||||||
SCG._waitForStreaming = false;
|
SCG._waitForStreaming = false;
|
||||||
|
|
||||||
var minHeight = surfaceSize;
|
var minHeight = config.Base.surfaceSize;
|
||||||
if (config.HeightMap?.minHeight != null)
|
if (config.HeightMap?.minHeight != null)
|
||||||
{
|
{
|
||||||
if (config.Water?.size >= config.HeightMap.minHeight) minHeight = config.Water.size; // use sea level if its higher
|
if (config.Water?.size >= config.HeightMap.minHeight) minHeight = config.Water.size; // use sea level if its higher
|
||||||
@ -48,52 +79,56 @@ namespace NewHorizons.Builder.Atmosphere
|
|||||||
var maxHeight = config.Atmosphere.size;
|
var maxHeight = config.Atmosphere.size;
|
||||||
if (config.Atmosphere.clouds?.outerCloudRadius != null) maxHeight = config.Atmosphere.clouds.outerCloudRadius;
|
if (config.Atmosphere.clouds?.outerCloudRadius != null) maxHeight = config.Atmosphere.clouds.outerCloudRadius;
|
||||||
|
|
||||||
if (config.Atmosphere.hasRain)
|
foreach (var particleField in config.ParticleFields)
|
||||||
{
|
{
|
||||||
var rainGO = Object.Instantiate(_rainEmitterPrefab, effectsGO.transform);
|
var prefab = GetPrefabByType(particleField.type);
|
||||||
rainGO.name = "RainEmitter";
|
var emitter = Object.Instantiate(prefab, effectsGO.transform);
|
||||||
rainGO.transform.position = planetGO.transform.position;
|
emitter.name = !string.IsNullOrWhiteSpace(particleField.rename) ? particleField.rename : prefab.name.Replace("Prefab_", "");
|
||||||
|
emitter.transform.position = planetGO.transform.position;
|
||||||
|
|
||||||
var pvc = rainGO.GetComponent<PlanetaryVectionController>();
|
var vfe = emitter.GetComponent<VectionFieldEmitter>();
|
||||||
pvc._densityByHeight = new AnimationCurve(new Keyframe[]
|
var pvc = emitter.GetComponent<PlanetaryVectionController>();
|
||||||
|
pvc._vectionFieldEmitter = vfe;
|
||||||
|
pvc._densityByHeight = particleField.densityByHeightCurve != null ? particleField.densityByHeightCurve.ToAnimationCurve() : new AnimationCurve(new Keyframe[]
|
||||||
{
|
{
|
||||||
new Keyframe(minHeight - 0.5f, 0),
|
new Keyframe(minHeight - 0.5f, 0),
|
||||||
new Keyframe(minHeight, 10f),
|
new Keyframe(minHeight, 10f),
|
||||||
new Keyframe(maxHeight, 0f)
|
new Keyframe(maxHeight, 0f)
|
||||||
});
|
});
|
||||||
|
pvc._followTarget = particleField.followTarget == ParticleFieldModule.FollowTarget.Probe ? PlanetaryVectionController.FollowTarget.Probe : PlanetaryVectionController.FollowTarget.Player;
|
||||||
|
pvc._activeInSector = sector;
|
||||||
|
pvc._exclusionSectors = new Sector[] { };
|
||||||
|
|
||||||
rainGO.GetComponent<PlanetaryVectionController>()._activeInSector = sector;
|
emitter.SetActive(true);
|
||||||
rainGO.GetComponent<PlanetaryVectionController>()._exclusionSectors = new Sector[] { };
|
|
||||||
rainGO.SetActive(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.Atmosphere.hasSnow)
|
|
||||||
{
|
|
||||||
var snowGO = new GameObject("SnowEffects");
|
|
||||||
snowGO.transform.parent = effectsGO.transform;
|
|
||||||
snowGO.transform.position = planetGO.transform.position;
|
|
||||||
for (int i = 0; i < 5; i++)
|
|
||||||
{
|
|
||||||
var snowEmitter = Object.Instantiate(_snowEmitterPrefab, snowGO.transform);
|
|
||||||
snowEmitter.name = "SnowEmitter";
|
|
||||||
snowEmitter.transform.position = planetGO.transform.position;
|
|
||||||
|
|
||||||
var pvc = snowEmitter.GetComponent<PlanetaryVectionController>();
|
|
||||||
pvc._densityByHeight = new AnimationCurve(new Keyframe[]
|
|
||||||
{
|
|
||||||
new Keyframe(minHeight - 0.5f, 0),
|
|
||||||
new Keyframe(minHeight, 10f),
|
|
||||||
new Keyframe(maxHeight, 0f)
|
|
||||||
});
|
|
||||||
|
|
||||||
snowEmitter.GetComponent<PlanetaryVectionController>()._activeInSector = sector;
|
|
||||||
snowEmitter.GetComponent<PlanetaryVectionController>()._exclusionSectors = new Sector[] { };
|
|
||||||
snowEmitter.SetActive(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
effectsGO.transform.position = planetGO.transform.position;
|
effectsGO.transform.position = planetGO.transform.position;
|
||||||
effectsGO.SetActive(true);
|
effectsGO.SetActive(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static GameObject GetPrefabByType(ParticleFieldModule.ParticleFieldType type)
|
||||||
|
{
|
||||||
|
return type switch
|
||||||
|
{
|
||||||
|
ParticleFieldModule.ParticleFieldType.Rain => _rainEmitterPrefab,
|
||||||
|
ParticleFieldModule.ParticleFieldType.SnowflakesHeavy => _snowEmitterPrefab,
|
||||||
|
ParticleFieldModule.ParticleFieldType.SnowflakesLight => _snowLightEmitterPrefab,
|
||||||
|
ParticleFieldModule.ParticleFieldType.Embers => _emberEmitterPrefab,
|
||||||
|
ParticleFieldModule.ParticleFieldType.Clouds => _cloudEmitterPrefab,
|
||||||
|
ParticleFieldModule.ParticleFieldType.Leaves => _leafEmitterPrefab,
|
||||||
|
ParticleFieldModule.ParticleFieldType.Bubbles => _bubbleEmitterPrefab,
|
||||||
|
ParticleFieldModule.ParticleFieldType.Fog => _fogEmitterPrefab,
|
||||||
|
ParticleFieldModule.ParticleFieldType.CrystalMotes => _crystalMoteEmitterPrefab,
|
||||||
|
ParticleFieldModule.ParticleFieldType.RockMotes => _rockMoteEmitterPrefab,
|
||||||
|
ParticleFieldModule.ParticleFieldType.IceMotes => _iceMoteEmitterPrefab,
|
||||||
|
ParticleFieldModule.ParticleFieldType.SandMotes => _sandMoteEmitterPrefab,
|
||||||
|
ParticleFieldModule.ParticleFieldType.Crawlies => _crawliesEmitterPrefab,
|
||||||
|
ParticleFieldModule.ParticleFieldType.Fireflies => _firefliesEmitterPrefab,
|
||||||
|
ParticleFieldModule.ParticleFieldType.Plankton => _planktonEmitterPrefab,
|
||||||
|
ParticleFieldModule.ParticleFieldType.Pollen => _pollenEmitterPrefab,
|
||||||
|
ParticleFieldModule.ParticleFieldType.Current => _currentEmitterPrefab,
|
||||||
|
_ => null,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
30
NewHorizons/External/Configs/PlanetConfig.cs
vendored
30
NewHorizons/External/Configs/PlanetConfig.cs
vendored
@ -13,6 +13,7 @@ using System.Collections.Generic;
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace NewHorizons.External.Configs
|
namespace NewHorizons.External.Configs
|
||||||
{
|
{
|
||||||
@ -167,6 +168,12 @@ namespace NewHorizons.External.Configs
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public WaterModule Water;
|
public WaterModule Water;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add particle effects in a field around the planet.
|
||||||
|
/// Also known as Vection Fields.
|
||||||
|
/// </summary>
|
||||||
|
public ParticleFieldModule[] ParticleFields;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add various volumes on this body
|
/// Add various volumes on this body
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -341,6 +348,29 @@ namespace NewHorizons.External.Configs
|
|||||||
// useBasicCloudShader is obsolete
|
// useBasicCloudShader is obsolete
|
||||||
if (Atmosphere.clouds != null && Atmosphere.clouds.useBasicCloudShader)
|
if (Atmosphere.clouds != null && Atmosphere.clouds.useBasicCloudShader)
|
||||||
Atmosphere.clouds.cloudsPrefab = CloudPrefabType.Basic;
|
Atmosphere.clouds.cloudsPrefab = CloudPrefabType.Basic;
|
||||||
|
|
||||||
|
if (Atmosphere.hasRain)
|
||||||
|
{
|
||||||
|
if (ParticleFields == null) ParticleFields = new ParticleFieldModule[0];
|
||||||
|
ParticleFields = ParticleFields.Append(new ParticleFieldModule
|
||||||
|
{
|
||||||
|
type = ParticleFieldModule.ParticleFieldType.Rain,
|
||||||
|
rename = "RainEmitter"
|
||||||
|
}).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Atmosphere.hasSnow)
|
||||||
|
{
|
||||||
|
if (ParticleFields == null) ParticleFields = new ParticleFieldModule[0];
|
||||||
|
for (int i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
ParticleFields = ParticleFields.Append(new ParticleFieldModule
|
||||||
|
{
|
||||||
|
type = ParticleFieldModule.ParticleFieldType.SnowflakesHeavy,
|
||||||
|
rename = "SnowEmitter"
|
||||||
|
}).ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Props?.tornados != null)
|
if (Props?.tornados != null)
|
||||||
|
|||||||
13
NewHorizons/External/Modules/AtmosphereModule.cs
vendored
13
NewHorizons/External/Modules/AtmosphereModule.cs
vendored
@ -76,14 +76,11 @@ namespace NewHorizons.External.Modules
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Does this planet have rain?
|
/// Does this planet have rain?
|
||||||
|
/// This is equivalent to effects of setting a rain particle/vection field, rain audio volume, and visor effect volume, combined for convenience.
|
||||||
|
/// For more control over the rain, use those individual components.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool hasRain;
|
public bool hasRain;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Does this planet have snow?
|
|
||||||
/// </summary>
|
|
||||||
public bool hasSnow;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scale height of the atmosphere
|
/// Scale height of the atmosphere
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -174,7 +171,6 @@ namespace NewHorizons.External.Modules
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[DefaultValue(0f)] public float rotationSpeed = 0f;
|
[DefaultValue(0f)] public float rotationSpeed = 0f;
|
||||||
|
|
||||||
|
|
||||||
#region Obsolete
|
#region Obsolete
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -189,6 +185,8 @@ namespace NewHorizons.External.Modules
|
|||||||
|
|
||||||
|
|
||||||
#region Obsolete
|
#region Obsolete
|
||||||
|
[Obsolete("HasSnow is deprecated, please use ParticleFields instead")]
|
||||||
|
public bool hasSnow;
|
||||||
|
|
||||||
[Obsolete("CloudTint is deprecated, please use CloudInfo instead")]
|
[Obsolete("CloudTint is deprecated, please use CloudInfo instead")]
|
||||||
public MColor cloudTint;
|
public MColor cloudTint;
|
||||||
@ -208,7 +206,8 @@ namespace NewHorizons.External.Modules
|
|||||||
[Obsolete("UseBasicCloudShader is deprecated, please use CloudInfo instead")]
|
[Obsolete("UseBasicCloudShader is deprecated, please use CloudInfo instead")]
|
||||||
public bool useBasicCloudShader;
|
public bool useBasicCloudShader;
|
||||||
|
|
||||||
[DefaultValue(true)] [Obsolete("ShadowsOnClouds is deprecated, please use CloudInfo instead")]
|
[DefaultValue(true)]
|
||||||
|
[Obsolete("ShadowsOnClouds is deprecated, please use CloudInfo instead")]
|
||||||
public bool shadowsOnClouds = true;
|
public bool shadowsOnClouds = true;
|
||||||
|
|
||||||
[Obsolete("HasAtmosphere is deprecated, please use UseAtmosphereShader instead")]
|
[Obsolete("HasAtmosphere is deprecated, please use UseAtmosphereShader instead")]
|
||||||
|
|||||||
79
NewHorizons/External/Modules/VectionFieldModule.cs
vendored
Normal file
79
NewHorizons/External/Modules/VectionFieldModule.cs
vendored
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
using NewHorizons.External.Modules.VariableSize;
|
||||||
|
using NewHorizons.External.SerializableData;
|
||||||
|
using NewHorizons.External.SerializableEnums;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
|
||||||
|
namespace NewHorizons.External.Modules
|
||||||
|
{
|
||||||
|
[JsonObject]
|
||||||
|
public class ParticleFieldModule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Particle type for this vection field.
|
||||||
|
/// </summary>
|
||||||
|
public ParticleFieldType type;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// What the particle field activates based on.
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue("player")] public FollowTarget followTarget = FollowTarget.Player;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Density by height curve. Determines how many particles are emitted at different heights.
|
||||||
|
/// Defaults to a curve based on minimum and maximum heights of various other modules.
|
||||||
|
/// </summary>
|
||||||
|
public HeightDensityPair[] densityByHeightCurve;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An optional rename of this object
|
||||||
|
/// </summary>
|
||||||
|
public string rename;
|
||||||
|
|
||||||
|
[JsonObject]
|
||||||
|
public class HeightDensityPair
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A specific radius
|
||||||
|
/// </summary>
|
||||||
|
public float height;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The particle count for this radius.
|
||||||
|
/// </summary>
|
||||||
|
public float density;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonConverter(typeof(StringEnumConverter))]
|
||||||
|
public enum ParticleFieldType
|
||||||
|
{
|
||||||
|
[EnumMember(Value = @"rain")] Rain,
|
||||||
|
[EnumMember(Value = @"snowflakesHeavy")] SnowflakesHeavy,
|
||||||
|
[EnumMember(Value = @"snowflakesLight")] SnowflakesLight,
|
||||||
|
[EnumMember(Value = @"embers")] Embers,
|
||||||
|
[EnumMember(Value = @"clouds")] Clouds,
|
||||||
|
[EnumMember(Value = @"leaves")] Leaves,
|
||||||
|
[EnumMember(Value = @"bubbles")] Bubbles,
|
||||||
|
[EnumMember(Value = @"fog")] Fog,
|
||||||
|
[EnumMember(Value = @"crystalMotes")] CrystalMotes,
|
||||||
|
[EnumMember(Value = @"rockMotes")] RockMotes,
|
||||||
|
[EnumMember(Value = @"iceMotes")] IceMotes,
|
||||||
|
[EnumMember(Value = @"sandMotes")] SandMotes,
|
||||||
|
[EnumMember(Value = @"crawlies")] Crawlies,
|
||||||
|
[EnumMember(Value = @"fireflies")] Fireflies,
|
||||||
|
[EnumMember(Value = @"plankton")] Plankton,
|
||||||
|
[EnumMember(Value = @"pollen")] Pollen,
|
||||||
|
[EnumMember(Value = @"current")] Current
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonConverter(typeof(StringEnumConverter))]
|
||||||
|
public enum FollowTarget
|
||||||
|
{
|
||||||
|
[EnumMember(Value = @"player")] Player,
|
||||||
|
[EnumMember(Value = @"probe")] Probe
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -654,9 +654,6 @@ namespace NewHorizons.Handlers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (body.Config.Atmosphere.hasRain || body.Config.Atmosphere.hasSnow)
|
|
||||||
EffectsBuilder.Make(go, sector, body.Config, surfaceSize);
|
|
||||||
|
|
||||||
if (body.Config.Atmosphere.fogSize != 0)
|
if (body.Config.Atmosphere.fogSize != 0)
|
||||||
{
|
{
|
||||||
fog = FogBuilder.Make(go, sector, body.Config.Atmosphere, body.Mod);
|
fog = FogBuilder.Make(go, sector, body.Config.Atmosphere, body.Mod);
|
||||||
@ -665,6 +662,11 @@ namespace NewHorizons.Handlers
|
|||||||
atmosphere = AtmosphereBuilder.Make(go, sector, body.Config.Atmosphere, surfaceSize).GetComponentInChildren<LODGroup>();
|
atmosphere = AtmosphereBuilder.Make(go, sector, body.Config.Atmosphere, surfaceSize).GetComponentInChildren<LODGroup>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (body.Config.ParticleFields != null)
|
||||||
|
{
|
||||||
|
EffectsBuilder.Make(go, sector, body.Config);
|
||||||
|
}
|
||||||
|
|
||||||
if (body.Config.Props != null)
|
if (body.Config.Props != null)
|
||||||
{
|
{
|
||||||
PropBuildManager.Make(go, sector, rb, body);
|
PropBuildManager.Make(go, sector, rb, body);
|
||||||
|
|||||||
@ -132,6 +132,13 @@
|
|||||||
"description": "Add water to this planet",
|
"description": "Add water to this planet",
|
||||||
"$ref": "#/definitions/WaterModule"
|
"$ref": "#/definitions/WaterModule"
|
||||||
},
|
},
|
||||||
|
"ParticleFields": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Add particle effects in a field around the planet.\nAlso known as Vection Fields.",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/ParticleFieldModule"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Volumes": {
|
"Volumes": {
|
||||||
"description": "Add various volumes on this body",
|
"description": "Add various volumes on this body",
|
||||||
"$ref": "#/definitions/VolumesModule"
|
"$ref": "#/definitions/VolumesModule"
|
||||||
@ -371,11 +378,7 @@
|
|||||||
},
|
},
|
||||||
"hasRain": {
|
"hasRain": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Does this planet have rain?"
|
"description": "Does this planet have rain? \nThis is equivalent to effects of setting a rain particle/vection field, rain audio volume, and visor effect volume, combined for convenience.\nFor more control over the rain, use those individual components."
|
||||||
},
|
|
||||||
"hasSnow": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Does this planet have snow?"
|
|
||||||
},
|
},
|
||||||
"size": {
|
"size": {
|
||||||
"type": "number",
|
"type": "number",
|
||||||
@ -3583,6 +3586,102 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ParticleFieldModule": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"description": "Particle type for this vection field.",
|
||||||
|
"$ref": "#/definitions/ParticleFieldType"
|
||||||
|
},
|
||||||
|
"followTarget": {
|
||||||
|
"description": "What the particle field activates based on.",
|
||||||
|
"default": "player",
|
||||||
|
"$ref": "#/definitions/FollowTarget"
|
||||||
|
},
|
||||||
|
"densityByHeightCurve": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Density by height curve. Determines how many particles are emitted at different heights.\nDefaults to a curve based on minimum and maximum heights of various other modules.",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/HeightDensityPair"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rename": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "An optional rename of this object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ParticleFieldType": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "",
|
||||||
|
"x-enumNames": [
|
||||||
|
"Rain",
|
||||||
|
"SnowflakesHeavy",
|
||||||
|
"SnowflakesLight",
|
||||||
|
"Embers",
|
||||||
|
"Clouds",
|
||||||
|
"Leaves",
|
||||||
|
"Bubbles",
|
||||||
|
"Fog",
|
||||||
|
"CrystalMotes",
|
||||||
|
"RockMotes",
|
||||||
|
"IceMotes",
|
||||||
|
"SandMotes",
|
||||||
|
"Crawlies",
|
||||||
|
"Fireflies",
|
||||||
|
"Plankton",
|
||||||
|
"Pollen",
|
||||||
|
"Current"
|
||||||
|
],
|
||||||
|
"enum": [
|
||||||
|
"rain",
|
||||||
|
"snowflakesHeavy",
|
||||||
|
"snowflakesLight",
|
||||||
|
"embers",
|
||||||
|
"clouds",
|
||||||
|
"leaves",
|
||||||
|
"bubbles",
|
||||||
|
"fog",
|
||||||
|
"crystalMotes",
|
||||||
|
"rockMotes",
|
||||||
|
"iceMotes",
|
||||||
|
"sandMotes",
|
||||||
|
"crawlies",
|
||||||
|
"fireflies",
|
||||||
|
"plankton",
|
||||||
|
"pollen",
|
||||||
|
"current"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"FollowTarget": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "",
|
||||||
|
"x-enumNames": [
|
||||||
|
"Player",
|
||||||
|
"Probe"
|
||||||
|
],
|
||||||
|
"enum": [
|
||||||
|
"player",
|
||||||
|
"probe"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"HeightDensityPair": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"height": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "A specific radius",
|
||||||
|
"format": "float"
|
||||||
|
},
|
||||||
|
"density": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "The particle count for this radius.",
|
||||||
|
"format": "float"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"VolumesModule": {
|
"VolumesModule": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using NewHorizons.External.Configs;
|
using NewHorizons.External.Configs;
|
||||||
|
using NewHorizons.External.Modules.VariableSize;
|
||||||
using NewHorizons.External.SerializableData;
|
using NewHorizons.External.SerializableData;
|
||||||
using NewHorizons.External.SerializableEnums;
|
using NewHorizons.External.SerializableEnums;
|
||||||
using NewHorizons.Utility.OWML;
|
using NewHorizons.Utility.OWML;
|
||||||
@ -12,6 +13,7 @@ using System.Reflection;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using static NewHorizons.External.Modules.ParticleFieldModule;
|
||||||
using NomaiCoordinates = NewHorizons.External.Configs.StarSystemConfig.NomaiCoordinates;
|
using NomaiCoordinates = NewHorizons.External.Configs.StarSystemConfig.NomaiCoordinates;
|
||||||
|
|
||||||
namespace NewHorizons.Utility
|
namespace NewHorizons.Utility
|
||||||
@ -277,5 +279,31 @@ namespace NewHorizons.Utility
|
|||||||
{
|
{
|
||||||
go.transform.rotation = Quaternion.FromToRotation(Vector3.forward, direction);
|
go.transform.rotation = Quaternion.FromToRotation(Vector3.forward, direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static AnimationCurve ToAnimationCurve(this TimeValuePair[] pairs)
|
||||||
|
{
|
||||||
|
var curve = new AnimationCurve();
|
||||||
|
if (pairs != null)
|
||||||
|
{
|
||||||
|
foreach (var pair in pairs)
|
||||||
|
{
|
||||||
|
curve.AddKey(new Keyframe(pair.time, pair.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return curve;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AnimationCurve ToAnimationCurve(this HeightDensityPair[] pairs)
|
||||||
|
{
|
||||||
|
var curve = new AnimationCurve();
|
||||||
|
if (pairs != null)
|
||||||
|
{
|
||||||
|
foreach (var pair in pairs)
|
||||||
|
{
|
||||||
|
curve.AddKey(new Keyframe(pair.height, pair.density));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return curve;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user