diff --git a/NewHorizons/Builder/Props/PropBuildManager.cs b/NewHorizons/Builder/Props/PropBuildManager.cs index d3dcbf4f..7f7f54bb 100644 --- a/NewHorizons/Builder/Props/PropBuildManager.cs +++ b/NewHorizons/Builder/Props/PropBuildManager.cs @@ -12,6 +12,20 @@ namespace NewHorizons.Builder.Props { public static void Make(GameObject go, Sector sector, OWRigidbody planetBody, PlanetConfig config, IModBehaviour mod) { + if (config.Props.shuttles != null) + { + foreach (var shuttleInfo in config.Props.shuttles) + { + try + { + ShuttleBuilder.Make(go, sector, shuttleInfo); + } + catch (Exception ex) + { + Logger.LogError($"Couldn't make shuttle [{shuttleInfo.id}] for [{go.name}]:\n{ex}"); + } + } + } if (config.Props.scatter != null) { try diff --git a/NewHorizons/Builder/Props/ShuttleBuilder.cs b/NewHorizons/Builder/Props/ShuttleBuilder.cs new file mode 100644 index 00000000..39adfba4 --- /dev/null +++ b/NewHorizons/Builder/Props/ShuttleBuilder.cs @@ -0,0 +1,122 @@ +using NewHorizons.Components; +using NewHorizons.Components.Volumes; +using NewHorizons.External.Modules; +using NewHorizons.Handlers; +using NewHorizons.Utility; +using UnityEngine; +using Logger = NewHorizons.Utility.Logger; + +namespace NewHorizons.Builder.Props +{ + public static class ShuttleBuilder + { + private static GameObject _prefab; + private static GameObject _orbPrefab; + private static GameObject _bodyPrefab; + + internal static void InitPrefab() + { + if (_prefab == null) + { + _prefab = SearchUtilities.Find("QuantumMoon_Body/Sector_QuantumMoon/QuantumShuttle/Prefab_NOM_Shuttle")?.InstantiateInactive()?.Rename("Prefab_QM_Shuttle")?.DontDestroyOnLoad(); + NomaiShuttleController shuttleController = _prefab.GetComponent(); + NHShuttleController nhShuttleController = _prefab.AddComponent(); + nhShuttleController._exteriorSector = _prefab.FindChild("Sector_Shuttle").GetComponent(); + nhShuttleController._interiorSector = _prefab.FindChild("Sector_NomaiShuttleInterior").GetComponent(); + nhShuttleController._shuttleBody = shuttleController._shuttleBody; + nhShuttleController._retrievalLength = shuttleController._retrievalLength; + nhShuttleController._launchSlot = shuttleController._launchSlot; + nhShuttleController._retrieveSlot = shuttleController._retrieveSlot; + nhShuttleController._landSlot = shuttleController._landSlot; + nhShuttleController._triggerVolume = shuttleController._triggerVolume; + nhShuttleController._beamResetVolume = shuttleController._beamResetVolume; + nhShuttleController._tractorBeam = shuttleController._tractorBeam; + nhShuttleController._forceVolume = shuttleController._forceVolume; + nhShuttleController._exteriorCollisionGroup = shuttleController._exteriorCollisionGroup; + nhShuttleController._exteriorColliderRoot = shuttleController._exteriorColliderRoot; + nhShuttleController._landingBeamRoot = shuttleController._landingBeamRoot; + nhShuttleController._warpEffect = _prefab.GetComponentInChildren(); + nhShuttleController._exteriorLegColliders = shuttleController._exteriorLegColliders; + nhShuttleController._id = NomaiShuttleController.ShuttleID.HourglassShuttle; + nhShuttleController._cannon = null; + GameObject slots = _prefab.FindChild("Sector_NomaiShuttleInterior/Interactibles_NomaiShuttleInterior/ControlPanel/Slots"); + GameObject neutralSlotObject = new GameObject("Slot_Neutral", typeof(NomaiInterfaceSlot)); + neutralSlotObject.transform.SetParent(slots.transform, false); + neutralSlotObject.transform.localPosition = new Vector3(-0.0153f, -0.2386f, 0.0205f); + neutralSlotObject.transform.localRotation = Quaternion.identity; + NomaiInterfaceSlot neutralSlot = neutralSlotObject.GetComponent(); + neutralSlot._exitRadius = 0.1f; + neutralSlot._radius = 0.05f; + neutralSlot._attractive = true; + neutralSlot._muteAudio = true; + nhShuttleController._neutralSlot = neutralSlot; + _orbPrefab = shuttleController._orb.gameObject?.InstantiateInactive()?.Rename("Prefab_QM_Shuttle_InterfaceOrbSmall")?.DontDestroyOnLoad(); + nhShuttleController._orb = _orbPrefab.GetComponent(); + nhShuttleController._orb._sector = nhShuttleController._interiorSector; + nhShuttleController._orb._slotRoot = slots; + nhShuttleController._orb._safetyRails = slots.GetComponentsInChildren(); + nhShuttleController._orb._slots = slots.GetComponentsInChildren(); + _bodyPrefab = shuttleController._shuttleBody.gameObject?.InstantiateInactive()?.Rename("Prefab_QM_Shuttle_Body")?.DontDestroyOnLoad(); + nhShuttleController._shuttleBody = _bodyPrefab.GetComponent(); + nhShuttleController._impactSensor = _bodyPrefab.GetComponent(); + nhShuttleController._forceApplier = _bodyPrefab.GetComponentInChildren(); + nhShuttleController._detectorObj = nhShuttleController._forceApplier.gameObject; + GameObject.DestroyImmediate(shuttleController); + GameObject.DestroyImmediate(_prefab.FindChild("Sector_NomaiShuttleInterior/Interactibles_NomaiShuttleInterior/Prefab_NOM_Recorder")); + } + } + + public static GameObject Make(GameObject planetGO, Sector sector, PropModule.ShuttleInfo info) + { + InitPrefab(); + + if (_prefab == null || planetGO == null || sector == null) return null; + + var detailInfo = new PropModule.DetailInfo() + { + position = info.position, + rotation = info.rotation, + parentPath = info.parentPath, + isRelativeToParent = info.isRelativeToParent, + rename = info.rename + }; + var shuttleObject = DetailBuilder.Make(planetGO, sector, _prefab, detailInfo); + shuttleObject.SetActive(false); + + StreamingHandler.SetUpStreaming(shuttleObject, sector); + + NHShuttleController shuttleController = shuttleObject.GetComponent(); + NomaiShuttleController.ShuttleID id = ShuttleHandler.GetShuttleID(info.id); + shuttleController._id = id; + shuttleController._cannon = Locator.GetGravityCannon(id); + + GameObject slots = shuttleObject.FindChild("Sector_NomaiShuttleInterior/Interactibles_NomaiShuttleInterior/ControlPanel/Slots"); + GameObject orbObject = _orbPrefab.InstantiateInactive().Rename("InterfaceOrbSmall"); + orbObject.transform.SetParent(slots.transform, false); + orbObject.transform.localPosition = new Vector3(-0.0153f, -0.2386f, 0.0205f); + shuttleController._orb = orbObject.GetComponent(); + shuttleController._orb._sector = shuttleController._interiorSector; + shuttleController._orb._slotRoot = slots; + shuttleController._orb._safetyRails = slots.GetComponentsInChildren(); + shuttleController._orb._slots = slots.GetComponentsInChildren(); + + StreamingHandler.SetUpStreaming(orbObject, sector); + + GameObject bodyObject = _bodyPrefab.InstantiateInactive().Rename("Shuttle_Body"); + bodyObject.transform.SetParent(shuttleObject.transform, false); + bodyObject.transform.localPosition = Vector3.zero; + bodyObject.transform.localEulerAngles = Vector3.zero; + shuttleController._shuttleBody = bodyObject.GetComponent(); + shuttleController._impactSensor = bodyObject.GetComponent(); + shuttleController._forceApplier = bodyObject.GetComponentInChildren(); + shuttleController._detectorObj = shuttleController._forceApplier.gameObject; + + shuttleObject.SetActive(true); + bodyObject.SetActive(true); + orbObject.SetActive(true); + shuttleController._orb.RemoveAllLocks(); + + return shuttleObject; + } + } +} diff --git a/NewHorizons/Components/NHShuttleController.cs b/NewHorizons/Components/NHShuttleController.cs new file mode 100644 index 00000000..522bce79 --- /dev/null +++ b/NewHorizons/Components/NHShuttleController.cs @@ -0,0 +1,17 @@ +using NewHorizons.Utility; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.Components +{ + public class NHShuttleController : NomaiShuttleController + { + public NomaiInterfaceSlot _neutralSlot; + public Sector _exteriorSector; + public Sector _interiorSector; + } +} diff --git a/NewHorizons/External/Modules/PropModule.cs b/NewHorizons/External/Modules/PropModule.cs index 839f75b6..df59a7ec 100644 --- a/NewHorizons/External/Modules/PropModule.cs +++ b/NewHorizons/External/Modules/PropModule.cs @@ -83,6 +83,11 @@ namespace NewHorizons.External.Modules /// public SignalModule.SignalInfo[] signals; + /// + /// Add shuttles to this planet + /// + public ShuttleInfo[] shuttles; + /// /// Add projection pools/platforms, whiteboards, and stones to this planet /// @@ -1000,5 +1005,39 @@ namespace NewHorizons.External.Modules public string rename; } } + + [JsonObject] + public class ShuttleInfo + { + /// + /// The unique shuttle id + /// + public string id; + + /// + /// The location of this shuttle. + /// + public MVector3 position; + + /// + /// The rotation of this shuttle. + /// + 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; + + /// + /// Whether the positional and rotational coordinates are relative to parent instead of the root planet object. + /// + public bool isRelativeToParent; + + /// + /// An optional rename of this object + /// + public string rename; + } } } \ No newline at end of file diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 4f74a553..fcac259d 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -288,6 +288,7 @@ namespace NewHorizons VolcanoBuilder.InitPrefab(); VolumesBuilder.InitPrefabs(); WaterBuilder.InitPrefabs(); + ShuttleBuilder.InitPrefab(); ProjectionBuilder.InitPrefabs(); CloakBuilder.InitPrefab();