Merge branch 'dev' into bramble-nodes

This commit is contained in:
JohnCorby 2022-07-01 12:44:57 -07:00
commit e4254ee6ec
35 changed files with 762 additions and 604 deletions

View File

@ -1,7 +1,6 @@
using NewHorizons.External.Configs;
using NewHorizons.Utility;
using OWML.ModHelper;
using System;
using System.Collections.Generic;
using System.Linq;

View File

@ -21,7 +21,7 @@ namespace NewHorizons.Builder.Atmosphere
if (info.isRaining)
{
var rainGO = GameObject.Instantiate(SearchUtilities.CachedFind("/GiantsDeep_Body/Sector_GD/Sector_GDInterior/Effects_GDInterior/Effects_GD_Rain"), effectsGO.transform);
var rainGO = GameObject.Instantiate(SearchUtilities.Find("GiantsDeep_Body/Sector_GD/Sector_GDInterior/Effects_GDInterior/Effects_GD_Rain"), effectsGO.transform);
rainGO.transform.position = planetGO.transform.position;
var pvc = rainGO.GetComponent<PlanetaryVectionController>();
@ -44,7 +44,7 @@ namespace NewHorizons.Builder.Atmosphere
snowGO.transform.position = planetGO.transform.position;
for (int i = 0; i < 5; i++)
{
var snowEmitter = GameObject.Instantiate(SearchUtilities.CachedFind("/BrittleHollow_Body/Sector_BH/Effects_BH/Effects_BH_Snowflakes"), snowGO.transform);
var snowEmitter = GameObject.Instantiate(SearchUtilities.Find("BrittleHollow_Body/Sector_BH/Effects_BH/Effects_BH_Snowflakes"), snowGO.transform);
snowEmitter.name = "SnowEmitter";
snowEmitter.transform.position = planetGO.transform.position;

View File

@ -1,21 +1,43 @@
using NewHorizons.External.Modules;
using NewHorizons.External.Modules;
using NewHorizons.External.Modules.VariableSize;
using UnityEngine;
namespace NewHorizons.Builder.Atmosphere
{
public static class SunOverrideBuilder
{
public static void Make(GameObject planetGO, Sector sector, AtmosphereModule atmo, float surfaceSize)
public static void Make(GameObject planetGO, Sector sector, AtmosphereModule atmo, WaterModule water, float surfaceSize)
{
GameObject overrideGO = new GameObject("SunOverride");
overrideGO.SetActive(false);
overrideGO.transform.parent = sector?.transform ?? planetGO.transform;
GiantsDeepSunOverrideVolume GDSOV = overrideGO.AddComponent<GiantsDeepSunOverrideVolume>();
GDSOV._sector = sector;
GDSOV._cloudsOuterRadius = atmo.size;
GDSOV._cloudsInnerRadius = atmo.size * 0.9f;
GDSOV._waterOuterRadius = surfaceSize;
GDSOV._waterInnerRadius = 0f;
if (water != null)
{
var GDSOV = overrideGO.AddComponent<GiantsDeepSunOverrideVolume>();
GDSOV._sector = sector;
GDSOV._cloudsOuterRadius = atmo.clouds.outerCloudRadius;
GDSOV._cloudsInnerRadius = atmo.clouds.innerCloudRadius;
GDSOV._waterOuterRadius = water.size;
GDSOV._waterInnerRadius = 0f;
}
else
{
var sunOverride = overrideGO.AddComponent<SunOverrideVolume>();
sunOverride._sector = sector;
sunOverride._overrideColor = true;
sunOverride._color = Color.black;
sunOverride._overrideIntensity = true;
sunOverride._intensity = 0f;
sunOverride._overrideShadowStrength = true;
sunOverride._shadowStrength = 1f;
sunOverride.shape = SimpleVolume.Shape.Sphere;
sunOverride.height = 2;
sunOverride.radius = atmo.clouds.innerCloudRadius;
}
overrideGO.transform.position = planetGO.transform.position;
overrideGO.SetActive(true);

View File

@ -62,7 +62,7 @@ namespace NewHorizons.Builder.Body
}
if (body.Config.Star != null)
{
var starGO = StarBuilder.MakeStarProxy(planetGO, newProxy, body.Config.Star);
var starGO = StarBuilder.MakeStarProxy(planetGO, newProxy, body.Config.Star, body.Mod);
if (realSize < body.Config.Star.size) realSize = body.Config.Star.size;
}
@ -93,18 +93,21 @@ namespace NewHorizons.Builder.Body
if (realSize < body.Config.Sand.size) realSize = body.Config.Sand.size;
}
// Could improve this to actually use the proper renders and materials
if (body.Config.Singularity != null)
if (body.Config.Props?.singularities != null)
{
if (body.Config.Singularity.type == SingularityModule.SingularityType.BlackHole)
foreach(var singularity in body.Config.Props.singularities)
{
MakeBlackHole(newProxy, body.Config.Singularity.size);
}
else
{
MakeWhiteHole(newProxy, body.Config.Singularity.size);
}
if (singularity.type == SingularityModule.SingularityType.BlackHole)
{
MakeBlackHole(newProxy, singularity.size);
}
else
{
MakeWhiteHole(newProxy, singularity.size);
}
if (realSize < body.Config.Singularity.size) realSize = body.Config.Singularity.size;
if (realSize < singularity.size) realSize = singularity.size;
}
}
if (body.Config.Base.hasCometTail)
{

View File

@ -1,4 +1,4 @@
using NewHorizons.Components;
using NewHorizons.Components;
using NewHorizons.Components.SizeControllers;
using NewHorizons.Utility;
using OWML.Common;
@ -45,7 +45,7 @@ namespace NewHorizons.Builder.Body
var trigger = ringVolume.AddComponent<OWTriggerVolume>();
trigger._shape = ringShape;
var sfv = ringVolume.AddComponent<SimpleFluidVolume>();
var sfv = ringVolume.AddComponent<RingFluidVolume>();
var fluidType = FluidVolume.Type.NONE;
try

View File

@ -5,6 +5,9 @@ using System;
using NewHorizons.External.Modules.VariableSize;
using UnityEngine;
using Logger = NewHorizons.Utility.Logger;
using System.Collections.Generic;
using System.Linq;
namespace NewHorizons.Builder.Body
{
public static class SingularityBuilder
@ -18,61 +21,73 @@ namespace NewHorizons.Builder.Body
private static readonly int DistortFadeDist = Shader.PropertyToID("_DistortFadeDist");
private static readonly int Color1 = Shader.PropertyToID("_Color");
public static void Make(GameObject go, Sector sector, OWRigidbody OWRB, PlanetConfig config)
private static Dictionary<string, GameObject> _singularitiesByID;
public static void Make(GameObject go, Sector sector, OWRigidbody OWRB, PlanetConfig config, SingularityModule singularity)
{
var size = config.Singularity.size;
var pairedSingularity = config.Singularity.pairedSingularity;
// If we've reloaded the first one will now be null so we have to refresh the list
if (_singularitiesByID?.Values?.FirstOrDefault() == null) _singularitiesByID = new Dictionary<string, GameObject>();
var polarity = config.Singularity.type;
var size = singularity.size;
var pairedSingularity = singularity.pairedSingularity;
bool isWormHole = config.Singularity?.targetStarSystem != null;
var polarity = singularity.type;
bool isWormHole = singularity?.targetStarSystem != null;
bool hasHazardVolume = !isWormHole && (pairedSingularity == null);
bool makeZeroGVolume = config.Singularity == null ? true : config.Singularity.makeZeroGVolume;
bool makeZeroGVolume = singularity == null ? true : singularity.makeZeroGVolume;
Vector3 localPosition = config.Singularity?.position == null ? Vector3.zero : (Vector3)config.Singularity.position;
Vector3 localPosition = singularity?.position == null ? Vector3.zero : singularity.position;
GameObject newSingularity = null;
switch (polarity)
{
case SingularityModule.SingularityType.BlackHole:
newSingularity = MakeBlackHole(go, sector, localPosition, size, hasHazardVolume, config.Singularity.targetStarSystem);
newSingularity = MakeBlackHole(go, sector, localPosition, size, hasHazardVolume, singularity.targetStarSystem);
break;
case SingularityModule.SingularityType.WhiteHole:
newSingularity = MakeWhiteHole(go, sector, OWRB, localPosition, size, makeZeroGVolume);
break;
}
var uniqueID = string.IsNullOrEmpty(singularity.uniqueID) ? config.name : singularity.uniqueID;
_singularitiesByID.Add(uniqueID, newSingularity);
// Try to pair them
if (pairedSingularity != null && newSingularity != null)
if (!string.IsNullOrEmpty(pairedSingularity) && newSingularity != null)
{
var pairedSingularityAO = AstroObjectLocator.GetAstroObject(pairedSingularity);
if (pairedSingularityAO != null)
if (_singularitiesByID.TryGetValue(pairedSingularity, out var pairedSingularityGO))
{
switch (polarity)
{
case SingularityModule.SingularityType.BlackHole:
PairSingularities(newSingularity, pairedSingularityAO.gameObject);
PairSingularities(uniqueID, pairedSingularity, newSingularity, pairedSingularityGO);
break;
case SingularityModule.SingularityType.WhiteHole:
PairSingularities(pairedSingularityAO.gameObject, newSingularity);
PairSingularities(pairedSingularity, uniqueID, pairedSingularityGO, newSingularity);
break;
}
}
}
}
public static void PairSingularities(GameObject blackHole, GameObject whiteHole)
public static void PairSingularities(string blackHoleID, string whiteHoleID, GameObject blackHole, GameObject whiteHole)
{
Logger.Log($"Pairing singularities {blackHole?.name}, {whiteHole?.name}");
try
if (blackHole == null || whiteHole == null) return;
Logger.Log($"Pairing singularities [{blackHoleID}], [{whiteHoleID}]");
var whiteHoleVolume = whiteHole.GetComponentInChildren<WhiteHoleVolume>();
var blackHoleVolume = blackHole.GetComponentInChildren<BlackHoleVolume>();
if (whiteHoleVolume == null || blackHoleVolume == null)
{
blackHole.GetComponentInChildren<BlackHoleVolume>()._whiteHole = whiteHole.GetComponentInChildren<WhiteHoleVolume>();
}
catch (Exception)
{
Logger.LogError($"Couldn't pair singularities");
Logger.Log($"[{blackHoleID}] and [{whiteHoleID}] do not have compatible polarities");
return;
}
blackHoleVolume._whiteHole = whiteHoleVolume;
}
public static GameObject MakeBlackHole(GameObject planetGO, Sector sector, Vector3 localPosition, float size, bool hasDestructionVolume, string targetSolarSystem, bool makeAudio = true)

View File

@ -5,6 +5,8 @@ using OWML.Utils;
using UnityEngine;
using NewHorizons.External.Modules.VariableSize;
using Logger = NewHorizons.Utility.Logger;
using OWML.ModHelper;
using OWML.Common;
namespace NewHorizons.Builder.Body
{
@ -19,9 +21,9 @@ namespace NewHorizons.Builder.Body
private static readonly int InnerRadius = Shader.PropertyToID("_InnerRadius");
private static readonly int OuterRadius = Shader.PropertyToID("_OuterRadius");
public static StarController Make(GameObject planetGO, Sector sector, StarModule starModule)
public static StarController Make(GameObject planetGO, Sector sector, StarModule starModule, IModBehaviour mod)
{
var starGO = MakeStarGraphics(planetGO, sector, starModule);
var starGO = MakeStarGraphics(planetGO, sector, starModule, mod);
var sunAudio = Object.Instantiate(SearchUtilities.Find("Sun_Body/Sector_SUN/Audio_SUN"), starGO.transform);
sunAudio.transform.localPosition = Vector3.zero;
@ -152,9 +154,9 @@ namespace NewHorizons.Builder.Body
return starController;
}
public static GameObject MakeStarProxy(GameObject planet, GameObject proxyGO, StarModule starModule)
public static GameObject MakeStarProxy(GameObject planet, GameObject proxyGO, StarModule starModule, IModBehaviour mod)
{
var starGO = MakeStarGraphics(proxyGO, null, starModule);
var starGO = MakeStarGraphics(proxyGO, null, starModule, mod);
var supernova = MakeSupernova(starGO, starModule);
@ -175,7 +177,7 @@ namespace NewHorizons.Builder.Body
return proxyGO;
}
public static GameObject MakeStarGraphics(GameObject rootObject, Sector sector, StarModule starModule)
public static GameObject MakeStarGraphics(GameObject rootObject, Sector sector, StarModule starModule, IModBehaviour mod)
{
if (_colorOverTime == null) _colorOverTime = ImageUtilities.GetTexture(Main.Instance, "Assets/textures/StarColorOverTime.png");
@ -208,10 +210,10 @@ namespace NewHorizons.Builder.Body
starGO.transform.position = rootObject.transform.position;
starGO.transform.localScale = starModule.size * Vector3.one;
TessellatedSphereRenderer surface = sunSurface.GetComponent<TessellatedSphereRenderer>();
if (starModule.tint != null)
{
TessellatedSphereRenderer surface = sunSurface.GetComponent<TessellatedSphereRenderer>();
var colour = starModule.tint.ToColor();
var sun = SearchUtilities.Find("Sun_Body");
@ -219,8 +221,8 @@ namespace NewHorizons.Builder.Body
var giantMaterial = sun.GetComponent<SunController>()._endSurfaceMaterial;
surface.sharedMaterial = new Material(starModule.size >= 3000 ? giantMaterial : mainSequenceMaterial);
var mod = Mathf.Max(1f, 2f * Mathf.Sqrt(starModule.solarLuminosity));
var adjustedColour = new Color(colour.r * mod, colour.g * mod, colour.b * mod);
var modifier = Mathf.Max(1f, 2f * Mathf.Sqrt(starModule.solarLuminosity));
var adjustedColour = new Color(colour.r * modifier, colour.g * modifier, colour.b * modifier);
surface.sharedMaterial.color = adjustedColour;
Color.RGBToHSV(adjustedColour, out var h, out var s, out var v);
@ -229,12 +231,21 @@ namespace NewHorizons.Builder.Body
if (starModule.endTint != null)
{
var endColour = starModule.endTint.ToColor();
darkenedColor = new Color(endColour.r * mod, endColour.g * mod, endColour.b * mod);
darkenedColor = new Color(endColour.r * modifier, endColour.g * modifier, endColour.b * modifier);
}
surface.sharedMaterial.SetTexture(ColorRamp, ImageUtilities.LerpGreyscaleImage(_colorOverTime, adjustedColour, darkenedColor));
}
if (!string.IsNullOrEmpty(starModule.starRampTexture))
{
var ramp = ImageUtilities.GetTexture(mod, starModule.starRampTexture);
if (ramp != null)
{
surface.sharedMaterial.SetTexture(ColorRamp, ramp);
}
}
return starGO;
}

View File

@ -15,8 +15,8 @@ namespace NewHorizons.Builder.General
var gravityRadius = GM / 0.1f;
if (exponent == 2f) gravityRadius = Mathf.Sqrt(gravityRadius);
// To let you actually orbit things the way you would expect we cap this at 4x the diameter if its not a star or black hole (this is what giants deep has)
if (config.Star == null && config.Singularity == null) gravityRadius = Mathf.Min(gravityRadius, 4 * config.Base.surfaceSize);
// To let you actually orbit things the way you would expect we cap this at 4x the diameter if its not a star (this is what giants deep has)
if (config.Star == null) gravityRadius = Mathf.Min(gravityRadius, 4 * config.Base.surfaceSize);
else gravityRadius = Mathf.Min(gravityRadius, 15 * config.Base.surfaceSize);
if (config.Base.soiOverride != 0f) gravityRadius = config.Base.soiOverride;

View File

@ -1,5 +1,7 @@
using NewHorizons.Components.Orbital;
using NewHorizons.External.Modules;
using NewHorizons.Utility;
using System.Linq;
using UnityEngine;
using Logger = NewHorizons.Utility.Logger;
namespace NewHorizons.Builder.Orbital
@ -13,7 +15,7 @@ namespace NewHorizons.Builder.Orbital
return SetInitialMotionFromConfig(initialMotion, primaryBody, secondaryBody, orbit);
}
public static InitialMotion SetInitialMotionFromConfig(InitialMotion initialMotion, AstroObject primaryBody, AstroObject secondaryBody, OrbitModule orbit)
public static InitialMotion SetInitialMotionFromConfig(InitialMotion initialMotion, AstroObject primaryBody, AstroObject secondaryBody, OrbitModule orbit, bool isCustom = true)
{
// This bit makes the initial motion not try to calculate the orbit velocity itself for reasons
initialMotion._orbitImpulseScalar = 0f;
@ -21,7 +23,12 @@ namespace NewHorizons.Builder.Orbital
// Rotation
initialMotion._initAngularSpeed = orbit.siderealPeriod == 0 ? 0f : 2f * Mathf.PI / (orbit.siderealPeriod * 60f);
var rotationAxis = Quaternion.AngleAxis(orbit.axialTilt, Vector3.right) * Vector3.up;
secondaryBody.transform.rotation = Quaternion.FromToRotation(Vector3.up, rotationAxis);
// For things with children this is broken
if (AstroObjectLocator.GetChildren(secondaryBody).Length == 0)
{
secondaryBody.transform.rotation = Quaternion.FromToRotation(Vector3.up, rotationAxis);
}
if (!orbit.isStatic && primaryBody != null)
{

View File

@ -52,7 +52,6 @@ namespace NewHorizons.Builder.Orbital
if (config.Orbit.tint != null) color = config.Orbit.tint.ToColor();
else if (config.Star?.tint != null) color = config.Star.tint.ToColor();
else if (config.Atmosphere?.clouds?.tint != null) color = config.Atmosphere.clouds.tint.ToColor();
else if (config.Singularity != null) color = new Color(1f, 0.5f, 1f);
else if (config.Water != null) color = new Color(0.5f, 0.5f, 1f);
else if (config.Lava != null) color = new Color(1f, 0.5f, 0.5f);
else if (config.Atmosphere != null && config.Atmosphere.fogTint != null) color = config.Atmosphere.fogTint.ToColor();

View File

@ -30,19 +30,27 @@ namespace NewHorizons.Builder.Props
detailGO = MakeDetail(go, sector, prefab, detail.position, detail.rotation, detail.scale, detail.alignToNormal);
}
else detailGO = MakeDetail(go, sector, detail.path, detail.position, detail.rotation, detail.scale, detail.alignToNormal);
if (detailGO != null && detail.removeChildren != null)
else
{
detailGO = MakeDetail(go, sector, detail.path, detail.position, detail.rotation, detail.scale, detail.alignToNormal);
}
if (detailGO == null) return;
if (detail.removeChildren != null)
{
var detailPath = detailGO.transform.GetPath();
foreach (var childPath in detail.removeChildren)
{
var childObj = detailGO.transform.Find(childPath);
// We purposefully use GameObject.Find here because we don't want to find inactive things.
// If you were to try and disable two children with the same name, if we were finding inactive then we'd disable the first one twice
var childObj = GameObject.Find($"{detailPath}/{childPath}");
if (childObj != null) childObj.gameObject.SetActive(false);
else Logger.LogWarning($"Couldn't find {childPath}");
}
}
if (detailGO != null && detail.removeComponents)
if (detail.removeComponents)
{
// Just swap all the children to a new game object
var newDetailGO = new GameObject(detailGO.name);
@ -67,6 +75,15 @@ namespace NewHorizons.Builder.Props
detailGO.name = detail.rename;
}
if (!string.IsNullOrEmpty(detail.parentPath))
{
var newParent = go.transform.Find(detail.parentPath);
if (newParent != null)
{
detailGO.transform.parent = newParent.transform;
}
}
detailInfoToCorrespondingSpawnedGameObject[detail] = detailGO;
}

View File

@ -1,6 +1,7 @@
using NewHorizons.External.Modules;
using NewHorizons.Handlers;
using OWML.Common;
using System.IO;
using System.Xml;
using UnityEngine;
namespace NewHorizons.Builder.Props
@ -76,8 +77,9 @@ namespace NewHorizons.Builder.Props
var dialogueTree = conversationZone.AddComponent<CharacterDialogueTree>();
var xml = System.IO.File.ReadAllText(mod.Manifest.ModFolderPath + info.xmlFile);
var xml = File.ReadAllText(mod.Manifest.ModFolderPath + info.xmlFile);
var text = new TextAsset(xml);
text.name = Path.GetFileNameWithoutExtension(info.xmlFile);
dialogueTree.SetTextXml(text);
AddTranslation(xml);

View File

@ -3,6 +3,7 @@ using NewHorizons.Handlers;
using NewHorizons.Utility;
using OWML.Common;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using UnityEngine;
@ -20,14 +21,14 @@ namespace NewHorizons.Builder.Props
private static GameObject _cairnPrefab;
private static GameObject _recorderPrefab;
private static GameObject _preCrashRecorderPrefab;
private static Dictionary<PropModule.NomaiTextArcInfo, GameObject> arcInfoToCorrespondingSpawnedGameObject = new Dictionary<PropModule.NomaiTextArcInfo, GameObject>();
public static GameObject GetSpawnedGameObjectByNomaiTextArcInfo(PropModule.NomaiTextArcInfo arc)
{
if (!arcInfoToCorrespondingSpawnedGameObject.ContainsKey(arc)) return null;
return arcInfoToCorrespondingSpawnedGameObject[arc];
}
private static Dictionary<PropModule.NomaiTextInfo, GameObject> conversationInfoToCorrespondingSpawnedGameObject = new Dictionary<PropModule.NomaiTextInfo, GameObject>();
public static GameObject GetSpawnedGameObjectByNomaiTextInfo(PropModule.NomaiTextInfo convo)
{
@ -85,7 +86,7 @@ namespace NewHorizons.Builder.Props
_recorderPrefab = SearchUtilities.Find("Comet_Body/Prefab_NOM_Shuttle/Sector_NomaiShuttleInterior/Interactibles_NomaiShuttleInterior/Prefab_NOM_Recorder").InstantiateInactive();
_recorderPrefab.name = "Prefab_NOM_Recorder";
_recorderPrefab.transform.rotation = Quaternion.identity;
_preCrashRecorderPrefab = SearchUtilities.Find("BrittleHollow_Body/Sector_BH/Sector_EscapePodCrashSite/Sector_CrashFragment/Interactables_CrashFragment/Prefab_NOM_Recorder").InstantiateInactive();
_preCrashRecorderPrefab.name = "Prefab_NOM_Recorder_Vessel";
_preCrashRecorderPrefab.transform.rotation = Quaternion.identity;
@ -100,191 +101,194 @@ namespace NewHorizons.Builder.Props
switch (info.type)
{
case PropModule.NomaiTextInfo.NomaiTextType.Wall:
{
var nomaiWallTextObj = MakeWallText(planetGO, sector, info, xmlPath).gameObject;
nomaiWallTextObj.transform.parent = sector?.transform ?? planetGO.transform;
nomaiWallTextObj.transform.position = planetGO.transform.TransformPoint(info.position);
if (info.normal != null)
{
// In global coordinates (normal was in local coordinates)
var up = (nomaiWallTextObj.transform.position - planetGO.transform.position).normalized;
var forward = planetGO.transform.TransformDirection(info.normal).normalized;
var nomaiWallTextObj = MakeWallText(planetGO, sector, info, xmlPath).gameObject;
nomaiWallTextObj.transform.up = up;
nomaiWallTextObj.transform.forward = forward;
}
if (info.rotation != null)
{
nomaiWallTextObj.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(info.rotation));
}
nomaiWallTextObj.SetActive(true);
conversationInfoToCorrespondingSpawnedGameObject[info] = nomaiWallTextObj;
break;
}
case PropModule.NomaiTextInfo.NomaiTextType.Scroll:
{
var customScroll = _scrollPrefab.InstantiateInactive();
var nomaiWallText = MakeWallText(planetGO, sector, info, xmlPath);
nomaiWallText.transform.parent = customScroll.transform;
nomaiWallText.transform.localPosition = Vector3.zero;
nomaiWallText.transform.localRotation = Quaternion.identity;
nomaiWallText._showTextOnStart = false;
// Don't want to be able to translate until its in a socket
nomaiWallText.GetComponent<Collider>().enabled = false;
nomaiWallText.gameObject.SetActive(true);
var scrollItem = customScroll.GetComponent<ScrollItem>();
// Idk why this thing is always around
GameObject.Destroy(customScroll.transform.Find("Arc_BH_City_Forum_2").gameObject);
// This variable is the bane of my existence i dont get it
scrollItem._nomaiWallText = nomaiWallText;
// Because the scroll was already awake it does weird shit in Awake and makes some of the entries in this array be null
scrollItem._colliders = new OWCollider[] { scrollItem.GetComponent<OWCollider>() };
// Else when you put them down you can't pick them back up
customScroll.GetComponent<OWCollider>()._physicsRemoved = false;
// Place scroll
customScroll.transform.parent = sector?.transform ?? planetGO.transform;
customScroll.transform.position = planetGO.transform.TransformPoint(info.position ?? Vector3.zero);
var up = planetGO.transform.InverseTransformPoint(customScroll.transform.position).normalized;
customScroll.transform.rotation = Quaternion.FromToRotation(customScroll.transform.up, up) * customScroll.transform.rotation;
customScroll.SetActive(true);
// Enable the collider and renderer
Main.Instance.ModHelper.Events.Unity.RunWhen(
() => Main.IsSystemReady,
() =>
nomaiWallTextObj.transform.parent = sector?.transform ?? planetGO.transform;
nomaiWallTextObj.transform.position = planetGO.transform.TransformPoint(info.position);
if (info.normal != null)
{
Logger.Log("Fixing scroll!");
scrollItem._nomaiWallText = nomaiWallText;
scrollItem.SetSector(sector);
customScroll.transform.Find("Props_NOM_Scroll/Props_NOM_Scroll_Geo").GetComponent<MeshRenderer>().enabled = true;
customScroll.transform.Find("Props_NOM_Scroll/Props_NOM_Scroll_Collider").gameObject.SetActive(true);
nomaiWallText.gameObject.GetComponent<Collider>().enabled = false;
customScroll.GetComponent<CapsuleCollider>().enabled = true;
// In global coordinates (normal was in local coordinates)
var up = (nomaiWallTextObj.transform.position - planetGO.transform.position).normalized;
var forward = planetGO.transform.TransformDirection(info.normal).normalized;
nomaiWallTextObj.transform.up = up;
nomaiWallTextObj.transform.forward = forward;
}
);
conversationInfoToCorrespondingSpawnedGameObject[info] = customScroll;
break;
}
if (info.rotation != null)
{
nomaiWallTextObj.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(info.rotation));
}
nomaiWallTextObj.SetActive(true);
conversationInfoToCorrespondingSpawnedGameObject[info] = nomaiWallTextObj;
break;
}
case PropModule.NomaiTextInfo.NomaiTextType.Scroll:
{
var customScroll = _scrollPrefab.InstantiateInactive();
var nomaiWallText = MakeWallText(planetGO, sector, info, xmlPath);
nomaiWallText.transform.parent = customScroll.transform;
nomaiWallText.transform.localPosition = Vector3.zero;
nomaiWallText.transform.localRotation = Quaternion.identity;
nomaiWallText._showTextOnStart = false;
// Don't want to be able to translate until its in a socket
nomaiWallText.GetComponent<Collider>().enabled = false;
nomaiWallText.gameObject.SetActive(true);
var scrollItem = customScroll.GetComponent<ScrollItem>();
// Idk why this thing is always around
GameObject.Destroy(customScroll.transform.Find("Arc_BH_City_Forum_2").gameObject);
// This variable is the bane of my existence i dont get it
scrollItem._nomaiWallText = nomaiWallText;
// Because the scroll was already awake it does weird shit in Awake and makes some of the entries in this array be null
scrollItem._colliders = new OWCollider[] { scrollItem.GetComponent<OWCollider>() };
// Else when you put them down you can't pick them back up
customScroll.GetComponent<OWCollider>()._physicsRemoved = false;
// Place scroll
customScroll.transform.parent = sector?.transform ?? planetGO.transform;
customScroll.transform.position = planetGO.transform.TransformPoint(info.position ?? Vector3.zero);
var up = planetGO.transform.InverseTransformPoint(customScroll.transform.position).normalized;
customScroll.transform.rotation = Quaternion.FromToRotation(customScroll.transform.up, up) * customScroll.transform.rotation;
customScroll.SetActive(true);
// Enable the collider and renderer
Main.Instance.ModHelper.Events.Unity.RunWhen(
() => Main.IsSystemReady,
() =>
{
Logger.Log("Fixing scroll!");
scrollItem._nomaiWallText = nomaiWallText;
scrollItem.SetSector(sector);
customScroll.transform.Find("Props_NOM_Scroll/Props_NOM_Scroll_Geo").GetComponent<MeshRenderer>().enabled = true;
customScroll.transform.Find("Props_NOM_Scroll/Props_NOM_Scroll_Collider").gameObject.SetActive(true);
nomaiWallText.gameObject.GetComponent<Collider>().enabled = false;
customScroll.GetComponent<CapsuleCollider>().enabled = true;
}
);
conversationInfoToCorrespondingSpawnedGameObject[info] = customScroll;
break;
}
case PropModule.NomaiTextInfo.NomaiTextType.Computer:
{
var computerObject = _computerPrefab.InstantiateInactive();
{
var computerObject = _computerPrefab.InstantiateInactive();
computerObject.transform.parent = sector?.transform ?? planetGO.transform;
computerObject.transform.position = planetGO.transform.TransformPoint(info?.position ?? Vector3.zero);
computerObject.transform.parent = sector?.transform ?? planetGO.transform;
computerObject.transform.position = planetGO.transform.TransformPoint(info?.position ?? Vector3.zero);
var up = computerObject.transform.position - planetGO.transform.position;
if (info.normal != null) up = planetGO.transform.TransformDirection(info.normal);
computerObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, up) * computerObject.transform.rotation;
var up = computerObject.transform.position - planetGO.transform.position;
if (info.normal != null) up = planetGO.transform.TransformDirection(info.normal);
computerObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, up) * computerObject.transform.rotation;
var computer = computerObject.GetComponent<NomaiComputer>();
computer.SetSector(sector);
var computer = computerObject.GetComponent<NomaiComputer>();
computer.SetSector(sector);
computer._dictNomaiTextData = MakeNomaiTextDict(xmlPath);
computer._nomaiTextAsset = new TextAsset(xmlPath);
AddTranslation(xmlPath);
computer._dictNomaiTextData = MakeNomaiTextDict(xmlPath);
computer._nomaiTextAsset = new TextAsset(xmlPath);
computer._nomaiTextAsset.name = Path.GetFileNameWithoutExtension(info.xmlFile);
AddTranslation(xmlPath);
// Make sure the computer model is loaded
OWAssetHandler.LoadObject(computerObject);
sector.OnOccupantEnterSector.AddListener((x) => OWAssetHandler.LoadObject(computerObject));
// Make sure the computer model is loaded
OWAssetHandler.LoadObject(computerObject);
sector.OnOccupantEnterSector.AddListener((x) => OWAssetHandler.LoadObject(computerObject));
computerObject.SetActive(true);
conversationInfoToCorrespondingSpawnedGameObject[info] = computerObject;
break;
}
computerObject.SetActive(true);
conversationInfoToCorrespondingSpawnedGameObject[info] = computerObject;
break;
}
case PropModule.NomaiTextInfo.NomaiTextType.Cairn:
{
var cairnObject = _cairnPrefab.InstantiateInactive();
cairnObject.transform.parent = sector?.transform ?? planetGO.transform;
cairnObject.transform.position = planetGO.transform.TransformPoint(info?.position ?? Vector3.zero);
if (info.rotation != null)
{
cairnObject.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(info.rotation));
var cairnObject = _cairnPrefab.InstantiateInactive();
cairnObject.transform.parent = sector?.transform ?? planetGO.transform;
cairnObject.transform.position = planetGO.transform.TransformPoint(info?.position ?? Vector3.zero);
if (info.rotation != null)
{
cairnObject.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(info.rotation));
}
else
{
// By default align it to normal
var up = (cairnObject.transform.position - planetGO.transform.position).normalized;
cairnObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, up) * cairnObject.transform.rotation;
}
// Idk do we have to set it active before finding things?
cairnObject.SetActive(true);
// Make it do the thing when it finishes being knocked over
foreach (var rock in cairnObject.GetComponent<NomaiCairn>()._rocks)
{
rock._returning = false;
rock._owCollider.SetActivation(true);
rock.enabled = false;
}
// So we can actually knock it over
cairnObject.GetComponent<CapsuleCollider>().enabled = true;
var nomaiWallText = cairnObject.transform.Find("Props_TH_ClutterSmall/Arc_Short").GetComponent<NomaiWallText>();
nomaiWallText.SetSector(sector);
nomaiWallText._dictNomaiTextData = MakeNomaiTextDict(xmlPath);
nomaiWallText._nomaiTextAsset = new TextAsset(xmlPath);
nomaiWallText._nomaiTextAsset.name = Path.GetFileNameWithoutExtension(info.xmlFile);
AddTranslation(xmlPath);
// Make sure the computer model is loaded
OWAssetHandler.LoadObject(cairnObject);
sector.OnOccupantEnterSector.AddListener((x) => OWAssetHandler.LoadObject(cairnObject));
conversationInfoToCorrespondingSpawnedGameObject[info] = cairnObject;
break;
}
else
{
// By default align it to normal
var up = (cairnObject.transform.position - planetGO.transform.position).normalized;
cairnObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, up) * cairnObject.transform.rotation;
}
// Idk do we have to set it active before finding things?
cairnObject.SetActive(true);
// Make it do the thing when it finishes being knocked over
foreach (var rock in cairnObject.GetComponent<NomaiCairn>()._rocks)
{
rock._returning = false;
rock._owCollider.SetActivation(true);
rock.enabled = false;
}
// So we can actually knock it over
cairnObject.GetComponent<CapsuleCollider>().enabled = true;
var nomaiWallText = cairnObject.transform.Find("Props_TH_ClutterSmall/Arc_Short").GetComponent<NomaiWallText>();
nomaiWallText.SetSector(sector);
nomaiWallText._dictNomaiTextData = MakeNomaiTextDict(xmlPath);
nomaiWallText._nomaiTextAsset = new TextAsset(xmlPath);
AddTranslation(xmlPath);
// Make sure the computer model is loaded
OWAssetHandler.LoadObject(cairnObject);
sector.OnOccupantEnterSector.AddListener((x) => OWAssetHandler.LoadObject(cairnObject));
conversationInfoToCorrespondingSpawnedGameObject[info] = cairnObject;
break;
}
case PropModule.NomaiTextInfo.NomaiTextType.PreCrashRecorder:
case PropModule.NomaiTextInfo.NomaiTextType.Recorder:
{
var recorderObject = (info.type == PropModule.NomaiTextInfo.NomaiTextType.PreCrashRecorder? _preCrashRecorderPrefab : _recorderPrefab).InstantiateInactive();
recorderObject.transform.parent = sector?.transform ?? planetGO.transform;
recorderObject.transform.position = planetGO.transform.TransformPoint(info?.position ?? Vector3.zero);
if (info.rotation != null)
{
recorderObject.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(info.rotation));
var recorderObject = (info.type == PropModule.NomaiTextInfo.NomaiTextType.PreCrashRecorder ? _preCrashRecorderPrefab : _recorderPrefab).InstantiateInactive();
recorderObject.transform.parent = sector?.transform ?? planetGO.transform;
recorderObject.transform.position = planetGO.transform.TransformPoint(info?.position ?? Vector3.zero);
if (info.rotation != null)
{
recorderObject.transform.rotation = planetGO.transform.TransformRotation(Quaternion.Euler(info.rotation));
}
else
{
var up = recorderObject.transform.position - planetGO.transform.position;
recorderObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, up) * recorderObject.transform.rotation;
}
var nomaiText = recorderObject.GetComponentInChildren<NomaiText>();
nomaiText.SetSector(sector);
nomaiText._dictNomaiTextData = MakeNomaiTextDict(xmlPath);
nomaiText._nomaiTextAsset = new TextAsset(xmlPath);
nomaiText._nomaiTextAsset.name = Path.GetFileNameWithoutExtension(info.xmlFile);
AddTranslation(xmlPath);
// Make sure the recorder model is loaded
OWAssetHandler.LoadObject(recorderObject);
sector.OnOccupantEnterSector.AddListener((x) => OWAssetHandler.LoadObject(recorderObject));
recorderObject.SetActive(true);
recorderObject.transform.Find("InteractSphere").gameObject.GetComponent<SphereShape>().enabled = true;
conversationInfoToCorrespondingSpawnedGameObject[info] = recorderObject;
break;
}
else
{
var up = recorderObject.transform.position - planetGO.transform.position;
recorderObject.transform.rotation = Quaternion.FromToRotation(Vector3.up, up) * recorderObject.transform.rotation;
}
var nomaiText = recorderObject.GetComponentInChildren<NomaiText>();
nomaiText.SetSector(sector);
nomaiText._dictNomaiTextData = MakeNomaiTextDict(xmlPath);
nomaiText._nomaiTextAsset = new TextAsset(xmlPath);
AddTranslation(xmlPath);
// Make sure the recorder model is loaded
OWAssetHandler.LoadObject(recorderObject);
sector.OnOccupantEnterSector.AddListener((x) => OWAssetHandler.LoadObject(recorderObject));
recorderObject.SetActive(true);
recorderObject.transform.Find("InteractSphere").gameObject.GetComponent<SphereShape>().enabled = true;
conversationInfoToCorrespondingSpawnedGameObject[info] = recorderObject;
break;
}
default:
Logger.LogError($"Unsupported NomaiText type {info.type}");
break;
@ -306,6 +310,7 @@ namespace NewHorizons.Builder.Props
var nomaiWallText = nomaiWallTextObj.AddComponent<NomaiWallText>();
var text = new TextAsset(xmlPath);
text.name = Path.GetFileNameWithoutExtension(info.xmlFile);
BuildArcs(xmlPath, nomaiWallText, nomaiWallTextObj, info);
AddTranslation(xmlPath);
@ -325,7 +330,7 @@ namespace NewHorizons.Builder.Props
RefreshArcs(nomaiWallText, conversationZone, info);
}
internal static void RefreshArcs(NomaiWallText nomaiWallText, GameObject conversationZone, PropModule.NomaiTextInfo info)
internal static void RefreshArcs(NomaiWallText nomaiWallText, GameObject conversationZone, PropModule.NomaiTextInfo info)
{
var dict = nomaiWallText._dictNomaiTextData;
Random.InitState(info.seed);
@ -349,7 +354,7 @@ namespace NewHorizons.Builder.Props
GameObject arc = MakeArc(arcInfo, conversationZone, parent, textEntryID);
arc.name = $"Arc {i} - Child of {parentID}";
arcsByID.Add(textEntryID, arc);
i++;
@ -419,7 +424,7 @@ namespace NewHorizons.Builder.Props
arc.GetComponent<MeshRenderer>().enabled = false;
arc.SetActive(true);
arcInfoToCorrespondingSpawnedGameObject[arcInfo] = arc;
return arc;

View File

@ -265,7 +265,7 @@ namespace NewHorizons.Builder.Props
// setup for visually supporting async texture loading
mindSlideProjector.enabled = false;
var visionBeamEffect = SearchUtilities.FindChild(standingTorch, "VisionBeam");
var visionBeamEffect = standingTorch.FindChild("VisionBeam");
visionBeamEffect.SetActive(false);
//

View File

@ -1,3 +1,4 @@
using NewHorizons.Builder.Body;
using NewHorizons.Builder.ShipLog;
using NewHorizons.External.Configs;
using OWML.Common;
@ -190,6 +191,13 @@ namespace NewHorizons.Builder.Props
Logger.LogError($"Couldn't make quantum group \"{quantumGroup.id}\" for [{go.name}] : {ex.Message}, {ex.StackTrace}");
}
}
}
if (config.Props.singularities != null)
{
foreach (var singularity in config.Props.singularities)
{
SingularityBuilder.Make(go, sector, go.GetComponent<OWRigidbody>(), config, singularity);
}
}
}
}

