Warp pads (#546)

## Major features
- Nomai warp pads! You can build transmitters (like the towers on Ash
Twin) and receivers on other planets. Can also be used to just make
permanent teleportation pads if the alignment window is set to 360
degrees. Receivers also take in position arguments for a Nomai computer
which will display the departure and arrival times.
This commit is contained in:
Nick 2023-03-23 00:58:44 -04:00 committed by GitHub
commit aa88285748
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 428 additions and 92 deletions

View File

@ -104,8 +104,7 @@ namespace NewHorizons.Builder.Body
default: geometryPrefab = _hubGeometry; break; default: geometryPrefab = _hubGeometry; break;
} }
var detailInfo = new PropModule.DetailInfo(); var geometry = DetailBuilder.Make(go, sector, geometryPrefab, new PropModule.DetailInfo());
var geometry = DetailBuilder.Make(go, sector, geometryPrefab, detailInfo);
var exitWarps = _exitWarps.InstantiateInactive(); var exitWarps = _exitWarps.InstantiateInactive();
var repelVolume = _repelVolume.InstantiateInactive(); var repelVolume = _repelVolume.InstantiateInactive();

View File

@ -1,11 +1,6 @@
using NewHorizons.External.Modules; using NewHorizons.External.Modules;
using NewHorizons.Utility; using NewHorizons.Utility;
using NewHorizons.Utility.OWUtilities; using NewHorizons.Utility.OWUtilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using Logger = NewHorizons.Utility.Logger; using Logger = NewHorizons.Utility.Logger;

View File

@ -360,14 +360,7 @@ namespace NewHorizons.Builder.Props
} }
case PropModule.NomaiTextType.PreCrashComputer: case PropModule.NomaiTextType.PreCrashComputer:
{ {
var detailInfo = new PropModule.DetailInfo() var computerObject = DetailBuilder.Make(planetGO, sector, _preCrashComputerPrefab, new PropModule.DetailInfo(info));
{
position = info.position,
parentPath = info.parentPath,
isRelativeToParent = info.isRelativeToParent,
rename = info.rename
};
var computerObject = DetailBuilder.Make(planetGO, sector, _preCrashComputerPrefab, detailInfo);
computerObject.SetActive(false); computerObject.SetActive(false);
var up = computerObject.transform.position - planetGO.transform.position; var up = computerObject.transform.position - planetGO.transform.position;
@ -487,14 +480,7 @@ namespace NewHorizons.Builder.Props
case PropModule.NomaiTextType.Recorder: case PropModule.NomaiTextType.Recorder:
{ {
var prefab = (info.type == PropModule.NomaiTextType.PreCrashRecorder ? _preCrashRecorderPrefab : _recorderPrefab); var prefab = (info.type == PropModule.NomaiTextType.PreCrashRecorder ? _preCrashRecorderPrefab : _recorderPrefab);
var detailInfo = new PropModule.DetailInfo { var recorderObject = DetailBuilder.Make(planetGO, sector, prefab, new PropModule.DetailInfo(info));
parentPath = info.parentPath,
rotation = info.rotation,
position = info.position,
isRelativeToParent = info.isRelativeToParent,
rename = info.rename
};
var recorderObject = DetailBuilder.Make(planetGO, sector, prefab, detailInfo);
recorderObject.SetActive(false); recorderObject.SetActive(false);
if (info.rotation == null) if (info.rotation == null)

View File

@ -202,16 +202,7 @@ namespace NewHorizons.Builder.Props
if (_visionTorchDetectorPrefab == null) return null; if (_visionTorchDetectorPrefab == null) return null;
// spawn a trigger for the vision torch // spawn a trigger for the vision torch
var detailInfo = new PropModule.DetailInfo() var g = DetailBuilder.Make(planetGO, sector, _visionTorchDetectorPrefab, new DetailInfo(info) { scale = 2, rename = !string.IsNullOrEmpty(info.rename) ? info.rename : "VisionStaffDetector" });
{
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);
if (g == null) if (g == null)
{ {
@ -248,15 +239,7 @@ namespace NewHorizons.Builder.Props
if (_standingVisionTorchPrefab == null) return null; if (_standingVisionTorchPrefab == null) return null;
// Spawn the torch itself // Spawn the torch itself
var detailInfo = new PropModule.DetailInfo() var standingTorch = DetailBuilder.Make(planetGO, sector, _standingVisionTorchPrefab, new DetailInfo(info));
{
position = info.position,
rotation = info.rotation,
parentPath = info.parentPath,
isRelativeToParent = info.isRelativeToParent,
rename = info.rename
};
var standingTorch = DetailBuilder.Make(planetGO, sector, _standingVisionTorchPrefab, detailInfo);
if (standingTorch == null) if (standingTorch == null)
{ {

View File

@ -7,6 +7,7 @@ using OWML.Common;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using static NewHorizons.External.Modules.PropModule;
using Logger = NewHorizons.Utility.Logger; using Logger = NewHorizons.Utility.Logger;
namespace NewHorizons.Builder.Props namespace NewHorizons.Builder.Props
{ {
@ -236,6 +237,34 @@ namespace NewHorizons.Builder.Props
} }
} }
} }
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}");
}
}
}
} }
} }
} }

