diff --git a/NewHorizons/Builder/Props/DetailBuilder.cs b/NewHorizons/Builder/Props/DetailBuilder.cs
index 18805836..fa460991 100644
--- a/NewHorizons/Builder/Props/DetailBuilder.cs
+++ b/NewHorizons/Builder/Props/DetailBuilder.cs
@@ -148,7 +148,7 @@ namespace NewHorizons.Builder.Props
///
///
///
- private static void FixSectoredComponent(Component component, Sector sector, bool isTorch)
+ private static void FixSectoredComponent(Component component, Sector sector, bool isTorch = false)
{
if (component is Sector s)
{
@@ -181,6 +181,11 @@ namespace NewHorizons.Builder.Props
{
sector.OnOccupantEnterSector.AddListener(_ => container.LoadStreamingTextures());
}
+
+ if (component is NomaiRemoteCameraPlatform remoteCameraPlatform)
+ {
+ remoteCameraPlatform._visualSector = sector;
+ }
}
///
diff --git a/NewHorizons/Builder/Props/PropBuildManager.cs b/NewHorizons/Builder/Props/PropBuildManager.cs
index 795b27c1..d90e1776 100644
--- a/NewHorizons/Builder/Props/PropBuildManager.cs
+++ b/NewHorizons/Builder/Props/PropBuildManager.cs
@@ -181,7 +181,7 @@ namespace NewHorizons.Builder.Props
{
if (!propsByGroup.ContainsKey(quantumGroup.id)) continue;
var propsInGroup = propsByGroup[quantumGroup.id];
-
+
try
{
QuantumBuilder.Make(go, sector, config, mod, quantumGroup, propsInGroup.ToArray());
@@ -220,6 +220,20 @@ namespace NewHorizons.Builder.Props
SignalBuilder.Make(go, sector, signal, mod);
}
}
+ if (config.Props.remotes != null)
+ {
+ foreach (var remoteInfo in config.Props.remotes)
+ {
+ try
+ {
+ RemoteBuilder.Make(go, sector, remoteInfo, mod);
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError($"Couldn't make remote [{remoteInfo.id}] for [{go.name}]:\n{ex}");
+ }
+ }
+ }
}
}
}
diff --git a/NewHorizons/Builder/Props/RemoteBuilder.cs b/NewHorizons/Builder/Props/RemoteBuilder.cs
new file mode 100644
index 00000000..f9ebf08b
--- /dev/null
+++ b/NewHorizons/Builder/Props/RemoteBuilder.cs
@@ -0,0 +1,294 @@
+using NewHorizons.External.Modules;
+using NewHorizons.Handlers;
+using NewHorizons.Utility;
+using OWML.Common;
+using System;
+using System.Linq;
+using UnityEngine;
+using Logger = NewHorizons.Utility.Logger;
+
+namespace NewHorizons.Builder.Props
+{
+ public static class RemoteBuilder
+ {
+ private static Material _decalMaterial;
+ private static Material _decalMaterialGold;
+ private static GameObject _remoteCameraPlatformPrefab;
+ private static GameObject _whiteboardPrefab;
+ private static GameObject _shareStonePrefab;
+
+ private static void InitPrefabs()
+ {
+ _decalMaterial = new Material(Shader.Find("Standard (Decal)"));
+ _decalMaterial.name = "Decal";
+ _decalMaterial.SetTexture("_MainTex", Texture2D.whiteTexture);
+ _decalMaterial.SetTexture("_EmissionMap", Texture2D.whiteTexture);
+ _decalMaterial.SetFloat("_Glossiness", 0);
+ _decalMaterial.SetFloat("_BumpScale", 0);
+ _decalMaterial.SetColor("_Color", new Color(0.3529412f, 0.3843137f, 1));
+ _decalMaterial.SetColor("_EmissionColor", new Color(0.2422811f, 0.2917706f, 2.440062f));
+ _decalMaterialGold = new Material(_decalMaterial);
+ _decalMaterialGold.name = "DecalGold";
+ _decalMaterialGold.SetColor("_Color", new Color(1, 0.6392157f, 0.3803922f));
+ _decalMaterialGold.SetColor("_EmissionColor", new Color(1, 0.3662527f, 0.1195384f));
+
+ _remoteCameraPlatformPrefab = SearchUtilities.Find("OrbitalProbeCannon_Body/Sector_OrbitalProbeCannon/Sector_Module_Broken/Interactables_Module_Broken/Prefab_NOM_RemoteViewer").InstantiateInactive();
+ _remoteCameraPlatformPrefab.name = "Prefab_NOM_RemoteViewer";
+ var remoteCameraPlatform = _remoteCameraPlatformPrefab.GetComponent();
+ remoteCameraPlatform.enabled = true;
+ remoteCameraPlatform._id = NomaiRemoteCameraPlatform.ID.None;
+ var AstroBodySymbolRenderer = _remoteCameraPlatformPrefab.FindChild("PedestalAnchor/Prefab_NOM_SharedPedestal/SharedPedestal_side01_bottom_jnt/SharedPedestal_side01_top_jnt/AstroBodySymbolRenderer");
+ var quad = GameObject.CreatePrimitive(PrimitiveType.Quad);
+ quad.transform.parent = AstroBodySymbolRenderer.transform.parent;
+ quad.transform.localPosition = AstroBodySymbolRenderer.transform.localPosition;
+ quad.transform.localRotation = AstroBodySymbolRenderer.transform.localRotation;
+ quad.transform.localScale = AstroBodySymbolRenderer.transform.localScale;
+ quad.AddComponent();
+ quad.GetComponent().sharedMaterial = _decalMaterial;
+ quad.name = "AstroBodySymbolRenderer";
+ GameObject.DestroyImmediate(AstroBodySymbolRenderer);
+
+ _whiteboardPrefab = SearchUtilities.Find("OrbitalProbeCannon_Body/Sector_OrbitalProbeCannon/Sector_Module_Broken/Interactables_Module_Broken/Prefab_NOM_Whiteboard_Shared").InstantiateInactive();
+ _whiteboardPrefab.name = "Prefab_NOM_Whiteboard_Shared";
+ var whiteboard = _whiteboardPrefab.GetComponent();
+ whiteboard.enabled = true;
+ whiteboard._id = NomaiRemoteCameraPlatform.ID.None;
+ _whiteboardPrefab.FindChild("ArcSocket").transform.DestroyAllChildrenImmediate();
+ whiteboard._remoteIDs = new NomaiRemoteCameraPlatform.ID[0];
+ whiteboard._nomaiTexts = new NomaiWallText[0];
+ var AstroBodySymbolRendererW = _whiteboardPrefab.FindChild("PedestalAnchor/Prefab_NOM_SharedPedestal/SharedPedestal_side01_bottom_jnt/SharedPedestal_side01_top_jnt/AstroBodySymbolRenderer");
+ var quadW = GameObject.CreatePrimitive(PrimitiveType.Quad);
+ quadW.transform.parent = AstroBodySymbolRendererW.transform.parent;
+ quadW.transform.localPosition = AstroBodySymbolRendererW.transform.localPosition;
+ quadW.transform.localRotation = AstroBodySymbolRendererW.transform.localRotation;
+ quadW.transform.localScale = AstroBodySymbolRendererW.transform.localScale;
+ quadW.AddComponent();
+ quadW.GetComponent().sharedMaterial = _decalMaterial;
+ quadW.name = "AstroBodySymbolRenderer";
+ GameObject.DestroyImmediate(AstroBodySymbolRendererW);
+
+ GameObject stone = new GameObject("ShareStoneFallback");
+ stone.SetActive(false);
+ SphereCollider sc = stone.AddComponent();
+ sc.center = Vector3.zero;
+ sc.radius = 0.4f;
+ sc.isTrigger = false;
+ OWCollider owc = stone.AddComponent();
+ owc._collider = sc;
+ SharedStone item = stone.AddComponent();
+ item._connectedPlatform = NomaiRemoteCameraPlatform.ID.None;
+ item._animDuration = 0.4f;
+ item._animOffsetY = 0.08f;
+ GameObject animRoot = new GameObject("AnimRoot");
+ animRoot.transform.parent = stone.transform;
+ TransformAnimator transformAnimator = animRoot.AddComponent();
+ item._animator = transformAnimator;
+ OWRenderer renderer = SearchUtilities.FindResourceOfTypeAndName("Props_NOM_SharedStone");
+ if (renderer != null) GameObject.Instantiate(renderer.gameObject, animRoot.transform);
+ GameObject planetDecal = GameObject.CreatePrimitive(PrimitiveType.Quad);
+ planetDecal.name = "PlanetDecal";
+ planetDecal.transform.parent = animRoot.transform;
+ planetDecal.transform.localPosition = new Vector3(0, 0.053f, 0);
+ planetDecal.transform.localEulerAngles = new Vector3(90, 0, 0);
+ planetDecal.transform.localScale = new Vector3(0.4f, 0.4f, 0.4f);
+ planetDecal.AddComponent();
+ planetDecal.GetComponent().sharedMaterial = _decalMaterialGold;
+ _shareStonePrefab = stone;
+ }
+
+ public static void Make(GameObject go, Sector sector, PropModule.RemoteInfo info, IModBehaviour mod)
+ {
+ if (_shareStonePrefab == null) InitPrefabs();
+
+ var id = RemoteHandler.GetPlatformID(info.id);
+
+ var decal = ImageUtilities.GetTexture(mod, info.decalPath, false, false);
+
+ if (info.platform != null)
+ {
+ try
+ {
+ RemoteBuilder.MakePlatform(go, sector, id, decal, info.platform, mod);
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError($"Couldn't make remote platform [{info.id}] for [{go.name}]:\n{ex}");
+ }
+ }
+
+ if (info.whiteboard != null)
+ {
+ try
+ {
+ RemoteBuilder.MakeWhiteboard(go, sector, id, decal, info.whiteboard, mod);
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError($"Couldn't make remote whiteboard [{info.id}] for [{go.name}]:\n{ex}");
+ }
+ }
+
+ if (info.stones != null)
+ {
+ foreach (var stoneInfo in info.stones)
+ {
+ try
+ {
+ RemoteBuilder.MakeStone(go, sector, id, decal, stoneInfo, mod);
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError($"Couldn't make remote stone [{info.id}] for [{go.name}]:\n{ex}");
+ }
+ }
+ }
+ }
+
+ public static void MakeWhiteboard(GameObject go, Sector sector, NomaiRemoteCameraPlatform.ID id, Texture2D decal, PropModule.RemoteInfo.WhiteboardInfo info, IModBehaviour mod)
+ {
+ var detailInfo = new PropModule.DetailInfo()
+ {
+ position = info.position,
+ rotation = info.rotation
+ };
+ var whiteboard = DetailBuilder.MakeDetail(go, sector, _whiteboardPrefab, detailInfo);
+ whiteboard.SetActive(false);
+
+ if (!string.IsNullOrEmpty(info.rename))
+ {
+ whiteboard.name = info.rename;
+ }
+
+ whiteboard.transform.parent = sector?.transform ?? go.transform;
+
+ if (!string.IsNullOrEmpty(info.parentPath))
+ {
+ var newParent = go.transform.Find(info.parentPath);
+ if (newParent != null)
+ {
+ whiteboard.transform.parent = newParent;
+ }
+ else
+ {
+ Logger.LogWarning($"Cannot find parent object at path: {go.name}/{info.parentPath}");
+ }
+ }
+
+ var decalMat = new Material(_decalMaterial);
+ decalMat.SetTexture("_MainTex", decal);
+ decalMat.SetTexture("_EmissionMap", decal);
+ whiteboard.FindChild("PedestalAnchor/Prefab_NOM_SharedPedestal/SharedPedestal_side01_bottom_jnt/SharedPedestal_side01_top_jnt/AstroBodySymbolRenderer").GetComponent().sharedMaterial = decalMat;
+
+ var component = whiteboard.GetComponent();
+ component._id = id;
+
+ component._remoteIDs = new NomaiRemoteCameraPlatform.ID[info.nomaiText.Length];
+ component._nomaiTexts = new NomaiWallText[info.nomaiText.Length];
+ for (int i = 0; i < info.nomaiText.Length; i++)
+ {
+ var textInfo = info.nomaiText[i];
+ component._remoteIDs[i] = RemoteHandler.GetPlatformID(textInfo.id);
+ var wallText = NomaiTextBuilder.Make(whiteboard, sector, new PropModule.NomaiTextInfo
+ {
+ arcInfo = textInfo.arcInfo,
+ location = textInfo.location,
+ parentPath = "ArcSocket",
+ position = new MVector3(0, 1, 0),
+ rename = textInfo.rename,
+ rotation = Vector3.zero,
+ seed = textInfo.seed,
+ type = PropModule.NomaiTextInfo.NomaiTextType.Wall,
+ xmlFile = textInfo.xmlFile
+ }, mod).GetComponent();
+ wallText._showTextOnStart = false;
+ component._nomaiTexts[i] = wallText;
+ }
+
+ whiteboard.SetActive(true);
+ }
+
+ public static void MakePlatform(GameObject go, Sector sector, NomaiRemoteCameraPlatform.ID id, Texture2D decal, PropModule.RemoteInfo.PlatformInfo info, IModBehaviour mod)
+ {
+ var detailInfo = new PropModule.DetailInfo()
+ {
+ position = info.position,
+ rotation = info.rotation
+ };
+ var platform = DetailBuilder.MakeDetail(go, sector, _remoteCameraPlatformPrefab, detailInfo);
+ platform.SetActive(false);
+
+ if (!string.IsNullOrEmpty(info.rename))
+ {
+ platform.name = info.rename;
+ }
+
+ platform.transform.parent = sector?.transform ?? go.transform;
+
+ if (!string.IsNullOrEmpty(info.parentPath))
+ {
+ var newParent = go.transform.Find(info.parentPath);
+ if (newParent != null)
+ {
+ platform.transform.parent = newParent;
+ }
+ else
+ {
+ Logger.LogWarning($"Cannot find parent object at path: {go.name}/{info.parentPath}");
+ }
+ }
+
+ var decalMat = new Material(_decalMaterial);
+ decalMat.SetTexture("_MainTex", decal);
+ decalMat.SetTexture("_EmissionMap", decal);
+ platform.FindChild("PedestalAnchor/Prefab_NOM_SharedPedestal/SharedPedestal_side01_bottom_jnt/SharedPedestal_side01_top_jnt/AstroBodySymbolRenderer").GetComponent().sharedMaterial = decalMat;
+
+ var component = platform.GetComponent();
+ component._id = id;
+ component._visualSector = sector;
+ component._dataPointID = info.reveals;
+
+ platform.SetActive(true);
+ }
+
+ public static void MakeStone(GameObject go, Sector sector, NomaiRemoteCameraPlatform.ID id, Texture2D decal, PropModule.RemoteInfo.StoneInfo info, IModBehaviour mod)
+ {
+ var shareStone = _shareStonePrefab.InstantiateInactive();
+
+ if (!string.IsNullOrEmpty(info.rename))
+ {
+ shareStone.name = info.rename;
+ }
+ else
+ {
+ shareStone.name = "ShareStone_" + id.ToString();
+ }
+
+ shareStone.transform.parent = sector?.transform ?? go.transform;
+
+ if (!string.IsNullOrEmpty(info.parentPath))
+ {
+ var newParent = go.transform.Find(info.parentPath);
+ if (newParent != null)
+ {
+ shareStone.transform.parent = newParent;
+ }
+ else
+ {
+ Logger.LogWarning($"Cannot find parent object at path: {go.name}/{info.parentPath}");
+ }
+ }
+
+ shareStone.transform.position = go.transform.TransformPoint((Vector3)(info.position ?? Vector3.zero));
+ shareStone.transform.rotation = go.transform.TransformRotation(Quaternion.Euler((Vector3)(info.rotation ?? Vector3.zero)));
+
+ shareStone.GetComponent()._connectedPlatform = id;
+
+ var decalMat = new Material(_decalMaterialGold);
+ decalMat.SetTexture("_MainTex", decal);
+ decalMat.SetTexture("_EmissionMap", decal);
+ shareStone.FindChild("AnimRoot/PlanetDecal").GetComponent().sharedMaterial = decalMat;
+
+ shareStone.SetActive(true);
+ }
+ }
+}
diff --git a/NewHorizons/External/Modules/PropModule.cs b/NewHorizons/External/Modules/PropModule.cs
index b463f554..0005cd54 100644
--- a/NewHorizons/External/Modules/PropModule.cs
+++ b/NewHorizons/External/Modules/PropModule.cs
@@ -62,7 +62,7 @@ namespace NewHorizons.External.Modules
/// Add slideshows (from the DLC) to the planet
///
public ProjectionInfo[] slideShows;
-
+
///
/// A list of quantum groups that props can be added to. An example of a group would be a list of possible locations for a QuantumSocketedObject.
///
@@ -93,6 +93,11 @@ namespace NewHorizons.External.Modules
///
public SignalModule.SignalInfo[] signals;
+ ///
+ /// Add projection pools/platforms, whiteboards, and stones to this planet
+ ///
+ public RemoteInfo[] remotes;
+
[JsonObject]
public class ScatterInfo
{
@@ -547,7 +552,6 @@ namespace NewHorizons.External.Modules
/// An optional rename of this object
///
public string rename;
-
}
[JsonObject]
@@ -596,7 +600,7 @@ namespace NewHorizons.External.Modules
public enum SlideShowType
{
[EnumMember(Value = @"slideReel")] SlideReel = 0,
-
+
[EnumMember(Value = @"autoProjector")] AutoProjector = 1,
[EnumMember(Value = @"visionTorchTarget")] VisionTorchTarget = 2,
@@ -717,8 +721,8 @@ namespace NewHorizons.External.Modules
}
-
-
+
+
[JsonConverter(typeof(StringEnumConverter))]
public enum QuantumGroupType
{
@@ -728,24 +732,24 @@ namespace NewHorizons.External.Modules
FailedValidation = 10
}
-
+
[JsonObject]
- public class QuantumGroupInfo
- {
+ public class QuantumGroupInfo
+ {
///
/// What type of group this is: does it define a list of states a single quantum object could take or a list of sockets one or more quantum objects could share?
///
- public QuantumGroupType type;
+ public QuantumGroupType type;
///
/// A unique string used by props (that are marked as quantum) use to refer back to this group
///
- public string id;
+ public string id;
///
/// Only required if type is `sockets`. This lists all the possible locations for any props assigned to this group.
///
- public QuantumSocketInfo[] sockets;
+ public QuantumSocketInfo[] sockets;
///
/// Optional. Only used if type is `states`. If this is true, then the first prop made part of this group will be used to construct a visibility box for an empty game object, which will be considered one of the states.
@@ -762,24 +766,24 @@ namespace NewHorizons.External.Modules
///
[DefaultValue(true)] public bool loop = true;
}
-
+
[JsonObject]
- public class QuantumSocketInfo
- {
+ public class QuantumSocketInfo
+ {
///
/// The location of this socket
///
- public MVector3 position;
+ public MVector3 position;
///
/// The rotation the quantum object will take if it's occupying this socket
///
- public MVector3 rotation;
+ public MVector3 rotation;
///
/// The probability any props that are part of this group will occupy this socket
///
- [DefaultValue(1f)] public float probability = 1f;
+ [DefaultValue(1f)] public float probability = 1f;
}
[JsonObject]
@@ -805,6 +809,151 @@ namespace NewHorizons.External.Modules
///
[DefaultValue("environment")] public AudioMixerTrackName track = AudioMixerTrackName.Environment;
}
+
+ [JsonObject]
+ public class RemoteInfo
+ {
+ ///
+ /// The unique remote id
+ ///
+ public string id;
+
+ ///
+ /// Icon that the will show on the stone, pedastal of the whiteboard, and pedastal of the platform.
+ ///
+ public string decalPath;
+
+ ///
+ /// whiteboard that the stones can put text onto
+ ///
+ public WhiteboardInfo whiteboard;
+
+ ///
+ /// camera platform that the stones can project to
+ ///
+ public PlatformInfo platform;
+
+ ///
+ /// projection stones
+ ///
+ public StoneInfo[] stones;
+
+ [JsonObject]
+ public class WhiteboardInfo
+ {
+ ///
+ /// The text for each stone
+ ///
+ public SharedNomaiTextInfo[] nomaiText;
+
+ ///
+ /// The location of this platform.
+ ///
+ public MVector3 position;
+
+ ///
+ /// The rotation of this platform.
+ ///
+ public MVector3 rotation;
+
+ ///
+ /// The relative path from the planet to the parent of this object. Optional (will default to the root sector).
+ ///
+ public string parentPath;
+
+ ///
+ /// An optional rename of this object
+ ///
+ public string rename;
+
+ [JsonObject]
+ public class SharedNomaiTextInfo
+ {
+ ///
+ /// The id of the stone this text will appear for
+ ///
+ public string id;
+
+ ///
+ /// Additional information about each arc in the text
+ ///
+ public NomaiTextArcInfo[] arcInfo;
+
+ ///
+ /// The random seed used to pick what the text arcs will look like.
+ ///
+ public int seed; // For randomizing arcs
+
+ ///
+ /// The location of this object.
+ ///
+ [DefaultValue("unspecified")] public NomaiTextInfo.NomaiTextLocation location = NomaiTextInfo.NomaiTextLocation.UNSPECIFIED;
+
+ ///
+ /// The relative path to the xml file for this object.
+ ///
+ public string xmlFile;
+
+ ///
+ /// An optional rename of this object
+ ///
+ public string rename;
+ }
+ }
+
+ [JsonObject]
+ public class PlatformInfo
+ {
+ ///
+ /// The location of this platform.
+ ///
+ public MVector3 position;
+
+ ///
+ /// The rotation of this platform.
+ ///
+ public MVector3 rotation;
+
+ ///
+ /// The relative path from the planet to the parent of this object. Optional (will default to the root sector).
+ ///
+ public string parentPath;
+
+ ///
+ /// An optional rename of this object
+ ///
+ public string rename;
+
+ ///
+ /// A ship log fact to reveal when the platform is connected to.
+ ///
+ [DefaultValue("")] public string reveals = "";
+ }
+
+ [JsonObject]
+ public class StoneInfo
+ {
+ ///
+ /// The location of this stone.
+ ///
+ public MVector3 position;
+
+ ///
+ /// The rotation of this stone.
+ ///
+ public MVector3 rotation;
+
+ ///
+ /// The relative path from the planet to the parent of this object. Optional (will default to the root sector).
+ ///
+ public string parentPath;
+
+ ///
+ /// An optional rename of this object
+ ///
+ public string rename;
+ }
+ }
}
[JsonConverter(typeof(StringEnumConverter))]
diff --git a/NewHorizons/Handlers/RemoteHandler.cs b/NewHorizons/Handlers/RemoteHandler.cs
new file mode 100644
index 00000000..6b9311c9
--- /dev/null
+++ b/NewHorizons/Handlers/RemoteHandler.cs
@@ -0,0 +1,62 @@
+using NewHorizons.Utility;
+using OWML.Common;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using Logger = NewHorizons.Utility.Logger;
+
+namespace NewHorizons.Handlers
+{
+ public static class RemoteHandler
+ {
+ private static Dictionary _customPlatformIDs;
+ private static readonly int _startingInt = 19;
+
+ public static void Init()
+ {
+ _customPlatformIDs = new Dictionary();
+ }
+
+ public static string GetPlatformIDName(NomaiRemoteCameraPlatform.ID id)
+ {
+ foreach (var pair in _customPlatformIDs)
+ {
+ if (pair.Value == id) return TranslationHandler.GetTranslation(pair.Key, TranslationHandler.TextType.UI);
+ }
+ return string.Empty;
+ }
+
+ public static NomaiRemoteCameraPlatform.ID GetPlatformID(string id)
+ {
+ try
+ {
+ NomaiRemoteCameraPlatform.ID platformID;
+ if (_customPlatformIDs.TryGetValue(id, out platformID) || Enum.TryParse(id, true, out platformID))
+ {
+ return platformID;
+ }
+ else
+ {
+ return AddCustomPlatformID(id);
+ }
+ }
+ catch (Exception e)
+ {
+ Logger.LogError($"Couldn't load platform id:\n{e}");
+ return NomaiRemoteCameraPlatform.ID.None;
+ }
+ }
+
+ public static NomaiRemoteCameraPlatform.ID AddCustomPlatformID(string id)
+ {
+ var platformID = (NomaiRemoteCameraPlatform.ID)_startingInt + _customPlatformIDs.Count();
+
+ Logger.LogVerbose($"Registering custom platform id {id} as {platformID}");
+
+ _customPlatformIDs.Add(id, platformID);
+
+ return platformID;
+ }
+ }
+}
diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs
index 9ec4dc65..07495389 100644
--- a/NewHorizons/Main.cs
+++ b/NewHorizons/Main.cs
@@ -296,6 +296,7 @@ namespace NewHorizons
AstroObjectLocator.Init();
StreamingHandler.Init();
AudioTypeHandler.Init();
+ RemoteHandler.Init();
AtmosphereBuilder.Init();
BrambleNodeBuilder.Init(BodyDict[CurrentStarSystem].Select(x => x.Config).Where(x => x.Bramble?.dimension != null).ToArray());
@@ -330,6 +331,9 @@ namespace NewHorizons
// Fix the map satellite
SearchUtilities.Find("HearthianMapSatellite_Body", false).AddComponent();
+
+ // Sector changes (so that projection pools actually turn off proxies and cull groups on these moons)
+
//Fix attlerock vanilla sector components (they were set to timber hearth's sector)
var thm = SearchUtilities.Find("Moon_Body/Sector_THM").GetComponent();
foreach (var component in thm.GetComponentsInChildren(true))
diff --git a/NewHorizons/Patches/RemotePatches.cs b/NewHorizons/Patches/RemotePatches.cs
new file mode 100644
index 00000000..1e7b90ea
--- /dev/null
+++ b/NewHorizons/Patches/RemotePatches.cs
@@ -0,0 +1,66 @@
+using HarmonyLib;
+using NewHorizons.Components;
+using NewHorizons.Handlers;
+using UnityEngine;
+
+namespace NewHorizons.Patches
+{
+ [HarmonyPatch]
+ public class RemotePatches
+ {
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(NomaiRemoteCameraPlatform), nameof(NomaiRemoteCameraPlatform.IDToPlanetString))]
+ public static bool NomaiRemoteCameraPlatform_IDToPlanetString(NomaiRemoteCameraPlatform.ID id, out string __result)
+ {
+ switch (id)
+ {
+ case NomaiRemoteCameraPlatform.ID.None:
+ __result = "None";
+ break;
+ case NomaiRemoteCameraPlatform.ID.SunStation:
+ __result = UITextLibrary.GetString(UITextType.LocationSS);
+ break;
+ case NomaiRemoteCameraPlatform.ID.HGT_TimeLoop:
+ __result = UITextLibrary.GetString(UITextType.LocationTT);
+ break;
+ case NomaiRemoteCameraPlatform.ID.TH_Mine:
+ __result = UITextLibrary.GetString(UITextType.LocationTH);
+ break;
+ case NomaiRemoteCameraPlatform.ID.THM_EyeLocator:
+ __result = UITextLibrary.GetString(UITextType.LocationTHMoon);
+ break;
+ case NomaiRemoteCameraPlatform.ID.BH_Observatory:
+ case NomaiRemoteCameraPlatform.ID.BH_GravityCannon:
+ case NomaiRemoteCameraPlatform.ID.BH_QuantumFragment:
+ case NomaiRemoteCameraPlatform.ID.BH_BlackHoleForge:
+ case NomaiRemoteCameraPlatform.ID.BH_NorthPole:
+ __result = UITextLibrary.GetString(UITextType.LocationBH);
+ break;
+ case NomaiRemoteCameraPlatform.ID.GD_ConstructionYardIsland1:
+ case NomaiRemoteCameraPlatform.ID.GD_ConstructionYardIsland2:
+ case NomaiRemoteCameraPlatform.ID.GD_StatueIsland:
+ __result = UITextLibrary.GetString(UITextType.LocationGD);
+ break;
+ case NomaiRemoteCameraPlatform.ID.GD_ProbeCannonSunkenModule:
+ __result = UITextLibrary.GetString(UITextType.LocationOPC_Module3);
+ break;
+ case NomaiRemoteCameraPlatform.ID.GD_ProbeCannonDamagedModule:
+ __result = UITextLibrary.GetString(UITextType.LocationOPC_Module2);
+ break;
+ case NomaiRemoteCameraPlatform.ID.GD_ProbeCannonIntactModule:
+ __result = UITextLibrary.GetString(UITextType.LocationOPC_Module1);
+ break;
+ case NomaiRemoteCameraPlatform.ID.VM_Interior:
+ __result = UITextLibrary.GetString(UITextType.LocationBHMoon);
+ break;
+ case NomaiRemoteCameraPlatform.ID.HGT_TLE:
+ __result = UITextLibrary.GetString(UITextType.LocationCT);
+ break;
+ default:
+ __result = RemoteHandler.GetPlatformIDName(id);
+ break;
+ }
+ return false;
+ }
+ }
+}