mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
commit
2fabfcb1a5
124
NewHorizons/Builder/Body/BrambleDimensionBuilder.cs
Normal file
124
NewHorizons/Builder/Body/BrambleDimensionBuilder.cs
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
using NewHorizons.Builder.Props;
|
||||||
|
using NewHorizons.Components.Orbital;
|
||||||
|
using NewHorizons.Handlers;
|
||||||
|
using NewHorizons.Utility;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NewHorizons.Builder.Body
|
||||||
|
{
|
||||||
|
public static class BrambleDimensionBuilder
|
||||||
|
{
|
||||||
|
public static readonly float BASE_DIMENSION_RADIUS = 1705f;
|
||||||
|
|
||||||
|
// location of all vanilla bramble dimensions
|
||||||
|
//-9116.795 -19873.44 2480.327
|
||||||
|
//-8460.688 -19873.44 6706.444
|
||||||
|
//-5015.165 -19873.44 4142.816
|
||||||
|
//-8993.414 -17059.44 4521.747
|
||||||
|
//-7044.813 -17135.44 3272.149
|
||||||
|
//-6904.48 -17048.44 5574.479
|
||||||
|
//-11096.95 -22786.44 4657.534
|
||||||
|
//-8716.807 -22786.44 4496.394
|
||||||
|
|
||||||
|
|
||||||
|
// keys are all node names that have been referenced as an exit by at least one dimension but do not (yet) exist
|
||||||
|
// values are all dimensions' warp controllers that link to a given dimension
|
||||||
|
// unpairedNodes[name of node that doesn't exist yet] => List{warp controller for dimension that exits to that node, ...}
|
||||||
|
private static Dictionary<string, List<OuterFogWarpVolume>> _unpairedDimensions = new();
|
||||||
|
|
||||||
|
public static void Init()
|
||||||
|
{
|
||||||
|
// Just in case something went wrong and a dimension never got paired last time
|
||||||
|
_unpairedDimensions.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GameObject Make(NewHorizonsBody body)
|
||||||
|
{
|
||||||
|
var config = body.Config.Bramble.dimension;
|
||||||
|
|
||||||
|
// spawn the dimension body
|
||||||
|
var dimensionPrefab = SearchUtilities.Find("DB_HubDimension_Body");
|
||||||
|
var dimension = dimensionPrefab.InstantiateInactive();
|
||||||
|
|
||||||
|
PlanetCreationHandler.UpdateBodyOrbit(body, dimension);
|
||||||
|
|
||||||
|
// fix name
|
||||||
|
var ao = dimension.GetComponent<NHAstroObject>();
|
||||||
|
ao.IsDimension = true;
|
||||||
|
var name = body.Config.name ?? "Custom Bramble Dimension";
|
||||||
|
ao._customName = name;
|
||||||
|
ao._name = AstroObject.Name.CustomString;
|
||||||
|
dimension.name = name.Replace(" ", "").Replace("'", "") + "_Body";
|
||||||
|
|
||||||
|
// set position
|
||||||
|
ao.transform.position = body.Config.Orbit.staticPosition;
|
||||||
|
|
||||||
|
// fix children's names and remove base game props (mostly just bramble nodes that are children to Interactibles) and set up the OuterWarp child
|
||||||
|
var dimensionSector = dimension.FindChild("Sector_HubDimension");
|
||||||
|
dimensionSector.name = "Sector";
|
||||||
|
var atmo = dimensionSector.FindChild("Atmosphere_HubDimension");
|
||||||
|
var geom = dimensionSector.FindChild("Geometry_HubDimension");
|
||||||
|
var vols = dimensionSector.FindChild("Volumes_HubDimension");
|
||||||
|
var efxs = dimensionSector.FindChild("Effects_HubDimension");
|
||||||
|
var intr = dimensionSector.FindChild("Interactables_HubDimension");
|
||||||
|
var exitWarps = intr.FindChild("OuterWarp_Hub");
|
||||||
|
|
||||||
|
exitWarps.name = "OuterWarp";
|
||||||
|
exitWarps.transform.parent = dimensionSector.transform;
|
||||||
|
atmo.name = "Atmosphere";
|
||||||
|
geom.name = "Geometry"; // disable this?
|
||||||
|
vols.name = "Volumes";
|
||||||
|
efxs.name = "Effects";
|
||||||
|
intr.name = "Interactibles";
|
||||||
|
GameObject.Destroy(intr);
|
||||||
|
|
||||||
|
// set up warps
|
||||||
|
var outerFogWarpVolume = exitWarps.GetComponent<OuterFogWarpVolume>();
|
||||||
|
outerFogWarpVolume._senderWarps.Clear();
|
||||||
|
outerFogWarpVolume._linkedInnerWarpVolume = null;
|
||||||
|
outerFogWarpVolume._name = OuterFogWarpVolume.Name.None;
|
||||||
|
|
||||||
|
PairExit(config.linksTo, outerFogWarpVolume);
|
||||||
|
|
||||||
|
// change fog color
|
||||||
|
if (body.Config.Bramble.dimension.fogTint != null)
|
||||||
|
{
|
||||||
|
var fogGO = atmo.FindChild("FogSphere_Hub");
|
||||||
|
var fog = fogGO.GetComponent<PlanetaryFogController>();
|
||||||
|
fog.fogTint = body.Config.Bramble.dimension.fogTint.ToColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
dimension.SetActive(true);
|
||||||
|
|
||||||
|
return dimension;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PairExit(string exitName, OuterFogWarpVolume warpController)
|
||||||
|
{
|
||||||
|
if (!BrambleNodeBuilder.namedNodes.ContainsKey(exitName))
|
||||||
|
{
|
||||||
|
if (!_unpairedDimensions.ContainsKey(exitName)) _unpairedDimensions[exitName] = new();
|
||||||
|
_unpairedDimensions[exitName].Add(warpController);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
warpController._linkedInnerWarpVolume = BrambleNodeBuilder.namedNodes[exitName];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FinishPairingDimensionsForExitNode(string nodeName)
|
||||||
|
{
|
||||||
|
if (!_unpairedDimensions.ContainsKey(nodeName)) return;
|
||||||
|
|
||||||
|
var warpControllers = _unpairedDimensions[nodeName].ToList();
|
||||||
|
foreach (var dimensionWarpController in warpControllers)
|
||||||
|
{
|
||||||
|
PairExit(nodeName, dimensionWarpController);
|
||||||
|
}
|
||||||
|
|
||||||
|
//unpairedDimensions.Remove(nodeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
277
NewHorizons/Builder/Props/BrambleNodeBuilder.cs
Normal file
277
NewHorizons/Builder/Props/BrambleNodeBuilder.cs
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
using NewHorizons.Builder.Body;
|
||||||
|
using NewHorizons.Handlers;
|
||||||
|
using NewHorizons.Utility;
|
||||||
|
using OWML.Common;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
using static NewHorizons.External.Modules.BrambleModule;
|
||||||
|
using static NewHorizons.External.Modules.SignalModule;
|
||||||
|
|
||||||
|
namespace NewHorizons.Builder.Props
|
||||||
|
{
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
//3) support for existing dimensions?
|
||||||
|
//5) test whether nodes can lead to vanilla dimensions
|
||||||
|
|
||||||
|
public static class BrambleNodeBuilder
|
||||||
|
{
|
||||||
|
// keys are all dimension names that have been referenced by at least one node but do not (yet) exist
|
||||||
|
// values are all nodes' warp controllers that link to a given dimension
|
||||||
|
// unpairedNodes[name of dimension that doesn't exist yet] => List{warp controller for node that links to that dimension, ...}
|
||||||
|
private static Dictionary<string, List<InnerFogWarpVolume>> _unpairedNodes = new();
|
||||||
|
private static Dictionary<string, List<SignalInfo>> _propogatedSignals = null;
|
||||||
|
|
||||||
|
public static readonly Dictionary<string, InnerFogWarpVolume> namedNodes = new();
|
||||||
|
public static readonly Dictionary<BrambleNodeInfo, GameObject> builtBrambleNodes = new();
|
||||||
|
|
||||||
|
public static void Init()
|
||||||
|
{
|
||||||
|
_unpairedNodes.Clear();
|
||||||
|
_propogatedSignals.Clear();
|
||||||
|
namedNodes.Clear();
|
||||||
|
builtBrambleNodes.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FinishPairingNodesForDimension(string dimensionName, AstroObject dimensionAO = null)
|
||||||
|
{
|
||||||
|
if (!_unpairedNodes.ContainsKey(dimensionName)) return;
|
||||||
|
|
||||||
|
foreach (var nodeWarpController in _unpairedNodes[dimensionName])
|
||||||
|
{
|
||||||
|
PairEntrance(nodeWarpController, dimensionName, dimensionAO);
|
||||||
|
}
|
||||||
|
|
||||||
|
_unpairedNodes.Remove(dimensionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RecordUnpairedNode(InnerFogWarpVolume warpVolume, string linksTo)
|
||||||
|
{
|
||||||
|
if (!_unpairedNodes.ContainsKey(linksTo)) _unpairedNodes[linksTo] = new();
|
||||||
|
|
||||||
|
_unpairedNodes[linksTo].Add(warpVolume);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static OuterFogWarpVolume GetOuterFogWarpVolumeFromAstroObject(GameObject go)
|
||||||
|
{
|
||||||
|
var outerWarpGO = go.FindChild("Sector/OuterWarp");
|
||||||
|
if (outerWarpGO == null) return null;
|
||||||
|
|
||||||
|
var outerFogWarpVolume = outerWarpGO.GetComponent<OuterFogWarpVolume>();
|
||||||
|
return outerFogWarpVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PropogateSignals()
|
||||||
|
{
|
||||||
|
// The purpose of this function is to determine which signals any given node should play, based on which dimension it links to
|
||||||
|
// you know how the main dark bramble node, the one that forms the core of the planet, plays Feldspar's harmonica signal, even though Feldspar isn't in the dimension that the node links directly to?
|
||||||
|
// that's what this function is for. it would determine that the main node should play Feldspar's signal
|
||||||
|
|
||||||
|
// New Strategy (thanks Damian):
|
||||||
|
// 1) Run Floyd-Warshall on the dimensions (where each dimension is a vertex and each node is an edge)
|
||||||
|
// 2) For each dimension A, if it's possible to reach dimension B, add dimension B's signals to the list propogatedSignals[A]
|
||||||
|
|
||||||
|
var allDimensions = PlanetCreationHandler.allBodies.Where(body => body?.Config?.Bramble?.dimension != null).Select(body => body.Config).ToList();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Floyd Warshall
|
||||||
|
//
|
||||||
|
|
||||||
|
// access will be our final answer - if access[i, j], then nodes linking to dimension i should display all of dimension j's signals
|
||||||
|
var access = new bool[allDimensions.Count(), allDimensions.Count()];
|
||||||
|
|
||||||
|
var dimensionNameToIndex = new Dictionary<string, int>();
|
||||||
|
for (int dimensionIndex = 0; dimensionIndex < allDimensions.Count(); dimensionIndex++) dimensionNameToIndex[allDimensions[dimensionIndex].name] = dimensionIndex;
|
||||||
|
|
||||||
|
// set up the direct links (ie, if dimension 0 contains a node that links to dimension 3, set access[0, 3] = true)
|
||||||
|
for (int dimensionIndex = 0; dimensionIndex < allDimensions.Count(); dimensionIndex++)
|
||||||
|
{
|
||||||
|
var dimension = allDimensions[dimensionIndex];
|
||||||
|
if (dimension.Bramble.nodes == null) continue;
|
||||||
|
foreach (var node in dimension.Bramble.nodes)
|
||||||
|
{
|
||||||
|
var destinationDimensionIndex = dimensionNameToIndex[node.linksTo];
|
||||||
|
access[dimensionIndex, destinationDimensionIndex] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// a node that links to dimension A should display all of dimension A's signals, so for the purposes of our function, we need to say that dimension A links to dimension A
|
||||||
|
for (int dimensionIndex = 0; dimensionIndex < allDimensions.Count(); dimensionIndex++) access[dimensionIndex, dimensionIndex] = true;
|
||||||
|
|
||||||
|
// The actual Floyd-Warshall - determine whether each pair of dimensions link indirectly (eg if A->B->C, then after this step, access[A, C] = true)
|
||||||
|
for (int k = 0; k < allDimensions.Count(); k++)
|
||||||
|
for (int i = 0; i < allDimensions.Count(); i++)
|
||||||
|
for (int j = 0; j < allDimensions.Count(); j++)
|
||||||
|
if (access[i, k] && access[k, j])
|
||||||
|
access[i, j] = true;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Build the list of dimensionName -> List<SignalInfo>
|
||||||
|
//
|
||||||
|
|
||||||
|
// this dictionary lists all the signals a given node should have, depending on the dimension it links to
|
||||||
|
// ie, if a node links to "dimension1", then that node should spawn all of the signals in the list propogatedSignals["dimension1"]
|
||||||
|
_propogatedSignals = new Dictionary<string, List<SignalInfo>>();
|
||||||
|
foreach (var dimension in allDimensions)
|
||||||
|
{
|
||||||
|
_propogatedSignals[dimension.name] = new();
|
||||||
|
var dimensionIndex = dimensionNameToIndex[dimension.name];
|
||||||
|
|
||||||
|
foreach (var destinationDimension in allDimensions)
|
||||||
|
{
|
||||||
|
if (destinationDimension.Signal?.signals == null) continue;
|
||||||
|
|
||||||
|
var destinationIndex = dimensionNameToIndex[destinationDimension.name];
|
||||||
|
if (access[dimensionIndex, destinationIndex])
|
||||||
|
{
|
||||||
|
_propogatedSignals[dimension.name].AddRange(destinationDimension.Signal.signals);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool PairEntrance(InnerFogWarpVolume nodeWarp, string destinationName, AstroObject dimensionAO = null)
|
||||||
|
{
|
||||||
|
var destinationAO = dimensionAO ?? AstroObjectLocator.GetAstroObject(destinationName); // find child "Sector/OuterWarp"
|
||||||
|
if (destinationAO == null) return false;
|
||||||
|
|
||||||
|
// link the node's warp volume to the destination's
|
||||||
|
var destination = GetOuterFogWarpVolumeFromAstroObject(destinationAO.gameObject);
|
||||||
|
if (destination == null) return false;
|
||||||
|
|
||||||
|
nodeWarp._linkedOuterWarpVolume = destination;
|
||||||
|
destination.RegisterSenderWarp(nodeWarp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// DB_EscapePodDimension_Body/Sector_EscapePodDimension/Interactables_EscapePodDimension/InnerWarp_ToAnglerNest // need to change the light shaft color
|
||||||
|
// DB_ExitOnlyDimension_Body/Sector_ExitOnlyDimension/Interactables_ExitOnlyDimension/InnerWarp_ToExitOnly // need to change the colors
|
||||||
|
// DB_HubDimension_Body/Sector_HubDimension/Interactables_HubDimension/InnerWarp_ToCluster // need to delete the child "Signal_Harmonica"
|
||||||
|
|
||||||
|
public static void Make(GameObject go, Sector sector, BrambleNodeInfo[] configs, IModBehaviour mod)
|
||||||
|
{
|
||||||
|
foreach(var config in configs)
|
||||||
|
{
|
||||||
|
Make(go, sector, config, mod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GameObject Make(GameObject go, Sector sector, BrambleNodeInfo config, IModBehaviour mod)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// spawn the bramble node
|
||||||
|
//
|
||||||
|
|
||||||
|
var brambleSeedPrefabPath = "DB_PioneerDimension_Body/Sector_PioneerDimension/Interactables_PioneerDimension/SeedWarp_ToPioneer (1)";
|
||||||
|
var brambleNodePrefabPath = "DB_HubDimension_Body/Sector_HubDimension/Interactables_HubDimension/InnerWarp_ToCluster";
|
||||||
|
|
||||||
|
var path = config.isSeed ? brambleSeedPrefabPath : brambleNodePrefabPath;
|
||||||
|
var brambleNode = DetailBuilder.MakeDetail(go, sector, path, config.position, config.rotation, 1, false);
|
||||||
|
brambleNode.name = "Bramble Node to " + config.linksTo;
|
||||||
|
var warpController = brambleNode.GetComponent<InnerFogWarpVolume>();
|
||||||
|
|
||||||
|
// this node comes with Feldspar's signal, we don't want that though
|
||||||
|
GameObject.Destroy(brambleNode.FindChild("Signal_Harmonica"));
|
||||||
|
|
||||||
|
//
|
||||||
|
// change the colors
|
||||||
|
//
|
||||||
|
|
||||||
|
if (config.isSeed) SetSeedColors(brambleNode, config.fogTint.ToColor(), config.lightTint.ToColor());
|
||||||
|
else SetNodeColors(brambleNode, config.fogTint.ToColor(), config.lightTint.ToColor());
|
||||||
|
|
||||||
|
//
|
||||||
|
// set up warps
|
||||||
|
//
|
||||||
|
|
||||||
|
warpController._sector = sector;
|
||||||
|
warpController._attachedBody = go.GetComponent<OWRigidbody>(); // I don't think this is necessary, it seems to be set correctly on its own
|
||||||
|
warpController._containerWarpVolume = GetOuterFogWarpVolumeFromAstroObject(go); // the OuterFogWarpVolume of the dimension this node is inside of (null if this node is not inside of a bramble dimension (eg it's sitting on a planet or something))
|
||||||
|
var success = PairEntrance(warpController, config.linksTo);
|
||||||
|
if (!success) RecordUnpairedNode(warpController, config.linksTo);
|
||||||
|
|
||||||
|
warpController.Awake(); // I can't spawn this game object disabled, but Awake needs to run after _sector is set. That means I need to call Awake myself
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup for dimension exits
|
||||||
|
//
|
||||||
|
if (config.name != null)
|
||||||
|
{
|
||||||
|
namedNodes[config.name] = warpController;
|
||||||
|
BrambleDimensionBuilder.FinishPairingDimensionsForExitNode(config.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make signals
|
||||||
|
//
|
||||||
|
if (_propogatedSignals == null) PropogateSignals();
|
||||||
|
foreach (var signalConfig in _propogatedSignals[config.linksTo])
|
||||||
|
{
|
||||||
|
var signalGO = SignalBuilder.Make(go, sector, signalConfig, mod);
|
||||||
|
signalGO.GetComponent<AudioSignal>()._identificationDistance = 0;
|
||||||
|
signalGO.GetComponent<AudioSignal>()._sourceRadius = 1;
|
||||||
|
signalGO.transform.position = brambleNode.transform.position;
|
||||||
|
signalGO.transform.parent = brambleNode.transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done!
|
||||||
|
return brambleNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetNodeColors(GameObject brambleNode, Color fogTint, Color lightTint)
|
||||||
|
{
|
||||||
|
if (fogTint != null)
|
||||||
|
{
|
||||||
|
var fogRenderer = brambleNode.GetComponent<InnerFogWarpVolume>();
|
||||||
|
|
||||||
|
fogRenderer._fogColor = fogTint;
|
||||||
|
fogRenderer._useFarFogColor = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lightTint != null)
|
||||||
|
{
|
||||||
|
var lightShafts = brambleNode.FindChild("Effects/DB_BrambleLightShafts");
|
||||||
|
|
||||||
|
var lightShaft1 = lightShafts.FindChild("BrambleLightShaft1");
|
||||||
|
var mat = lightShaft1.GetComponent<MeshRenderer>().material;
|
||||||
|
mat.color = lightTint;
|
||||||
|
|
||||||
|
for (int i = 1; i <= 6; i++)
|
||||||
|
{
|
||||||
|
var lightShaft = lightShafts.FindChild($"BrambleLightShaft{i}");
|
||||||
|
lightShaft.GetComponent<MeshRenderer>().sharedMaterial = mat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetSeedColors(GameObject brambleSeed, Color fogTint, Color lightTint)
|
||||||
|
{
|
||||||
|
if (fogTint != null)
|
||||||
|
{
|
||||||
|
var fogRenderer = brambleSeed.FindChild("VolumetricFogSphere (2)");
|
||||||
|
|
||||||
|
var fogMeshRenderer = fogRenderer.GetComponent<MeshRenderer>();
|
||||||
|
var mat = fogMeshRenderer.material;
|
||||||
|
mat.color = fogTint;
|
||||||
|
fogMeshRenderer.sharedMaterial = mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lightTint != null)
|
||||||
|
{
|
||||||
|
var lightShafts = brambleSeed.FindChild("Terrain_DB_BrambleSphere_Seed_V2 (2)/DB_SeedLightShafts");
|
||||||
|
|
||||||
|
var lightShaft1 = lightShafts.FindChild("DB_SeedLightShafts1");
|
||||||
|
var mat = lightShaft1.GetComponent<MeshRenderer>().material;
|
||||||
|
mat.color = lightTint;
|
||||||
|
|
||||||
|
for (int i = 1; i <= 6; i++)
|
||||||
|
{
|
||||||
|
var lightShaft = lightShafts.FindChild($"DB_SeedLightShafts{i}");
|
||||||
|
lightShaft.GetComponent<MeshRenderer>().sharedMaterial = mat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -133,7 +133,7 @@ namespace NewHorizons.Builder.Props
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Make(GameObject planetGO, Sector sector, SignalModule.SignalInfo info, IModBehaviour mod)
|
public static GameObject Make(GameObject planetGO, Sector sector, SignalModule.SignalInfo info, IModBehaviour mod)
|
||||||
{
|
{
|
||||||
var signalGO = new GameObject($"Signal_{info.name}");
|
var signalGO = new GameObject($"Signal_{info.name}");
|
||||||
signalGO.SetActive(false);
|
signalGO.SetActive(false);
|
||||||
@ -167,7 +167,7 @@ namespace NewHorizons.Builder.Props
|
|||||||
if (clip == null)
|
if (clip == null)
|
||||||
{
|
{
|
||||||
Logger.LogError($"Couldn't find AudioClip {info.audioClip} or AudioFile {info.audioFilePath}");
|
Logger.LogError($"Couldn't find AudioClip {info.audioClip} or AudioFile {info.audioFilePath}");
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
audioSignal.SetSector(sector);
|
audioSignal.SetSector(sector);
|
||||||
@ -180,7 +180,8 @@ namespace NewHorizons.Builder.Props
|
|||||||
audioSignal._revealFactID = info.reveals;
|
audioSignal._revealFactID = info.reveals;
|
||||||
audioSignal._onlyAudibleToScope = info.onlyAudibleToScope;
|
audioSignal._onlyAudibleToScope = info.onlyAudibleToScope;
|
||||||
audioSignal._identificationDistance = info.identificationRadius;
|
audioSignal._identificationDistance = info.identificationRadius;
|
||||||
audioSignal._canBePickedUpByScope = true;
|
audioSignal._canBePickedUpByScope = true;
|
||||||
|
audioSignal._outerFogWarpVolume = planetGO.GetComponentInChildren<OuterFogWarpVolume>(); // shouldn't break non-bramble signals
|
||||||
|
|
||||||
source.clip = clip;
|
source.clip = clip;
|
||||||
source.loop = true;
|
source.loop = true;
|
||||||
@ -218,7 +219,9 @@ namespace NewHorizons.Builder.Props
|
|||||||
audioSignalDetectionTrigger._trigger = owTriggerVolume;
|
audioSignalDetectionTrigger._trigger = owTriggerVolume;
|
||||||
|
|
||||||
signalGO.SetActive(true);
|
signalGO.SetActive(true);
|
||||||
signalDetectionGO.SetActive(true);
|
signalDetectionGO.SetActive(true);
|
||||||
|
|
||||||
|
return signalGO;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SignalFrequency StringToFrequency(string str)
|
private static SignalFrequency StringToFrequency(string str)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
using NewHorizons.External.Modules;
|
using NewHorizons.External.Modules;
|
||||||
namespace NewHorizons.Components.Orbital
|
namespace NewHorizons.Components.Orbital
|
||||||
{
|
{
|
||||||
public class NHAstroObject : AstroObject, IOrbitalParameters
|
public class NHAstroObject : AstroObject, IOrbitalParameters
|
||||||
@ -10,6 +10,7 @@ namespace NewHorizons.Components.Orbital
|
|||||||
public float argumentOfPeriapsis { get; set; }
|
public float argumentOfPeriapsis { get; set; }
|
||||||
public float trueAnomaly { get; set; }
|
public float trueAnomaly { get; set; }
|
||||||
public bool HideDisplayName { get; set; }
|
public bool HideDisplayName { get; set; }
|
||||||
|
public bool IsDimension { get; set; }
|
||||||
|
|
||||||
public void SetOrbitalParametersFromConfig(OrbitModule orbit)
|
public void SetOrbitalParametersFromConfig(OrbitModule orbit)
|
||||||
{
|
{
|
||||||
|
|||||||
16
NewHorizons/External/Configs/PlanetConfig.cs
vendored
16
NewHorizons/External/Configs/PlanetConfig.cs
vendored
@ -7,6 +7,7 @@ using NewHorizons.Builder.Orbital;
|
|||||||
using NewHorizons.External.Modules;
|
using NewHorizons.External.Modules;
|
||||||
using NewHorizons.External.Modules.VariableSize;
|
using NewHorizons.External.Modules.VariableSize;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Logger = NewHorizons.Utility.Logger;
|
||||||
|
|
||||||
namespace NewHorizons.External.Configs
|
namespace NewHorizons.External.Configs
|
||||||
{
|
{
|
||||||
@ -31,6 +32,11 @@ namespace NewHorizons.External.Configs
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public BaseModule Base;
|
public BaseModule Base;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add bramble nodes to this planet and/or make this planet a bramble dimension
|
||||||
|
/// </summary>
|
||||||
|
public BrambleModule Bramble;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set to a higher number if you wish for this body to be built sooner
|
/// Set to a higher number if you wish for this body to be built sooner
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -171,12 +177,18 @@ namespace NewHorizons.External.Configs
|
|||||||
if (ReferenceFrame == null) ReferenceFrame = new ReferenceFrameModule();
|
if (ReferenceFrame == null) ReferenceFrame = new ReferenceFrameModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MigrateAndValidate()
|
public void Validate()
|
||||||
{
|
{
|
||||||
// Validate
|
// If we can correct a part of the config, do it
|
||||||
|
// If it cannot be solved, throw an exception
|
||||||
if (Base.centerOfSolarSystem) Orbit.isStatic = true;
|
if (Base.centerOfSolarSystem) Orbit.isStatic = true;
|
||||||
if (Atmosphere?.clouds?.lightningGradient != null) Atmosphere.clouds.hasLightning = true;
|
if (Atmosphere?.clouds?.lightningGradient != null) Atmosphere.clouds.hasLightning = true;
|
||||||
|
if (Bramble?.dimension != null && Orbit?.staticPosition == null) throw new Exception($"Dimension {name} must have Orbit.staticPosition defined.");
|
||||||
|
if (Orbit?.staticPosition != null) Orbit.isStatic = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Migrate()
|
||||||
|
{
|
||||||
// Backwards compatability
|
// Backwards compatability
|
||||||
// Should be the only place that obsolete things are referenced
|
// Should be the only place that obsolete things are referenced
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
|
|||||||
81
NewHorizons/External/Modules/BrambleModule.cs
vendored
Normal file
81
NewHorizons/External/Modules/BrambleModule.cs
vendored
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
using NewHorizons.Utility;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NewHorizons.External.Modules
|
||||||
|
{
|
||||||
|
|
||||||
|
[JsonObject]
|
||||||
|
public class BrambleModule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Defining this value will make this body a bramble dimension. Leave it null to not do that.
|
||||||
|
/// </summary>
|
||||||
|
public BrambleDimensionInfo dimension;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Place nodes/seeds that take you to other bramble dimensions
|
||||||
|
/// </summary>
|
||||||
|
public BrambleNodeInfo[] nodes;
|
||||||
|
|
||||||
|
|
||||||
|
[JsonObject]
|
||||||
|
public class BrambleDimensionInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The color of the fog inside this dimension. Leave blank for the default yellowish color
|
||||||
|
/// </summary>
|
||||||
|
public MColor fogTint;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the *node* that the player is taken to when exiting this dimension.
|
||||||
|
/// </summary>
|
||||||
|
public string linksTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[JsonObject]
|
||||||
|
public class BrambleNodeInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The physical position of the node
|
||||||
|
/// </summary>
|
||||||
|
public MVector3 position;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The physical rotation of the node
|
||||||
|
/// </summary>
|
||||||
|
public MVector3 rotation;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The name of the planet that hosts the dimension this node links to
|
||||||
|
/// </summary>
|
||||||
|
public string linksTo;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The name of this node. Only required if this node should serve as an exit.
|
||||||
|
/// </summary>
|
||||||
|
public string name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set this to true to make this node a seed instead of a node the player can enter
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(false)] public bool isSeed = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The color of the fog inside the node. Leave blank for the default yellowish color (default: 131, 124, 105, 255)
|
||||||
|
/// </summary>
|
||||||
|
public MColor fogTint;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The color of the shafts of light coming from the entrances to the node. Leave blank for the default yellowish color
|
||||||
|
/// </summary>
|
||||||
|
public MColor lightTint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
NewHorizons/External/Modules/OrbitModule.cs
vendored
9
NewHorizons/External/Modules/OrbitModule.cs
vendored
@ -1,4 +1,4 @@
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using NewHorizons.Components.Orbital;
|
using NewHorizons.Components.Orbital;
|
||||||
using NewHorizons.Utility;
|
using NewHorizons.Utility;
|
||||||
@ -8,7 +8,12 @@ namespace NewHorizons.External.Modules
|
|||||||
{
|
{
|
||||||
[JsonObject]
|
[JsonObject]
|
||||||
public class OrbitModule : IOrbitalParameters
|
public class OrbitModule : IOrbitalParameters
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Specify this if you want the body to remain stationary at a given location (ie not orbit its parent). Required for Bramble dimensions
|
||||||
|
/// </summary>
|
||||||
|
public MVector3 staticPosition;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the body this one will orbit around
|
/// The name of the body this one will orbit around
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -23,6 +23,21 @@ namespace NewHorizons.Handlers
|
|||||||
private static Dictionary<AstroObject, NewHorizonsBody> ExistingAOConfigs;
|
private static Dictionary<AstroObject, NewHorizonsBody> ExistingAOConfigs;
|
||||||
|
|
||||||
private static Dictionary<NHAstroObject, NewHorizonsBody> _dict;
|
private static Dictionary<NHAstroObject, NewHorizonsBody> _dict;
|
||||||
|
private static Dictionary<AstroObject, NewHorizonsBody> _dimensions;
|
||||||
|
|
||||||
|
public static List<NewHorizonsBody> allBodies;
|
||||||
|
|
||||||
|
public static NewHorizonsBody GetNewHorizonsBody(AstroObject ao)
|
||||||
|
{
|
||||||
|
if (ao is NHAstroObject nhAO)
|
||||||
|
{
|
||||||
|
if (_dict.ContainsKey(nhAO)) return _dict[nhAO];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_dimensions.ContainsKey(ao)) return null;
|
||||||
|
|
||||||
|
return _dimensions[ao];
|
||||||
|
}
|
||||||
|
|
||||||
public static void Init(List<NewHorizonsBody> bodies)
|
public static void Init(List<NewHorizonsBody> bodies)
|
||||||
{
|
{
|
||||||
@ -30,6 +45,8 @@ namespace NewHorizons.Handlers
|
|||||||
|
|
||||||
ExistingAOConfigs = new Dictionary<AstroObject, NewHorizonsBody>();
|
ExistingAOConfigs = new Dictionary<AstroObject, NewHorizonsBody>();
|
||||||
_dict = new Dictionary<NHAstroObject, NewHorizonsBody>();
|
_dict = new Dictionary<NHAstroObject, NewHorizonsBody>();
|
||||||
|
_dimensions = new Dictionary<AstroObject, NewHorizonsBody>();
|
||||||
|
allBodies = bodies;
|
||||||
|
|
||||||
// Set up stars
|
// Set up stars
|
||||||
// Need to manage this when there are multiple stars
|
// Need to manage this when there are multiple stars
|
||||||
@ -223,7 +240,11 @@ namespace NewHorizons.Handlers
|
|||||||
var planetObject = GenerateBody(body, defaultPrimaryToSun);
|
var planetObject = GenerateBody(body, defaultPrimaryToSun);
|
||||||
if (planetObject == null) return false;
|
if (planetObject == null) return false;
|
||||||
planetObject.SetActive(true);
|
planetObject.SetActive(true);
|
||||||
_dict.Add(planetObject.GetComponent<NHAstroObject>(), body);
|
|
||||||
|
var ao = planetObject.GetComponent<NHAstroObject>();
|
||||||
|
|
||||||
|
if (!ao.IsDimension) _dict.Add(ao, body);
|
||||||
|
else _dimensions.Add(ao, body);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -268,6 +289,44 @@ namespace NewHorizons.Handlers
|
|||||||
// Only called when making new planets
|
// Only called when making new planets
|
||||||
public static GameObject GenerateBody(NewHorizonsBody body, bool defaultPrimaryToSun = false)
|
public static GameObject GenerateBody(NewHorizonsBody body, bool defaultPrimaryToSun = false)
|
||||||
{
|
{
|
||||||
|
if (body.Config?.Bramble?.dimension != null)
|
||||||
|
{
|
||||||
|
if (body.Config?.Orbit?.staticPosition == null)
|
||||||
|
{
|
||||||
|
Logger.LogError($"Unable to build bramble dimension {body.Config?.name} because it does not have Orbit.staticPosition defined.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GenerateBrambleDimensionBody(body);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return GenerateStandardBody(body, defaultPrimaryToSun);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GameObject GenerateBrambleDimensionBody(NewHorizonsBody body)
|
||||||
|
{
|
||||||
|
var go = BrambleDimensionBuilder.Make(body);
|
||||||
|
var ao = go.GetComponent<NHAstroObject>();
|
||||||
|
var sector = go.FindChild("Sector").GetComponent<Sector>();
|
||||||
|
var owRigidBody = go.GetComponent<OWRigidbody>();
|
||||||
|
|
||||||
|
go = SharedGenerateBody(body, go, sector, owRigidBody);
|
||||||
|
body.Object = go;
|
||||||
|
|
||||||
|
if (ao.GetAstroObjectName() == AstroObject.Name.CustomString)
|
||||||
|
{
|
||||||
|
AstroObjectLocator.RegisterCustomAstroObject(ao);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Log($"returning GO named {go.name}");
|
||||||
|
|
||||||
|
return go;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GameObject GenerateStandardBody(NewHorizonsBody body, bool defaultPrimaryToSun = false)
|
||||||
|
{
|
||||||
// Focal points are weird
|
// Focal points are weird
|
||||||
if (body.Config.FocalPoint != null) FocalPointBuilder.ValidateConfig(body.Config);
|
if (body.Config.FocalPoint != null) FocalPointBuilder.ValidateConfig(body.Config);
|
||||||
|
|
||||||
@ -351,6 +410,10 @@ namespace NewHorizons.Handlers
|
|||||||
{
|
{
|
||||||
DetectorBuilder.Make(go, owRigidBody, primaryBody, ao, body.Config);
|
DetectorBuilder.Make(go, owRigidBody, primaryBody, ao, body.Config);
|
||||||
}
|
}
|
||||||
|
else if (body.Config.Orbit.staticPosition != null)
|
||||||
|
{
|
||||||
|
ao.transform.position = body.Config.Orbit.staticPosition;
|
||||||
|
}
|
||||||
|
|
||||||
if (ao.GetAstroObjectName() == AstroObject.Name.CustomString)
|
if (ao.GetAstroObjectName() == AstroObject.Name.CustomString)
|
||||||
{
|
{
|
||||||
@ -406,6 +469,19 @@ namespace NewHorizons.Handlers
|
|||||||
StarLightController.AddStar(StarBuilder.Make(go, sector, body.Config.Star, body.Mod));
|
StarLightController.AddStar(StarBuilder.Make(go, sector, body.Config.Star, body.Mod));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (body.Config?.Bramble != null)
|
||||||
|
{
|
||||||
|
if (body.Config.Bramble.nodes != null)
|
||||||
|
{
|
||||||
|
BrambleNodeBuilder.Make(go, sector, body.Config.Bramble.nodes, body.Mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (body.Config.Bramble.dimension != null)
|
||||||
|
{
|
||||||
|
BrambleNodeBuilder.FinishPairingNodesForDimension(body.Config.name, go.GetComponent<AstroObject>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (body.Config.Ring != null)
|
if (body.Config.Ring != null)
|
||||||
{
|
{
|
||||||
RingBuilder.Make(go, sector, body.Config.Ring, body.Mod);
|
RingBuilder.Make(go, sector, body.Config.Ring, body.Mod);
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using NewHorizons.AchievementsPlus;
|
using NewHorizons.AchievementsPlus;
|
||||||
|
using NewHorizons.Builder.Body;
|
||||||
using NewHorizons.Builder.Props;
|
using NewHorizons.Builder.Props;
|
||||||
using NewHorizons.Components;
|
using NewHorizons.Components;
|
||||||
using NewHorizons.External;
|
using NewHorizons.External;
|
||||||
@ -268,6 +269,8 @@ namespace NewHorizons
|
|||||||
|
|
||||||
NewHorizonsData.Load();
|
NewHorizonsData.Load();
|
||||||
SignalBuilder.Init();
|
SignalBuilder.Init();
|
||||||
|
BrambleDimensionBuilder.Init();
|
||||||
|
BrambleNodeBuilder.Init();
|
||||||
AstroObjectLocator.Init();
|
AstroObjectLocator.Init();
|
||||||
OWAssetHandler.Init();
|
OWAssetHandler.Init();
|
||||||
PlanetCreationHandler.Init(BodyDict[CurrentStarSystem]);
|
PlanetCreationHandler.Init(BodyDict[CurrentStarSystem]);
|
||||||
@ -485,7 +488,8 @@ namespace NewHorizons
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Has to happen after we make sure theres a system config
|
// Has to happen after we make sure theres a system config
|
||||||
config.MigrateAndValidate();
|
config.Validate();
|
||||||
|
config.Migrate();
|
||||||
|
|
||||||
body = new NewHorizonsBody(config, mod, relativePath);
|
body = new NewHorizonsBody(config, mod, relativePath);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,10 @@
|
|||||||
"description": "Base Properties of this Body",
|
"description": "Base Properties of this Body",
|
||||||
"$ref": "#/definitions/BaseModule"
|
"$ref": "#/definitions/BaseModule"
|
||||||
},
|
},
|
||||||
|
"Bramble": {
|
||||||
|
"description": "Add bramble nodes to this planet and/or make this planet a bramble dimension",
|
||||||
|
"$ref": "#/definitions/BrambleModule"
|
||||||
|
},
|
||||||
"buildPriority": {
|
"buildPriority": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"description": "Set to a higher number if you wish for this body to be built sooner",
|
"description": "Set to a higher number if you wish for this body to be built sooner",
|
||||||
@ -484,6 +488,72 @@
|
|||||||
"inverseSquared"
|
"inverseSquared"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"BrambleModule": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"dimension": {
|
||||||
|
"description": "Defining this value will make this body a bramble dimension. Leave it null to not do that.",
|
||||||
|
"$ref": "#/definitions/BrambleDimensionInfo"
|
||||||
|
},
|
||||||
|
"nodes": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Place nodes/seeds that take you to other bramble dimensions",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/BrambleNodeInfo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"BrambleDimensionInfo": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"fogTint": {
|
||||||
|
"description": "The color of the fog inside this dimension. Leave blank for the default yellowish color",
|
||||||
|
"$ref": "#/definitions/MColor"
|
||||||
|
},
|
||||||
|
"linksTo": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The name of the *node* that the player is taken to when exiting this dimension."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"BrambleNodeInfo": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"position": {
|
||||||
|
"description": "The physical position of the node",
|
||||||
|
"$ref": "#/definitions/MVector3"
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"description": "The physical rotation of the node",
|
||||||
|
"$ref": "#/definitions/MVector3"
|
||||||
|
},
|
||||||
|
"linksTo": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The name of the planet that hosts the dimension this node links to"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The name of this node. Only required if this node should serve as an exit."
|
||||||
|
},
|
||||||
|
"isSeed": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Set this to true to make this node a seed instead of a node the player can enter",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"fogTint": {
|
||||||
|
"description": "The color of the fog inside the node. Leave blank for the default yellowish color (default: 131, 124, 105, 255)",
|
||||||
|
"$ref": "#/definitions/MColor"
|
||||||
|
},
|
||||||
|
"lightTint": {
|
||||||
|
"description": "The color of the shafts of light coming from the entrances to the node. Leave blank for the default yellowish color",
|
||||||
|
"$ref": "#/definitions/MColor"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"CloakModule": {
|
"CloakModule": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
@ -630,6 +700,10 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"staticPosition": {
|
||||||
|
"description": "Specify this if you want the body to remain stationary at a given location (ie not orbit its parent). Required for Bramble dimensions",
|
||||||
|
"$ref": "#/definitions/MVector3"
|
||||||
|
},
|
||||||
"primaryBody": {
|
"primaryBody": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The name of the body this one will orbit around"
|
"description": "The name of the body this one will orbit around"
|
||||||
|
|||||||
@ -142,7 +142,7 @@ namespace NewHorizons.Utility.DebugMenu
|
|||||||
Vector3 latestPropSphericalPosDelta = VectorInput(mostRecentlyPlacedPropSphericalPos, propSphericalPosDelta, out propSphericalPosDelta, "lat ", "lon ", "height");
|
Vector3 latestPropSphericalPosDelta = VectorInput(mostRecentlyPlacedPropSphericalPos, propSphericalPosDelta, out propSphericalPosDelta, "lat ", "lon ", "height");
|
||||||
if (latestPropSphericalPosDelta != Vector3.zero)
|
if (latestPropSphericalPosDelta != Vector3.zero)
|
||||||
{
|
{
|
||||||
DeltaSphericalPosition(mostRecentlyPlacedProp, latestPropSphericalPosDelta);
|
SetSphericalPosition(mostRecentlyPlacedProp, mostRecentlyPlacedPropSphericalPos + latestPropSphericalPosDelta);
|
||||||
mostRecentlyPlacedPropSphericalPos = mostRecentlyPlacedPropSphericalPos + latestPropSphericalPosDelta;
|
mostRecentlyPlacedPropSphericalPos = mostRecentlyPlacedPropSphericalPos + latestPropSphericalPosDelta;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,6 +209,40 @@ namespace NewHorizons.Utility.DebugMenu
|
|||||||
return newSpherical;
|
return newSpherical;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DB_EscapePodDimension_Body/Sector_EscapePodDimension/Interactables_EscapePodDimension/InnerWarp_ToAnglerNest
|
||||||
|
// DB_ExitOnlyDimension_Body/Sector_ExitOnlyDimension/Interactables_ExitOnlyDimension/InnerWarp_ToExitOnly // need to change the colors
|
||||||
|
// DB_HubDimension_Body/Sector_HubDimension/Interactables_HubDimension/InnerWarp_ToCluster // need to delete the child "Signal_Harmonica"
|
||||||
|
|
||||||
|
private Vector3 SetSphericalPosition(GameObject prop, Vector3 newSpherical)
|
||||||
|
{
|
||||||
|
Transform astroObject = prop.transform.parent.parent;
|
||||||
|
Transform sector = prop.transform.parent;
|
||||||
|
Vector3 originalLocalPos = astroObject.InverseTransformPoint(prop.transform.position); // parent is the sector, this gives localPos relative to the astroobject (what the DetailBuilder asks for)
|
||||||
|
Vector3 sphericalPos = CoordinateUtilities.CartesianToSpherical(originalLocalPos);
|
||||||
|
|
||||||
|
if (newSpherical == sphericalPos) return sphericalPos;
|
||||||
|
|
||||||
|
Vector3 finalLocalPosition = CoordinateUtilities.SphericalToCartesian(newSpherical);
|
||||||
|
Vector3 finalAbsolutePosition = astroObject.TransformPoint(finalLocalPosition);
|
||||||
|
prop.transform.localPosition = prop.transform.parent.InverseTransformPoint(finalAbsolutePosition);
|
||||||
|
Logger.Log("new position: " + prop.transform.localPosition);
|
||||||
|
|
||||||
|
var onlyChangingRAndRIsNegative = false;
|
||||||
|
|
||||||
|
// first, rotate the object by the astroObject's rotation, that means anything afterwards is relative to this rotation (ie, we can pretend the astroObject has 0 rotation)
|
||||||
|
// then, rotate by the difference in position, basically accounting for the curvature of a sphere
|
||||||
|
// then re-apply the local rotations of the hierarchy down to the prop (apply the sector local rotation, then the prop local rotation)
|
||||||
|
|
||||||
|
// since we're doing all rotation relative to the astro object, we start with its absolute rotation
|
||||||
|
// then we apply the rotation about the astroobject using FromTooRotation
|
||||||
|
// then we reapply the local rotations down through the hierarchy
|
||||||
|
Vector3 originalLocalPos_ForcedPositiveR = CoordinateUtilities.SphericalToCartesian(new Vector3(sphericalPos.x, sphericalPos.y, Mathf.Abs(sphericalPos.z)));
|
||||||
|
Vector3 finalLocalPos_ForcedPositiveR = CoordinateUtilities.SphericalToCartesian(new Vector3(newSpherical.x, newSpherical.y, Mathf.Abs(newSpherical.z)));
|
||||||
|
if (!onlyChangingRAndRIsNegative) prop.transform.rotation = astroObject.rotation * Quaternion.FromToRotation(originalLocalPos_ForcedPositiveR.normalized, finalLocalPos_ForcedPositiveR.normalized) * sector.localRotation * prop.transform.localRotation;
|
||||||
|
|
||||||
|
return newSpherical;
|
||||||
|
}
|
||||||
|
|
||||||
private Vector3 VectorInput(Vector3 input, Vector3 deltaControls, out Vector3 deltaControlsOut, string labelX, string labelY, string labelZ)
|
private Vector3 VectorInput(Vector3 input, Vector3 deltaControls, out Vector3 deltaControlsOut, string labelX, string labelY, string labelZ)
|
||||||
{
|
{
|
||||||
var dx = deltaControls.x;
|
var dx = deltaControls.x;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user