View File

@ -7,6 +7,7 @@ using OWML.Common;
using System; using System;
using System.Linq; using System.Linq;
using UnityEngine; using UnityEngine;
using static NewHorizons.External.Modules.PropModule;
using Logger = NewHorizons.Utility.Logger; using Logger = NewHorizons.Utility.Logger;
namespace NewHorizons.Builder.Props namespace NewHorizons.Builder.Props
@ -171,15 +172,7 @@ namespace NewHorizons.Builder.Props
public static void MakeWhiteboard(GameObject go, Sector sector, NomaiRemoteCameraPlatform.ID id, Texture2D decal, PropModule.RemoteInfo.WhiteboardInfo info, NewHorizonsBody nhBody) public static void MakeWhiteboard(GameObject go, Sector sector, NomaiRemoteCameraPlatform.ID id, Texture2D decal, PropModule.RemoteInfo.WhiteboardInfo info, NewHorizonsBody nhBody)
{ {
var detailInfo = new PropModule.DetailInfo() var whiteboard = DetailBuilder.Make(go, sector, _whiteboardPrefab, new DetailInfo(info));
{
position = info.position,
rotation = info.rotation,
parentPath = info.parentPath,
isRelativeToParent = info.isRelativeToParent,
rename = info.rename
};
var whiteboard = DetailBuilder.Make(go, sector, _whiteboardPrefab, detailInfo);
whiteboard.SetActive(false); whiteboard.SetActive(false);
var decalMat = new Material(_decalMaterial); var decalMat = new Material(_decalMaterial);
@ -196,7 +189,7 @@ namespace NewHorizons.Builder.Props
{ {
var textInfo = info.nomaiText[i]; var textInfo = info.nomaiText[i];
component._remoteIDs[i] = RemoteHandler.GetPlatformID(textInfo.id); 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, arcInfo = textInfo.arcInfo,
location = textInfo.location, location = textInfo.location,
@ -205,7 +198,7 @@ namespace NewHorizons.Builder.Props
rename = textInfo.rename, rename = textInfo.rename,
rotation = Vector3.zero, rotation = Vector3.zero,
seed = textInfo.seed, seed = textInfo.seed,
type = PropModule.NomaiTextType.Wall, type = NomaiTextType.Wall,
xmlFile = textInfo.xmlFile xmlFile = textInfo.xmlFile
}, nhBody).GetComponent<NomaiWallText>(); }, nhBody).GetComponent<NomaiWallText>();
wallText._showTextOnStart = false; wallText._showTextOnStart = false;
@ -219,15 +212,7 @@ namespace NewHorizons.Builder.Props
public static void MakePlatform(GameObject go, Sector sector, NomaiRemoteCameraPlatform.ID id, Texture2D decal, PropModule.RemoteInfo.PlatformInfo info, IModBehaviour mod) public static void MakePlatform(GameObject go, Sector sector, NomaiRemoteCameraPlatform.ID id, Texture2D decal, PropModule.RemoteInfo.PlatformInfo info, IModBehaviour mod)
{ {
var detailInfo = new PropModule.DetailInfo() var platform = DetailBuilder.Make(go, sector, _remoteCameraPlatformPrefab, new DetailInfo(info));
{
position = info.position,
rotation = info.rotation,
parentPath = info.parentPath,
isRelativeToParent = info.isRelativeToParent,
rename = info.rename
};
var platform = DetailBuilder.Make(go, sector, _remoteCameraPlatformPrefab, detailInfo);
platform.SetActive(false); platform.SetActive(false);
var decalMat = new Material(_decalMaterial); var decalMat = new Material(_decalMaterial);

View File

@ -22,7 +22,7 @@ namespace NewHorizons.Builder.Props.TranslatorText
private static Material _adultArcMaterial; private static Material _adultArcMaterial;
private static Material _childArcMaterial; private static Material _childArcMaterial;
private static GameObject _scrollPrefab; private static GameObject _scrollPrefab;
private static GameObject _computerPrefab; public static GameObject ComputerPrefab { get; private set; }
private static GameObject _preCrashComputerPrefab; private static GameObject _preCrashComputerPrefab;
private static GameObject _cairnPrefab; private static GameObject _cairnPrefab;
private static GameObject _cairnVariantPrefab; private static GameObject _cairnVariantPrefab;
@ -80,9 +80,9 @@ namespace NewHorizons.Builder.Props.TranslatorText
_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(); _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) if (_preCrashComputerPrefab == null)
@ -208,7 +208,7 @@ namespace NewHorizons.Builder.Props.TranslatorText
} }
case PropModule.NomaiTextType.Computer: 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<NomaiComputer>(); var computer = computerObject.GetComponent<NomaiComputer>();
computer.SetSector(sector); computer.SetSector(sector);
@ -229,16 +229,7 @@ namespace NewHorizons.Builder.Props.TranslatorText
} }
case PropModule.NomaiTextType.PreCrashComputer: case PropModule.NomaiTextType.PreCrashComputer:
{ {
var detailInfo = new PropModule.DetailInfo() var computerObject = DetailBuilder.Make(planetGO, sector, _preCrashComputerPrefab, new PropModule.DetailInfo(info));
{
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);
computerObject.SetActive(false); computerObject.SetActive(false);
var computer = computerObject.GetComponent<NomaiVesselComputer>(); var computer = computerObject.GetComponent<NomaiVesselComputer>();
@ -314,15 +305,7 @@ namespace NewHorizons.Builder.Props.TranslatorText
case PropModule.NomaiTextType.Recorder: case PropModule.NomaiTextType.Recorder:
{ {
var prefab = (info.type == PropModule.NomaiTextType.PreCrashRecorder ? _preCrashRecorderPrefab : _recorderPrefab); var prefab = (info.type == PropModule.NomaiTextType.PreCrashRecorder ? _preCrashRecorderPrefab : _recorderPrefab);
var detailInfo = new PropModule.DetailInfo { var recorderObject = DetailBuilder.Make(planetGO, sector, prefab, new PropModule.DetailInfo(info));
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);
recorderObject.SetActive(false); recorderObject.SetActive(false);
var nomaiText = recorderObject.GetComponentInChildren<NomaiText>(); var nomaiText = recorderObject.GetComponentInChildren<NomaiText>();

View File

@ -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<NomaiWarpStreaming>().gameObject);
}
if (_receiverPrefab == null)
{
_receiverPrefab = SearchUtilities.Find("SunStation_Body/Sector_SunStation/Sector_WarpModule/Interactables_WarpModule/Prefab_NOM_WarpReceiver")
.InstantiateInactive()
.DontDestroyOnLoad();
GameObject.Destroy(_receiverPrefab.GetComponentInChildren<NomaiWarpStreaming>().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<NomaiWarpStreaming>().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<NomaiWarpReceiver>();
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<NomaiWarpTransmitter>();
transmitter._frequency = GetFrequency(info.frequency);
transmitter._alignmentWindow = info.alignmentWindow;
transmitter.GetComponent<BoxShape>().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<NomaiComputer>();
computer.SetSector(sector);
Delay.FireOnNextUpdate(computer.ClearAllEntries);
var computerLogger = computerObject.AddComponent<NomaiWarpComputerLogger>();
computerLogger._warpReceiver = receiver;
computerObject.SetActive(true);
}
private static NomaiWarpPlatform.Frequency GetFrequency(string frequency)
{
if (!EnumUtils.TryParse<NomaiWarpPlatform.Frequency>(frequency, out var frequencyEnum))
{
frequencyEnum = EnumUtilities.Create<NomaiWarpPlatform.Frequency>(frequency);
}
return frequencyEnum;
}
}
}

View File

@ -282,7 +282,10 @@ namespace NewHorizons.External.Configs
Vessel.hasPhysics = Vessel.hasPhysics ?? otherConfig.Vessel.hasPhysics; Vessel.hasPhysics = Vessel.hasPhysics ?? otherConfig.Vessel.hasPhysics;
Vessel.hasZeroGravityVolume = Vessel.hasZeroGravityVolume ?? otherConfig.Vessel.hasZeroGravityVolume; Vessel.hasZeroGravityVolume = Vessel.hasZeroGravityVolume ?? otherConfig.Vessel.hasZeroGravityVolume;
} }
Vessel = Vessel == null ? otherConfig.Vessel : Vessel; else
{
Vessel ??= otherConfig.Vessel;
}
entryPositions = Concatenate(entryPositions, otherConfig.entryPositions); entryPositions = Concatenate(entryPositions, otherConfig.entryPositions);
curiosities = Concatenate(curiosities, otherConfig.curiosities); curiosities = Concatenate(curiosities, otherConfig.curiosities);

