mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
Merge branch 'dev' into update-hgt-orbits
This commit is contained in:
commit
7a46f56e02
@ -1,4 +1,5 @@
|
||||
using NewHorizons.External.Configs;
|
||||
using NewHorizons.External.Modules;
|
||||
using NewHorizons.Utility;
|
||||
using UnityEngine;
|
||||
namespace NewHorizons.Builder.Atmosphere
|
||||
@ -7,6 +8,21 @@ namespace NewHorizons.Builder.Atmosphere
|
||||
{
|
||||
private static GameObject _rainEmitterPrefab;
|
||||
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;
|
||||
|
||||
@ -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 (_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();
|
||||
|
||||
@ -36,7 +67,7 @@ namespace NewHorizons.Builder.Atmosphere
|
||||
SCG._dynamicCullingBounds = false;
|
||||
SCG._waitForStreaming = false;
|
||||
|
||||
var minHeight = surfaceSize;
|
||||
var minHeight = config.Base.surfaceSize;
|
||||
if (config.HeightMap?.minHeight != null)
|
||||
{
|
||||
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;
|
||||
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);
|
||||
rainGO.name = "RainEmitter";
|
||||
rainGO.transform.position = planetGO.transform.position;
|
||||
var prefab = GetPrefabByType(particleField.type);
|
||||
var emitter = Object.Instantiate(prefab, effectsGO.transform);
|
||||
emitter.name = !string.IsNullOrWhiteSpace(particleField.rename) ? particleField.rename : prefab.name.Replace("Prefab_", "");
|
||||
emitter.transform.position = planetGO.transform.position;
|
||||
|
||||
var pvc = rainGO.GetComponent<PlanetaryVectionController>();
|
||||
pvc._densityByHeight = new AnimationCurve(new Keyframe[]
|
||||
var vfe = emitter.GetComponent<VectionFieldEmitter>();
|
||||
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, 10f),
|
||||
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;
|
||||
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);
|
||||
}
|
||||
emitter.SetActive(true);
|
||||
}
|
||||
|
||||
effectsGO.transform.position = planetGO.transform.position;
|
||||
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,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,9 @@ using NewHorizons.External.Modules.VariableSize;
|
||||
using Tessellation;
|
||||
using NewHorizons.Utility.OWML;
|
||||
using NewHorizons.Utility.OuterWilds;
|
||||
using NewHorizons.External.Configs;
|
||||
using NewHorizons.Components.Volumes;
|
||||
using System.Linq;
|
||||
|
||||
namespace NewHorizons.Builder.Body
|
||||
{
|
||||
@ -41,10 +44,12 @@ namespace NewHorizons.Builder.Body
|
||||
if (_oceanAmbientLight == null) _oceanAmbientLight = SearchUtilities.Find("Ocean_GD").GetComponent<OceanLODController>()._ambientLight.gameObject.InstantiateInactive().Rename("OceanAmbientLight").DontDestroyOnLoad();
|
||||
}
|
||||
|
||||
public static RadialFluidVolume Make(GameObject planetGO, Sector sector, OWRigidbody rb, WaterModule module)
|
||||
public static RadialFluidVolume Make(GameObject planetGO, Sector sector, OWRigidbody rb, PlanetConfig config)
|
||||
{
|
||||
InitPrefabs();
|
||||
|
||||
var module = config.Water;
|
||||
|
||||
var waterSize = module.size;
|
||||
|
||||
GameObject waterGO = new GameObject("Water");
|
||||
@ -154,6 +159,11 @@ namespace NewHorizons.Builder.Body
|
||||
fogGO.GetComponent<MeshRenderer>().material.SetFloat("_Radius2", 0);
|
||||
}
|
||||
|
||||
if (config.Cloak != null)
|
||||
{
|
||||
fluidVolume.gameObject.AddComponent<WaterCloakFixerVolume>().material = TSR.sharedMaterials.First(x => x.name == "Ocean_GD_Surface_mat");
|
||||
}
|
||||
|
||||
// TODO: fix ruleset making the sand bubble pop up
|
||||
|
||||
waterGO.transform.position = planetGO.transform.position;
|
||||
|
||||
@ -61,15 +61,17 @@ namespace NewHorizons.Builder.Orbital
|
||||
|
||||
var fade = isMoon;
|
||||
|
||||
/*
|
||||
if (config.Base.IsSatellite)
|
||||
if (config.Orbit.orbitLineFadeStartDistance >= 0)
|
||||
{
|
||||
if (config.Orbit.Tint != null) color = new Color(0.4082f, 0.516f, 0.4469f, 1f);
|
||||
fade = true;
|
||||
orbitLine._fadeEndDist = 5000;
|
||||
orbitLine._fadeStartDist = 3000;
|
||||
orbitLine._fadeStartDist = config.Orbit.orbitLineFadeStartDistance;
|
||||
}
|
||||
|
||||
if (config.Orbit.orbitLineFadeEndDistance >= 0)
|
||||
{
|
||||
fade = true;
|
||||
orbitLine._fadeEndDist = config.Orbit.orbitLineFadeEndDistance;
|
||||
}
|
||||
*/
|
||||
|
||||
orbitLine._color = color;
|
||||
lineRenderer.endColor = new Color(color.r, color.g, color.b, 0f);
|
||||
|
||||
@ -41,7 +41,9 @@ namespace NewHorizons.Builder.Props.Audio
|
||||
|
||||
Initialized = true;
|
||||
|
||||
SceneManager.sceneUnloaded -= OnSceneUnloaded;
|
||||
SceneManager.sceneUnloaded += OnSceneUnloaded;
|
||||
Main.Instance.OnStarSystemLoaded.RemoveListener(OnStarSystemLoaded);
|
||||
Main.Instance.OnStarSystemLoaded.AddListener(OnStarSystemLoaded);
|
||||
}
|
||||
|
||||
|
||||
@ -257,10 +257,20 @@ namespace NewHorizons.Builder.Props
|
||||
|
||||
// Seed fog works differently, so it doesn't need to be fixed
|
||||
// (it's also located on a different child path, so the below FindChild calls wouldn't work)
|
||||
// Default size is 70
|
||||
var fog = brambleNode.FindChild("Effects/InnerWarpFogSphere");
|
||||
var fogMaterial = fog.GetComponent<MeshRenderer>().material;
|
||||
fogMaterial.SetFloat("_Radius", fogMaterial.GetFloat("_Radius") * config.scale);
|
||||
fogMaterial.SetFloat("_Density", fogMaterial.GetFloat("_Density") / config.scale);
|
||||
fog.transform.localScale = Vector3.one * config.scale * 70f;
|
||||
|
||||
// Copy shared material to not be shared
|
||||
var fogRenderer = fog.GetComponent<MeshRenderer>();
|
||||
fogRenderer.material = new Material(fogRenderer.sharedMaterial);
|
||||
fogRenderer.material.SetFloat("_Radius", fogRenderer.material.GetFloat("_Radius") * config.scale);
|
||||
fogRenderer.material.SetFloat("_Density", fogRenderer.material.GetFloat("_Density") / config.scale);
|
||||
// Fixes bramble nodes being a weird colour until you approach the first time #372
|
||||
if (config.fogTint != null)
|
||||
{
|
||||
fog.GetComponent<OWRenderer>().SetColor(config.fogTint.ToColor());
|
||||
}
|
||||
}
|
||||
|
||||
// Set colors
|
||||
@ -391,7 +401,8 @@ namespace NewHorizons.Builder.Props
|
||||
}
|
||||
}
|
||||
|
||||
StreamingHandler.SetUpStreaming(brambleNode, sector);
|
||||
// If the outer fog warp volume is null we're exposed to the solar system so treat it as a keepLoaded type prop
|
||||
StreamingHandler.SetUpStreaming(brambleNode, outerFogWarpVolume == null ? null : sector);
|
||||
|
||||
// Done!
|
||||
brambleNode.SetActive(true);
|
||||
|
||||
@ -116,25 +116,33 @@ namespace NewHorizons.Builder.Props
|
||||
|
||||
foreach (var component in prop.GetComponentsInChildren<Component>(true))
|
||||
{
|
||||
// Components can come through as null here (yes, really),
|
||||
// Usually if a script was added to a prefab in an asset bundle but isn't present in the loaded mod DLLs
|
||||
if (component == null)
|
||||
// Rather than having the entire prop not exist when a detail fails let's just try-catch and log an error
|
||||
try
|
||||
{
|
||||
invalidComponentFound = true;
|
||||
continue;
|
||||
}
|
||||
if (component.gameObject == prop && component is OWItem) isItem = true;
|
||||
// Components can come through as null here (yes, really),
|
||||
// Usually if a script was added to a prefab in an asset bundle but isn't present in the loaded mod DLLs
|
||||
if (component == null)
|
||||
{
|
||||
invalidComponentFound = true;
|
||||
continue;
|
||||
}
|
||||
if (component.gameObject == prop && component is OWItem) isItem = true;
|
||||
|
||||
if (sector == null)
|
||||
{
|
||||
if (FixUnsectoredComponent(component)) continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
FixSectoredComponent(component, sector, existingSectors, detail.keepLoaded);
|
||||
}
|
||||
if (sector == null)
|
||||
{
|
||||
if (FixUnsectoredComponent(component)) continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
FixSectoredComponent(component, sector, existingSectors, detail.keepLoaded);
|
||||
}
|
||||
|
||||
FixComponent(component, go, detail.ignoreSun);
|
||||
FixComponent(component, go, detail.ignoreSun);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
NHLogger.LogError($"Failed to correct component {component?.GetType()?.Name} on {go?.name} - {e}");
|
||||
}
|
||||
}
|
||||
|
||||
if (detail.path != null)
|
||||
@ -155,7 +163,7 @@ namespace NewHorizons.Builder.Props
|
||||
}
|
||||
}
|
||||
|
||||
// Items shouldn't use these else they get weird
|
||||
// Items should always be kept loaded else they will vanish in your hand as you leave the sector
|
||||
if (isItem) detail.keepLoaded = true;
|
||||
|
||||
prop.transform.localScale = detail.stretch ?? (detail.scale != 0 ? Vector3.one * detail.scale : prefab.transform.localScale);
|
||||
@ -374,7 +382,7 @@ namespace NewHorizons.Builder.Props
|
||||
else if (component is NomaiInterfaceOrb orb)
|
||||
{
|
||||
// detect planet gravity
|
||||
var gravityVolume = planetGO.GetAttachedOWRigidbody().GetAttachedGravityVolume();
|
||||
var gravityVolume = planetGO.GetAttachedOWRigidbody()?.GetAttachedGravityVolume();
|
||||
orb.GetComponent<ConstantForceDetector>()._detectableFields = gravityVolume ? new ForceVolume[] { gravityVolume } : new ForceVolume[] { };
|
||||
}
|
||||
|
||||
|
||||
@ -631,6 +631,12 @@ namespace NewHorizons.Builder.Props.TranslatorText
|
||||
XmlDocument xmlDocument = new XmlDocument();
|
||||
xmlDocument.LoadXml(xmlPath);
|
||||
XmlNode rootNode = xmlDocument.SelectSingleNode("NomaiObject");
|
||||
|
||||
if (rootNode == null)
|
||||
{
|
||||
NHLogger.LogError($"Couldn't find NomaiObject in [{xmlPath}]");
|
||||
return dict;
|
||||
}
|
||||
|
||||
foreach (object obj in rootNode.SelectNodes("TextBlock"))
|
||||
{
|
||||
|
||||
@ -26,6 +26,12 @@ namespace NewHorizons.Components.Props
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
// We delay else some props don't get properly initialized before being disappeared
|
||||
Delay.FireOnNextUpdate(LateStart);
|
||||
}
|
||||
|
||||
private void LateStart()
|
||||
{
|
||||
var currentConditionState = DialogueConditionManager.SharedInstance.GetConditionState(DialogueCondition);
|
||||
|
||||
|
||||
@ -259,7 +259,7 @@ namespace NewHorizons.Components.ShipLog
|
||||
if (!name.Equals(uniqueID)) return name;
|
||||
|
||||
// Else we return a default name
|
||||
if (uniqueID.Equals("SolarSystem")) return "Hearthian System";
|
||||
if (uniqueID.Equals("SolarSystem")) return "The Outer Wilds";
|
||||
|
||||
var splitString = uniqueID.Split('.');
|
||||
if (splitString.Length > 1) splitString = splitString.Skip(1).ToArray();
|
||||
|
||||
@ -454,6 +454,8 @@ namespace NewHorizons.Components.SizeControllers
|
||||
|
||||
public float GetSupernovaRadius() => supernova.GetSupernovaRadius();
|
||||
|
||||
public float GetSurfaceRadius() => transform.localScale.x;
|
||||
|
||||
public float GetMaxSupernovaRadius() => supernovaSize;
|
||||
|
||||
protected new void FixedUpdate()
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using NewHorizons.Builder.Atmosphere;
|
||||
using NewHorizons.Components.SizeControllers;
|
||||
using NewHorizons.Utility.OWML;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
@ -17,7 +18,11 @@ namespace NewHorizons.Components.Stars
|
||||
private readonly List<StarController> _stars = new();
|
||||
private readonly List<Light> _lights = new();
|
||||
|
||||
private StarController _activeStar;
|
||||
// SunController or StarEvolutionController
|
||||
public StarEvolutionController ActiveStarEvolutionController { get; private set; }
|
||||
public SunController ActiveSunController { get; private set; }
|
||||
|
||||
private StarController _activeStarController;
|
||||
private SunLightController _sunLightController;
|
||||
private SunLightParamUpdater _sunLightParamUpdater;
|
||||
|
||||
@ -54,7 +59,7 @@ namespace NewHorizons.Components.Stars
|
||||
NHLogger.LogVerbose($"Removing star from list: {star?.gameObject?.name}");
|
||||
if (Instance._stars.Contains(star))
|
||||
{
|
||||
if (Instance._activeStar != null && Instance._activeStar.Equals(star))
|
||||
if (Instance._activeStarController != null && Instance._activeStarController.Equals(star))
|
||||
{
|
||||
Instance._stars.Remove(star);
|
||||
if (Instance._stars.Count > 0) Instance.ChangeActiveStar(Instance._stars[0]);
|
||||
@ -121,11 +126,11 @@ namespace NewHorizons.Components.Stars
|
||||
|
||||
if (_stars.Count > 0)
|
||||
{
|
||||
if (_activeStar == null || !_activeStar.gameObject.activeInHierarchy)
|
||||
if (_activeStarController == null || !_activeStarController.gameObject.activeInHierarchy)
|
||||
{
|
||||
if (_stars.Contains(_activeStar))
|
||||
if (_stars.Contains(_activeStarController))
|
||||
{
|
||||
_stars.Remove(_activeStar);
|
||||
_stars.Remove(_activeStarController);
|
||||
}
|
||||
|
||||
if (_stars.Count > 0)
|
||||
@ -145,8 +150,8 @@ namespace NewHorizons.Components.Stars
|
||||
// Update atmo shaders
|
||||
foreach (var (planet, material) in AtmosphereBuilder.Skys)
|
||||
{
|
||||
var sqrDist = (planet.transform.position - _activeStar.transform.position).sqrMagnitude;
|
||||
var intensity = Mathf.Min(_activeStar.Intensity / (sqrDist / hearthSunDistanceSqr), 1f);
|
||||
var sqrDist = (planet.transform.position - _activeStarController.transform.position).sqrMagnitude;
|
||||
var intensity = Mathf.Min(_activeStarController.Intensity / (sqrDist / hearthSunDistanceSqr), 1f);
|
||||
|
||||
material.SetFloat(SunIntensity, intensity);
|
||||
}
|
||||
@ -156,7 +161,7 @@ namespace NewHorizons.Components.Stars
|
||||
if (star == null) continue;
|
||||
if (!(star.gameObject.activeSelf && star.gameObject.activeInHierarchy)) continue;
|
||||
|
||||
if (star.Intensity * (star.transform.position - origin).sqrMagnitude < _activeStar.Intensity * (_activeStar.transform.position - origin).sqrMagnitude)
|
||||
if (star.Intensity * (star.transform.position - origin).sqrMagnitude < _activeStarController.Intensity * (_activeStarController.transform.position - origin).sqrMagnitude)
|
||||
{
|
||||
ChangeActiveStar(star);
|
||||
break;
|
||||
@ -170,11 +175,13 @@ namespace NewHorizons.Components.Stars
|
||||
{
|
||||
if (_sunLightController == null || _sunLightParamUpdater == null) return;
|
||||
|
||||
if (_activeStar != null) _activeStar.Disable();
|
||||
_activeStarController?.Disable();
|
||||
|
||||
NHLogger.LogVerbose($"Switching active star: {star.gameObject.name}");
|
||||
|
||||
_activeStar = star;
|
||||
_activeStarController = star;
|
||||
ActiveStarEvolutionController = star.GetComponentInChildren<StarEvolutionController>();
|
||||
ActiveSunController = star.GetComponent<SunController>();
|
||||
|
||||
star.Enable();
|
||||
|
||||
@ -194,7 +201,8 @@ namespace NewHorizons.Components.Stars
|
||||
transform.localPosition = Vector3.zero;
|
||||
|
||||
// Some effects use Locator.GetSunTransform so hopefully its fine to change it
|
||||
Locator._sunTransform = transform;
|
||||
// Use the root transform of the star because that's the default behaviour, breaks SunProxy if not (potentially others)
|
||||
Locator._sunTransform = star.transform;
|
||||
|
||||
// TODO?: maybe also turn off star controller stuff (mainly proxy light) since idk if that can handle more than 1 being on
|
||||
}
|
||||
|
||||
54
NewHorizons/Components/Volumes/WaterCloakFixerVolume.cs
Normal file
54
NewHorizons/Components/Volumes/WaterCloakFixerVolume.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NewHorizons.Components.Volumes
|
||||
{
|
||||
/// <summary>
|
||||
/// A cloak can interfere with the rendering of water
|
||||
/// Water has a lower render queue and is transparent, so you can see the background black cloak over top of the water
|
||||
/// We fix this by setting the water's render queue to that of the cloak
|
||||
/// However, this means that when you are inside the water you will see through the cloak since it's not rendered on top
|
||||
/// To fix that, we set the render queue back to normal when the player enters the water
|
||||
/// Currently this doesnt nothing to fix probe camera pictures. If you are outside of the water, the probe will see the stars and through the cloak
|
||||
/// Oh well
|
||||
/// </summary>
|
||||
internal class WaterCloakFixerVolume : MonoBehaviour
|
||||
{
|
||||
public Material material;
|
||||
private OWTriggerVolume _volume;
|
||||
|
||||
public const int WATER_RENDER_QUEUE = 2990;
|
||||
public const int CLOAK_RENDER_QUEUE = 3000;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
_volume = GetComponent<RadialFluidVolume>().GetOWTriggerVolume();
|
||||
|
||||
_volume.OnEntry += WaterCloakFixerVolume_OnEntry;
|
||||
_volume.OnExit += WaterCloakFixerVolume_OnExit;
|
||||
|
||||
material.renderQueue = CLOAK_RENDER_QUEUE;
|
||||
}
|
||||
|
||||
public void OnDestroy()
|
||||
{
|
||||
_volume.OnEntry -= WaterCloakFixerVolume_OnEntry;
|
||||
_volume.OnExit -= WaterCloakFixerVolume_OnExit;
|
||||
}
|
||||
|
||||
private void WaterCloakFixerVolume_OnEntry(GameObject hitObj)
|
||||
{
|
||||
if (hitObj.CompareTag("PlayerDetector"))
|
||||
{
|
||||
material.renderQueue = WATER_RENDER_QUEUE;
|
||||
}
|
||||
}
|
||||
|
||||
private void WaterCloakFixerVolume_OnExit(GameObject hitObj)
|
||||
{
|
||||
if (hitObj.CompareTag("PlayerDetector"))
|
||||
{
|
||||
material.renderQueue = CLOAK_RENDER_QUEUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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.DataAnnotations;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NewHorizons.External.Configs
|
||||
{
|
||||
@ -167,6 +168,12 @@ namespace NewHorizons.External.Configs
|
||||
/// </summary>
|
||||
public WaterModule Water;
|
||||
|
||||
/// <summary>
|
||||
/// Add particle effects in a field around the planet.
|
||||
/// Also known as Vection Fields.
|
||||
/// </summary>
|
||||
public ParticleFieldModule[] ParticleFields;
|
||||
|
||||
/// <summary>
|
||||
/// Add various volumes on this body
|
||||
/// </summary>
|
||||
@ -341,6 +348,29 @@ namespace NewHorizons.External.Configs
|
||||
// useBasicCloudShader is obsolete
|
||||
if (Atmosphere.clouds != null && Atmosphere.clouds.useBasicCloudShader)
|
||||
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)
|
||||
|
||||
17
NewHorizons/External/Modules/AtmosphereModule.cs
vendored
17
NewHorizons/External/Modules/AtmosphereModule.cs
vendored
@ -57,7 +57,7 @@ namespace NewHorizons.External.Modules
|
||||
/// Colour of fog on the planet, if you put fog.
|
||||
/// </summary>
|
||||
public MColor fogTint;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Relative filepath to the fog color ramp texture, if you put fog.
|
||||
/// x axis is angle to sun (left at midnight, right at noon), y axis is distance to camera (close at bottom, far at top).
|
||||
@ -75,15 +75,12 @@ namespace NewHorizons.External.Modules
|
||||
public bool hasTrees;
|
||||
|
||||
/// <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>
|
||||
public bool hasRain;
|
||||
|
||||
/// <summary>
|
||||
/// Does this planet have snow?
|
||||
/// </summary>
|
||||
public bool hasSnow;
|
||||
|
||||
/// <summary>
|
||||
/// Scale height of the atmosphere
|
||||
/// </summary>
|
||||
@ -174,7 +171,6 @@ namespace NewHorizons.External.Modules
|
||||
/// </summary>
|
||||
[DefaultValue(0f)] public float rotationSpeed = 0f;
|
||||
|
||||
|
||||
#region Obsolete
|
||||
|
||||
/// <summary>
|
||||
@ -189,6 +185,8 @@ namespace NewHorizons.External.Modules
|
||||
|
||||
|
||||
#region Obsolete
|
||||
[Obsolete("HasSnow is deprecated, please use ParticleFields instead")]
|
||||
public bool hasSnow;
|
||||
|
||||
[Obsolete("CloudTint is deprecated, please use CloudInfo instead")]
|
||||
public MColor cloudTint;
|
||||
@ -208,7 +206,8 @@ namespace NewHorizons.External.Modules
|
||||
[Obsolete("UseBasicCloudShader is deprecated, please use CloudInfo instead")]
|
||||
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;
|
||||
|
||||
[Obsolete("HasAtmosphere is deprecated, please use UseAtmosphereShader instead")]
|
||||
|
||||
22
NewHorizons/External/Modules/OrbitModule.cs
vendored
22
NewHorizons/External/Modules/OrbitModule.cs
vendored
@ -45,6 +45,12 @@ namespace NewHorizons.External.Modules
|
||||
/// </summary>
|
||||
public bool isTidallyLocked;
|
||||
|
||||
/// <summary>
|
||||
/// Is the body meant to stay in one place without moving? If staticPosition is not set, the initial position
|
||||
/// will be determined using its orbital parameters.
|
||||
/// </summary>
|
||||
public bool isStatic;
|
||||
|
||||
/// <summary>
|
||||
/// If it is tidally locked, this direction will face towards the primary. Ex: Interloper uses `0, -1, 0`. Most planets
|
||||
/// will want something like `-1, 0, 0`.
|
||||
@ -62,12 +68,6 @@ namespace NewHorizons.External.Modules
|
||||
/// </summary>
|
||||
public bool dottedOrbitLine;
|
||||
|
||||
/// <summary>
|
||||
/// Is the body meant to stay in one place without moving? If staticPosition is not set, the initial position
|
||||
/// will be determined using its orbital parameters.
|
||||
/// </summary>
|
||||
public bool isStatic;
|
||||
|
||||
/// <summary>
|
||||
/// Colour of the orbit-line in the map view.
|
||||
/// </summary>
|
||||
@ -78,6 +78,16 @@ namespace NewHorizons.External.Modules
|
||||
/// </summary>
|
||||
public bool trackingOrbitLine;
|
||||
|
||||
/// <summary>
|
||||
/// If the camera is farther than this distance the orbit line will fade out. Leave empty to not have it fade out.
|
||||
/// </summary>
|
||||
public float orbitLineFadeEndDistance = -1f;
|
||||
|
||||
/// <summary>
|
||||
/// If the camera is closer than this distance the orbit line will fade out. Leave empty to not have it fade out.
|
||||
/// </summary>
|
||||
public float orbitLineFadeStartDistance = -1f;
|
||||
|
||||
/// <summary>
|
||||
/// The semi-major axis of the ellipse that is the body's orbit. For a circular orbit this is the radius.
|
||||
/// </summary>
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -17,6 +17,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using NewHorizons.Streaming;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace NewHorizons.Handlers
|
||||
{
|
||||
@ -34,6 +35,8 @@ namespace NewHorizons.Handlers
|
||||
public static float SolarSystemRadius { get; private set; }
|
||||
public static float DefaultFurthestOrbit => 30000f;
|
||||
|
||||
public static List<Action<GameObject, string>> CustomBuilders;
|
||||
|
||||
public static void Init(List<NewHorizonsBody> bodies)
|
||||
{
|
||||
// Start by destroying all planets if need be
|
||||
@ -158,8 +161,20 @@ namespace NewHorizons.Handlers
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (body?.Config?.name == null) NHLogger.LogError($"How is there no name for {body}");
|
||||
else existingPlanet = SearchUtilities.Find(body.Config.name.Replace(" ", "") + "_Body", false);
|
||||
if (body?.Config?.name == null)
|
||||
{
|
||||
NHLogger.LogError($"How is there no name for {body}");
|
||||
}
|
||||
else
|
||||
{
|
||||
existingPlanet = SearchUtilities.Find(body.Config.name.Replace(" ", "") + "_Body", false);
|
||||
}
|
||||
}
|
||||
|
||||
if (existingPlanet == null && body.Config.destroy)
|
||||
{
|
||||
NHLogger.LogError($"{body.Config.name} was meant to be destroyed, but was not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (existingPlanet != null)
|
||||
@ -169,8 +184,14 @@ namespace NewHorizons.Handlers
|
||||
if (body.Config.destroy)
|
||||
{
|
||||
var ao = existingPlanet.GetComponent<AstroObject>();
|
||||
if (ao != null) Delay.FireInNUpdates(() => PlanetDestructionHandler.RemoveBody(ao), 2);
|
||||
else Delay.FireInNUpdates(() => PlanetDestructionHandler.DisableBody(existingPlanet, false), 2);
|
||||
if (ao != null)
|
||||
{
|
||||
Delay.FireInNUpdates(() => PlanetDestructionHandler.DisableAstroObject(ao), 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
Delay.FireInNUpdates(() => PlanetDestructionHandler.DisableGameObject(existingPlanet), 2);
|
||||
}
|
||||
}
|
||||
else if (body.Config.isQuantumState)
|
||||
{
|
||||
@ -391,7 +412,8 @@ namespace NewHorizons.Handlers
|
||||
if (defaultPrimaryToSun)
|
||||
{
|
||||
NHLogger.LogError($"Couldn't find {body.Config.Orbit.primaryBody}, defaulting to center of solar system");
|
||||
primaryBody = Locator.GetCenterOfTheUniverse().GetAttachedOWRigidbody().GetComponent<AstroObject>();
|
||||
// TODO: Make this work in other systems. We tried using Locator.GetCenterOfUniverse before but that doesn't work since its too early now
|
||||
primaryBody = SearchUtilities.Find("Sun_Body")?.GetComponent<AstroObject>();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -627,7 +649,7 @@ namespace NewHorizons.Handlers
|
||||
|
||||
if (body.Config.Water != null)
|
||||
{
|
||||
WaterBuilder.Make(go, sector, rb, body.Config.Water);
|
||||
WaterBuilder.Make(go, sector, rb, body.Config);
|
||||
}
|
||||
|
||||
if (body.Config.Sand != null)
|
||||
@ -654,9 +676,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)
|
||||
{
|
||||
fog = FogBuilder.Make(go, sector, body.Config.Atmosphere, body.Mod);
|
||||
@ -665,6 +684,11 @@ namespace NewHorizons.Handlers
|
||||
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)
|
||||
{
|
||||
PropBuildManager.Make(go, sector, rb, body);
|
||||
@ -680,6 +704,21 @@ namespace NewHorizons.Handlers
|
||||
FunnelBuilder.Make(go, sector, rb, body.Config.Funnel);
|
||||
}
|
||||
|
||||
if (body.Config.extras != null)
|
||||
{
|
||||
foreach (var customBuilder in CustomBuilders)
|
||||
{
|
||||
try
|
||||
{
|
||||
customBuilder.Invoke(go, JsonConvert.SerializeObject(body.Config.extras));
|
||||
}
|
||||
catch
|
||||
{
|
||||
NHLogger.LogError($"Failed to use custom builder on body {body.Config.name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Has to go last probably
|
||||
if (willHaveCloak)
|
||||
{
|
||||
|
||||
@ -6,53 +6,15 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using NewHorizons.Components;
|
||||
|
||||
namespace NewHorizons.Handlers
|
||||
{
|
||||
public static class PlanetDestructionHandler
|
||||
{
|
||||
private static readonly string[] _solarSystemBodies = new string[]
|
||||
{
|
||||
"Ash Twin",
|
||||
"Attlerock",
|
||||
"Brittle Hollow",
|
||||
"Dark Bramble",
|
||||
"DreamWorld",
|
||||
"Ember Twin",
|
||||
"Giant's Deep",
|
||||
"Hollow's Lantern",
|
||||
"Interloper",
|
||||
"Map Satellite",
|
||||
"Orbital Probe Cannon",
|
||||
"Quantum Moon",
|
||||
"RingWorld",
|
||||
"Sun",
|
||||
"Sun Station",
|
||||
"Timber Hearth",
|
||||
"White Hole"
|
||||
};
|
||||
|
||||
private static readonly string[] _eyeOfTheUniverseBodies = new string[]
|
||||
{
|
||||
"Eye Of The Universe",
|
||||
"Vessel"
|
||||
};
|
||||
|
||||
private static readonly string[] _suspendBlacklist = new string[]
|
||||
{
|
||||
"Player_Body",
|
||||
"Ship_Body"
|
||||
};
|
||||
public static readonly string[] _suspendBlacklist = new string[] { "Player_Body", "Probe_Body", "Ship_Body" };
|
||||
|
||||
public static void RemoveStockPlanets()
|
||||
{
|
||||
if (Main.Instance.CurrentStarSystem == "EyeOfTheUniverse")
|
||||
RemoveEyeOfTheUniverse();
|
||||
else
|
||||
RemoveSolarSystem();
|
||||
}
|
||||
|
||||
public static void RemoveSolarSystem()
|
||||
{
|
||||
// Adapted from EOTS thanks corby
|
||||
var toDisable = new List<GameObject>();
|
||||
@ -60,51 +22,41 @@ namespace NewHorizons.Handlers
|
||||
// Collect all rigid bodies and proxies
|
||||
foreach (var rigidbody in CenterOfTheUniverse.s_rigidbodies)
|
||||
{
|
||||
if (rigidbody.name is not ("Player_Body" or "Probe_Body" or "Ship_Body"))
|
||||
if (!_suspendBlacklist.Contains(rigidbody.name))
|
||||
{
|
||||
toDisable.Add(rigidbody.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var proxyBody in GameObject.FindObjectsOfType<ProxyBody>())
|
||||
{
|
||||
toDisable.Add(proxyBody.gameObject);
|
||||
}
|
||||
|
||||
Delay.FireInNUpdates(() =>
|
||||
{
|
||||
foreach (var gameObject in toDisable)
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
// Kill all non nh proxies
|
||||
foreach (var proxy in GameObject.FindObjectsOfType<ProxyBody>())
|
||||
{
|
||||
if (proxy is not NHProxy)
|
||||
{
|
||||
proxy.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
GameObject.FindObjectOfType<SunProxy>().gameObject.SetActive(false);
|
||||
|
||||
// force call update here to make it switch to an active star. idk why we didnt have to do this before
|
||||
SunLightEffectsController.Instance.Update();
|
||||
|
||||
// Since we didn't call RemoveBody on the Stranger have to call this here
|
||||
StrangerRemoved();
|
||||
if (Main.Instance.CurrentStarSystem != "EyeOfTheUniverse")
|
||||
{
|
||||
// Since we didn't call RemoveBody on the all planets there are some we have to call here
|
||||
StrangerRemoved();
|
||||
TimberHearthRemoved();
|
||||
GiantsDeepRemoved();
|
||||
SunRemoved();
|
||||
}
|
||||
|
||||
// Don't forget to fix THE WARP BUG
|
||||
DisableBody(SearchUtilities.Find("StreamingGroup_TH"), true);
|
||||
}, 2); // Have to wait or shit goes wild
|
||||
|
||||
foreach (var streamingAssetBundle in StreamingManager.s_activeBundles)
|
||||
{
|
||||
//streamingAssetBundle.Unload();
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveEyeOfTheUniverse()
|
||||
{
|
||||
foreach (var name in _eyeOfTheUniverseBodies)
|
||||
{
|
||||
var ao = AstroObjectLocator.GetAstroObject(name);
|
||||
if (ao != null) Delay.FireInNUpdates(() => RemoveBody(ao, false), 2);
|
||||
else NHLogger.LogError($"Couldn't find [{name}]");
|
||||
}
|
||||
}
|
||||
|
||||
#region Planet specific removals
|
||||
public static void StrangerRemoved()
|
||||
{
|
||||
CloakHandler.FlagStrangerDisabled = true;
|
||||
@ -115,101 +67,122 @@ namespace NewHorizons.Handlers
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveBody(AstroObject ao, bool delete = false, List<AstroObject> toDestroy = null)
|
||||
private static void SunRemoved()
|
||||
{
|
||||
NHLogger.LogVerbose($"Removing [{ao.name}]");
|
||||
var sun = SearchUtilities.Find("Sun_Body").GetComponent<AstroObject>();
|
||||
|
||||
if (ao.GetAstroObjectName() == AstroObject.Name.RingWorld)
|
||||
var starController = sun.gameObject.GetComponent<StarController>();
|
||||
SunLightEffectsController.RemoveStar(starController);
|
||||
SunLightEffectsController.RemoveStarLight(sun.transform.Find("Sector_SUN/Effects_SUN/SunLight").GetComponent<Light>());
|
||||
UnityEngine.Object.Destroy(starController);
|
||||
|
||||
var audio = sun.GetComponentInChildren<SunSurfaceAudioController>();
|
||||
UnityEngine.Object.Destroy(audio);
|
||||
|
||||
foreach (var owAudioSource in sun.GetComponentsInChildren<OWAudioSource>())
|
||||
{
|
||||
StrangerRemoved();
|
||||
owAudioSource.Stop();
|
||||
UnityEngine.Object.Destroy(owAudioSource);
|
||||
}
|
||||
|
||||
foreach (var audioSource in sun.GetComponentsInChildren<AudioSource>())
|
||||
{
|
||||
audioSource.Stop();
|
||||
UnityEngine.Object.Destroy(audioSource);
|
||||
}
|
||||
|
||||
foreach (var sunProxy in UnityEngine.Object.FindObjectsOfType<SunProxy>())
|
||||
{
|
||||
NHLogger.LogVerbose($"Destroying SunProxy {sunProxy.gameObject.name}");
|
||||
UnityEngine.Object.Destroy(sunProxy.gameObject);
|
||||
}
|
||||
|
||||
// Stop the sun from breaking stuff when the supernova gets triggered
|
||||
GlobalMessenger.RemoveListener("TriggerSupernova", sun.GetComponent<SunController>().OnTriggerSupernova);
|
||||
|
||||
// Just to be safe
|
||||
SunLightEffectsController.Instance.Update();
|
||||
}
|
||||
|
||||
private static void TimberHearthRemoved()
|
||||
{
|
||||
// Always just fucking kill this one to stop THE WARP BUG!!!
|
||||
GameObject.Destroy(SearchUtilities.Find("StreamingGroup_TH").gameObject);
|
||||
|
||||
var timberHearth = SearchUtilities.Find("TimberHearth_Body");
|
||||
foreach (var obj in timberHearth.GetComponentsInChildren<DayNightTracker>())
|
||||
{
|
||||
GameObject.Destroy(obj.gameObject);
|
||||
}
|
||||
foreach (var obj in timberHearth.GetComponentsInChildren<VillageMusicVolume>())
|
||||
{
|
||||
GameObject.Destroy(obj.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private static void GiantsDeepRemoved()
|
||||
{
|
||||
foreach (var jelly in UnityEngine.Object.FindObjectsOfType<JellyfishController>())
|
||||
{
|
||||
if (jelly.GetSector().GetRootSector().GetName() == Sector.Name.GiantsDeep)
|
||||
{
|
||||
DisableGameObject(jelly.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static void DisableAstroObject(AstroObject ao, List<AstroObject> toDisable = null)
|
||||
{
|
||||
if (ao.gameObject == null || !ao.gameObject.activeInHierarchy)
|
||||
{
|
||||
NHLogger.LogVerbose($"[{ao.name}] was already removed");
|
||||
NHLogger.LogVerbose($"[{ao?.name}] was already removed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (toDestroy == null) toDestroy = new List<AstroObject>();
|
||||
NHLogger.LogVerbose($"Removing [{ao.name}]");
|
||||
|
||||
if (toDestroy.Contains(ao))
|
||||
toDisable ??= new List<AstroObject>();
|
||||
|
||||
if (toDisable.Contains(ao))
|
||||
{
|
||||
NHLogger.LogVerbose($"Possible infinite recursion in RemoveBody: {ao.name} might be it's own primary body?");
|
||||
return;
|
||||
}
|
||||
|
||||
toDestroy.Add(ao);
|
||||
toDisable.Add(ao);
|
||||
|
||||
try
|
||||
{
|
||||
switch(ao._name)
|
||||
{
|
||||
case AstroObject.Name.BrittleHollow:
|
||||
RemoveBody(AstroObjectLocator.GetAstroObject(AstroObject.Name.WhiteHole.ToString()), delete, toDestroy);
|
||||
DisableAstroObject(AstroObjectLocator.GetAstroObject(AstroObject.Name.WhiteHole.ToString()), toDisable);
|
||||
// Might prevent leftover fragments from existing
|
||||
// Might also prevent people from using their own detachable fragments however
|
||||
foreach(var fragment in UnityEngine.Object.FindObjectsOfType<DetachableFragment>())
|
||||
{
|
||||
DisableBody(fragment.gameObject, delete);
|
||||
DisableGameObject(fragment.gameObject);
|
||||
}
|
||||
break;
|
||||
|
||||
case AstroObject.Name.CaveTwin:
|
||||
case AstroObject.Name.TowerTwin:
|
||||
DisableBody(SearchUtilities.Find("FocalBody"), delete);
|
||||
DisableBody(SearchUtilities.Find("SandFunnel_Body", false), delete);
|
||||
DisableGameObject(SearchUtilities.Find("FocalBody"));
|
||||
DisableGameObject(SearchUtilities.Find("SandFunnel_Body", false));
|
||||
break;
|
||||
|
||||
case AstroObject.Name.GiantsDeep:
|
||||
// Might prevent leftover jellyfish from existing
|
||||
// Might also prevent people from using their own jellyfish however
|
||||
foreach (var jelly in UnityEngine.Object.FindObjectsOfType<JellyfishController>())
|
||||
{
|
||||
DisableBody(jelly.gameObject, delete);
|
||||
}
|
||||
// Else it will re-eanble the pieces
|
||||
// ao.GetComponent<OrbitalProbeLaunchController>()._realDebrisSectorProxies = null;
|
||||
GiantsDeepRemoved();
|
||||
break;
|
||||
case AstroObject.Name.TimberHearth:
|
||||
// Always just fucking kill this one to stop THE WARP BUG!!!
|
||||
DisableBody(SearchUtilities.Find("StreamingGroup_TH"), true);
|
||||
|
||||
foreach (var obj in UnityEngine.Object.FindObjectsOfType<DayNightTracker>())
|
||||
{
|
||||
DisableBody(obj.gameObject, true);
|
||||
}
|
||||
foreach (var obj in UnityEngine.Object.FindObjectsOfType<VillageMusicVolume>())
|
||||
{
|
||||
DisableBody(obj.gameObject, true);
|
||||
}
|
||||
TimberHearthRemoved();
|
||||
break;
|
||||
case AstroObject.Name.Sun:
|
||||
var starController = ao.gameObject.GetComponent<StarController>();
|
||||
SunLightEffectsController.RemoveStar(starController);
|
||||
SunLightEffectsController.RemoveStarLight(ao.transform.Find("Sector_SUN/Effects_SUN/SunLight").GetComponent<Light>());
|
||||
UnityEngine.Object.Destroy(starController);
|
||||
|
||||
var audio = ao.GetComponentInChildren<SunSurfaceAudioController>();
|
||||
UnityEngine.Object.Destroy(audio);
|
||||
|
||||
foreach (var owAudioSource in ao.GetComponentsInChildren<OWAudioSource>())
|
||||
{
|
||||
owAudioSource.Stop();
|
||||
UnityEngine.Object.Destroy(owAudioSource);
|
||||
}
|
||||
|
||||
foreach (var audioSource in ao.GetComponentsInChildren<AudioSource>())
|
||||
{
|
||||
audioSource.Stop();
|
||||
UnityEngine.Object.Destroy(audioSource);
|
||||
}
|
||||
|
||||
foreach (var sunProxy in UnityEngine.Object.FindObjectsOfType<SunProxy>())
|
||||
{
|
||||
NHLogger.LogVerbose($"Destroying SunProxy {sunProxy.gameObject.name}");
|
||||
UnityEngine.Object.Destroy(sunProxy.gameObject);
|
||||
}
|
||||
|
||||
// Stop the sun from breaking stuff when the supernova gets triggered
|
||||
GlobalMessenger.RemoveListener("TriggerSupernova", ao.GetComponent<SunController>().OnTriggerSupernova);
|
||||
SunRemoved();
|
||||
break;
|
||||
case AstroObject.Name.RingWorld:
|
||||
StrangerRemoved();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -226,8 +199,14 @@ namespace NewHorizons.Handlers
|
||||
|
||||
// Some children might be astro objects and as such can have children of their own
|
||||
var childAO = child.GetComponent<AstroObject>();
|
||||
if (childAO != null) RemoveBody(childAO, false, toDestroy);
|
||||
else DisableBody(child, true);
|
||||
if (childAO != null)
|
||||
{
|
||||
DisableAstroObject(childAO, toDisable);
|
||||
}
|
||||
else
|
||||
{
|
||||
DisableGameObject(child);
|
||||
}
|
||||
}
|
||||
|
||||
// Always delete moons
|
||||
@ -235,7 +214,7 @@ namespace NewHorizons.Handlers
|
||||
{
|
||||
if (obj == null) continue;
|
||||
|
||||
RemoveBody(obj.GetComponent<AstroObject>(), false, toDestroy);
|
||||
DisableAstroObject(obj.GetComponent<AstroObject>(), toDisable);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -243,36 +222,8 @@ namespace NewHorizons.Handlers
|
||||
NHLogger.LogError($"Exception thrown when trying to delete bodies related to [{ao.name}]:\n{e}");
|
||||
}
|
||||
|
||||
// Deal with proxies
|
||||
foreach (var p in UnityEngine.Object.FindObjectsOfType<ProxyOrbiter>())
|
||||
{
|
||||
if (p._originalBody == ao.gameObject)
|
||||
{
|
||||
DisableBody(p.gameObject, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
RemoveProxy(ao.name.Replace("_Body", ""));
|
||||
|
||||
Delay.RunWhen(() => Main.IsSystemReady, () => DisableBody(ao.gameObject, delete));
|
||||
|
||||
foreach (ProxyBody proxy in UnityEngine.Object.FindObjectsOfType<ProxyBody>())
|
||||
{
|
||||
if (proxy?._realObjectTransform?.gameObject == ao.gameObject)
|
||||
{
|
||||
UnityEngine.Object.Destroy(proxy.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveAllProxies()
|
||||
{
|
||||
UnityEngine.Object.Destroy(UnityEngine.Object.FindObjectOfType<DistantProxyManager>().gameObject);
|
||||
|
||||
foreach (var name in _solarSystemBodies)
|
||||
{
|
||||
RemoveProxy(name.Replace(" ", "").Replace("'", ""));
|
||||
}
|
||||
DisableGameObject(ao.gameObject);
|
||||
RemoveProxy(ao);
|
||||
}
|
||||
|
||||
private static bool CanSuspend(OWRigidbody rigidbody, string name)
|
||||
@ -282,7 +233,7 @@ namespace NewHorizons.Handlers
|
||||
return CanSuspend(rigidbody._origParentBody, name);
|
||||
}
|
||||
|
||||
internal static void DisableBody(GameObject go, bool delete)
|
||||
internal static void DisableGameObject(GameObject go)
|
||||
{
|
||||
if (go == null) return;
|
||||
|
||||
@ -313,33 +264,18 @@ namespace NewHorizons.Handlers
|
||||
}
|
||||
}
|
||||
|
||||
if (delete)
|
||||
go.SetActive(false);
|
||||
var ol = go.GetComponentInChildren<OrbitLine>();
|
||||
if (ol)
|
||||
{
|
||||
UnityEngine.Object.Destroy(go);
|
||||
}
|
||||
else
|
||||
{
|
||||
go.SetActive(false);
|
||||
var ol = go.GetComponentInChildren<OrbitLine>();
|
||||
if (ol)
|
||||
{
|
||||
ol.enabled = false;
|
||||
}
|
||||
ol.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void RemoveProxy(string name)
|
||||
private static void RemoveProxy(AstroObject ao)
|
||||
{
|
||||
if (name.Equals("TowerTwin")) name = "AshTwin";
|
||||
if (name.Equals("CaveTwin")) name = "EmberTwin";
|
||||
var distantProxy = SearchUtilities.Find(name + "_DistantProxy", false);
|
||||
var distantProxyClone = SearchUtilities.Find(name + "_DistantProxy(Clone)", false);
|
||||
|
||||
if (distantProxy != null) UnityEngine.Object.Destroy(distantProxy.gameObject);
|
||||
if (distantProxyClone != null) UnityEngine.Object.Destroy(distantProxyClone.gameObject);
|
||||
|
||||
if (distantProxy == null && distantProxyClone == null)
|
||||
NHLogger.LogVerbose($"Couldn't find proxy for {name}");
|
||||
ProxyHandler.GetVanillaProxyBody(ao.transform)?.gameObject?.SetActive(false);
|
||||
ProxyHandler.GetVanillaProxyOrbiter(ao.transform)?.gameObject?.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,11 +10,11 @@ namespace NewHorizons.Handlers
|
||||
{
|
||||
public static void SetUpPlayerSpawn()
|
||||
{
|
||||
var spawnPoint = Main.SystemDict[Main.Instance.CurrentStarSystem].SpawnPoint;
|
||||
if (spawnPoint != null)
|
||||
if (UsingCustomSpawn())
|
||||
{
|
||||
SearchUtilities.Find("Player_Body").GetComponent<MatchInitialMotion>().SetBodyToMatch(spawnPoint.GetAttachedOWRigidbody());
|
||||
GetPlayerSpawner().SetInitialSpawnPoint(spawnPoint);
|
||||
var spawn = GetDefaultSpawn();
|
||||
SearchUtilities.Find("Player_Body").GetComponent<MatchInitialMotion>().SetBodyToMatch(spawn.GetAttachedOWRigidbody());
|
||||
GetPlayerSpawner().SetInitialSpawnPoint(spawn);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -44,24 +44,45 @@ namespace NewHorizons.Handlers
|
||||
// Arbitrary number, depending on the machine some people die, some people fall through the floor, its very inconsistent
|
||||
Delay.StartCoroutine(SpawnCoroutine(30));
|
||||
}
|
||||
|
||||
var cloak = GetDefaultSpawn()?.GetAttachedOWRigidbody()?.GetComponentInChildren<CloakFieldController>();
|
||||
if (cloak != null)
|
||||
{
|
||||
// Ensures it has invoked everything and actually placed the player in the cloaking field #671
|
||||
cloak._firstUpdate = true;
|
||||
}
|
||||
|
||||
// Spawn ship
|
||||
Delay.FireInNUpdates(SpawnShip, 30);
|
||||
}
|
||||
|
||||
public static void SpawnShip()
|
||||
{
|
||||
var ship = SearchUtilities.Find("Ship_Body");
|
||||
if (ship != null)
|
||||
|
||||
if (SpawnPointBuilder.ShipSpawn != null)
|
||||
{
|
||||
ship.SetActive(true);
|
||||
NHLogger.Log("Spawning player ship");
|
||||
|
||||
var pos = SpawnPointBuilder.ShipSpawn.transform.position;
|
||||
|
||||
// Move it up a bit more when aligning to surface
|
||||
if (SpawnPointBuilder.ShipSpawnOffset != null)
|
||||
if (ship != null)
|
||||
{
|
||||
pos += SpawnPointBuilder.ShipSpawn.transform.TransformDirection(SpawnPointBuilder.ShipSpawnOffset);
|
||||
}
|
||||
ship.SetActive(true);
|
||||
|
||||
SpawnBody(ship.GetAttachedOWRigidbody(), SpawnPointBuilder.ShipSpawn, pos);
|
||||
var pos = SpawnPointBuilder.ShipSpawn.transform.position;
|
||||
|
||||
// Move it up a bit more when aligning to surface
|
||||
if (SpawnPointBuilder.ShipSpawnOffset != null)
|
||||
{
|
||||
pos += SpawnPointBuilder.ShipSpawn.transform.TransformDirection(SpawnPointBuilder.ShipSpawnOffset);
|
||||
}
|
||||
|
||||
SpawnBody(ship.GetAttachedOWRigidbody(), SpawnPointBuilder.ShipSpawn, pos);
|
||||
}
|
||||
}
|
||||
else if (Main.Instance.CurrentStarSystem != "SolarSystem" && !Main.Instance.IsWarpingFromShip)
|
||||
{
|
||||
NHLogger.Log("System has no ship spawn. Deactivating it.");
|
||||
ship?.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,20 +95,6 @@ namespace NewHorizons.Handlers
|
||||
}
|
||||
|
||||
InvulnerabilityHandler.MakeInvulnerable(false);
|
||||
|
||||
if (!Main.Instance.IsWarpingFromShip)
|
||||
{
|
||||
if (SpawnPointBuilder.ShipSpawn != null)
|
||||
{
|
||||
NHLogger.Log("Spawning player ship");
|
||||
SpawnShip();
|
||||
}
|
||||
else
|
||||
{
|
||||
NHLogger.Log("System has no ship spawn. Deactivating it.");
|
||||
SearchUtilities.Find("Ship_Body")?.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void FixPlayerVelocity()
|
||||
|
||||
@ -1,11 +1,21 @@
|
||||
using NewHorizons.Components;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NewHorizons.Handlers
|
||||
{
|
||||
public static class ProxyHandler
|
||||
{
|
||||
private static List<NHProxy> _proxies = new List<NHProxy>();
|
||||
private static List<NHProxy> _proxies = new();
|
||||
private static Dictionary<Transform, ProxyBody> _vanillaProxyBody = new();
|
||||
private static Dictionary<Transform, ProxyOrbiter> _vanillaProxyOrbiter = new();
|
||||
|
||||
public static void ClearCache()
|
||||
{
|
||||
_proxies.Clear();
|
||||
_vanillaProxyBody.Clear();
|
||||
_vanillaProxyOrbiter.Clear();
|
||||
}
|
||||
|
||||
public static NHProxy GetProxy(string astroName)
|
||||
{
|
||||
@ -17,6 +27,48 @@ namespace NewHorizons.Handlers
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void RegisterVanillaProxyBody(ProxyBody proxy)
|
||||
{
|
||||
if (proxy.realObjectTransform != null)
|
||||
{
|
||||
_vanillaProxyBody.Add(proxy.realObjectTransform, proxy);
|
||||
}
|
||||
}
|
||||
|
||||
public static ProxyBody GetVanillaProxyBody(Transform t)
|
||||
{
|
||||
if (_vanillaProxyBody.TryGetValue(t, out ProxyBody proxy))
|
||||
{
|
||||
return proxy;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void RegisterVanillaProxyOrbiter(ProxyOrbiter proxy)
|
||||
{
|
||||
// The _originalBody is the moon
|
||||
// For _originalPlanetBody, that game object will also have a ProxyBody on it so it'd be counted via the other cache
|
||||
if (proxy._originalBody != null)
|
||||
{
|
||||
_vanillaProxyOrbiter.Add(proxy._originalBody, proxy);
|
||||
}
|
||||
}
|
||||
|
||||
public static ProxyOrbiter GetVanillaProxyOrbiter(Transform t)
|
||||
{
|
||||
if (_vanillaProxyOrbiter.TryGetValue(t, out ProxyOrbiter proxy))
|
||||
{
|
||||
return proxy;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void RegisterProxy(NHProxy proxy)
|
||||
{
|
||||
_proxies.SafeAdd(proxy);
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
using NewHorizons.Handlers;
|
||||
using OWML.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -92,6 +93,11 @@ namespace NewHorizons
|
||||
/// Uses JSONPath to query the current star system
|
||||
///</summary>
|
||||
T QuerySystem<T>(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Register your own builder that will act on the given GameObject by reading the json string of its "extras" module
|
||||
/// </summary>
|
||||
void RegisterCustomBuilder(Action<GameObject, string> builder);
|
||||
#endregion
|
||||
|
||||
#region Spawn props
|
||||
|
||||
@ -59,8 +59,27 @@ namespace NewHorizons
|
||||
public static bool IsSystemReady { get; private set; }
|
||||
|
||||
public string DefaultStarSystem => SystemDict.ContainsKey(_defaultSystemOverride) ? _defaultSystemOverride : _defaultStarSystem;
|
||||
public string CurrentStarSystem => _currentStarSystem;
|
||||
public bool TimeLoopEnabled => SystemDict[CurrentStarSystem]?.Config?.enableTimeLoop ?? true;
|
||||
public string CurrentStarSystem
|
||||
{
|
||||
get
|
||||
{
|
||||
return _currentStarSystem;
|
||||
}
|
||||
set
|
||||
{
|
||||
// Prevent invalid values
|
||||
if (value != "SolarSystem" && value != "EyeOfTheUniverse" && !SystemDict.ContainsKey(value) && !BodyDict.ContainsKey(value))
|
||||
{
|
||||
NHLogger.LogError($"System \"{value}\" does not exist!");
|
||||
_currentStarSystem = DefaultStarSystem;
|
||||
}
|
||||
_currentStarSystem = value;
|
||||
}
|
||||
}
|
||||
private string _currentStarSystem;
|
||||
private string _previousStarSystem;
|
||||
|
||||
public bool TimeLoopEnabled => CurrentStarSystem == null || (SystemDict[CurrentStarSystem]?.Config?.enableTimeLoop ?? true);
|
||||
public bool IsWarpingFromShip { get; private set; } = false;
|
||||
public bool IsWarpingFromVessel { get; private set; } = false;
|
||||
public bool IsWarpingBackToEye { get; internal set; } = false;
|
||||
@ -73,7 +92,7 @@ namespace NewHorizons
|
||||
public static bool HasWarpDrive { get; private set; } = false;
|
||||
|
||||
private string _defaultStarSystem = "SolarSystem";
|
||||
internal string _currentStarSystem = "SolarSystem";
|
||||
|
||||
private bool _firstLoad = true;
|
||||
|
||||
private bool _playerAwake;
|
||||
@ -260,11 +279,20 @@ namespace NewHorizons
|
||||
|
||||
private void OnSceneUnloaded(Scene scene)
|
||||
{
|
||||
// Caches of GameObjects must always be cleared
|
||||
SearchUtilities.ClearCache();
|
||||
ImageUtilities.ClearCache();
|
||||
AudioUtilities.ClearCache();
|
||||
AssetBundleUtilities.ClearCache();
|
||||
EnumUtilities.ClearCache();
|
||||
ProxyHandler.ClearCache();
|
||||
|
||||
// Caches of other assets only have to be cleared if we changed star systems
|
||||
if (CurrentStarSystem != _previousStarSystem)
|
||||
{
|
||||
NHLogger.Log($"Changing star system from {_previousStarSystem} to {CurrentStarSystem} - Clearing system-specific caches!");
|
||||
ImageUtilities.ClearCache();
|
||||
AudioUtilities.ClearCache();
|
||||
AssetBundleUtilities.ClearCache();
|
||||
EnumUtilities.ClearCache();
|
||||
}
|
||||
|
||||
IsSystemReady = false;
|
||||
}
|
||||
|
||||
@ -330,7 +358,7 @@ namespace NewHorizons
|
||||
|
||||
if (isEyeOfTheUniverse)
|
||||
{
|
||||
_currentStarSystem = "EyeOfTheUniverse";
|
||||
CurrentStarSystem = "EyeOfTheUniverse";
|
||||
}
|
||||
else if (IsWarpingBackToEye)
|
||||
{
|
||||
@ -341,14 +369,8 @@ namespace NewHorizons
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SystemDict.ContainsKey(_currentStarSystem) || !BodyDict.ContainsKey(_currentStarSystem))
|
||||
{
|
||||
NHLogger.LogError($"System \"{_currentStarSystem}\" does not exist!");
|
||||
_currentStarSystem = DefaultStarSystem;
|
||||
}
|
||||
|
||||
// Set time loop stuff if its enabled and if we're warping to a new place
|
||||
if (IsChangingStarSystem && (SystemDict[_currentStarSystem].Config.enableTimeLoop || _currentStarSystem == "SolarSystem") && SecondsElapsedInLoop > 0f)
|
||||
if (IsChangingStarSystem && (SystemDict[CurrentStarSystem].Config.enableTimeLoop || CurrentStarSystem == "SolarSystem") && SecondsElapsedInLoop > 0f)
|
||||
{
|
||||
TimeLoopUtilities.SetSecondsElapsed(SecondsElapsedInLoop);
|
||||
// Prevent the OPC from firing
|
||||
@ -363,7 +385,7 @@ namespace NewHorizons
|
||||
launchController.enabled = false;
|
||||
}
|
||||
var nomaiProbe = SearchUtilities.Find("NomaiProbe_Body");
|
||||
if (nomaiProbe != null) nomaiProbe.gameObject.SetActive(false);
|
||||
nomaiProbe?.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
// Reset this
|
||||
@ -518,6 +540,10 @@ namespace NewHorizons
|
||||
{
|
||||
ResetCurrentStarSystem();
|
||||
}
|
||||
|
||||
// We only check previous when the scene unloads, and at that point current should be updated to the new system
|
||||
NHLogger.LogVerbose($"Set the previous system to {CurrentStarSystem}");
|
||||
_previousStarSystem = CurrentStarSystem;
|
||||
}
|
||||
|
||||
// Had a bunch of separate unity things firing stuff when the system is ready so I moved it all to here
|
||||
@ -567,7 +593,7 @@ namespace NewHorizons
|
||||
if (starSystemName != "SolarSystem")
|
||||
{
|
||||
SetDefaultSystem(starSystemName);
|
||||
_currentStarSystem = DefaultStarSystem;
|
||||
CurrentStarSystem = DefaultStarSystem;
|
||||
}
|
||||
}
|
||||
|
||||
@ -784,7 +810,7 @@ namespace NewHorizons
|
||||
// If we're just on the title screen set the system for later
|
||||
if (LoadManager.GetCurrentScene() == OWScene.TitleScreen)
|
||||
{
|
||||
_currentStarSystem = newStarSystem;
|
||||
CurrentStarSystem = newStarSystem;
|
||||
IsWarpingFromShip = warp;
|
||||
IsWarpingFromVessel = vessel;
|
||||
DidWarpFromVessel = false;
|
||||
@ -828,13 +854,13 @@ namespace NewHorizons
|
||||
{
|
||||
PlayerData.SaveEyeCompletion(); // So that the title screen doesn't keep warping you back to eye
|
||||
|
||||
if (SystemDict[_currentStarSystem].Config.enableTimeLoop) SecondsElapsedInLoop = TimeLoop.GetSecondsElapsed();
|
||||
if (SystemDict[CurrentStarSystem].Config.enableTimeLoop) SecondsElapsedInLoop = TimeLoop.GetSecondsElapsed();
|
||||
else SecondsElapsedInLoop = -1;
|
||||
|
||||
sceneToLoad = OWScene.SolarSystem;
|
||||
}
|
||||
|
||||
_currentStarSystem = newStarSystem;
|
||||
CurrentStarSystem = newStarSystem;
|
||||
|
||||
// Freeze player inputs
|
||||
OWInput.ChangeInputMode(InputMode.None);
|
||||
@ -854,7 +880,7 @@ namespace NewHorizons
|
||||
// We reset the solar system on death
|
||||
if (!IsChangingStarSystem)
|
||||
{
|
||||
if (SystemDict[_currentStarSystem].Config.respawnHere) return;
|
||||
if (SystemDict[CurrentStarSystem].Config.respawnHere) return;
|
||||
|
||||
ResetCurrentStarSystem();
|
||||
}
|
||||
@ -864,19 +890,20 @@ namespace NewHorizons
|
||||
{
|
||||
if (SystemDict.ContainsKey(_defaultSystemOverride))
|
||||
{
|
||||
_currentStarSystem = _defaultSystemOverride;
|
||||
CurrentStarSystem = _defaultSystemOverride;
|
||||
|
||||
// Sometimes the override will not support spawning regularly, so always warp in
|
||||
IsWarpingFromShip = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_defaultSystemOverride))
|
||||
// Ignore first load because it doesn't even know what systems we have
|
||||
if (!_firstLoad && !string.IsNullOrEmpty(_defaultSystemOverride))
|
||||
{
|
||||
NHLogger.LogError($"The given default system override {_defaultSystemOverride} is invalid - no system exists with that name");
|
||||
}
|
||||
|
||||
_currentStarSystem = _defaultStarSystem;
|
||||
CurrentStarSystem = _defaultStarSystem;
|
||||
IsWarpingFromShip = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ using NewHorizons.External.Modules.Props.Audio;
|
||||
using NewHorizons.External.Modules.Props.Dialogue;
|
||||
using NewHorizons.External.Modules.TranslatorText;
|
||||
using NewHorizons.External.SerializableData;
|
||||
using NewHorizons.Handlers;
|
||||
using NewHorizons.Utility;
|
||||
using NewHorizons.Utility.OWML;
|
||||
using Newtonsoft.Json;
|
||||
@ -315,5 +316,11 @@ namespace NewHorizons
|
||||
|
||||
RumorModeBuilder.AddShipLogXML(GameObject.FindObjectOfType<ShipLogManager>(), xml, body);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register your own builder that will act on the given GameObject by reading its raw json string
|
||||
/// </summary>
|
||||
/// <param name="builder"></param>
|
||||
public void RegisterCustomBuilder(Action<GameObject, string> builder) => PlanetCreationHandler.CustomBuilders.Add(builder);
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,10 +12,10 @@ namespace NewHorizons.Patches.EyeScenePatches
|
||||
PlayerData.SaveEyeCompletion();
|
||||
|
||||
// Switch to default just in case another mod warps back.
|
||||
if (Main.Instance.CurrentStarSystem == "EyeOfTheUniverse") Main.Instance._currentStarSystem = Main.Instance.DefaultStarSystem;
|
||||
if (Main.Instance.CurrentStarSystem == "EyeOfTheUniverse") Main.Instance.CurrentStarSystem = Main.Instance.DefaultStarSystem;
|
||||
}
|
||||
// Switch to eye just in case another mod warps there.
|
||||
else if (scene == OWScene.EyeOfTheUniverse) Main.Instance._currentStarSystem = "EyeOfTheUniverse";
|
||||
else if (scene == OWScene.EyeOfTheUniverse) Main.Instance.CurrentStarSystem = "EyeOfTheUniverse";
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
|
||||
@ -1,15 +1,22 @@
|
||||
using HarmonyLib;
|
||||
using NewHorizons.Handlers;
|
||||
|
||||
namespace NewHorizons.Patches.ProxyPatches
|
||||
namespace NewHorizons.Patches.ProxyPatches;
|
||||
|
||||
[HarmonyPatch(typeof(ProxyBody))]
|
||||
public static class ProxyBodyPatches
|
||||
{
|
||||
[HarmonyPatch(typeof(ProxyBody))]
|
||||
public static class ProxyBodyPatches
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(nameof(ProxyBody.LateInitialize))]
|
||||
public static void ProxyBody_LateInitialize(ProxyBody __instance)
|
||||
{
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(ProxyBody.IsObjectInSupernova))]
|
||||
public static bool ProxyBody_IsObjectInSupernova(ProxyBody __instance)
|
||||
{
|
||||
return Locator.GetSunController() != null;
|
||||
}
|
||||
ProxyHandler.RegisterVanillaProxyBody(__instance);
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(ProxyBody.IsObjectInSupernova))]
|
||||
public static bool ProxyBody_IsObjectInSupernova(ProxyBody __instance)
|
||||
{
|
||||
return Locator.GetSunController() != null;
|
||||
}
|
||||
}
|
||||
|
||||
15
NewHorizons/Patches/ProxyPatches/ProxyOrbiterPatches.cs
Normal file
15
NewHorizons/Patches/ProxyPatches/ProxyOrbiterPatches.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using HarmonyLib;
|
||||
using NewHorizons.Handlers;
|
||||
|
||||
namespace NewHorizons.Patches.ProxyPatches;
|
||||
|
||||
[HarmonyPatch(typeof(ProxyOrbiter))]
|
||||
public static class ProxyOrbiterPatches
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(nameof(ProxyOrbiter.SetOriginalBodies))]
|
||||
public static void ProxyOrbiter_SetOriginalBodies(ProxyOrbiter __instance)
|
||||
{
|
||||
ProxyHandler.RegisterVanillaProxyOrbiter(__instance);
|
||||
}
|
||||
}
|
||||
19
NewHorizons/Patches/ProxyPatches/SunProxyPatches.cs
Normal file
19
NewHorizons/Patches/ProxyPatches/SunProxyPatches.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using HarmonyLib;
|
||||
using NewHorizons.Utility;
|
||||
|
||||
namespace NewHorizons.Patches.ProxyPatches
|
||||
{
|
||||
[HarmonyPatch(typeof(SunProxy))]
|
||||
public static class SunProxyPatches
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(nameof(SunProxy.Start))]
|
||||
public static void SunProxy_Start(SunProxy __instance)
|
||||
{
|
||||
// We mess with the Locator.GetSunTransform() value to switch it to other relevant stars since it's used for some other effects
|
||||
// However if it's set to a different star when the SunProxy starts it breaks, so we double check it here
|
||||
__instance._sunTransform = SearchUtilities.Find("Sun_Body").transform;
|
||||
__instance._realSunController = __instance._sunTransform.GetComponent<SunController>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
using HarmonyLib;
|
||||
using NewHorizons.Handlers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NewHorizons.Patches.ShipLogPatches
|
||||
{
|
||||
[HarmonyPatch(typeof(ShipLogEntryLocation))]
|
||||
public static class ShipLogEntryLocationPatches
|
||||
{
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(nameof(ShipLogEntryLocation.OnValidate))]
|
||||
public static bool ShipLogEntryLocation_OnValidate(ShipLogEntryLocation __instance)
|
||||
{
|
||||
// This part is unchanged
|
||||
if (!__instance._entryID.Equals(string.Empty) && !__instance.gameObject.name.Equals(__instance._entryID))
|
||||
{
|
||||
__instance.gameObject.name = __instance._entryID;
|
||||
}
|
||||
|
||||
// Base method checks if its on the Ringworld to see if it can be cloaked, we wanna check for a cloak field controller instead
|
||||
var cloak = __instance.GetComponentInChildren<CloakFieldController>();
|
||||
__instance._isWithinCloakField = cloak != null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
using HarmonyLib;
|
||||
using NewHorizons.Components.Stars;
|
||||
using UnityEngine;
|
||||
namespace NewHorizons.Patches.SunPatches
|
||||
{
|
||||
@ -13,10 +14,20 @@ namespace NewHorizons.Patches.SunPatches
|
||||
{
|
||||
Vector3 position = __instance.transform.position;
|
||||
float w = 2000f;
|
||||
if (__instance._sunController != null)
|
||||
|
||||
var sunController = SunLightEffectsController.Instance.ActiveSunController;
|
||||
var starEvolutionController = SunLightEffectsController.Instance.ActiveStarEvolutionController;
|
||||
|
||||
if (sunController != null)
|
||||
{
|
||||
w = __instance._sunController.HasSupernovaStarted() ? __instance._sunController.GetSupernovaRadius() : __instance._sunController.GetSurfaceRadius();
|
||||
w = sunController.HasSupernovaStarted() ? sunController.GetSupernovaRadius() : sunController.GetSurfaceRadius();
|
||||
}
|
||||
// This is an addition in this patch, to work with our stars
|
||||
else if (starEvolutionController != null)
|
||||
{
|
||||
w = starEvolutionController.HasSupernovaStarted() ? starEvolutionController.GetSupernovaRadius() : starEvolutionController.GetSurfaceRadius();
|
||||
}
|
||||
|
||||
float range = __instance.sunLight.range;
|
||||
Color color = __instance._sunLightController != null ? __instance._sunLightController.sunColor : __instance.sunLight.color;
|
||||
float w2 = __instance._sunLightController != null ? __instance._sunLightController.sunIntensity : __instance.sunLight.intensity;
|
||||
|
||||
@ -29,12 +29,22 @@ namespace NewHorizons.Patches.WarpPatches
|
||||
[HarmonyPatch(nameof(VesselWarpController.CheckSystemActivation))]
|
||||
public static void VesselWarpController_CheckSystemActivation(VesselWarpController __instance)
|
||||
{
|
||||
if (Locator.GetEyeStateManager() == null && Main.Instance.CurrentStarSystem != "EyeOfTheUniverse")
|
||||
// Base method only manages the state of the source warp platform blackhole if the EyeStateManager isn't null
|
||||
// However we place the vessel into other systems, so we want to handle the state in those locations as well
|
||||
// For some reason the blackhole can also just be null in which case we ignore all this. Happens in Intervention 1.0.3
|
||||
if (Locator.GetEyeStateManager() == null && Main.Instance.CurrentStarSystem != "EyeOfTheUniverse" && __instance._sourceWarpPlatform._blackHole != null)
|
||||
{
|
||||
if (!__instance._sourceWarpPlatform.IsBlackHoleOpen() && __instance._hasPower && __instance._warpPlatformPowerSlot.IsActivated() && __instance._targetWarpPlatform != null)
|
||||
__instance._sourceWarpPlatform.OpenBlackHole(__instance._targetWarpPlatform, true);
|
||||
else if (__instance._sourceWarpPlatform.IsBlackHoleOpen() && (!__instance._hasPower || !__instance._warpPlatformPowerSlot.IsActivated()))
|
||||
var isBlackHoleOpen = __instance._sourceWarpPlatform.IsBlackHoleOpen();
|
||||
var shouldBlackHoleBeOpen = __instance._hasPower && __instance._warpPlatformPowerSlot.IsActivated() && __instance._targetWarpPlatform != null;
|
||||
|
||||
if (isBlackHoleOpen && !shouldBlackHoleBeOpen)
|
||||
{
|
||||
__instance._sourceWarpPlatform.CloseBlackHole();
|
||||
}
|
||||
else if (!isBlackHoleOpen && shouldBlackHoleBeOpen)
|
||||
{
|
||||
__instance._sourceWarpPlatform.OpenBlackHole(__instance._targetWarpPlatform, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,7 +63,7 @@ namespace NewHorizons.Patches.WarpPatches
|
||||
Locator.GetPauseCommandListener().AddPauseCommandLock();
|
||||
if (canWarpToEye || canWarpToStarSystem && targetSystem == "EyeOfTheUniverse")
|
||||
{
|
||||
Main.Instance._currentStarSystem = "EyeOfTheUniverse";
|
||||
Main.Instance.CurrentStarSystem = "EyeOfTheUniverse";
|
||||
LoadManager.LoadSceneAsync(OWScene.EyeOfTheUniverse, false, LoadManager.FadeType.ToWhite);
|
||||
}
|
||||
else if (canWarpToStarSystem)
|
||||
|
||||
@ -132,6 +132,13 @@
|
||||
"description": "Add water to this planet",
|
||||
"$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": {
|
||||
"description": "Add various volumes on this body",
|
||||
"$ref": "#/definitions/VolumesModule"
|
||||
@ -371,11 +378,7 @@
|
||||
},
|
||||
"hasRain": {
|
||||
"type": "boolean",
|
||||
"description": "Does this planet have rain?"
|
||||
},
|
||||
"hasSnow": {
|
||||
"type": "boolean",
|
||||
"description": "Does this planet have snow?"
|
||||
"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."
|
||||
},
|
||||
"size": {
|
||||
"type": "number",
|
||||
@ -1056,6 +1059,10 @@
|
||||
"type": "boolean",
|
||||
"description": "Should the body always have one side facing its primary?"
|
||||
},
|
||||
"isStatic": {
|
||||
"type": "boolean",
|
||||
"description": "Is the body meant to stay in one place without moving? If staticPosition is not set, the initial position\nwill be determined using its orbital parameters."
|
||||
},
|
||||
"alignmentAxis": {
|
||||
"description": "If it is tidally locked, this direction will face towards the primary. Ex: Interloper uses `0, -1, 0`. Most planets\nwill want something like `-1, 0, 0`.",
|
||||
"$ref": "#/definitions/MVector3"
|
||||
@ -1069,10 +1076,6 @@
|
||||
"type": "boolean",
|
||||
"description": "Should the orbit line be dotted?"
|
||||
},
|
||||
"isStatic": {
|
||||
"type": "boolean",
|
||||
"description": "Is the body meant to stay in one place without moving? If staticPosition is not set, the initial position\nwill be determined using its orbital parameters."
|
||||
},
|
||||
"tint": {
|
||||
"description": "Colour of the orbit-line in the map view.",
|
||||
"$ref": "#/definitions/MColor"
|
||||
@ -1081,6 +1084,16 @@
|
||||
"type": "boolean",
|
||||
"description": "Should we just draw a line behind its orbit instead of the entire circle/ellipse?"
|
||||
},
|
||||
"orbitLineFadeEndDistance": {
|
||||
"type": "number",
|
||||
"description": "If the camera is farther than this distance the orbit line will fade out. Leave empty to not have it fade out.",
|
||||
"format": "float"
|
||||
},
|
||||
"orbitLineFadeStartDistance": {
|
||||
"type": "number",
|
||||
"description": "If the camera is closer than this distance the orbit line will fade out. Leave empty to not have it fade out.",
|
||||
"format": "float"
|
||||
},
|
||||
"semiMajorAxis": {
|
||||
"type": "number",
|
||||
"description": "The semi-major axis of the ellipse that is the body's orbit. For a circular orbit this is the radius.",
|
||||
@ -3573,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": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using NewHorizons.External.Configs;
|
||||
using NewHorizons.External.Modules.VariableSize;
|
||||
using NewHorizons.External.SerializableData;
|
||||
using NewHorizons.External.SerializableEnums;
|
||||
using NewHorizons.Utility.OWML;
|
||||
@ -12,6 +13,7 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEngine;
|
||||
using static NewHorizons.External.Modules.ParticleFieldModule;
|
||||
using NomaiCoordinates = NewHorizons.External.Configs.StarSystemConfig.NomaiCoordinates;
|
||||
|
||||
namespace NewHorizons.Utility
|
||||
@ -277,5 +279,31 @@ namespace NewHorizons.Utility
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,11 +10,13 @@ namespace NewHorizons.Utility
|
||||
public static class SearchUtilities
|
||||
{
|
||||
private static readonly Dictionary<string, GameObject> CachedGameObjects = new Dictionary<string, GameObject>();
|
||||
private static readonly Dictionary<string, GameObject> CachedRootGameObjects = new Dictionary<string, GameObject>();
|
||||
|
||||
public static void ClearCache()
|
||||
{
|
||||
NHLogger.LogVerbose("Clearing search cache");
|
||||
CachedGameObjects.Clear();
|
||||
CachedRootGameObjects.Clear();
|
||||
}
|
||||
|
||||
public static List<T> FindObjectsOfTypeAndName<T>(string name) where T : Object
|
||||
@ -107,8 +109,16 @@ namespace NewHorizons.Utility
|
||||
// 2: find inactive using root + transform.find
|
||||
var names = path.Split('/');
|
||||
|
||||
// Cache the root objects so we don't loop through all of them each time
|
||||
var rootName = names[0];
|
||||
var root = SceneManager.GetActiveScene().GetRootGameObjects().FirstOrDefault(x => x.name == rootName);
|
||||
if (!CachedRootGameObjects.TryGetValue(rootName, out var root))
|
||||
{
|
||||
root = SceneManager.GetActiveScene().GetRootGameObjects().FirstOrDefault(x => x.name == rootName);
|
||||
if (root != null)
|
||||
{
|
||||
CachedRootGameObjects.Add(rootName, root);
|
||||
}
|
||||
}
|
||||
|
||||
var childPath = string.Join("/", names.Skip(1));
|
||||
go = root ? root.FindChild(childPath) : null;
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
"author": "xen, Bwc9876, clay, MegaPiggy, John, Trifid, Hawkbar, Book",
|
||||
"name": "New Horizons",
|
||||
"uniqueName": "xen.NewHorizons",
|
||||
"version": "1.14.6",
|
||||
"version": "1.16.0",
|
||||
"owmlVersion": "2.9.3",
|
||||
"dependencies": [ "JohnCorby.VanillaFix", "_nebula.MenuFramework", "xen.CommonCameraUtility", "dgarro.CustomShipLogModes" ],
|
||||
"conflicts": [ "Raicuparta.QuantumSpaceBuddies", "PacificEngine.OW_CommonResources" ],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user