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
}