View File

@ -1,12 +1,13 @@
using NewHorizons.External.Modules.VariableSize;
using NewHorizons.External.Modules.WarpPad;
using NewHorizons.Utility; using NewHorizons.Utility;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using System;
using System.ComponentModel; using System.ComponentModel;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using NewHorizons.External.Modules.VariableSize;
namespace NewHorizons.External.Modules namespace NewHorizons.External.Modules
{ {
@ -94,6 +95,16 @@ namespace NewHorizons.External.Modules
/// </summary> /// </summary>
public RemoteInfo[] remotes; public RemoteInfo[] remotes;
/// <summary>
/// Add warp pad receivers to this planet. These are the warp pads you are sent to from Ash Twin.
/// </summary>
public NomaiWarpReceiverInfo[] warpReceivers;
/// <summary>
/// Add warp pad transmitters to this planet. These are the warp pads seen on the Ash Twin.
/// </summary>
public NomaiWarpTransmitterInfo[] warpTransmitters;
[Obsolete("reveal is deprecated. Use Volumes->revealVolumes instead.")] public VolumesModule.RevealVolumeInfo[] reveal; [Obsolete("reveal is deprecated. Use Volumes->revealVolumes instead.")] public VolumesModule.RevealVolumeInfo[] reveal;
[Obsolete("audioVolumes is deprecated. Use Volumes->audioVolumes instead.")] public VolumesModule.AudioVolumeInfo[] audioVolumes; [Obsolete("audioVolumes is deprecated. Use Volumes->audioVolumes instead.")] public VolumesModule.AudioVolumeInfo[] audioVolumes;
@ -165,6 +176,13 @@ namespace NewHorizons.External.Modules
[JsonObject] [JsonObject]
public class DetailInfo : GeneralPropInfo public class DetailInfo : GeneralPropInfo
{ {
public DetailInfo() { }
public DetailInfo(GeneralPointPropInfo info)
{
JsonConvert.PopulateObject(JsonConvert.SerializeObject(info), this);
}
/// <summary> /// <summary>
/// Relative filepath to an asset-bundle to load the prefab defined in `path` from /// Relative filepath to an asset-bundle to load the prefab defined in `path` from
/// </summary> /// </summary>

View File

@ -0,0 +1,9 @@
using Newtonsoft.Json;
namespace NewHorizons.External.Modules.WarpPad
{
[JsonObject]
public class NomaiWarpComputerLoggerInfo : GeneralPropInfo
{
}
}

View File

@ -0,0 +1,10 @@
using Newtonsoft.Json;
namespace NewHorizons.External.Modules.WarpPad
{
[JsonObject]
public abstract class NomaiWarpPadInfo : GeneralPropInfo
{
public string frequency;
}
}

View File

@ -0,0 +1,24 @@
using Newtonsoft.Json;
namespace NewHorizons.External.Modules.WarpPad
{
[JsonObject]
public class NomaiWarpReceiverInfo : NomaiWarpPadInfo
{
/// <summary>
/// The body the transmitter must be aligned with to warp to this receiver.
/// Defaults to the body the receiver is on.
/// </summary>
public string alignmentTargetBody;
/// <summary>
/// Will create a modern Nomai computer linked to this receiver.
/// </summary>
public NomaiWarpComputerLoggerInfo computer;
/// <summary>
/// Set to true if you want to include Nomai ruin details around the warp pad.
/// </summary>
public bool detailed;
}
}

View File

@ -0,0 +1,19 @@
using Newtonsoft.Json;
using System.ComponentModel;
namespace NewHorizons.External.Modules.WarpPad
{
[JsonObject]
public class NomaiWarpTransmitterInfo : NomaiWarpPadInfo
{
/// <summary>
/// In degrees. Gives a margin of error for alignments.
/// </summary>
[DefaultValue(5f)] public float alignmentWindow = 5f;
/// <summary>
/// Is this transmitter upsidedown? Means alignment will be checked facing the other way.
/// </summary>
public bool upsideDown = false;
}
}

View File

@ -297,6 +297,8 @@ namespace NewHorizons
ProjectionBuilder.InitPrefabs(); ProjectionBuilder.InitPrefabs();
CloakBuilder.InitPrefab(); CloakBuilder.InitPrefab();
RaftBuilder.InitPrefab(); RaftBuilder.InitPrefab();
WarpPadBuilder.InitPrefabs();
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -1088,6 +1088,20 @@
"items": { "items": {
"$ref": "#/definitions/RemoteInfo" "$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": { "ReferenceFrameModule": {
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,

View File

@ -188,6 +188,11 @@ namespace NewHorizons.Utility
return copy; return copy;
} }
public static GameObject Instantiate(this GameObject original)
{
return UnityEngine.Object.Instantiate(original);
}
public static T DontDestroyOnLoad<T>(this T target) where T : UnityEngine.Object public static T DontDestroyOnLoad<T>(this T target) where T : UnityEngine.Object
{ {
UnityEngine.Object.DontDestroyOnLoad(target); UnityEngine.Object.DontDestroyOnLoad(target);

View File

@ -4,7 +4,7 @@ Hide_In_Nav: True
Render_TOC: False Render_TOC: False
--- ---
# Page Not Found # Page Not Found
The page you requested could not be found. The page you requested could not be found.