diff --git a/NewHorizons/Builder/ShipLog/RevealBuilder.cs b/NewHorizons/Builder/ShipLog/RevealBuilder.cs index 95f118b6..59662218 100644 --- a/NewHorizons/Builder/ShipLog/RevealBuilder.cs +++ b/NewHorizons/Builder/ShipLog/RevealBuilder.cs @@ -41,7 +41,22 @@ namespace NewHorizons.Builder.ShipLog GameObject revealTriggerVolume = new GameObject("Reveal Volume (" + info.revealOn + ")"); revealTriggerVolume.SetActive(false); revealTriggerVolume.transform.parent = sector?.transform ?? planetGO.transform; + + if (!string.IsNullOrEmpty(info.parentPath)) + { + var newParent = planetGO.transform.Find(info.parentPath); + if (newParent != null) + { + revealTriggerVolume.transform.parent = newParent; + } + else + { + Logger.LogWarning($"Cannot find parent object at path: {planetGO.name}/{info.parentPath}"); + } + } + revealTriggerVolume.transform.position = planetGO.transform.TransformPoint(info.position ?? Vector3.zero); + return revealTriggerVolume; } diff --git a/NewHorizons/Builder/Volumes/AudioVolumeBuilder.cs b/NewHorizons/Builder/Volumes/AudioVolumeBuilder.cs index b487670a..2952f590 100644 --- a/NewHorizons/Builder/Volumes/AudioVolumeBuilder.cs +++ b/NewHorizons/Builder/Volumes/AudioVolumeBuilder.cs @@ -19,6 +19,20 @@ namespace NewHorizons.Builder.Volumes go.SetActive(false); go.transform.parent = sector?.transform ?? planetGO.transform; + + if (!string.IsNullOrEmpty(info.parentPath)) + { + var newParent = planetGO.transform.Find(info.parentPath); + if (newParent != null) + { + go.transform.parent = newParent; + } + else + { + Logger.LogWarning($"Cannot find parent object at path: {planetGO.name}/{info.parentPath}"); + } + } + go.transform.position = planetGO.transform.TransformPoint(info.position != null ? (Vector3)info.position : Vector3.zero); go.layer = LayerMask.NameToLayer("AdvancedEffectVolume"); diff --git a/NewHorizons/Builder/Volumes/HazardVolumeBuilder.cs b/NewHorizons/Builder/Volumes/HazardVolumeBuilder.cs index 67c6f22c..d52b4352 100644 --- a/NewHorizons/Builder/Volumes/HazardVolumeBuilder.cs +++ b/NewHorizons/Builder/Volumes/HazardVolumeBuilder.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using UnityEngine; +using Logger = NewHorizons.Utility.Logger; namespace NewHorizons.Builder.Volumes { @@ -16,6 +17,20 @@ namespace NewHorizons.Builder.Volumes go.SetActive(false); go.transform.parent = sector?.transform ?? planetGO.transform; + + if (!string.IsNullOrEmpty(info.parentPath)) + { + var newParent = planetGO.transform.Find(info.parentPath); + if (newParent != null) + { + go.transform.parent = newParent; + } + else + { + Logger.LogWarning($"Cannot find parent object at path: {planetGO.name}/{info.parentPath}"); + } + } + go.transform.position = planetGO.transform.TransformPoint(info.position != null ? (Vector3)info.position : Vector3.zero); go.layer = LayerMask.NameToLayer("BasicEffectVolume"); diff --git a/NewHorizons/Builder/Volumes/NotificationVolumeBuilder.cs b/NewHorizons/Builder/Volumes/NotificationVolumeBuilder.cs index c91e4161..496a9ea7 100644 --- a/NewHorizons/Builder/Volumes/NotificationVolumeBuilder.cs +++ b/NewHorizons/Builder/Volumes/NotificationVolumeBuilder.cs @@ -21,6 +21,20 @@ namespace NewHorizons.Builder.Volumes go.SetActive(false); go.transform.parent = sector?.transform ?? planetGO.transform; + + if (!string.IsNullOrEmpty(info.parentPath)) + { + var newParent = planetGO.transform.Find(info.parentPath); + if (newParent != null) + { + go.transform.parent = newParent; + } + else + { + Logger.LogWarning($"Cannot find parent object at path: {planetGO.name}/{info.parentPath}"); + } + } + go.transform.position = planetGO.transform.TransformPoint(info.position != null ? (Vector3)info.position : Vector3.zero); go.layer = LayerMask.NameToLayer("BasicEffectVolume"); diff --git a/NewHorizons/Builder/Volumes/VolumeBuilder.cs b/NewHorizons/Builder/Volumes/VolumeBuilder.cs new file mode 100644 index 00000000..afeffd73 --- /dev/null +++ b/NewHorizons/Builder/Volumes/VolumeBuilder.cs @@ -0,0 +1,46 @@ +using NewHorizons.Components; +using NewHorizons.External.Modules; +using UnityEngine; +using Logger = NewHorizons.Utility.Logger; + +namespace NewHorizons.Builder.Volumes +{ + public static class VolumeBuilder + { + public static TVolume Make(GameObject planetGO, Sector sector, VolumesModule.VolumeInfo info) where TVolume : MonoBehaviour //Could be BaseVolume but I need to create vanilla volumes too. + { + var go = new GameObject(typeof(TVolume).Name); + go.SetActive(false); + + go.transform.parent = sector?.transform ?? planetGO.transform; + + if (!string.IsNullOrEmpty(info.parentPath)) + { + var newParent = planetGO.transform.Find(info.parentPath); + if (newParent != null) + { + go.transform.parent = newParent; + } + else + { + Logger.LogWarning($"Cannot find parent object at path: {planetGO.name}/{info.parentPath}"); + } + } + + go.transform.position = planetGO.transform.TransformPoint(info.position != null ? (Vector3)info.position : Vector3.zero); + go.layer = LayerMask.NameToLayer("BasicEffectVolume"); + + var shape = go.AddComponent(); + shape.radius = info.radius; + + var owTriggerVolume = go.AddComponent(); + owTriggerVolume._shape = shape; + + var volume = go.AddComponent(); + + go.SetActive(true); + + return volume; + } + } +} diff --git a/NewHorizons/Builder/Volumes/VolumesBuildManager.cs b/NewHorizons/Builder/Volumes/VolumesBuildManager.cs index f7a664b9..9e9a9c36 100644 --- a/NewHorizons/Builder/Volumes/VolumesBuildManager.cs +++ b/NewHorizons/Builder/Volumes/VolumesBuildManager.cs @@ -1,6 +1,7 @@ using NewHorizons.Builder.Body; using NewHorizons.Builder.ShipLog; using NewHorizons.Builder.Volumes; +using NewHorizons.Components; using NewHorizons.External.Configs; using OWML.Common; using System; @@ -49,6 +50,34 @@ namespace NewHorizons.Builder.Volumes HazardVolumeBuilder.Make(go, sector, planetBody, hazardVolume, mod); } } + if (config.Volumes.mapRestrictionVolumes != null) + { + foreach (var mapRestrictionVolume in config.Volumes.mapRestrictionVolumes) + { + VolumeBuilder.Make(go, sector, mapRestrictionVolume); + } + } + if (config.Volumes.interferenceVolumes != null) + { + foreach (var interferenceVolume in config.Volumes.interferenceVolumes) + { + VolumeBuilder.Make(go, sector, interferenceVolume); + } + } + if (config.Volumes.reverbVolumes != null) + { + foreach (var reverbVolume in config.Volumes.reverbVolumes) + { + VolumeBuilder.Make(go, sector, reverbVolume); + } + } + if (config.Volumes.insulatingVolumes != null) + { + foreach (var insulatingVolume in config.Volumes.insulatingVolumes) + { + VolumeBuilder.Make(go, sector, insulatingVolume); + } + } } } } diff --git a/NewHorizons/Components/BaseVolume.cs b/NewHorizons/Components/BaseVolume.cs new file mode 100644 index 00000000..6ddccada --- /dev/null +++ b/NewHorizons/Components/BaseVolume.cs @@ -0,0 +1,28 @@ +using UnityEngine; + +namespace NewHorizons.Components +{ + [RequireComponent(typeof(OWTriggerVolume))] + public abstract class BaseVolume : MonoBehaviour + { + private OWTriggerVolume _triggerVolume; + + public virtual void Awake() + { + _triggerVolume = this.GetRequiredComponent(); + _triggerVolume.OnEntry += OnTriggerVolumeEntry; + _triggerVolume.OnExit += OnTriggerVolumeExit; + } + + public virtual void OnDestroy() + { + if (_triggerVolume == null) return; + _triggerVolume.OnEntry -= OnTriggerVolumeEntry; + _triggerVolume.OnExit -= OnTriggerVolumeExit; + } + + public abstract void OnTriggerVolumeEntry(GameObject hitObj); + + public abstract void OnTriggerVolumeExit(GameObject hitObj); + } +} diff --git a/NewHorizons/Components/InterferenceVolume.cs b/NewHorizons/Components/InterferenceVolume.cs new file mode 100644 index 00000000..43cf34ac --- /dev/null +++ b/NewHorizons/Components/InterferenceVolume.cs @@ -0,0 +1,54 @@ +using NewHorizons.Handlers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace NewHorizons.Components +{ + public class InterferenceVolume : BaseVolume + { + public override void OnTriggerVolumeEntry(GameObject hitObj) + { + if (hitObj.CompareTag("PlayerDetector")) + { + OnPlayerEnter(); + } + else if (hitObj.CompareTag("ProbeDetector")) + { + OnProbeEnter(); + } + else if (hitObj.CompareTag("ShipDetector")) + { + OnShipEnter(); + } + } + + public override void OnTriggerVolumeExit(GameObject hitObj) + { + if (hitObj.CompareTag("PlayerDetector")) + { + OnPlayerExit(); + } + else if (hitObj.CompareTag("ProbeDetector")) + { + OnProbeExit(); + } + else if (hitObj.CompareTag("ShipDetector")) + { + OnShipExit(); + } + } + + public void OnPlayerEnter() => InterferenceHandler.OnPlayerEnterInterferenceVolume(this); + public void OnPlayerExit() => InterferenceHandler.OnPlayerExitInterferenceVolume(this); + + public void OnProbeEnter() => InterferenceHandler.OnProbeEnterInterferenceVolume(this); + public void OnProbeExit() => InterferenceHandler.OnProbeExitInterferenceVolume(this); + + public void OnShipEnter() => InterferenceHandler.OnShipEnterInterferenceVolume(this); + public void OnShipExit() => InterferenceHandler.OnShipExitInterferenceVolume(this); + } +} diff --git a/NewHorizons/Components/MapRestrictionVolume.cs b/NewHorizons/Components/MapRestrictionVolume.cs new file mode 100644 index 00000000..04442840 --- /dev/null +++ b/NewHorizons/Components/MapRestrictionVolume.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +namespace NewHorizons.Components +{ + public class MapRestrictionVolume : BaseVolume + { + public override void OnTriggerVolumeEntry(GameObject hitObj) + { + if (hitObj.CompareTag("PlayerDetector")) + { + Locator.GetMapController()?.OnPlayerEnterMapRestriction(); + } + } + + public override void OnTriggerVolumeExit(GameObject hitObj) + { + if (hitObj.CompareTag("PlayerDetector")) + { + Locator.GetMapController()?.OnPlayerExitMapRestriction(); + } + } + } +} diff --git a/NewHorizons/Components/NotificationVolume.cs b/NewHorizons/Components/NotificationVolume.cs index 2dc81ed1..6fe7b746 100644 --- a/NewHorizons/Components/NotificationVolume.cs +++ b/NewHorizons/Components/NotificationVolume.cs @@ -7,29 +7,13 @@ using UnityEngine; namespace NewHorizons.Components { - [RequireComponent(typeof(OWTriggerVolume))] - public class NotificationVolume : MonoBehaviour + public class NotificationVolume : BaseVolume { private NotificationTarget _target = NotificationTarget.All; private bool _pin = false; - private OWTriggerVolume _triggerVolume; private NotificationData _entryNotification; private NotificationData _exitNotification; - public void Awake() - { - _triggerVolume = this.GetRequiredComponent(); - _triggerVolume.OnEntry += OnTriggerVolumeEntry; - _triggerVolume.OnExit += OnTriggerVolumeExit; - } - - public void OnDestroy() - { - if (_triggerVolume == null) return; - _triggerVolume.OnEntry -= OnTriggerVolumeEntry; - _triggerVolume.OnExit -= OnTriggerVolumeExit; - } - public void SetPinned(bool pin) => _pin = pin; public void SetTarget(External.Modules.VolumesModule.NotificationVolumeInfo.NotificationTarget target) => SetTarget(EnumUtils.Parse(target.ToString(), NotificationTarget.All)); @@ -46,7 +30,7 @@ namespace NewHorizons.Components _exitNotification = new NotificationData(_target, TranslationHandler.GetTranslation(displayMessage, TranslationHandler.TextType.UI), duration); } - public void OnTriggerVolumeEntry(GameObject hitObj) + public override void OnTriggerVolumeEntry(GameObject hitObj) { if (_target == NotificationTarget.All) { @@ -71,7 +55,7 @@ namespace NewHorizons.Components } } - public void OnTriggerVolumeExit(GameObject hitObj) + public override void OnTriggerVolumeExit(GameObject hitObj) { if (_target == NotificationTarget.All) { diff --git a/NewHorizons/External/Modules/VolumesModule.cs b/NewHorizons/External/Modules/VolumesModule.cs index 43059fbf..a3c810a0 100644 --- a/NewHorizons/External/Modules/VolumesModule.cs +++ b/NewHorizons/External/Modules/VolumesModule.cs @@ -15,27 +15,66 @@ namespace NewHorizons.External.Modules public class VolumesModule { /// - /// Add audio volumes to this planet + /// Add audio volumes to this planet. /// public AudioVolumeInfo[] audioVolumes; /// - /// Add hazard volumes to this planet + /// Add hazard volumes to this planet. /// public HazardVolumeInfo[] hazardVolumes; /// - /// Add notification volumes to this planet + /// Add interference volumes to this planet. + /// + public VolumeInfo[] interferenceVolumes; + + /// + /// Add insulating volumes to this planet. These will stop electricty hazard volumes from affecting you (just like the jellyfish). + /// + public VolumeInfo[] insulatingVolumes; + + /// + /// Add map restriction volumes to this planet. + /// + public VolumeInfo[] mapRestrictionVolumes; + + /// + /// Add notification volumes to this planet. /// public NotificationVolumeInfo[] notificationVolumes; /// - /// Add triggers that reveal parts of the ship log on this planet + /// Add triggers that reveal parts of the ship log on this planet. /// public RevealVolumeInfo[] revealVolumes; + /// + /// Add reverb volumes to this planet. Great for echoes in caves. + /// + public VolumeInfo[] reverbVolumes; + [JsonObject] - public class RevealVolumeInfo + public class VolumeInfo + { + /// + /// The location of this volume. Optional (will default to 0,0,0). + /// + public MVector3 position; + + /// + /// The radius of this volume. + /// + public float radius = 1f; + + /// + /// The relative path from the planet to the parent of this object. Optional (will default to the root sector). + /// + public string parentPath; + } + + [JsonObject] + public class RevealVolumeInfo : VolumeInfo { [JsonConverter(typeof(StringEnumConverter))] public enum RevealVolumeType @@ -57,16 +96,6 @@ namespace NewHorizons.External.Modules /// public float maxDistance = -1f; // Snapshot & Observe Only - /// - /// The position to place this volume at - /// - public MVector3 position; - - /// - /// The radius of this reveal volume - /// - public float radius = 1f; - /// /// What needs to be done to the volume to unlock the facts /// @@ -84,18 +113,8 @@ namespace NewHorizons.External.Modules } [JsonObject] - public class AudioVolumeInfo + public class AudioVolumeInfo : VolumeInfo { - /// - /// The location of this audio volume. Optional (will default to 0,0,0). - /// - public MVector3 position; - - /// - /// The radius of this audio volume - /// - public float radius; - /// /// The audio to use. Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list. /// @@ -113,23 +132,13 @@ namespace NewHorizons.External.Modules } [JsonObject] - public class NotificationVolumeInfo + public class NotificationVolumeInfo : VolumeInfo { /// /// What the notification will show for. /// [DefaultValue("all")] public NotificationTarget target = NotificationTarget.All; - /// - /// The location of this notification volume. Optional (will default to 0,0,0). - /// - public MVector3 position; - - /// - /// The radius of this notification volume. - /// - public float radius; - /// /// The notification that will play when you enter this volume. /// @@ -165,18 +174,8 @@ namespace NewHorizons.External.Modules } [JsonObject] - public class HazardVolumeInfo + public class HazardVolumeInfo : VolumeInfo { - /// - /// The location of this hazard volume. Optional (will default to 0,0,0). - /// - public MVector3 position; - - /// - /// The radius of this hazard volume. - /// - public float radius; - /// /// The type of hazard for this volume. /// @@ -202,7 +201,7 @@ namespace NewHorizons.External.Modules { [EnumMember(Value = @"none")] NONE = 0, [EnumMember(Value = @"general")] GENERAL = 1, - [EnumMember(Value = @"darkMatter")] DARKMATTER = 2, + [EnumMember(Value = @"ghostMatter")] DARKMATTER = 2, [EnumMember(Value = @"heat")] HEAT = 4, [EnumMember(Value = @"fire")] FIRE = 8, [EnumMember(Value = @"sandfall")] SANDFALL = 16, diff --git a/NewHorizons/Handlers/InterferenceHandler.cs b/NewHorizons/Handlers/InterferenceHandler.cs new file mode 100644 index 00000000..97ff0046 --- /dev/null +++ b/NewHorizons/Handlers/InterferenceHandler.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NewHorizons.Handlers +{ + using InterferenceVolume = NewHorizons.Components.InterferenceVolume; + + public static class InterferenceHandler + { + private static List _playerInterference; + private static List _probeInterference; + private static List _shipInterference; + + public static void Init() + { + _playerInterference = new List(); + _probeInterference = new List(); + _shipInterference = new List(); + } + + public static bool PlayerHasInterference() => _playerInterference.Any(volume => volume != null); + public static bool ProbeHasInterference() => _probeInterference.Any(volume => volume != null); + public static bool ShipHasInterference() => _shipInterference.Any(volume => volume != null); + + public static bool IsPlayerSameAsProbe() + { + _playerInterference.RemoveAll(volume => volume == null); + return _playerInterference.All(_probeInterference.Contains) && _playerInterference.Count == _probeInterference.Count; + } + + public static bool IsPlayerSameAsShip() + { + _playerInterference.RemoveAll(volume => volume == null); + return _playerInterference.All(_shipInterference.Contains) && _playerInterference.Count == _shipInterference.Count; + } + + public static void OnPlayerEnterInterferenceVolume(InterferenceVolume interferenceVolume) + { + _playerInterference.SafeAdd(interferenceVolume); + GlobalMessenger.FireEvent("RefreshHUDVisibility"); + } + + public static void OnPlayerExitInterferenceVolume(InterferenceVolume interferenceVolume) + { + _playerInterference.Remove(interferenceVolume); + GlobalMessenger.FireEvent("RefreshHUDVisibility"); + } + + public static void OnProbeEnterInterferenceVolume(InterferenceVolume interferenceVolume) + { + _probeInterference.SafeAdd(interferenceVolume); + GlobalMessenger.FireEvent("RefreshHUDVisibility"); + } + + public static void OnProbeExitInterferenceVolume(InterferenceVolume interferenceVolume) + { + _probeInterference.Remove(interferenceVolume); + GlobalMessenger.FireEvent("RefreshHUDVisibility"); + } + + public static void OnShipEnterInterferenceVolume(InterferenceVolume interferenceVolume) + { + _shipInterference.SafeAdd(interferenceVolume); + GlobalMessenger.FireEvent("RefreshHUDVisibility"); + } + public static void OnShipExitInterferenceVolume(InterferenceVolume interferenceVolume) + { + _shipInterference.Remove(interferenceVolume); + GlobalMessenger.FireEvent("RefreshHUDVisibility"); + } + } +} diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index 80f5dc53..9204ed45 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -305,6 +305,7 @@ namespace NewHorizons AstroObjectLocator.Init(); StreamingHandler.Init(); AudioTypeHandler.Init(); + InterferenceHandler.Init(); RemoteHandler.Init(); AtmosphereBuilder.Init(); BrambleNodeBuilder.Init(BodyDict[CurrentStarSystem].Select(x => x.Config).Where(x => x.Bramble?.dimension != null).ToArray()); diff --git a/NewHorizons/Patches/HUDPatches.cs b/NewHorizons/Patches/HUDPatches.cs index bbb0061a..fc37e4e0 100644 --- a/NewHorizons/Patches/HUDPatches.cs +++ b/NewHorizons/Patches/HUDPatches.cs @@ -1,4 +1,5 @@ using HarmonyLib; +using NewHorizons.Handlers; namespace NewHorizons.Patches { @@ -9,6 +10,8 @@ namespace NewHorizons.Patches [HarmonyPatch(typeof(HUDMarker), nameof(HUDMarker.Awake))] public static void HUDMarker_Awake(HUDMarker __instance) { + GlobalMessenger.AddListener("RefreshHUDVisibility", __instance.RefreshOwnVisibility); + GlobalMessenger.AddListener("RefreshHUDVisibility", __instance.RefreshOwnVisibility); GlobalMessenger.AddListener("PlayerEnterCloakField", __instance.OnPlayerEnterCloakField); GlobalMessenger.AddListener("PlayerExitCloakField", __instance.OnPlayerExitCloakField); } @@ -17,6 +20,8 @@ namespace NewHorizons.Patches [HarmonyPatch(typeof(HUDMarker), nameof(HUDMarker.OnDestroy))] public static void HUDMarker_OnDestroy(HUDMarker __instance) { + GlobalMessenger.RemoveListener("RefreshHUDVisibility", __instance.RefreshOwnVisibility); + GlobalMessenger.RemoveListener("RefreshHUDVisibility", __instance.RefreshOwnVisibility); GlobalMessenger.RemoveListener("PlayerEnterCloakField", __instance.OnPlayerEnterCloakField); GlobalMessenger.RemoveListener("PlayerExitCloakField", __instance.OnPlayerExitCloakField); } @@ -53,11 +58,67 @@ namespace NewHorizons.Patches GlobalMessenger.RemoveListener("ShipExitCloakField", __instance.RefreshOwnVisibility); } + [HarmonyPrefix] + [HarmonyPatch(typeof(ProbeHUDMarker), nameof(ProbeHUDMarker.RefreshOwnVisibility))] + public static bool ProbeHUDMarker_RefreshOwnVisibility(ProbeHUDMarker __instance) + { + bool insideEYE = Locator.GetEyeStateManager() != null && Locator.GetEyeStateManager().IsInsideTheEye(); + bool insideQM = __instance._quantumMoon != null && (__instance._quantumMoon.IsPlayerInside() || __instance._quantumMoon.IsProbeInside()); + bool insideRW = Locator.GetRingWorldController() != null && Locator.GetRingWorldController().isPlayerInside == Locator.GetRingWorldController().isProbeInside; + bool insideIP = Locator.GetCloakFieldController() != null && Locator.GetCloakFieldController().isPlayerInsideCloak == Locator.GetCloakFieldController().isProbeInsideCloak; + bool insideCloak = Components.CloakSectorController.isPlayerInside == Components.CloakSectorController.isProbeInside; + bool sameInterference = InterferenceHandler.IsPlayerSameAsProbe(); + bool isActive = __instance.gameObject.activeInHierarchy || __instance._isTLCDuplicate; + + __instance._isVisible = isActive && !insideEYE && !insideQM && !__instance._translatorEquipped && !__instance._inConversation && __instance._launched && (__instance._isWearingHelmet || __instance._atFlightConsole) && insideRW && insideIP && insideCloak && sameInterference; + + if (__instance._canvasMarker != null) __instance._canvasMarker.SetVisibility(__instance._isVisible); + + return false; + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(ShipHUDMarker), nameof(ShipHUDMarker.RefreshOwnVisibility))] + public static bool ShipHUDMarker_RefreshOwnVisibility(ShipHUDMarker __instance) + { + bool insideEYE = Locator.GetEyeStateManager() != null && Locator.GetEyeStateManager().IsInsideTheEye(); + bool insideQM = __instance._quantumMoon != null && (__instance._quantumMoon.IsPlayerInside() || __instance._quantumMoon.IsShipInside()); + bool insideRW = Locator.GetRingWorldController() != null && Locator.GetRingWorldController().isPlayerInside; + bool insideIP = Locator.GetCloakFieldController() != null ? true : Locator.GetCloakFieldController().isPlayerInsideCloak == Locator.GetCloakFieldController().isShipInsideCloak; + bool insideCloak = Components.CloakSectorController.isPlayerInside == Components.CloakSectorController.isShipInside; + bool sameInterference = InterferenceHandler.IsPlayerSameAsShip(); + + __instance._isVisible = !insideEYE && !insideQM && !insideRW && !__instance._translatorEquipped && !__instance._inConversation && !__instance._shipDestroyed && !__instance._playerInShip && PlayerState.HasPlayerEnteredShip() && __instance._isWearingHelmet && insideIP && insideCloak && sameInterference; + + if (__instance._canvasMarker != null) __instance._canvasMarker.SetVisibility(__instance._isVisible); + + return false; + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(ShipLogEntryHUDMarker), nameof(ShipLogEntryHUDMarker.RefreshOwnVisibility))] + public static bool ShipLogEntryHUDMarker_RefreshOwnVisibility(ShipLogEntryHUDMarker __instance) + { + bool hasEntryLocation = ShipLogEntryHUDMarker.s_entryLocation != null; + bool insideEYE = Locator.GetEyeStateManager() != null && Locator.GetEyeStateManager().IsInsideTheEye(); + bool insideQM = __instance._quantumMoon != null && __instance._quantumMoon.IsPlayerInside(); + bool insideRW = Locator.GetRingWorldController() != null && Locator.GetRingWorldController().isPlayerInside && ShipLogEntryHUDMarker.s_entryLocationID == "IP_RING_WORLD"; + bool insideIP = (hasEntryLocation && ShipLogEntryHUDMarker.s_entryLocation.IsWithinCloakField()) || !(Locator.GetCloakFieldController() != null && Locator.GetCloakFieldController().isPlayerInsideCloak); + bool insideCloak = (hasEntryLocation && ShipLogEntryHUDMarker.s_entryLocation.IsWithinCloakField()) || !Components.CloakSectorController.isPlayerInside; + + __instance._isVisible = (!insideEYE && !insideQM && !insideRW && !__instance._translatorEquipped && !__instance._inConversation && hasEntryLocation && (__instance._isWearingHelmet || __instance._atFlightConsole) && insideIP && insideCloak); + + if (__instance._canvasMarker != null) __instance._canvasMarker.SetVisibility(__instance._isVisible); + + return false; + } + + [HarmonyPostfix] [HarmonyPatch(typeof(ProbeCamera), nameof(ProbeCamera.HasInterference))] public static void ProbeCamera_HasInterference(ProbeCamera __instance, ref bool __result) { - __result = __result || Components.CloakSectorController.isPlayerInside != Components.CloakSectorController.isProbeInside; + __result = __result || (__instance._id != ProbeCamera.ID.PreLaunch && (Components.CloakSectorController.isPlayerInside != Components.CloakSectorController.isProbeInside || !InterferenceHandler.IsPlayerSameAsProbe())); } } } diff --git a/NewHorizons/Schemas/body_schema.json b/NewHorizons/Schemas/body_schema.json index 2a4b8881..b1a756cd 100644 --- a/NewHorizons/Schemas/body_schema.json +++ b/NewHorizons/Schemas/body_schema.json @@ -2395,31 +2395,59 @@ "properties": { "audioVolumes": { "type": "array", - "description": "Add audio volumes to this planet", + "description": "Add audio volumes to this planet.", "items": { "$ref": "#/definitions/AudioVolumeInfo" } }, "hazardVolumes": { "type": "array", - "description": "Add hazard volumes to this planet", + "description": "Add hazard volumes to this planet.", "items": { "$ref": "#/definitions/HazardVolumeInfo" } }, + "interferenceVolumes": { + "type": "array", + "description": "Add interference volumes to this planet.", + "items": { + "$ref": "#/definitions/VolumeInfo" + } + }, + "insulatingVolumes": { + "type": "array", + "description": "Add insulating volumes to this planet. These will stop electricty hazard volumes from affecting you (just like the jellyfish).", + "items": { + "$ref": "#/definitions/VolumeInfo" + } + }, + "mapRestrictionVolumes": { + "type": "array", + "description": "Add map restriction volumes to this planet.", + "items": { + "$ref": "#/definitions/VolumeInfo" + } + }, "notificationVolumes": { "type": "array", - "description": "Add notification volumes to this planet", + "description": "Add notification volumes to this planet.", "items": { "$ref": "#/definitions/NotificationVolumeInfo" } }, "revealVolumes": { "type": "array", - "description": "Add triggers that reveal parts of the ship log on this planet", + "description": "Add triggers that reveal parts of the ship log on this planet.", "items": { "$ref": "#/definitions/RevealVolumeInfo" } + }, + "reverbVolumes": { + "type": "array", + "description": "Add reverb volumes to this planet. Great for echoes in caves.", + "items": { + "$ref": "#/definitions/VolumeInfo" + } } } }, @@ -2428,14 +2456,18 @@ "additionalProperties": false, "properties": { "position": { - "description": "The location of this audio volume. Optional (will default to 0,0,0).", + "description": "The location of this volume. Optional (will default to 0,0,0).", "$ref": "#/definitions/MVector3" }, "radius": { "type": "number", - "description": "The radius of this audio volume", + "description": "The radius of this volume.", "format": "float" }, + "parentPath": { + "type": "string", + "description": "The relative path from the planet to the parent of this object. Optional (will default to the root sector)." + }, "audio": { "type": "string", "description": "The audio to use. Can be a path to a .wav/.ogg/.mp3 file, or taken from the AudioClip list." @@ -2497,14 +2529,18 @@ "additionalProperties": false, "properties": { "position": { - "description": "The location of this hazard volume. Optional (will default to 0,0,0).", + "description": "The location of this volume. Optional (will default to 0,0,0).", "$ref": "#/definitions/MVector3" }, "radius": { "type": "number", - "description": "The radius of this hazard volume.", + "description": "The radius of this volume.", "format": "float" }, + "parentPath": { + "type": "string", + "description": "The relative path from the planet to the parent of this object. Optional (will default to the root sector)." + }, "type": { "description": "The type of hazard for this volume.", "default": "general", @@ -2544,7 +2580,7 @@ "enum": [ "none", "general", - "darkMatter", + "ghostMatter", "heat", "fire", "sandfall", @@ -2566,24 +2602,47 @@ "electrical" ] }, - "NotificationVolumeInfo": { + "VolumeInfo": { "type": "object", "additionalProperties": false, "properties": { - "target": { - "description": "What the notification will show for.", - "default": "all", - "$ref": "#/definitions/NotificationTarget" - }, "position": { - "description": "The location of this notification volume. Optional (will default to 0,0,0).", + "description": "The location of this volume. Optional (will default to 0,0,0).", "$ref": "#/definitions/MVector3" }, "radius": { "type": "number", - "description": "The radius of this notification volume.", + "description": "The radius of this volume.", "format": "float" }, + "parentPath": { + "type": "string", + "description": "The relative path from the planet to the parent of this object. Optional (will default to the root sector)." + } + } + }, + "NotificationVolumeInfo": { + "type": "object", + "additionalProperties": false, + "properties": { + "position": { + "description": "The location of this volume. Optional (will default to 0,0,0).", + "$ref": "#/definitions/MVector3" + }, + "radius": { + "type": "number", + "description": "The radius of this volume.", + "format": "float" + }, + "parentPath": { + "type": "string", + "description": "The relative path from the planet to the parent of this object. Optional (will default to the root sector)." + }, + "target": { + "description": "What the notification will show for.", + "default": "all", + "$ref": "#/definitions/NotificationTarget" + }, "entryNotification": { "description": "The notification that will play when you enter this volume.", "$ref": "#/definitions/NotificationInfo" @@ -2628,6 +2687,19 @@ "type": "object", "additionalProperties": false, "properties": { + "position": { + "description": "The location of this volume. Optional (will default to 0,0,0).", + "$ref": "#/definitions/MVector3" + }, + "radius": { + "type": "number", + "description": "The radius of this volume.", + "format": "float" + }, + "parentPath": { + "type": "string", + "description": "The relative path from the planet to the parent of this object. Optional (will default to the root sector)." + }, "maxAngle": { "type": "number", "description": "The max view angle (in degrees) the player can see the volume with to unlock the fact (`observe` only)", @@ -2638,15 +2710,6 @@ "description": "The max distance the user can be away from the volume to reveal the fact (`snapshot` and `observe` only)", "format": "float" }, - "position": { - "description": "The position to place this volume at", - "$ref": "#/definitions/MVector3" - }, - "radius": { - "type": "number", - "description": "The radius of this reveal volume", - "format": "float" - }, "revealOn": { "description": "What needs to be done to the volume to unlock the facts", "default": "enter",