diff --git a/NewHorizons/Builder/Body/BrambleDimensionBuilder.cs b/NewHorizons/Builder/Body/BrambleDimensionBuilder.cs index 5ef9764db..fcbd1f872 100644 --- a/NewHorizons/Builder/Body/BrambleDimensionBuilder.cs +++ b/NewHorizons/Builder/Body/BrambleDimensionBuilder.cs @@ -104,8 +104,7 @@ public static GameObject Make(NewHorizonsBody body, GameObject go, NHAstroObject default: geometryPrefab = _hubGeometry; break; } - var detailInfo = new PropModule.DetailInfo(); - var geometry = DetailBuilder.Make(go, sector, geometryPrefab, detailInfo); + var geometry = DetailBuilder.Make(go, sector, geometryPrefab, new PropModule.DetailInfo()); var exitWarps = _exitWarps.InstantiateInactive(); var repelVolume = _repelVolume.InstantiateInactive(); diff --git a/NewHorizons/Builder/Props/GeneralPropBuilder.cs b/NewHorizons/Builder/Props/GeneralPropBuilder.cs index eae23d74d..41a3319ec 100644 --- a/NewHorizons/Builder/Props/GeneralPropBuilder.cs +++ b/NewHorizons/Builder/Props/GeneralPropBuilder.cs @@ -1,11 +1,6 @@ using NewHorizons.External.Modules; using NewHorizons.Utility; using NewHorizons.Utility.OWUtilities; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using UnityEngine; using Logger = NewHorizons.Utility.Logger; diff --git a/NewHorizons/Builder/Props/NomaiTextBuilder.cs b/NewHorizons/Builder/Props/NomaiTextBuilder.cs index 5b8e91d43..19af1f49b 100644 --- a/NewHorizons/Builder/Props/NomaiTextBuilder.cs +++ b/NewHorizons/Builder/Props/NomaiTextBuilder.cs @@ -360,14 +360,7 @@ public static GameObject Make(GameObject planetGO, Sector sector, PropModule.Nom } case PropModule.NomaiTextType.PreCrashComputer: { - var detailInfo = new PropModule.DetailInfo() - { - position = info.position, - parentPath = info.parentPath, - isRelativeToParent = info.isRelativeToParent, - rename = info.rename - }; - var computerObject = DetailBuilder.Make(planetGO, sector, _preCrashComputerPrefab, detailInfo); + var computerObject = DetailBuilder.Make(planetGO, sector, _preCrashComputerPrefab, new PropModule.DetailInfo(info)); computerObject.SetActive(false); var up = computerObject.transform.position - planetGO.transform.position; @@ -487,14 +480,7 @@ public static GameObject Make(GameObject planetGO, Sector sector, PropModule.Nom case PropModule.NomaiTextType.Recorder: { var prefab = (info.type == PropModule.NomaiTextType.PreCrashRecorder ? _preCrashRecorderPrefab : _recorderPrefab); - var detailInfo = new PropModule.DetailInfo { - parentPath = info.parentPath, - rotation = info.rotation, - position = info.position, - isRelativeToParent = info.isRelativeToParent, - rename = info.rename - }; - var recorderObject = DetailBuilder.Make(planetGO, sector, prefab, detailInfo); + var recorderObject = DetailBuilder.Make(planetGO, sector, prefab, new PropModule.DetailInfo(info)); recorderObject.SetActive(false); if (info.rotation == null) diff --git a/NewHorizons/Builder/Props/ProjectionBuilder.cs b/NewHorizons/Builder/Props/ProjectionBuilder.cs index 19e1225ff..6bddf3036 100644 --- a/NewHorizons/Builder/Props/ProjectionBuilder.cs +++ b/NewHorizons/Builder/Props/ProjectionBuilder.cs @@ -202,16 +202,7 @@ public static GameObject MakeMindSlidesTarget(GameObject planetGO, Sector sector if (_visionTorchDetectorPrefab == null) return null; // spawn a trigger for the vision torch - var detailInfo = new PropModule.DetailInfo() - { - position = info.position, - rotation = info.rotation, - parentPath = info.parentPath, - isRelativeToParent = info.isRelativeToParent, - rename = !string.IsNullOrEmpty(info.rename) ? info.rename : "VisionStaffDetector", - scale = 2 - }; - var g = DetailBuilder.Make(planetGO, sector, _visionTorchDetectorPrefab, detailInfo); + var g = DetailBuilder.Make(planetGO, sector, _visionTorchDetectorPrefab, new DetailInfo(info) { scale = 2, rename = !string.IsNullOrEmpty(info.rename) ? info.rename : "VisionStaffDetector" }); if (g == null) { @@ -248,15 +239,7 @@ public static GameObject MakeStandingVisionTorch(GameObject planetGO, Sector sec if (_standingVisionTorchPrefab == null) return null; // Spawn the torch itself - var detailInfo = new PropModule.DetailInfo() - { - position = info.position, - rotation = info.rotation, - parentPath = info.parentPath, - isRelativeToParent = info.isRelativeToParent, - rename = info.rename - }; - var standingTorch = DetailBuilder.Make(planetGO, sector, _standingVisionTorchPrefab, detailInfo); + var standingTorch = DetailBuilder.Make(planetGO, sector, _standingVisionTorchPrefab, new DetailInfo(info)); if (standingTorch == null) { diff --git a/NewHorizons/Builder/Props/PropBuildManager.cs b/NewHorizons/Builder/Props/PropBuildManager.cs index 3b96432fb..7466c19cf 100644 --- a/NewHorizons/Builder/Props/PropBuildManager.cs +++ b/NewHorizons/Builder/Props/PropBuildManager.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; using UnityEngine; +using static NewHorizons.External.Modules.PropModule; using Logger = NewHorizons.Utility.Logger; namespace NewHorizons.Builder.Props { @@ -236,6 +237,34 @@ public static void Make(GameObject go, Sector sector, OWRigidbody planetBody, Ne } } } + if (config.Props.warpReceivers != null) + { + foreach (var warpReceiver in config.Props.warpReceivers) + { + try + { + WarpPadBuilder.Make(go, sector, warpReceiver); + } + catch (Exception ex) + { + Logger.LogError($"Couldn't make warp receiver [{warpReceiver.frequency}] for [{go.name}]:\n{ex}"); + } + } + } + if (config.Props.warpTransmitters != null) + { + foreach (var warpTransmitter in config.Props.warpTransmitters) + { + try + { + WarpPadBuilder.Make(go, sector, warpTransmitter); + } + catch (Exception ex) + { + Logger.LogError($"Couldn't make warp transmitter [{warpTransmitter.frequency}] for [{go.name}]:\n{ex}"); + } + } + } } } } diff --git a/NewHorizons/Builder/Props/RemoteBuilder.cs b/NewHorizons/Builder/Props/RemoteBuilder.cs index 4cd1e19db..98cf8534a 100644 --- a/NewHorizons/Builder/Props/RemoteBuilder.cs +++ b/NewHorizons/Builder/Props/RemoteBuilder.cs @@ -7,6 +7,7 @@ using System; using System.Linq; using UnityEngine; +using static NewHorizons.External.Modules.PropModule; using Logger = NewHorizons.Utility.Logger; namespace NewHorizons.Builder.Props @@ -171,15 +172,7 @@ public static void Make(GameObject go, Sector sector, PropModule.RemoteInfo info public static void MakeWhiteboard(GameObject go, Sector sector, NomaiRemoteCameraPlatform.ID id, Texture2D decal, PropModule.RemoteInfo.WhiteboardInfo info, NewHorizonsBody nhBody) { - var detailInfo = new PropModule.DetailInfo() - { - position = info.position, - rotation = info.rotation, - parentPath = info.parentPath, - isRelativeToParent = info.isRelativeToParent, - rename = info.rename - }; - var whiteboard = DetailBuilder.Make(go, sector, _whiteboardPrefab, detailInfo); + var whiteboard = DetailBuilder.Make(go, sector, _whiteboardPrefab, new DetailInfo(info)); whiteboard.SetActive(false); var decalMat = new Material(_decalMaterial); @@ -196,7 +189,7 @@ public static void MakeWhiteboard(GameObject go, Sector sector, NomaiRemoteCamer { var textInfo = info.nomaiText[i]; component._remoteIDs[i] = RemoteHandler.GetPlatformID(textInfo.id); - var wallText = TranslatorTextBuilder.Make(whiteboard, sector, new PropModule.TranslatorTextInfo + var wallText = TranslatorTextBuilder.Make(whiteboard, sector, new TranslatorTextInfo { arcInfo = textInfo.arcInfo, location = textInfo.location, @@ -205,7 +198,7 @@ public static void MakeWhiteboard(GameObject go, Sector sector, NomaiRemoteCamer rename = textInfo.rename, rotation = Vector3.zero, seed = textInfo.seed, - type = PropModule.NomaiTextType.Wall, + type = NomaiTextType.Wall, xmlFile = textInfo.xmlFile }, nhBody).GetComponent(); wallText._showTextOnStart = false; @@ -219,15 +212,7 @@ public static void MakeWhiteboard(GameObject go, Sector sector, NomaiRemoteCamer 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, - parentPath = info.parentPath, - isRelativeToParent = info.isRelativeToParent, - rename = info.rename - }; - var platform = DetailBuilder.Make(go, sector, _remoteCameraPlatformPrefab, detailInfo); + var platform = DetailBuilder.Make(go, sector, _remoteCameraPlatformPrefab, new DetailInfo(info)); platform.SetActive(false); var decalMat = new Material(_decalMaterial); diff --git a/NewHorizons/Builder/Props/TranslatorText/TranslatorTextBuilder.cs b/NewHorizons/Builder/Props/TranslatorText/TranslatorTextBuilder.cs index 972bc8436..2c096bd86 100644 --- a/NewHorizons/Builder/Props/TranslatorText/TranslatorTextBuilder.cs +++ b/NewHorizons/Builder/Props/TranslatorText/TranslatorTextBuilder.cs @@ -22,7 +22,7 @@ public static class TranslatorTextBuilder private static Material _adultArcMaterial; private static Material _childArcMaterial; private static GameObject _scrollPrefab; - private static GameObject _computerPrefab; + public static GameObject ComputerPrefab { get; private set; } private static GameObject _preCrashComputerPrefab; private static GameObject _cairnPrefab; private static GameObject _cairnVariantPrefab; @@ -80,9 +80,9 @@ internal static void InitPrefabs() _scrollPrefab = SearchUtilities.Find("BrittleHollow_Body/Sector_BH/Sector_NorthHemisphere/Sector_NorthPole/Sector_HangingCity/Sector_HangingCity_District2/Interactables_HangingCity_District2/Prefab_NOM_Scroll").InstantiateInactive().Rename("Prefab_NOM_Scroll").DontDestroyOnLoad(); } - if (_computerPrefab == null) + if (ComputerPrefab == null) { - _computerPrefab = SearchUtilities.Find("VolcanicMoon_Body/Sector_VM/Interactables_VM/Prefab_NOM_Computer").InstantiateInactive().Rename("Prefab_NOM_Computer").DontDestroyOnLoad(); + ComputerPrefab = SearchUtilities.Find("VolcanicMoon_Body/Sector_VM/Interactables_VM/Prefab_NOM_Computer").InstantiateInactive().Rename("Prefab_NOM_Computer").DontDestroyOnLoad(); } if (_preCrashComputerPrefab == null) @@ -208,7 +208,7 @@ public static GameObject Make(GameObject planetGO, Sector sector, PropModule.Tra } case PropModule.NomaiTextType.Computer: { - var computerObject = GeneralPropBuilder.MakeFromPrefab(_computerPrefab, _computerPrefab.name, planetGO, sector, info); + var computerObject = GeneralPropBuilder.MakeFromPrefab(ComputerPrefab, ComputerPrefab.name, planetGO, sector, info); var computer = computerObject.GetComponent(); computer.SetSector(sector); @@ -229,16 +229,7 @@ public static GameObject Make(GameObject planetGO, Sector sector, PropModule.Tra } case PropModule.NomaiTextType.PreCrashComputer: { - var detailInfo = new PropModule.DetailInfo() - { - position = info.position, - rotation = info.rotation, - parentPath = info.parentPath, - isRelativeToParent = info.isRelativeToParent, - alignRadial = info.alignRadial, - rename = info.rename - }; - var computerObject = DetailBuilder.Make(planetGO, sector, _preCrashComputerPrefab, detailInfo); + var computerObject = DetailBuilder.Make(planetGO, sector, _preCrashComputerPrefab, new PropModule.DetailInfo(info)); computerObject.SetActive(false); var computer = computerObject.GetComponent(); @@ -314,15 +305,7 @@ public static GameObject Make(GameObject planetGO, Sector sector, PropModule.Tra case PropModule.NomaiTextType.Recorder: { var prefab = (info.type == PropModule.NomaiTextType.PreCrashRecorder ? _preCrashRecorderPrefab : _recorderPrefab); - var detailInfo = new PropModule.DetailInfo { - parentPath = info.parentPath, - rotation = info.rotation, - position = info.position, - isRelativeToParent = info.isRelativeToParent, - rename = info.rename, - alignRadial = info.alignRadial, - }; - var recorderObject = DetailBuilder.Make(planetGO, sector, prefab, detailInfo); + var recorderObject = DetailBuilder.Make(planetGO, sector, prefab, new PropModule.DetailInfo(info)); recorderObject.SetActive(false); var nomaiText = recorderObject.GetComponentInChildren(); diff --git a/NewHorizons/Builder/Props/WarpPadBuilder.cs b/NewHorizons/Builder/Props/WarpPadBuilder.cs new file mode 100644 index 000000000..f106dc57e --- /dev/null +++ b/NewHorizons/Builder/Props/WarpPadBuilder.cs @@ -0,0 +1,145 @@ +using NewHorizons.Builder.Props.TranslatorText; +using NewHorizons.External.Modules; +using NewHorizons.External.Modules.WarpPad; +using NewHorizons.Utility; +using NewHorizons.Utility.OWMLUtilities; +using OWML.Utils; +using UnityEngine; +using Logger = NewHorizons.Utility.Logger; + +namespace NewHorizons.Builder.Props +{ + public static class WarpPadBuilder + { + private static GameObject _detailedReceiverPrefab; + private static GameObject _receiverPrefab; + private static GameObject _transmitterPrefab; + private static GameObject _platformContainerPrefab; + + public static void InitPrefabs() + { + if (_platformContainerPrefab == null) + { + // Put this around the platforms without details + // Trifid is a Nomai ruins genius + _platformContainerPrefab = SearchUtilities.Find("BrittleHollow_Body/Sector_BH/Sector_SouthHemisphere/Sector_SouthPole/Sector_Observatory/Interactables_Observatory/Prefab_NOM_RemoteViewer/Structure_NOM_RemoteViewer") + .InstantiateInactive() + .DontDestroyOnLoad(); + _platformContainerPrefab.transform.localScale = new Vector3(0.85f, 3f, 0.85f); + } + + if (_detailedReceiverPrefab == null) + { + var thReceiverLamp = SearchUtilities.Find("TimberHearth_Body/Sector_TH/Sector_NomaiCrater/Geometry_NomaiCrater/OtherComponentsGroup/Structure_NOM_WarpReceiver_TimberHearth_Lamp"); + var thReceiver = SearchUtilities.Find("TimberHearth_Body/Sector_TH/Sector_NomaiCrater/Interactables_NomaiCrater/Prefab_NOM_WarpReceiver"); + + _detailedReceiverPrefab = new GameObject("NomaiWarpReceiver"); + + var detailedReceiver = thReceiver.InstantiateInactive(); + detailedReceiver.transform.parent = _detailedReceiverPrefab.transform; + detailedReceiver.transform.localPosition = Vector3.zero; + detailedReceiver.transform.localRotation = Quaternion.identity; + + var lamp = thReceiverLamp.InstantiateInactive(); + lamp.transform.parent = _detailedReceiverPrefab.transform; + lamp.transform.localPosition = thReceiver.transform.InverseTransformPoint(thReceiverLamp.transform.position); + lamp.transform.localRotation = thReceiver.transform.InverseTransformRotation(thReceiverLamp.transform.rotation); + + _detailedReceiverPrefab.SetActive(false); + lamp.SetActive(true); + detailedReceiver.SetActive(true); + + _detailedReceiverPrefab.DontDestroyOnLoad(); + + GameObject.Destroy(_detailedReceiverPrefab.GetComponentInChildren().gameObject); + } + + if (_receiverPrefab == null) + { + _receiverPrefab = SearchUtilities.Find("SunStation_Body/Sector_SunStation/Sector_WarpModule/Interactables_WarpModule/Prefab_NOM_WarpReceiver") + .InstantiateInactive() + .DontDestroyOnLoad(); + GameObject.Destroy(_receiverPrefab.GetComponentInChildren().gameObject); + + var structure = _platformContainerPrefab.Instantiate(); + structure.transform.parent = _receiverPrefab.transform; + structure.transform.localPosition = new Vector3(0, 0.8945f, 0); + structure.transform.localRotation = Quaternion.identity; + structure.SetActive(true); + } + + if (_transmitterPrefab == null) + { + _transmitterPrefab = SearchUtilities.Find("TowerTwin_Body/Sector_TowerTwin/Sector_Tower_SS/Interactables_Tower_SS/Tower_SS_VisibleFrom_TowerTwin/Prefab_NOM_WarpTransmitter") + .InstantiateInactive() + .DontDestroyOnLoad(); + GameObject.Destroy(_transmitterPrefab.GetComponentInChildren().gameObject); + + var structure = _platformContainerPrefab.Instantiate(); + structure.transform.parent = _transmitterPrefab.transform; + structure.transform.localPosition = new Vector3(0, 0.8945f, 0); + structure.transform.localRotation = Quaternion.identity; + structure.SetActive(true); + } + } + + public static void Make(GameObject planetGO, Sector sector, NomaiWarpReceiverInfo info) + { + var detailInfo = new PropModule.DetailInfo(info); + var receiverObject = DetailBuilder.Make(planetGO, sector, info.detailed ? _detailedReceiverPrefab : _receiverPrefab, detailInfo); + + Logger.Log($"Position is {detailInfo.position} was {info.position}"); + + var receiver = receiverObject.GetComponentInChildren(); + + receiver._frequency = GetFrequency(info.frequency); + + receiver._alignmentTarget = planetGO?.transform; + + receiverObject.SetActive(true); + + if (info.computer != null) + { + CreateComputer(planetGO, sector, info.computer, receiver); + } + } + + public static void Make(GameObject planetGO, Sector sector, NomaiWarpTransmitterInfo info) + { + var transmitterObject = DetailBuilder.Make(planetGO, sector, _transmitterPrefab, new PropModule.DetailInfo(info)); + + var transmitter = transmitterObject.GetComponentInChildren(); + transmitter._frequency = GetFrequency(info.frequency); + + transmitter._alignmentWindow = info.alignmentWindow; + + transmitter.GetComponent().enabled = true; + + transmitterObject.SetActive(true); + } + + private static void CreateComputer(GameObject planetGO, Sector sector, NomaiWarpComputerLoggerInfo computerInfo, NomaiWarpReceiver receiver) + { + var computerObject = DetailBuilder.Make(planetGO, sector, TranslatorTextBuilder.ComputerPrefab, new PropModule.DetailInfo(computerInfo)); + + var computer = computerObject.GetComponentInChildren(); + computer.SetSector(sector); + + Delay.FireOnNextUpdate(computer.ClearAllEntries); + + var computerLogger = computerObject.AddComponent(); + computerLogger._warpReceiver = receiver; + + computerObject.SetActive(true); + } + + private static NomaiWarpPlatform.Frequency GetFrequency(string frequency) + { + if (!EnumUtils.TryParse(frequency, out var frequencyEnum)) + { + frequencyEnum = EnumUtilities.Create(frequency); + } + return frequencyEnum; + } + } +} diff --git a/NewHorizons/External/Configs/StarSystemConfig.cs b/NewHorizons/External/Configs/StarSystemConfig.cs index 514c393e8..3e3ccf1c2 100644 --- a/NewHorizons/External/Configs/StarSystemConfig.cs +++ b/NewHorizons/External/Configs/StarSystemConfig.cs @@ -282,7 +282,10 @@ public void Merge(StarSystemConfig otherConfig) Vessel.hasPhysics = Vessel.hasPhysics ?? otherConfig.Vessel.hasPhysics; Vessel.hasZeroGravityVolume = Vessel.hasZeroGravityVolume ?? otherConfig.Vessel.hasZeroGravityVolume; } - Vessel = Vessel == null ? otherConfig.Vessel : Vessel; + else + { + Vessel ??= otherConfig.Vessel; + } entryPositions = Concatenate(entryPositions, otherConfig.entryPositions); curiosities = Concatenate(curiosities, otherConfig.curiosities); diff --git a/NewHorizons/External/Modules/PropModule.cs b/NewHorizons/External/Modules/PropModule.cs index 7b305af9c..8ed805bd1 100644 --- a/NewHorizons/External/Modules/PropModule.cs +++ b/NewHorizons/External/Modules/PropModule.cs @@ -1,12 +1,13 @@ - +using NewHorizons.External.Modules.VariableSize; +using NewHorizons.External.Modules.WarpPad; using NewHorizons.Utility; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; -using System.Runtime.Serialization; using Newtonsoft.Json; using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; using System; -using NewHorizons.External.Modules.VariableSize; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; namespace NewHorizons.External.Modules { @@ -94,6 +95,16 @@ public class PropModule /// public RemoteInfo[] remotes; + /// + /// Add warp pad receivers to this planet. These are the warp pads you are sent to from Ash Twin. + /// + public NomaiWarpReceiverInfo[] warpReceivers; + + /// + /// Add warp pad transmitters to this planet. These are the warp pads seen on the Ash Twin. + /// + public NomaiWarpTransmitterInfo[] warpTransmitters; + [Obsolete("reveal is deprecated. Use Volumes->revealVolumes instead.")] public VolumesModule.RevealVolumeInfo[] reveal; [Obsolete("audioVolumes is deprecated. Use Volumes->audioVolumes instead.")] public VolumesModule.AudioVolumeInfo[] audioVolumes; @@ -165,6 +176,13 @@ public class ScatterInfo [JsonObject] public class DetailInfo : GeneralPropInfo { + public DetailInfo() { } + + public DetailInfo(GeneralPointPropInfo info) + { + JsonConvert.PopulateObject(JsonConvert.SerializeObject(info), this); + } + /// /// Relative filepath to an asset-bundle to load the prefab defined in `path` from /// diff --git a/NewHorizons/External/Modules/WarpPad/NomaiWarpComputerInfo.cs b/NewHorizons/External/Modules/WarpPad/NomaiWarpComputerInfo.cs new file mode 100644 index 000000000..bd2bb6d75 --- /dev/null +++ b/NewHorizons/External/Modules/WarpPad/NomaiWarpComputerInfo.cs @@ -0,0 +1,9 @@ +using Newtonsoft.Json; + +namespace NewHorizons.External.Modules.WarpPad +{ + [JsonObject] + public class NomaiWarpComputerLoggerInfo : GeneralPropInfo + { + } +} diff --git a/NewHorizons/External/Modules/WarpPad/NomaiWarpPadInfo.cs b/NewHorizons/External/Modules/WarpPad/NomaiWarpPadInfo.cs new file mode 100644 index 000000000..f4cd75153 --- /dev/null +++ b/NewHorizons/External/Modules/WarpPad/NomaiWarpPadInfo.cs @@ -0,0 +1,10 @@ +using Newtonsoft.Json; + +namespace NewHorizons.External.Modules.WarpPad +{ + [JsonObject] + public abstract class NomaiWarpPadInfo : GeneralPropInfo + { + public string frequency; + } +} diff --git a/NewHorizons/External/Modules/WarpPad/NomaiWarpPadReceiverInfo.cs b/NewHorizons/External/Modules/WarpPad/NomaiWarpPadReceiverInfo.cs new file mode 100644 index 000000000..6680284c1 --- /dev/null +++ b/NewHorizons/External/Modules/WarpPad/NomaiWarpPadReceiverInfo.cs @@ -0,0 +1,24 @@ +using Newtonsoft.Json; + +namespace NewHorizons.External.Modules.WarpPad +{ + [JsonObject] + public class NomaiWarpReceiverInfo : NomaiWarpPadInfo + { + /// + /// The body the transmitter must be aligned with to warp to this receiver. + /// Defaults to the body the receiver is on. + /// + public string alignmentTargetBody; + + /// + /// Will create a modern Nomai computer linked to this receiver. + /// + public NomaiWarpComputerLoggerInfo computer; + + /// + /// Set to true if you want to include Nomai ruin details around the warp pad. + /// + public bool detailed; + } +} diff --git a/NewHorizons/External/Modules/WarpPad/NomaiWarpTransmitterInfo.cs b/NewHorizons/External/Modules/WarpPad/NomaiWarpTransmitterInfo.cs new file mode 100644 index 000000000..6e704f368 --- /dev/null +++ b/NewHorizons/External/Modules/WarpPad/NomaiWarpTransmitterInfo.cs @@ -0,0 +1,19 @@ +using Newtonsoft.Json; +using System.ComponentModel; + +namespace NewHorizons.External.Modules.WarpPad +{ + [JsonObject] + public class NomaiWarpTransmitterInfo : NomaiWarpPadInfo + { + /// + /// In degrees. Gives a margin of error for alignments. + /// + [DefaultValue(5f)] public float alignmentWindow = 5f; + + /// + /// Is this transmitter upsidedown? Means alignment will be checked facing the other way. + /// + public bool upsideDown = false; + } +} diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 080bae406..3955d27b4 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -297,6 +297,8 @@ private void OnSceneLoaded(Scene scene, LoadSceneMode mode) ProjectionBuilder.InitPrefabs(); CloakBuilder.InitPrefab(); RaftBuilder.InitPrefab(); + + WarpPadBuilder.InitPrefabs(); } catch (Exception e) { diff --git a/NewHorizons/Schemas/body_schema.json b/NewHorizons/Schemas/body_schema.json index 0a081eae9..6b56c515e 100644 --- a/NewHorizons/Schemas/body_schema.json +++ b/NewHorizons/Schemas/body_schema.json @@ -1088,6 +1088,20 @@ "items": { "$ref": "#/definitions/RemoteInfo" } + }, + "warpReceivers": { + "type": "array", + "description": "Add warp pad receivers to this planet. These are the warp pads you are sent to from Ash Twin.", + "items": { + "$ref": "#/definitions/NomaiWarpReceiverInfo" + } + }, + "warpTransmitters": { + "type": "array", + "description": "Add warp pad transmitters to this planet. These are the warp pads seen on the Ash Twin.", + "items": { + "$ref": "#/definitions/NomaiWarpTransmitterInfo" + } } } }, @@ -2393,6 +2407,133 @@ } } }, + "NomaiWarpReceiverInfo": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency": { + "type": "string" + }, + "rotation": { + "description": "Rotation of the object", + "$ref": "#/definitions/MVector3" + }, + "alignRadial": { + "type": [ + "boolean", + "null" + ], + "description": "Do we try to automatically align this object to stand upright relative to the body's center? Stacks with rotation.\nDefaults to true for geysers, tornados, and volcanoes, and false for everything else." + }, + "position": { + "description": "Position of the object", + "$ref": "#/definitions/MVector3" + }, + "parentPath": { + "type": "string", + "description": "The relative path from the planet to the parent of this object. Optional (will default to the root sector)." + }, + "isRelativeToParent": { + "type": "boolean", + "description": "Whether the positional and rotational coordinates are relative to parent instead of the root planet object." + }, + "rename": { + "type": "string", + "description": "An optional rename of this object" + }, + "alignmentTargetBody": { + "type": "string", + "description": "The body the transmitter must be aligned with to warp to this receiver.\nDefaults to the body the receiver is on." + }, + "computer": { + "description": "Will create a modern Nomai computer linked to this receiver.", + "$ref": "#/definitions/NomaiWarpComputerLoggerInfo" + }, + "detailed": { + "type": "boolean", + "description": "Set to true if you want to include Nomai ruin details around the warp pad." + } + } + }, + "NomaiWarpComputerLoggerInfo": { + "type": "object", + "additionalProperties": false, + "properties": { + "rotation": { + "description": "Rotation of the object", + "$ref": "#/definitions/MVector3" + }, + "alignRadial": { + "type": [ + "boolean", + "null" + ], + "description": "Do we try to automatically align this object to stand upright relative to the body's center? Stacks with rotation.\nDefaults to true for geysers, tornados, and volcanoes, and false for everything else." + }, + "position": { + "description": "Position of the object", + "$ref": "#/definitions/MVector3" + }, + "parentPath": { + "type": "string", + "description": "The relative path from the planet to the parent of this object. Optional (will default to the root sector)." + }, + "isRelativeToParent": { + "type": "boolean", + "description": "Whether the positional and rotational coordinates are relative to parent instead of the root planet object." + }, + "rename": { + "type": "string", + "description": "An optional rename of this object" + } + } + }, + "NomaiWarpTransmitterInfo": { + "type": "object", + "additionalProperties": false, + "properties": { + "frequency": { + "type": "string" + }, + "rotation": { + "description": "Rotation of the object", + "$ref": "#/definitions/MVector3" + }, + "alignRadial": { + "type": [ + "boolean", + "null" + ], + "description": "Do we try to automatically align this object to stand upright relative to the body's center? Stacks with rotation.\nDefaults to true for geysers, tornados, and volcanoes, and false for everything else." + }, + "position": { + "description": "Position of the object", + "$ref": "#/definitions/MVector3" + }, + "parentPath": { + "type": "string", + "description": "The relative path from the planet to the parent of this object. Optional (will default to the root sector)." + }, + "isRelativeToParent": { + "type": "boolean", + "description": "Whether the positional and rotational coordinates are relative to parent instead of the root planet object." + }, + "rename": { + "type": "string", + "description": "An optional rename of this object" + }, + "alignmentWindow": { + "type": "number", + "description": "In degrees. Gives a margin of error for alignments.", + "format": "float", + "default": 5.0 + }, + "upsideDown": { + "type": "boolean", + "description": "Is this transmitter upsidedown? Means alignment will be checked facing the other way." + } + } + }, "ReferenceFrameModule": { "type": "object", "additionalProperties": false, diff --git a/NewHorizons/Utility/NewHorizonExtensions.cs b/NewHorizons/Utility/NewHorizonExtensions.cs index a00475c9c..ca3a2cf1e 100644 --- a/NewHorizons/Utility/NewHorizonExtensions.cs +++ b/NewHorizons/Utility/NewHorizonExtensions.cs @@ -188,6 +188,11 @@ public static GameObject InstantiateInactive(this GameObject original) return copy; } + public static GameObject Instantiate(this GameObject original) + { + return UnityEngine.Object.Instantiate(original); + } + public static T DontDestroyOnLoad(this T target) where T : UnityEngine.Object { UnityEngine.Object.DontDestroyOnLoad(target); diff --git a/docs/content/pages/404.md b/docs/content/pages/404.md index a999f1856..2d3034e98 100644 --- a/docs/content/pages/404.md +++ b/docs/content/pages/404.md @@ -4,7 +4,7 @@ Hide_In_Nav: True Render_TOC: False --- -# Page Not Found +# Page Not Found The page you requested could not be found.