diff --git a/QSB/QSBCore.cs b/QSB/QSBCore.cs index fe529389..d241a14d 100644 --- a/QSB/QSBCore.cs +++ b/QSB/QSBCore.cs @@ -220,6 +220,16 @@ namespace QSB GUI.Label(new Rect(220, offset, 400f, 20f), $"- Thrusting : {player.JetpackAcceleration?.IsThrusting}"); offset += _debugLineSpacing; } + GUI.Label(new Rect(220, offset, 200f, 20f), $"QM Illuminated : {Locator.GetQuantumMoon().IsIlluminated()}"); + offset += _debugLineSpacing; + GUI.Label(new Rect(220, offset, 200f, 20f), $"QM Visible by :"); + offset += _debugLineSpacing; + var tracker = Locator.GetQuantumMoon().GetValue("_visibilityTracker"); + foreach (var player in QSBPlayerManager.GetPlayersWithCameras()) + { + GUI.Label(new Rect(220, offset, 200f, 20f), $" - {player.PlayerId} : {tracker.GetType().GetMethod("IsInFrustum", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(tracker, new object[] { player.Camera.GetFrustumPlanes() })}"); + offset += _debugLineSpacing; + } if (SocketedObjToDebug == -1) { diff --git a/QSB/QuantumSync/Patches/QuantumPatches.cs b/QSB/QuantumSync/Patches/QuantumPatches.cs index 6553557f..58a561f6 100644 --- a/QSB/QuantumSync/Patches/QuantumPatches.cs +++ b/QSB/QuantumSync/Patches/QuantumPatches.cs @@ -435,7 +435,7 @@ namespace QSB.QuantumSync.Patches fogAlpha = Mathf.InverseLerp(____fogThickness + ____fogRolloffDistance, ____fogThickness, distanceFromFog); if (distanceFromFog < 0f) { - if ((bool)__instance.GetType().GetMethod("IsLockedByProbeSnapshot", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, null) || QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, true)) + if ((bool)__instance.GetType().GetMethod("IsLockedByProbeSnapshot", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, null) || QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, true).First) { ____isPlayerInside = true; __instance.GetType().GetMethod("SetSurfaceState", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, new object[] { ____stateIndex }); @@ -456,7 +456,7 @@ namespace QSB.QuantumSync.Patches if (____stateIndex != 5) { ____isPlayerInside = false; - if (!(bool)__instance.GetType().GetMethod("IsLockedByProbeSnapshot", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, null) && !QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, true)) + if (!(bool)__instance.GetType().GetMethod("IsLockedByProbeSnapshot", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, null) && !QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, true).First) { __instance.GetType().GetMethod("Collapse", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(__instance, new object[] { true }); } diff --git a/QSB/QuantumSync/Patches/QuantumVisibilityPatches.cs b/QSB/QuantumSync/Patches/QuantumVisibilityPatches.cs index b7c484f6..cd5f9b24 100644 --- a/QSB/QuantumSync/Patches/QuantumVisibilityPatches.cs +++ b/QSB/QuantumSync/Patches/QuantumVisibilityPatches.cs @@ -41,7 +41,7 @@ namespace QSB.QuantumSync.Patches public static bool ShapeIsVisibleUsingCameraFrustum(ShapeVisibilityTracker __instance, ref bool __result) { - __result = QuantumManager.IsVisibleUsingCameraFrustum(__instance, false); + __result = QuantumManager.IsVisibleUsingCameraFrustum(__instance, false).First; return false; } diff --git a/QSB/QuantumSync/Patches/ServerQuantumPatches.cs b/QSB/QuantumSync/Patches/ServerQuantumPatches.cs index c4f9859c..8e53c80e 100644 --- a/QSB/QuantumSync/Patches/ServerQuantumPatches.cs +++ b/QSB/QuantumSync/Patches/ServerQuantumPatches.cs @@ -1,8 +1,9 @@ using OWML.Common; using QSB.Events; using QSB.Patches; +using QSB.Player; using QSB.Utility; -using System.Diagnostics; +using System.Linq; using System.Reflection; using UnityEngine; @@ -40,16 +41,36 @@ namespace QSB.QuantumSync.Patches GameObject[] ____deactivateAtEye ) { - if (QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, skipInstantVisibilityCheck) && !QuantumManager.Shrine.IsPlayerInDarkness()) + var isVisibleOutput = QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, skipInstantVisibilityCheck); + //var moonVisible = isVisibleOutput.First; + var moonVisiblePlayers = isVisibleOutput.Second; + var inMoonPlayers = QSBPlayerManager.PlayerList.Where(x => x.IsInMoon); + var inShrinePlayers = QSBPlayerManager.PlayerList.Where(x => x.IsInShrine); + //var outMoonPlayers = QSBPlayerManager.PlayerList.Where(x => !x.IsInMoon); + var outShrinePlayers = QSBPlayerManager.PlayerList.Where(x => !x.IsInShrine); + var shrineLit = QuantumManager.Shrine.IsPlayerInDarkness(); + + // If any of the players in the moon are not in the shrine + if (inMoonPlayers.Any(x => !x.IsInShrine)) { - if (!skipInstantVisibilityCheck) - { - var method = new StackTrace().GetFrame(3).GetMethod(); - DebugLog.ToConsole($"Warning - Tried to change moon state while still observed. Called by {method.DeclaringType}.{method.Name}", MessageType.Warning); - } __result = false; return false; } + + // If any of the players outside the shrine can see the moon + if (outShrinePlayers.Any(moonVisiblePlayers.Contains)) + { + __result = false; + return false; + } + + // If there are players in the shrine and the shrine is not lit + if(inShrinePlayers.Count() != 0 && !shrineLit) + { + __result = false; + return false; + } + var flag = false; if (____isPlayerInside && ____hasSunCollapsed) { @@ -98,7 +119,7 @@ namespace QSB.QuantumSync.Patches { Physics.SyncTransforms(); } - if (__instance.IsPlayerEntangled() || !QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, skipInstantVisibilityCheck)) + if (__instance.IsPlayerEntangled() || !QuantumManager.IsVisibleUsingCameraFrustum((ShapeVisibilityTracker)____visibilityTracker, skipInstantVisibilityCheck).First) { ____moonBody.transform.position = position; if (!Physics.autoSyncTransforms) diff --git a/QSB/QuantumSync/QuantumManager.cs b/QSB/QuantumSync/QuantumManager.cs index 6a56867b..e0d84cd9 100644 --- a/QSB/QuantumSync/QuantumManager.cs +++ b/QSB/QuantumSync/QuantumManager.cs @@ -76,19 +76,22 @@ namespace QSB.QuantumSync } } - public static bool IsVisibleUsingCameraFrustum(ShapeVisibilityTracker tracker, bool ignoreLocalCamera) + public static Tuple> IsVisibleUsingCameraFrustum(ShapeVisibilityTracker tracker, bool ignoreLocalCamera) { var playersWithCameras = QSBPlayerManager.GetPlayersWithCameras(!ignoreLocalCamera); if (playersWithCameras.Count == 0) { DebugLog.ToConsole($"Warning - Trying to run IsVisibleUsingCameraFrustum when there are no players!", MessageType.Warning); - return false; + return new Tuple>(false, null); } if (!tracker.gameObject.activeInHierarchy) { - return false; + return new Tuple>(false, null); } var frustumMethod = tracker.GetType().GetMethod("IsInFrustum", BindingFlags.NonPublic | BindingFlags.Instance); + + var playersWhoCanSee = new List(); + var foundPlayers = false; foreach (var player in playersWithCameras) { if (player.Camera == null) @@ -99,16 +102,18 @@ namespace QSB.QuantumSync var isInFrustum = (bool)frustumMethod.Invoke(tracker, new object[] { player.Camera.GetFrustumPlanes() }); if (isInFrustum) { - return true; + playersWhoCanSee.Add(player); + foundPlayers = true; } } - return false; + + return new Tuple>(foundPlayers, playersWhoCanSee); } public static bool IsVisible(ShapeVisibilityTracker tracker, bool ignoreLocalCamera) { return tracker.gameObject.activeInHierarchy - && IsVisibleUsingCameraFrustum(tracker, ignoreLocalCamera) + && IsVisibleUsingCameraFrustum(tracker, ignoreLocalCamera).First && QSBPlayerManager.GetPlayersWithCameras(!ignoreLocalCamera) .Any(x => VisibilityOccluder.CanYouSee(tracker, x.Camera.mainCamera.transform.position)); }