diff --git a/NewHorizons/Components/InterferenceVolume.cs b/NewHorizons/Components/InterferenceVolume.cs index b13276c5..2b2881fd 100644 --- a/NewHorizons/Components/InterferenceVolume.cs +++ b/NewHorizons/Components/InterferenceVolume.cs @@ -10,19 +10,21 @@ namespace NewHorizons.Components { public class InterferenceVolume : BaseVolume { + private string _id = Guid.NewGuid().ToString(); + public override void OnTriggerVolumeEntry(GameObject hitObj) { if (hitObj.CompareTag("PlayerDetector")) { - InterferenceHandler.OnPlayerEnterInterferenceVolume(); + InterferenceHandler.OnPlayerEnterInterferenceVolume(_id); } else if (hitObj.CompareTag("ProbeDetector")) { - InterferenceHandler.OnProbeEnterInterferenceVolume(); + InterferenceHandler.OnProbeEnterInterferenceVolume(_id); } else if (hitObj.CompareTag("ShipDetector")) { - InterferenceHandler.OnShipEnterInterferenceVolume(); + InterferenceHandler.OnShipEnterInterferenceVolume(_id); } } @@ -30,16 +32,25 @@ namespace NewHorizons.Components { if (hitObj.CompareTag("PlayerDetector")) { - InterferenceHandler.OnPlayerExitInterferenceVolume(); + InterferenceHandler.OnPlayerExitInterferenceVolume(_id); } else if (hitObj.CompareTag("ProbeDetector")) { - InterferenceHandler.OnProbeExitInterferenceVolume(); + InterferenceHandler.OnProbeExitInterferenceVolume(_id); } else if (hitObj.CompareTag("ShipDetector")) { - InterferenceHandler.OnShipExitInterferenceVolume(); + InterferenceHandler.OnShipExitInterferenceVolume(_id); } } + + public void OnPlayerEnter() => InterferenceHandler.OnPlayerEnterInterferenceVolume(_id); + public void OnPlayerExit() => InterferenceHandler.OnPlayerExitInterferenceVolume(_id); + + public void OnProbeEnter() => InterferenceHandler.OnProbeEnterInterferenceVolume(_id); + public void OnProbeExit() => InterferenceHandler.OnProbeExitInterferenceVolume(_id); + + public void OnShipEnter() => InterferenceHandler.OnShipEnterInterferenceVolume(_id); + public void OnShipExit() => InterferenceHandler.OnShipExitInterferenceVolume(_id); } } diff --git a/NewHorizons/Handlers/InterferenceHandler.cs b/NewHorizons/Handlers/InterferenceHandler.cs index 71384f02..2e854afa 100644 --- a/NewHorizons/Handlers/InterferenceHandler.cs +++ b/NewHorizons/Handlers/InterferenceHandler.cs @@ -8,21 +8,57 @@ namespace NewHorizons.Handlers { public static class InterferenceHandler { - public static bool _playerInterference; - public static bool _probeInterference; - public static bool _shipInterference; + private static List _playerInterference; + private static List _probeInterference; + private static List _shipInterference; - public static bool PlayerHasInterference() => _playerInterference; - public static bool ProbeHasInterference() => _probeInterference; - public static bool ShipHasInterference() => _shipInterference; + public static void Init() + { + _playerInterference = new List(); + _probeInterference = new List(); + _shipInterference = new List(); + } - public static void OnPlayerEnterInterferenceVolume() => _playerInterference = true; - public static void OnPlayerExitInterferenceVolume() => _playerInterference = false; + public static bool PlayerHasInterference() => _playerInterference.Any(); + public static bool ProbeHasInterference() => _probeInterference.Any(); + public static bool ShipHasInterference() => _shipInterference.Any(); - public static void OnProbeEnterInterferenceVolume() => _probeInterference = true; - public static void OnProbeExitInterferenceVolume() => _probeInterference = false; + public static bool IsPlayerSameAsProbe() => _playerInterference.All(_probeInterference.Contains) && _playerInterference.Count == _probeInterference.Count; + public static bool IsPlayerSameAsShip() => _playerInterference.All(_shipInterference.Contains) && _playerInterference.Count == _shipInterference.Count; - public static void OnShipEnterInterferenceVolume() => _shipInterference = true; - public static void OnShipExitInterferenceVolume() => _shipInterference = false; + public static void OnPlayerEnterInterferenceVolume(string id) + { + _playerInterference.SafeAdd(id); + GlobalMessenger.FireEvent("RefreshHUDVisibility"); + } + + public static void OnPlayerExitInterferenceVolume(string id) + { + _playerInterference.Remove(id); + GlobalMessenger.FireEvent("RefreshHUDVisibility"); + } + + public static void OnProbeEnterInterferenceVolume(string id) + { + _probeInterference.SafeAdd(id); + GlobalMessenger.FireEvent("RefreshHUDVisibility"); + } + + public static void OnProbeExitInterferenceVolume(string id) + { + _probeInterference.Remove(id); + GlobalMessenger.FireEvent("RefreshHUDVisibility"); + } + + public static void OnShipEnterInterferenceVolume(string id) + { + _shipInterference.SafeAdd(id); + GlobalMessenger.FireEvent("RefreshHUDVisibility"); + } + public static void OnShipExitInterferenceVolume(string id) + { + _shipInterference.Remove(id); + 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 adcde38e..fc37e4e0 100644 --- a/NewHorizons/Patches/HUDPatches.cs +++ b/NewHorizons/Patches/HUDPatches.cs @@ -10,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); } @@ -18,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); } @@ -54,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 || (__instance._id != ProbeCamera.ID.PreLaunch && (Components.CloakSectorController.isPlayerInside != Components.CloakSectorController.isProbeInside || InterferenceHandler.PlayerHasInterference() != InterferenceHandler.ProbeHasInterference())); + __result = __result || (__instance._id != ProbeCamera.ID.PreLaunch && (Components.CloakSectorController.isPlayerInside != Components.CloakSectorController.isProbeInside || !InterferenceHandler.IsPlayerSameAsProbe())); } } }