View File

@ -101,7 +101,7 @@ namespace NewHorizons.Builder.ShipLog
Logger.Log($"Adding ship log astro object for {body.Config.name}");
GameObject unviewedReference = SearchUtilities.CachedFind(ShipLogHandler.PAN_ROOT_PATH + "/TimberHearth/UnviewedIcon");
GameObject unviewedReference = SearchUtilities.Find(ShipLogHandler.PAN_ROOT_PATH + "/TimberHearth/UnviewedIcon");
ShipLogAstroObject astroObject = gameObject.AddComponent<ShipLogAstroObject>();
astroObject._id = ShipLogHandler.GetAstroObjectId(body);
@ -249,7 +249,7 @@ namespace NewHorizons.Builder.ShipLog
}
else if (Main.Instance.CurrentStarSystem == "SolarSystem")
{
GameObject gameObject = SearchUtilities.CachedFind(ShipLogHandler.PAN_ROOT_PATH + "/" + name);
GameObject gameObject = SearchUtilities.Find(ShipLogHandler.PAN_ROOT_PATH + "/" + name);
if (body.Config.destroy || (body.Config.ShipLog?.mapMode?.remove ?? false))
{
ShipLogAstroObject astroObject = gameObject.GetComponent<ShipLogAstroObject>();
@ -522,14 +522,6 @@ namespace NewHorizons.Builder.ShipLog
{
try
{
switch (body.Config?.Singularity?.type)
{
case SingularityModule.SingularityType.BlackHole:
return Color.black;
case SingularityModule.SingularityType.WhiteHole:
return Color.white;
}
var starColor = body.Config?.Star?.tint;
if (starColor != null) return starColor.ToColor();
@ -555,6 +547,14 @@ namespace NewHorizons.Builder.ShipLog
var sandColor = body.Config.Sand?.tint;
if (sandColor != null) return sandColor.ToColor();
switch (body.Config?.Props?.singularities?.FirstOrDefault()?.type)
{
case SingularityModule.SingularityType.BlackHole:
return Color.black;
case SingularityModule.SingularityType.WhiteHole:
return Color.white;
}
}
catch (Exception)
{

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace NewHorizons.Components
{
public class RingFluidVolume : SimpleFluidVolume
{
public override void OnEffectVolumeEnter(GameObject hitObj)
{
FluidDetector fluidDetector = hitObj.GetComponent<FluidDetector>();
if (fluidDetector == null) return;
ForceDetector forceDetector = hitObj.GetComponent<ForceDetector>();
if (forceDetector != null && forceDetector._activeVolumes != null && forceDetector._activeVolumes.Count > 0 && forceDetector._activeVolumes.Where(activeVolume => activeVolume is ForceVolume).Select(activeVolume => activeVolume as ForceVolume).Any(activeVolume => activeVolume.GetAffectsAlignment(forceDetector._attachedBody))) return;
fluidDetector.AddVolume(this);
}
}
}

View File

@ -50,6 +50,9 @@ namespace NewHorizons.External.Configs
[Obsolete("ChildrenToDestroy is deprecated, please use RemoveChildren instead")]
public string[] childrenToDestroy;
[Obsolete("Singularity is deprecated, please use Props->singularities")]
public SingularityModule Singularity;
#endregion Obsolete
/// <summary>
@ -138,11 +141,6 @@ namespace NewHorizons.External.Configs
/// </summary>
public SignalModule Signal;
/// <summary>
/// Add a black or white hole to this planet
/// </summary>
public SingularityModule Singularity;
/// <summary>
/// Spawn the player at this planet
/// </summary>
@ -329,6 +327,13 @@ namespace NewHorizons.External.Configs
}
}
// Singularity is now a list in props so you can have many per planet
if (Singularity != null)
{
if (Props == null) Props = new PropModule();
if (Props.singularities == null) Props.singularities = new SingularityModule[0];
Props.singularities = Props.singularities.Append(Singularity).ToArray();
}
}
}
}

