diff --git a/QSB/QuantumSync/Patches/QuantumPatches.cs b/QSB/QuantumSync/Patches/QuantumPatches.cs index 0da7ade9..4c6eafb4 100644 --- a/QSB/QuantumSync/Patches/QuantumPatches.cs +++ b/QSB/QuantumSync/Patches/QuantumPatches.cs @@ -478,4 +478,10 @@ public class QuantumPatches : QSBPatch return false; } + [HarmonyPrefix] + [HarmonyPatch(typeof(QuantumObject), nameof(QuantumObject.OnProbeSnapshot))] + public static bool OnProbeSnapshot() + { + return false; + } } \ No newline at end of file diff --git a/QSB/QuantumSync/QuantumManager.cs b/QSB/QuantumSync/QuantumManager.cs index 1d932e6e..bc11ae5f 100644 --- a/QSB/QuantumSync/QuantumManager.cs +++ b/QSB/QuantumSync/QuantumManager.cs @@ -126,6 +126,19 @@ internal class QuantumManager : WorldObjectManager return QSBPlayerManager.PlayerList.Where(x => x.EntangledObject == worldObj); } + public static void OnTakeProbeSnapshot(PlayerInfo player, ProbeCamera.ID cameraId) + { + DebugLog.DebugWrite($"{player} took a probe snapshot with cameraid {cameraId}"); + + foreach (var quantumObject in QSBWorldSync.GetWorldObjects()) + { + if (quantumObject.ControllingPlayer == QSBPlayerManager.LocalPlayerId) + { + quantumObject.OnTakeProbeSnapshot(player, cameraId); + } + } + } + #region debug shapes private static GameObject _debugSphere, _debugCube, _debugCapsule; diff --git a/QSB/QuantumSync/WorldObjects/IQSBQuantumObject.cs b/QSB/QuantumSync/WorldObjects/IQSBQuantumObject.cs index 55d43df0..9fdd6ab6 100644 --- a/QSB/QuantumSync/WorldObjects/IQSBQuantumObject.cs +++ b/QSB/QuantumSync/WorldObjects/IQSBQuantumObject.cs @@ -1,4 +1,5 @@ -using QSB.WorldSync; +using QSB.Player; +using QSB.WorldSync; using System.Collections.Generic; namespace QSB.QuantumSync.WorldObjects; @@ -12,4 +13,5 @@ public interface IQSBQuantumObject : IWorldObject void SetIsQuantum(bool isQuantum); VisibilityObject GetVisibilityObject(); + void OnTakeProbeSnapshot(PlayerInfo player, ProbeCamera.ID cameraId); } \ No newline at end of file diff --git a/QSB/QuantumSync/WorldObjects/QSBQuantumObject.cs b/QSB/QuantumSync/WorldObjects/QSBQuantumObject.cs index 9f9011a2..67183f35 100644 --- a/QSB/QuantumSync/WorldObjects/QSBQuantumObject.cs +++ b/QSB/QuantumSync/WorldObjects/QSBQuantumObject.cs @@ -3,6 +3,7 @@ using OWML.Common; using QSB.Messaging; using QSB.Player; using QSB.QuantumSync.Messages; +using QSB.Tools.ProbeTool; using QSB.Utility; using QSB.WorldSync; using System.Collections.Generic; @@ -28,6 +29,8 @@ internal abstract class QSBQuantumObject : WorldObject, IQSBQuantumObject public uint ControllingPlayer { get; set; } public bool IsEnabled { get; private set; } + private List _visibleToProbes = new(); + public override void OnRemoval() { if (HostControls) @@ -174,6 +177,100 @@ internal abstract class QSBQuantumObject : WorldObject, IQSBQuantumObject ((IQSBQuantumObject)this).SendMessage(new QuantumAuthorityMessage(0u)); }); + public void OnTakeProbeSnapshot(PlayerInfo player, ProbeCamera.ID cameraId) + { + DebugLog.DebugWrite($"{AttachedObject.name} OnTakeProbeSnapshot playerId:{player.PlayerId} cameraId:{cameraId}"); + if (player.IsLocalPlayer) + { + DebugLog.DebugWrite($"- is local player"); + var probe = Locator.GetProbe(); + ProbeCamera probeCamera = default; + switch (cameraId) + { + case ProbeCamera.ID.Forward: + probeCamera = probe.GetForwardCamera(); + break; + case ProbeCamera.ID.Reverse: + probeCamera = probe.GetReverseCamera(); + break; + case ProbeCamera.ID.Rotating: + probeCamera = probe.GetRotatingCamera(); + break; + case ProbeCamera.ID.PreLaunch: + probeCamera = player.LocalProbeLauncher._preLaunchCamera; + break; + } + + var distance = Vector3.Distance(AttachedObject.transform.position, probeCamera.transform.position); + DebugLog.DebugWrite($"- distance is {distance}"); + if (distance < AttachedObject._maxSnapshotLockRange + && AttachedObject.IsIlluminated() + && !probeCamera.HasInterference() + && AttachedObject.CheckVisibilityFromProbe(probeCamera.GetOWCamera())) + { + DebugLog.DebugWrite($"- Visible in probe snapshot for local player!"); + if (!_visibleToProbes.Contains(player)) + { + _visibleToProbes.Add(player); + } + + AttachedObject._visibleInProbeSnapshot = _visibleToProbes.Any(x => x != null); + return; + } + else + { + DebugLog.DebugWrite($"- not visible :("); + } + } + else + { + DebugLog.DebugWrite($"- not local player"); + var probe = player.Probe; + QSBProbeCamera probeCamera = default; + switch (cameraId) + { + case ProbeCamera.ID.Forward: + probeCamera = probe.GetForwardCamera(); + break; + case ProbeCamera.ID.Reverse: + probeCamera = probe.GetReverseCamera(); + break; + case ProbeCamera.ID.Rotating: + probeCamera = probe.GetRotatingCamera(); + break; + case ProbeCamera.ID.PreLaunch: + //TODO : uhhhh yeah do this lol + probeCamera = null; + break; + } + + var distance = Vector3.Distance(AttachedObject.transform.position, probeCamera.transform.position); + if (distance < AttachedObject._maxSnapshotLockRange + && AttachedObject.IsIlluminated() + && !probeCamera.HasInterference() + && AttachedObject.CheckVisibilityFromProbe(probeCamera.GetOWCamera())) + { + DebugLog.DebugWrite($"Visible in probe snapshot for {player.PlayerId}!"); + if (!_visibleToProbes.Contains(player)) + { + _visibleToProbes.Add(player); + } + + _visibleToProbes.Add(player); + AttachedObject._visibleInProbeSnapshot = _visibleToProbes.Any(x => x != null); + return; + } + } + + if (_visibleToProbes.Contains(player)) + { + DebugLog.DebugWrite($"NOT visible in probe snapshot for {player.PlayerId}!"); + _visibleToProbes.Remove(player); + } + + AttachedObject._visibleInProbeSnapshot = _visibleToProbes.Any(x => x != null); + } + public override void DisplayLines() { if (AttachedObject == null) diff --git a/QSB/Tools/ProbeLauncherTool/Messages/PlayerLauncherTakeSnapshotMessage.cs b/QSB/Tools/ProbeLauncherTool/Messages/PlayerLauncherTakeSnapshotMessage.cs index 2ff0dfda..93b090d0 100644 --- a/QSB/Tools/ProbeLauncherTool/Messages/PlayerLauncherTakeSnapshotMessage.cs +++ b/QSB/Tools/ProbeLauncherTool/Messages/PlayerLauncherTakeSnapshotMessage.cs @@ -1,16 +1,22 @@ using QSB.Messaging; using QSB.Player; +using QSB.QuantumSync; using QSB.WorldSync; namespace QSB.Tools.ProbeLauncherTool.Messages; -internal class PlayerLauncherTakeSnapshotMessage : QSBMessage +internal class PlayerLauncherTakeSnapshotMessage : QSBMessage { + public PlayerLauncherTakeSnapshotMessage(ProbeCamera.ID cameraId) : base(cameraId) { } + public override bool ShouldReceive => QSBWorldSync.AllObjectsReady; + public override void OnReceiveLocal() => QuantumManager.OnTakeProbeSnapshot(QSBPlayerManager.LocalPlayer, Data); + public override void OnReceiveRemote() { var player = QSBPlayerManager.GetPlayer(From); player.ProbeLauncherTool.TakeSnapshot(); + QuantumManager.OnTakeProbeSnapshot(player, Data); } } diff --git a/QSB/Tools/ProbeLauncherTool/Messages/TakeSnapshotMessage.cs b/QSB/Tools/ProbeLauncherTool/Messages/TakeSnapshotMessage.cs index a92b5b7e..ec88deeb 100644 --- a/QSB/Tools/ProbeLauncherTool/Messages/TakeSnapshotMessage.cs +++ b/QSB/Tools/ProbeLauncherTool/Messages/TakeSnapshotMessage.cs @@ -1,4 +1,6 @@ using QSB.Messaging; +using QSB.Player; +using QSB.QuantumSync; using QSB.Tools.ProbeLauncherTool.WorldObjects; using System; using System.Collections.Generic; @@ -8,9 +10,11 @@ using System.Threading.Tasks; namespace QSB.Tools.ProbeLauncherTool.Messages; -internal class TakeSnapshotMessage : QSBWorldObjectMessage +internal class TakeSnapshotMessage : QSBWorldObjectMessage { - public TakeSnapshotMessage() : base() { } + public TakeSnapshotMessage(ProbeCamera.ID cameraId) : base(cameraId) { } - public override void OnReceiveRemote() => WorldObject.TakeSnapshot(); + public override void OnReceiveLocal() => QuantumManager.OnTakeProbeSnapshot(QSBPlayerManager.LocalPlayer, Data); + + public override void OnReceiveRemote() => WorldObject.TakeSnapshot(QSBPlayerManager.GetPlayer(From), Data); } diff --git a/QSB/Tools/ProbeLauncherTool/Patches/LauncherPatches.cs b/QSB/Tools/ProbeLauncherTool/Patches/LauncherPatches.cs index 40cbeac3..7b04554e 100644 --- a/QSB/Tools/ProbeLauncherTool/Patches/LauncherPatches.cs +++ b/QSB/Tools/ProbeLauncherTool/Patches/LauncherPatches.cs @@ -107,7 +107,7 @@ internal class LauncherPatches : QSBPatch } } - [HarmonyPostfix] + /*[HarmonyPostfix] [HarmonyPatch(typeof(ProbeLauncherEffects), nameof(ProbeLauncherEffects.PlaySnapshotClip))] public static void ProbeLauncherEffects_PlaySnapshotClip(ProbeLauncherEffects __instance) { @@ -122,5 +122,24 @@ internal class LauncherPatches : QSBPatch { new PlayerLauncherTakeSnapshotMessage().Send(); } + }*/ + + [HarmonyPostfix] + [HarmonyPatch(typeof(ProbeLauncher), nameof(ProbeLauncher.TakeSnapshotWithCamera))] + public static void TakeSnapshotWithCamera(ProbeLauncher __instance, ProbeCamera camera) + { + DebugLog.DebugWrite($"TakeSnapshotWithCamera - cameraid:{camera.GetID()}"); + if (__instance != QSBPlayerManager.LocalPlayer.LocalProbeLauncher) + { + DebugLog.DebugWrite($"- not local launcher"); + __instance + ?.GetWorldObject() + ?.SendMessage(new TakeSnapshotMessage(camera.GetID())); + } + else + { + DebugLog.DebugWrite($"- local launcher"); + new PlayerLauncherTakeSnapshotMessage(camera.GetID()).Send(); + } } } \ No newline at end of file diff --git a/QSB/Tools/ProbeLauncherTool/WorldObjects/QSBProbeLauncher.cs b/QSB/Tools/ProbeLauncherTool/WorldObjects/QSBProbeLauncher.cs index 8315228c..87ab16bd 100644 --- a/QSB/Tools/ProbeLauncherTool/WorldObjects/QSBProbeLauncher.cs +++ b/QSB/Tools/ProbeLauncherTool/WorldObjects/QSBProbeLauncher.cs @@ -1,5 +1,7 @@ using Cysharp.Threading.Tasks; using QSB.Messaging; +using QSB.Player; +using QSB.QuantumSync; using QSB.Tools.ProbeLauncherTool.Messages; using QSB.WorldSync; using System.Threading; @@ -66,9 +68,10 @@ public class QSBProbeLauncher : WorldObject AttachedObject._effects.PlayChangeModeClip(); } - public void TakeSnapshot() + public void TakeSnapshot(PlayerInfo player, ProbeCamera.ID cameraId) { // Not using PlaySnapshotClip because that uses Locator.GetPlayerAudioController() instead of owAudioSource for some reason AttachedObject._effects._owAudioSource.PlayOneShot(global::AudioType.ToolProbeTakePhoto, 1f); + QuantumManager.OnTakeProbeSnapshot(player, cameraId); } } \ No newline at end of file diff --git a/QSB/Utility/DebugActions.cs b/QSB/Utility/DebugActions.cs index c741dffd..06c14888 100644 --- a/QSB/Utility/DebugActions.cs +++ b/QSB/Utility/DebugActions.cs @@ -2,6 +2,7 @@ using QSB.ItemSync.WorldObjects.Items; using QSB.Messaging; using QSB.Player; +using QSB.QuantumSync.WorldObjects; using QSB.RespawnSync; using QSB.ShipSync; using QSB.Utility.Messages; @@ -15,7 +16,7 @@ namespace QSB.Utility; public class DebugActions : MonoBehaviour, IAddComponentOnStart { - public static Type WorldObjectSelection; + public static Type WorldObjectSelection = typeof(QSBSocketedQuantumObject); private static void GoToVessel() {