diff --git a/QSB/EchoesOfTheEye/AlarmTotemSync/Patches/AlarmTotemPatches.cs b/QSB/EchoesOfTheEye/AlarmTotemSync/Patches/AlarmTotemPatches.cs index 1d134b37..599dc2d4 100644 --- a/QSB/EchoesOfTheEye/AlarmTotemSync/Patches/AlarmTotemPatches.cs +++ b/QSB/EchoesOfTheEye/AlarmTotemSync/Patches/AlarmTotemPatches.cs @@ -56,44 +56,37 @@ public class AlarmTotemPatches : QSBPatch } } + /// + /// do local fixed update to check for local visibility + /// + /// [HarmonyPrefix] [HarmonyPatch(typeof(AlarmTotem), nameof(AlarmTotem.FixedUpdate))] - private static bool FixedUpdate(AlarmTotem __instance) + private static void FixedUpdate(AlarmTotem __instance) { - var isPlayerVisible = __instance._isPlayerVisible; - __instance._isPlayerVisible = __instance.CheckPlayerVisible(); - if (__instance._isPlayerVisible && !isPlayerVisible) + if (!QSBWorldSync.AllObjectsReady) { - Locator.GetAlarmSequenceController().IncreaseAlarmCounter(); - __instance._simTotemMaterials[0] = __instance._simAlarmMaterial; - __instance._simTotemRenderer.sharedMaterials = __instance._simTotemMaterials; - __instance._simVisionConeRenderer.SetColor(__instance._simAlarmColor); - if (__instance._isTutorialTotem) - { - GlobalMessenger.FireEvent("TutorialAlarmTotemTriggered"); - } - - if (QSBWorldSync.AllObjectsReady) - { - __instance.GetWorldObject() - .SendMessage(new SetVisibleMessage(true)); - } - } - else if (isPlayerVisible && !__instance._isPlayerVisible) - { - Locator.GetAlarmSequenceController().DecreaseAlarmCounter(); - __instance._simTotemMaterials[0] = __instance._origSimEyeMaterial; - __instance._simTotemRenderer.sharedMaterials = __instance._simTotemMaterials; - __instance._simVisionConeRenderer.SetColor(__instance._simVisionConeRenderer.GetOriginalColor()); - __instance._pulseLightController.FadeTo(0f, 0.5f); - - if (QSBWorldSync.AllObjectsReady) - { - __instance.GetWorldObject() - .SendMessage(new SetVisibleMessage(false)); - } + return; } + var qsbAlarmTotem = __instance.GetWorldObject(); + qsbAlarmTotem.FixedUpdate(); + } + + /// + /// check for global visibility + /// + [HarmonyPrefix] + [HarmonyPatch(typeof(AlarmTotem), nameof(AlarmTotem.CheckPlayerVisible))] + private static bool CheckPlayerVisible(AlarmTotem __instance, ref bool __result) + { + if (!QSBWorldSync.AllObjectsReady) + { + return true; + } + + var qsbAlarmTotem = __instance.GetWorldObject(); + __result = qsbAlarmTotem.IsVisible(); return false; } } diff --git a/QSB/EchoesOfTheEye/AlarmTotemSync/WorldObjects/QSBAlarmTotem.cs b/QSB/EchoesOfTheEye/AlarmTotemSync/WorldObjects/QSBAlarmTotem.cs index 2765b458..d80eb1b1 100644 --- a/QSB/EchoesOfTheEye/AlarmTotemSync/WorldObjects/QSBAlarmTotem.cs +++ b/QSB/EchoesOfTheEye/AlarmTotemSync/WorldObjects/QSBAlarmTotem.cs @@ -42,6 +42,8 @@ public class QSBAlarmTotem : WorldObject private void OnPlayerLeave(PlayerInfo player) => _visibleFor.QuickRemove(player.PlayerId); + public bool IsVisible() => _visibleFor.Count > 0; + public void SetVisible(uint playerId, bool visible) { if (visible) @@ -84,4 +86,56 @@ public class QSBAlarmTotem : WorldObject } } } + + #region local visibility + + private bool _isLocallyVisible; + + public void FixedUpdate() + { + var isLocallyVisible = _isLocallyVisible; + _isLocallyVisible = CheckPlayerVisible(); + if (_isLocallyVisible && !isLocallyVisible) + { + Locator.GetAlarmSequenceController().IncreaseAlarmCounter(); + AttachedObject._simTotemMaterials[0] = AttachedObject._simAlarmMaterial; + AttachedObject._simTotemRenderer.sharedMaterials = AttachedObject._simTotemMaterials; + AttachedObject._simVisionConeRenderer.SetColor(AttachedObject._simAlarmColor); + if (AttachedObject._isTutorialTotem) + { + GlobalMessenger.FireEvent("TutorialAlarmTotemTriggered"); + } + } + else if (isLocallyVisible && !_isLocallyVisible) + { + Locator.GetAlarmSequenceController().DecreaseAlarmCounter(); + AttachedObject._simTotemMaterials[0] = AttachedObject._origSimEyeMaterial; + AttachedObject._simTotemRenderer.sharedMaterials = AttachedObject._simTotemMaterials; + AttachedObject._simVisionConeRenderer.SetColor(AttachedObject._simVisionConeRenderer.GetOriginalColor()); + AttachedObject._pulseLightController.FadeTo(0f, 0.5f); + } + } + + private bool CheckPlayerVisible() + { + if (!AttachedObject._isFaceOpen) + { + return false; + } + + var lanternController = Locator.GetDreamWorldController().GetPlayerLantern().GetLanternController(); + var playerLightSensor = Locator.GetPlayerLightSensor(); + if (lanternController.IsHeldByPlayer() && !lanternController.IsConcealed() || playerLightSensor.IsIlluminated()) + { + var position = Locator.GetPlayerCamera().transform.position; + if (AttachedObject.CheckPointInVisionCone(position) && !AttachedObject.CheckLineOccluded(AttachedObject._sightOrigin.position, position)) + { + return true; + } + } + + return false; + } + + #endregion }