View File

@ -6,6 +6,7 @@ using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using NewHorizons.External.Modules.VariableSize;
namespace NewHorizons.External.Modules
{
@ -77,6 +78,11 @@ namespace NewHorizons.External.Modules
/// </summary>
public VolcanoInfo[] volcanoes;
/// <summary>
/// Add black/white-holes to this planet
/// </summary>
public SingularityModule[] singularities;
[JsonObject]
public class ScatterInfo
{
@ -169,6 +175,11 @@ namespace NewHorizons.External.Modules
/// If this value is not null, this prop will be quantum. Assign this field to the id of the quantum group it should be a part of. The group it is assigned to determines what kind of quantum object it is
/// </summary>
public string quantumGroupID;
/// <summary>
/// The path (not including the root planet object) of the parent of this game object. Optional (will default to the root sector).
/// </summary>
public string parentPath;
}
[JsonObject]

View File

@ -1,4 +1,4 @@
using System.ComponentModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using NewHorizons.Utility;
@ -24,11 +24,16 @@ namespace NewHorizons.External.Modules.VariableSize
[DefaultValue(true)] public bool makeZeroGVolume = true;
/// <summary>
/// The name of the white hole or black hole that is paired to this one. If you don't set a value, entering will kill
/// The uniqueID of the white hole or black hole that is paired to this one. If you don't set a value, entering will kill
/// the player
/// </summary>
public string pairedSingularity;
/// <summary>
/// The uniqueID of this white hole or black hole. If not set it will default to the name of the planet
/// </summary>
public string uniqueID;
/// <summary>
/// Position of the singularity
/// </summary>

View File

@ -56,6 +56,11 @@ namespace NewHorizons.External.Modules.VariableSize
/// </summary>
public MColor tint;
/// <summary>
/// Path to the texture to put as the star ramp. Optional.
/// </summary>
public string starRampTexture;
/// <summary>
/// How far the light from the star can reach.
/// </summary>

View File

@ -269,7 +269,9 @@ namespace NewHorizons.Handlers
{
foreach (var child in body.Config.removeChildren)
{
Main.Instance.ModHelper.Events.Unity.FireInNUpdates(() => SearchUtilities.Find(go.name + "/" + child)?.SetActive(false), 2);
// We purposefully use GameObject.Find here because we don't want to find inactive things.
// If you were to try and disable two children with the same name, if we were finding inactive then we'd disable the first one twice
Main.Instance.ModHelper.Events.Unity.FireInNUpdates(() => GameObject.Find(go.name + "/" + child)?.SetActive(false), 2);
}
}
@ -456,7 +458,7 @@ namespace NewHorizons.Handlers
if (body.Config.Star != null)
{
StarLightController.AddStar(StarBuilder.Make(go, sector, body.Config.Star));
StarLightController.AddStar(StarBuilder.Make(go, sector, body.Config.Star, body.Mod));
}
if (body.Config?.Bramble?.nodes != null)
@ -516,7 +518,7 @@ namespace NewHorizons.Handlers
if (!string.IsNullOrEmpty(body.Config.Atmosphere?.clouds?.texturePath))
{
CloudsBuilder.Make(go, sector, body.Config.Atmosphere, body.Mod);
SunOverrideBuilder.Make(go, sector, body.Config.Atmosphere, surfaceSize);
SunOverrideBuilder.Make(go, sector, body.Config.Atmosphere, body.Config.Water, surfaceSize);
}
if (body.Config.Atmosphere.hasRain || body.Config.Atmosphere.hasSnow)
@ -538,11 +540,6 @@ namespace NewHorizons.Handlers
SignalBuilder.Make(go, sector, body.Config.Signal, body.Mod);
}
if (body.Config.Singularity != null)
{
SingularityBuilder.Make(go, sector, rb, body.Config);
}
if (body.Config.Funnel != null)
{
FunnelBuilder.Make(go, go.GetComponentInChildren<ConstantForceDetector>(), rb, body.Config.Funnel);

View File

@ -29,7 +29,7 @@ namespace NewHorizons.Handlers
GameObject panRoot = SearchUtilities.Find(PAN_ROOT_PATH);
if (panRoot != null)
{
List<GameObject> gameObjects = SearchUtilities.GetAllChildren(panRoot);
List<GameObject> gameObjects = panRoot.GetAllChildren();
_vanillaBodies = gameObjects.ConvertAll(g => g.name).ToArray();
_vanillaBodyIDs = gameObjects.ConvertAll(g => g.GetComponent<ShipLogAstroObject>()?.GetID()).ToArray();
}

View File

@ -0,0 +1,35 @@
using OWML.Common;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace NewHorizons
{
public interface INewHorizons
{
[Obsolete("Create(Dictionary<string, object> config) is deprecated, please use LoadConfigs(IModBehaviour mod) instead")]
void Create(Dictionary<string, object> config);
[Obsolete("Create(Dictionary<string, object> config) is deprecated, please use LoadConfigs(IModBehaviour mod) instead")]
void Create(Dictionary<string, object> config, IModBehaviour mod);
void LoadConfigs(IModBehaviour mod);
GameObject GetPlanet(string name);
string GetCurrentStarSystem();
UnityEvent<string> GetChangeStarSystemEvent();
UnityEvent<string> GetStarSystemLoadedEvent();
bool SetDefaultSystem(string name);
bool ChangeCurrentStarSystem(string name);
string[] GetInstalledAddons();
GameObject SpawnObject(GameObject planet, Sector sector, string propToCopyPath, Vector3 position, Vector3 eulerAngles, float scale, bool alignWithNormal);
}
}

View File

@ -8,6 +8,7 @@ using NewHorizons.Handlers;
using NewHorizons.Utility;
using NewHorizons.Utility.DebugMenu;
using NewHorizons.Utility.DebugUtilities;
using NewHorizons.VoiceActing;
using OWML.Common;
using OWML.ModHelper;
using System;
@ -183,6 +184,7 @@ namespace NewHorizons
Instance.ModHelper.Menus.PauseMenu.OnInit += DebugReload.InitializePauseMenu;
AchievementHandler.Init();
VoiceHandler.Init();
}
public void OnDestroy()
@ -198,15 +200,6 @@ namespace NewHorizons
private static void OnWakeUp()
{
IsSystemReady = true;
try
{
Logger.Log($"Star system loaded [{Instance.CurrentStarSystem}]");
Instance.OnStarSystemLoaded?.Invoke(Instance.CurrentStarSystem);
}
catch (Exception e)
{
Logger.LogError($"Exception thrown when invoking star system loaded event with parameter [{Instance.CurrentStarSystem}] : {e.GetType().FullName} {e.Message} {e.StackTrace}");
}
}
private void OnSceneUnloaded(Scene scene)
@ -302,6 +295,16 @@ namespace NewHorizons
// Fix the map satellite
SearchUtilities.Find("HearthianMapSatellite_Body", false).AddComponent<MapSatelliteOrbitFix>();
try
{
Logger.Log($"Star system loaded [{Instance.CurrentStarSystem}]");
Instance.OnStarSystemLoaded?.Invoke(Instance.CurrentStarSystem);
}
catch (Exception e)
{
Logger.LogError($"Exception thrown when invoking star system loaded event with parameter [{Instance.CurrentStarSystem}] : {e.GetType().FullName} {e.Message} {e.StackTrace}");
}
}
else
{

View File

@ -9,9 +9,10 @@ using System.Linq;
using UnityEngine;
using UnityEngine.Events;
using Logger = NewHorizons.Utility.Logger;
namespace NewHorizons
{
public class NewHorizonsApi
public class NewHorizonsApi : INewHorizons
{
[Obsolete("Create(Dictionary<string, object> config) is deprecated, please use LoadConfigs(IModBehaviour mod) instead")]
public void Create(Dictionary<string, object> config)

View File

@ -145,7 +145,7 @@ namespace NewHorizons.Patches
__instance._startingAstroObjectID = navMatrix[1][0].GetID();
if (Main.Instance.CurrentStarSystem != "SolarSystem")
{
List<GameObject> delete = SearchUtilities.GetAllChildren(panRoot).Where(g => g.name.Contains("_ShipLog") == false).ToList();
List<GameObject> delete = panRoot.GetAllChildren().Where(g => g.name.Contains("_ShipLog") == false).ToList();
foreach (GameObject gameObject in delete)
{
Object.Destroy(SearchUtilities.Find(ShipLogHandler.PAN_ROOT_PATH + "/" + gameObject.name));
@ -182,7 +182,7 @@ namespace NewHorizons.Patches
Transform detailsParent = __instance.transform.Find("Details");
if (detailsParent != null)
{
foreach (GameObject child in SearchUtilities.GetAllChildren(detailsParent.gameObject))
foreach (GameObject child in detailsParent.gameObject.GetAllChildren())
{
if (child.TryGetComponent(typeof(ShipLogDetail), out Component detail))
{

View File

@ -102,10 +102,6 @@
"description": "Add signals that can be heard via the signal-scope to this planet",
"$ref": "#/definitions/SignalModule"
},
"Singularity": {
"description": "Add a black or white hole to this planet",
"$ref": "#/definitions/SingularityModule"
},
"Spawn": {
"description": "Spawn the player at this planet",
"$ref": "#/definitions/SpawnModule"
@ -811,6 +807,13 @@
"items": {
"$ref": "#/definitions/VolcanoInfo"
}
},
"singularities": {
"type": "array",
"description": "Add black/white-holes to this planet",
"items": {
"$ref": "#/definitions/SingularityModule"
}
}
}
},
@ -862,6 +865,10 @@
"quantumGroupID": {
"type": "string",
"description": "If this value is not null, this prop will be quantum. Assign this field to the id of the quantum group it should be a part of. The group it is assigned to determines what kind of quantum object it is"
},
"parentPath": {
"type": "string",
"description": "The path (not including the root planet object) of the parent of this game object. Optional (will default to the root sector)."
}
}
},
@ -1447,6 +1454,62 @@
}
}
},
"SingularityModule": {
"type": "object",
"additionalProperties": false,
"properties": {
"curve": {
"type": "array",
"description": "Scale this module over time",
"items": {
"$ref": "#/definitions/TimeValuePair"
}
},
"makeZeroGVolume": {
"type": "boolean",
"description": "Only for White Holes. Should this white hole repel the player from it.",
"default": true
},
"pairedSingularity": {
"type": "string",
"description": "The uniqueID of the white hole or black hole that is paired to this one. If you don't set a value, entering will kill\nthe player"
},
"uniqueID": {
"type": "string",
"description": "The uniqueID of this white hole or black hole. If not set it will default to the name of the planet"
},
"position": {
"description": "Position of the singularity",
"$ref": "#/definitions/MVector3"
},
"size": {
"type": "number",
"description": "Radius of the singularity. Note that this isn't the same as the event horizon, but includes the entire volume that\nhas warped effects in it.",
"format": "float",
"minimum": 0.0
},
"targetStarSystem": {
"type": "string",
"description": "If you want a black hole to load a new star system scene, put its name here."
},
"type": {
"description": "Type of singularity (white hole or black hole)",
"$ref": "#/definitions/SingularityType"
}
}
},
"SingularityType": {
"type": "string",
"description": "",
"x-enumNames": [
"BlackHole",
"WhiteHole"
],
"enum": [
"blackHole",
"whiteHole"
]
},
"ReferenceFrameModule": {
"type": "object",
"additionalProperties": false,
@ -1725,58 +1788,6 @@
}
}
},
"SingularityModule": {
"type": "object",
"additionalProperties": false,
"properties": {
"curve": {
"type": "array",
"description": "Scale this module over time",
"items": {
"$ref": "#/definitions/TimeValuePair"
}
},
"makeZeroGVolume": {
"type": "boolean",
"description": "Only for White Holes. Should this white hole repel the player from it.",
"default": true
},
"pairedSingularity": {
"type": "string",
"description": "The name of the white hole or black hole that is paired to this one. If you don't set a value, entering will kill\nthe player"
},
"position": {
"description": "Position of the singularity",
"$ref": "#/definitions/MVector3"
},
"size": {
"type": "number",
"description": "Radius of the singularity. Note that this isn't the same as the event horizon, but includes the entire volume that\nhas warped effects in it.",
"format": "float",
"minimum": 0.0
},
"targetStarSystem": {
"type": "string",
"description": "If you want a black hole to load a new star system scene, put its name here."
},
"type": {
"description": "Type of singularity (white hole or black hole)",
"$ref": "#/definitions/SingularityType"
}
}
},
"SingularityType": {
"type": "string",
"description": "",
"x-enumNames": [
"BlackHole",
"WhiteHole"
],
"enum": [
"blackHole",
"whiteHole"
]
},
"SpawnModule": {
"type": "object",
"additionalProperties": false,
@ -1859,6 +1870,10 @@
"description": "Colour of the star.",
"$ref": "#/definitions/MColor"
},
"starRampTexture": {
"type": "string",
"description": "Path to the texture to put as the star ramp. Optional."
},
"lightRadius": {
"type": "number",
"description": "How far the light from the star can reach.",

View File

@ -1,151 +1,160 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace NewHorizons.Utility
{
public static class AstroObjectLocator
{
private static Dictionary<string, AstroObject> _customAstroObjectDictionary = new Dictionary<string, AstroObject>();
public static void Init()
{
_customAstroObjectDictionary = new Dictionary<string, AstroObject>();
foreach (AstroObject ao in GameObject.FindObjectsOfType<AstroObject>())
{
// Ignore the sun station debris, we handle it as a child of the sun station
if (ao.gameObject.name == "SS_Debris_Body") continue;
RegisterCustomAstroObject(ao);
}
}
public static AstroObject GetAstroObject(string name, bool flag = false)
{
if (string.IsNullOrEmpty(name)) return null;
if (_customAstroObjectDictionary.ContainsKey(name))
{
return _customAstroObjectDictionary[name];
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace NewHorizons.Utility
{
public static class AstroObjectLocator
{
private static Dictionary<string, AstroObject> _customAstroObjectDictionary = new Dictionary<string, AstroObject>();
public static void Init()
{
_customAstroObjectDictionary = new Dictionary<string, AstroObject>();
foreach (AstroObject ao in GameObject.FindObjectsOfType<AstroObject>())
{
// Ignore the sun station debris, we handle it as a child of the sun station
if (ao.gameObject.name == "SS_Debris_Body") continue;
RegisterCustomAstroObject(ao);
}
// Else check stock names
var stringID = name.ToUpper().Replace(" ", "_").Replace("'", "");
if (stringID.Equals("ATTLEROCK")) stringID = "TIMBER_MOON";
if (stringID.Equals("HOLLOWS_LANTERN")) stringID = "VOLCANIC_MOON";
if (stringID.Equals("ASH_TWIN")) stringID = "TOWER_TWIN";
if (stringID.Equals("EMBER_TWIN")) stringID = "CAVE_TWIN";
if (stringID.Equals("INTERLOPER")) stringID = "COMET";
string key;
if (stringID.ToUpper().Replace("_", "").Equals("MAPSATELLITE"))
{
key = AstroObject.Name.MapSatellite.ToString();
}
else
{
key = AstroObject.StringIDToAstroObjectName(stringID).ToString();
}
if (_customAstroObjectDictionary.ContainsKey(key))
{
return _customAstroObjectDictionary[key];
}
// Try again
if (!flag) return GetAstroObject(name.Replace(" ", ""), true);
return null;
}
public static void RegisterCustomAstroObject(AstroObject ao)
{
var key = ao._name == AstroObject.Name.CustomString ? ao.GetCustomName() : ao._name.ToString();
if (_customAstroObjectDictionary.Keys.Contains(key))
{
Logger.LogWarning($"Registering duplicate [{ao.name}] as [{key}]");
_customAstroObjectDictionary[key] = ao;
}
else
{
Logger.Log($"Registering [{ao.name}] as [{key}]");
_customAstroObjectDictionary.Add(key, ao);
}
}
public static void DeregisterCustomAstroObject(AstroObject ao)
{
var key = ao._name == AstroObject.Name.CustomString ? ao.GetCustomName() : ao._name.ToString();
_customAstroObjectDictionary.Remove(key);
}
public static AstroObject[] GetAllAstroObjects()
{
return _customAstroObjectDictionary.Values.ToArray();
}
public static GameObject[] GetMoons(AstroObject primary)
{
return _customAstroObjectDictionary.Values.Where(x => x._primaryBody == primary).Select(x => x.gameObject).ToArray();
}
public static GameObject[] GetChildren(AstroObject primary)
{
if (primary == null) return new GameObject[0];
var otherChildren = new List<GameObject>();
switch (primary._name)
{
case AstroObject.Name.TowerTwin:
otherChildren.Add(SearchUtilities.Find("TimeLoopRing_Body"));
break;
case AstroObject.Name.ProbeCannon:
otherChildren.Add(SearchUtilities.Find("NomaiProbe_Body"));
otherChildren.Add(SearchUtilities.Find("CannonMuzzle_Body"));
otherChildren.Add(SearchUtilities.Find("FakeCannonMuzzle_Body (1)"));
otherChildren.Add(SearchUtilities.Find("CannonBarrel_Body"));
otherChildren.Add(SearchUtilities.Find("FakeCannonBarrel_Body (1)"));
otherChildren.Add(SearchUtilities.Find("Debris_Body (1)"));
break;
case AstroObject.Name.GiantsDeep:
otherChildren.Add(SearchUtilities.Find("BrambleIsland_Body"));
otherChildren.Add(SearchUtilities.Find("GabbroIsland_Body"));
otherChildren.Add(SearchUtilities.Find("QuantumIsland_Body"));
otherChildren.Add(SearchUtilities.Find("StatueIsland_Body"));
otherChildren.Add(SearchUtilities.Find("ConstructionYardIsland_Body"));
otherChildren.Add(SearchUtilities.Find("GabbroShip_Body"));
break;
case AstroObject.Name.WhiteHole:
otherChildren.Add(SearchUtilities.Find("WhiteholeStation_Body"));
otherChildren.Add(SearchUtilities.Find("WhiteholeStationSuperstructure_Body"));
break;
case AstroObject.Name.TimberHearth:
otherChildren.Add(SearchUtilities.Find("MiningRig_Body"));
otherChildren.Add(SearchUtilities.Find("Ship_Body"));
otherChildren.Add(SearchUtilities.Find("ModelRocket_Body"));
break;
case AstroObject.Name.DreamWorld:
otherChildren.Add(SearchUtilities.Find("BackRaft_Body"));
otherChildren.Add(SearchUtilities.Find("SealRaft_Body"));
break;
case AstroObject.Name.MapSatellite:
otherChildren.Add(SearchUtilities.Find("HearthianRecorder_Body"));
break;
// For some dumb reason the sun station doesn't use AstroObject.Name.SunStation
case AstroObject.Name.CustomString:
if (primary._customName.Equals("Sun Station"))
{
// there are multiple debris with the same name
otherChildren.AddRange(Object.FindObjectsOfType<AstroObject>()
.Select(x => x.gameObject)
.Where(x => x.name == "SS_Debris_Body"));
}
break;
default:
break;
}
return otherChildren.ToArray();
}
}
}
}
public static AstroObject GetAstroObject(string name, bool flag = false)
{
if (string.IsNullOrEmpty(name)) return null;
if (_customAstroObjectDictionary.ContainsKey(name))
{
return _customAstroObjectDictionary[name];
}
// Else check stock names
var stringID = name.ToUpper().Replace(" ", "_").Replace("'", "");
if (stringID.Equals("ATTLEROCK")) stringID = "TIMBER_MOON";
if (stringID.Equals("HOLLOWS_LANTERN")) stringID = "VOLCANIC_MOON";
if (stringID.Equals("ASH_TWIN")) stringID = "TOWER_TWIN";
if (stringID.Equals("EMBER_TWIN")) stringID = "CAVE_TWIN";
if (stringID.Equals("INTERLOPER")) stringID = "COMET";
string key;
if (stringID.ToUpper().Replace("_", "").Equals("MAPSATELLITE"))
{
key = AstroObject.Name.MapSatellite.ToString();
}
else
{
key = AstroObject.StringIDToAstroObjectName(stringID).ToString();
}
if (_customAstroObjectDictionary.ContainsKey(key))
{
return _customAstroObjectDictionary[key];
}
// Try again
if (!flag) return GetAstroObject(name.Replace(" ", ""), true);
return null;
}
public static void RegisterCustomAstroObject(AstroObject ao)
{
var key = ao._name == AstroObject.Name.CustomString ? ao.GetCustomName() : ao._name.ToString();
if (_customAstroObjectDictionary.Keys.Contains(key))
{
Logger.LogWarning($"Registering duplicate [{ao.name}] as [{key}]");
_customAstroObjectDictionary[key] = ao;
}
else
{
Logger.Log($"Registering [{ao.name}] as [{key}]");
_customAstroObjectDictionary.Add(key, ao);
}
}
public static void DeregisterCustomAstroObject(AstroObject ao)
{
var key = ao._name == AstroObject.Name.CustomString ? ao.GetCustomName() : ao._name.ToString();
_customAstroObjectDictionary.Remove(key);
}
public static AstroObject[] GetAllAstroObjects()
{
return _customAstroObjectDictionary.Values.ToArray();
}
public static GameObject[] GetMoons(AstroObject primary)
{
return _customAstroObjectDictionary.Values.Where(x => x._primaryBody == primary).Select(x => x.gameObject).ToArray();
}
public static GameObject[] GetChildren(AstroObject primary)
{
if (primary == null) return new GameObject[0];
var otherChildren = new List<GameObject>();
switch (primary._name)
{
case AstroObject.Name.TowerTwin:
otherChildren.Add(SearchUtilities.Find("TimeLoopRing_Body"));
break;
case AstroObject.Name.ProbeCannon:
otherChildren.Add(SearchUtilities.Find("NomaiProbe_Body"));
otherChildren.Add(SearchUtilities.Find("CannonMuzzle_Body"));
otherChildren.Add(SearchUtilities.Find("FakeCannonMuzzle_Body (1)"));
otherChildren.Add(SearchUtilities.Find("CannonBarrel_Body"));
otherChildren.Add(SearchUtilities.Find("FakeCannonBarrel_Body (1)"));
otherChildren.Add(SearchUtilities.Find("Debris_Body (1)"));
break;
case AstroObject.Name.GiantsDeep:
otherChildren.Add(SearchUtilities.Find("BrambleIsland_Body"));
otherChildren.Add(SearchUtilities.Find("GabbroIsland_Body"));
otherChildren.Add(SearchUtilities.Find("QuantumIsland_Body"));
otherChildren.Add(SearchUtilities.Find("StatueIsland_Body"));
otherChildren.Add(SearchUtilities.Find("ConstructionYardIsland_Body"));
otherChildren.Add(SearchUtilities.Find("GabbroShip_Body"));
break;
case AstroObject.Name.WhiteHole:
otherChildren.Add(SearchUtilities.Find("WhiteholeStation_Body"));
otherChildren.Add(SearchUtilities.Find("WhiteholeStationSuperstructure_Body"));
break;
case AstroObject.Name.TimberHearth:
otherChildren.Add(SearchUtilities.Find("MiningRig_Body"));
otherChildren.Add(SearchUtilities.Find("Ship_Body"));
otherChildren.Add(SearchUtilities.Find("ModelRocket_Body"));
break;
case AstroObject.Name.DreamWorld:
otherChildren.Add(SearchUtilities.Find("BackRaft_Body"));
otherChildren.Add(SearchUtilities.Find("SealRaft_Body"));
break;
case AstroObject.Name.MapSatellite:
otherChildren.Add(SearchUtilities.Find("HearthianRecorder_Body"));
break;
case AstroObject.Name.DarkBramble:
otherChildren.Add(SearchUtilities.Find("DB_ClusterDimension_Body"));
otherChildren.Add(SearchUtilities.Find("DB_VesselDimension_Body"));
otherChildren.Add(SearchUtilities.Find("DB_PioneerDimension_Body"));
otherChildren.Add(SearchUtilities.Find("DB_HubDimension_Body"));
otherChildren.Add(SearchUtilities.Find("DB_ExitOnlyDimension_Body"));
otherChildren.Add(SearchUtilities.Find("DB_EscapePodDimension_Body"));
otherChildren.Add(SearchUtilities.Find("DB_AnglerNestDimension_Body"));
break;
// For some dumb reason the sun station doesn't use AstroObject.Name.SunStation
case AstroObject.Name.CustomString:
if (primary._customName.Equals("Sun Station"))
{
// there are multiple debris with the same name
otherChildren.AddRange(Object.FindObjectsOfType<AstroObject>()
.Select(x => x.gameObject)
.Where(x => x.name == "SS_Debris_Body"));
}
break;
default:
break;
}
return otherChildren.ToArray();
}
}
}

View File

@ -100,7 +100,7 @@ namespace NewHorizons.Utility.DebugUtilities
var hitAstroObject = o.GetComponent<AstroObject>() ?? o.GetComponentInParent<AstroObject>();
data.bodyName = o.name;
data.bodyPath = SearchUtilities.GetPath(o.transform);
data.bodyPath = o.transform.GetPath();
data.hitObject = o;
data.hitBodyGameObject = hitAstroObject?.gameObject ?? o;
data.plane = ConstructPlane(data);

View File

@ -36,7 +36,7 @@ namespace NewHorizons.Utility
public static void LogPath(GameObject go)
{
if (go == null) Log("Can't print path: GameObject is null");
else Log($"{SearchUtilities.GetPath(go.transform)}");
else Log($"{go.transform.GetPath()}");
}
public static void Log(string text, LogType type)

View File

@ -1,8 +1,10 @@
using System;
using HarmonyLib;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
using Object = UnityEngine.Object;
namespace NewHorizons.Utility
{
public static class SearchUtilities
@ -15,23 +17,6 @@ namespace NewHorizons.Utility
CachedGameObjects.Clear();
}
public static GameObject CachedFind(string path)
{
if (CachedGameObjects.ContainsKey(path))
{
return CachedGameObjects[path];
}
else
{
GameObject foundObject = GameObject.Find(path);
if (foundObject != null)
{
CachedGameObjects.Add(path, foundObject);
}
return foundObject;
}
}
public static List<T> FindObjectsOfTypeAndName<T>(string name) where T : Object
{
T[] firstList = GameObject.FindObjectsOfType<T>();
@ -94,118 +79,47 @@ namespace NewHorizons.Utility
return null;
}
public static string GetPath(Transform current)
public static string GetPath(this Transform current)
{
if (current.parent == null) return current.name;
return GetPath(current.parent) + "/" + current.name;
return current.parent.GetPath() + "/" + current.name;
}
/*
public static GameObject Find(string path)
{
var go = GameObject.Find(path);
if (go != null) return go;
var names = path.Split(new char[] { '\\', '/' });
foreach (var possibleMatch in FindObjectsOfTypeAndName<GameObject>(names.Last()))
{
Logger.LogPath(possibleMatch);
if (GetPath(possibleMatch.transform) == path) return possibleMatch;
}
return null;
}
*/
public static GameObject FindChild(GameObject g, string childName)
{
foreach(Transform child in g.transform)
{
if (child.gameObject.name == childName) return child.gameObject;
}
return null;
}
public static GameObject FindChild(this GameObject g, string childPath) =>
g.transform.Find(childPath)?.gameObject;
public static GameObject Find(string path, bool warn = true)
{
if (CachedGameObjects.ContainsKey(path))
{
return CachedGameObjects[path];
}
try
{
var go = GameObject.Find(path);
var names = path.Split(new char[] { '\\', '/' });
if (go == null)
{
// Get the root object and hope its the right one
var root = GameObject.Find(names[0]);
if (root == null) root = UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects().Where(x => x.name.Equals(names[0])).FirstOrDefault();
var t = root?.transform;
if (t == null)
{
if (warn) Logger.LogWarning($"Couldn't find root object in path ({names[0]})");
}
else
{
for (int i = 1; i < names.Length; i++)
{
var child = t.transform.Find(names[i]);
if (child == null)
{
foreach (Transform c in t.GetComponentsInChildren<Transform>(true))
{
if (c.name.Equals(names[i]))
{
child = c;
break;
}
}
}
if (child == null)
{
if (warn) Logger.LogWarning($"Couldn't find object in path ({names[i]})");
t = null;
break;
}
t = child;
}
}
go = t?.gameObject;
}
if (go == null)
{
var name = names.Last();
if (warn) Logger.LogWarning($"Couldn't find object {path}, will look for potential matches for name {name}");
go = FindObjectOfTypeAndName<GameObject>(name);
}
if (go != null)
{
CachedGameObjects.Add(path, go);
}
return go;
}
catch (Exception)
if (CachedGameObjects.TryGetValue(path, out var go)) return go;
go = GameObject.Find(path);
if (go != null) return go;
var names = path.Split('/');
var rootName = names[0];
var root = SceneManager.GetActiveScene().GetRootGameObjects().FirstOrDefault(x => x.name == rootName);
if (root == null)
{
if (warn) Logger.LogWarning($"Couldn't find root object in path ({path})");
return null;
}
var childPath = names.Skip(1).Join(delimiter: "/");
go = root.FindChild(childPath);
if (go == null)
{
var name = names.Last();
if (warn) Logger.LogWarning($"Couldn't find object in path ({path}), will look for potential matches for name {name}");
go = FindObjectOfTypeAndName<GameObject>(name);
}
CachedGameObjects.Add(path, go);
return go;
}
public static List<GameObject> GetAllChildren(GameObject parent)
public static List<GameObject> GetAllChildren(this GameObject parent)
{
List<GameObject> children = new List<GameObject>();
var children = new List<GameObject>();
foreach (Transform child in parent.transform)
{
children.Add(child.gameObject);

View File

@ -0,0 +1,7 @@
namespace NewHorizons.VoiceActing
{
public interface IVoiceMod
{
void RegisterAssets(string assetsFolder);
}
}

View File

@ -0,0 +1,41 @@
using NewHorizons.Utility;
using System.IO;
using System.Linq;
namespace NewHorizons.VoiceActing
{
public static class VoiceHandler
{
public static bool Enabled { get; private set; }
private static IVoiceMod API;
public static void Init()
{
API = Main.Instance.ModHelper.Interaction.TryGetModApi<IVoiceMod>("Krevace.VoiceMod");
if (API == null)
{
Logger.Log("VoiceMod isn't installed");
Enabled = false;
return;
}
Enabled = true;
foreach (var mod in Main.Instance.GetDependants().Append(Main.Instance))
{
var folder = $"{mod.ModHelper.Manifest.ModFolderPath}VoiceMod";
if (Directory.Exists(folder))
{
Logger.Log($"Registering VoiceMod audio for {mod.ModHelper.Manifest.Name} from {folder}");
API.RegisterAssets(folder);
}
else
{
Logger.Log($"Didn't find VoiceMod audio for {mod.ModHelper.Manifest.Name} at {folder}");
}
}
}
}
}

View File

@ -1,9 +1,10 @@
{
"$schema": "https://raw.githubusercontent.com/amazingalek/owml/master/schemas/manifest_schema.json",
"filename": "NewHorizons.dll",
"author": "xen and Bwc9876",
"author": "xen, Bwc9876, clay, MegaPiggy, John, Book",
"name": "New Horizons",
"uniqueName": "xen.NewHorizons",
"version": "1.3.1",
"version": "1.3.2",
"owmlVersion": "2.5.2",
"conflicts": [ "Raicuparta.QuantumSpaceBuddies", "Vesper.AutoResume", "PacificEngine.OW_Randomizer" ],
"pathsToPreserve": [ "planets", "systems", "translations" ]