From 618a8491bf4a06bfd242418fee2727bd0db5dfc5 Mon Sep 17 00:00:00 2001
From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Date: Tue, 7 Nov 2023 15:07:26 +1100
Subject: [PATCH] Add `BeforeApplyState` event to replay playback (#4536)
---
Robust.Client/Replays/Playback/IReplayPlaybackManager.cs | 8 +++++++-
.../Replays/Playback/ReplayPlaybackManager.Checkpoint.cs | 1 +
.../Replays/Playback/ReplayPlaybackManager.Time.cs | 4 +++-
.../Replays/Playback/ReplayPlaybackManager.Update.cs | 4 +++-
Robust.Client/Replays/Playback/ReplayPlaybackManager.cs | 2 ++
5 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/Robust.Client/Replays/Playback/IReplayPlaybackManager.cs b/Robust.Client/Replays/Playback/IReplayPlaybackManager.cs
index 3073bc754..3793f8140 100644
--- a/Robust.Client/Replays/Playback/IReplayPlaybackManager.cs
+++ b/Robust.Client/Replays/Playback/IReplayPlaybackManager.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Robust.Shared.GameObjects;
+using Robust.Shared.GameStates;
using Robust.Shared.Network;
using Robust.Shared.Replays;
using Robust.Shared.Serialization.Markdown.Mapping;
@@ -128,6 +129,11 @@ public interface IReplayPlaybackManager
///
event Action? ReplayUnpaused;
+ ///
+ /// Invoked just before a replay applies a game state.
+ ///
+ event Action<(GameState Current, GameState? Next)>? BeforeApplyState;
+
///
/// If currently replaying a client-side recording, this is the user that recorded the replay.
/// Useful for setting default observer spawn positions.
@@ -137,5 +143,5 @@ public interface IReplayPlaybackManager
///
/// Fetches the entity that the is currently attached to.
///
- public bool TryGetRecorderEntity([NotNullWhen(true)] out EntityUid? uid);
+ bool TryGetRecorderEntity([NotNullWhen(true)] out EntityUid? uid);
}
diff --git a/Robust.Client/Replays/Playback/ReplayPlaybackManager.Checkpoint.cs b/Robust.Client/Replays/Playback/ReplayPlaybackManager.Checkpoint.cs
index cfd9f77e0..adc8ed124 100644
--- a/Robust.Client/Replays/Playback/ReplayPlaybackManager.Checkpoint.cs
+++ b/Robust.Client/Replays/Playback/ReplayPlaybackManager.Checkpoint.cs
@@ -66,6 +66,7 @@ internal sealed partial class ReplayPlaybackManager
_gameState.ClearDetachQueue();
EnsureDetachedExist(checkpoint);
_gameState.DetachImmediate(checkpoint.Detached);
+ BeforeApplyState?.Invoke((checkpoint.State, next));
_gameState.ApplyGameState(checkpoint.State, next);
}
diff --git a/Robust.Client/Replays/Playback/ReplayPlaybackManager.Time.cs b/Robust.Client/Replays/Playback/ReplayPlaybackManager.Time.cs
index 8be336320..9643ae1ac 100644
--- a/Robust.Client/Replays/Playback/ReplayPlaybackManager.Time.cs
+++ b/Robust.Client/Replays/Playback/ReplayPlaybackManager.Time.cs
@@ -63,7 +63,9 @@ internal sealed partial class ReplayPlaybackManager
// Clear existing lerps
_entMan.EntitySysManager.GetEntitySystem().Reset();
- _gameState.ApplyGameState(state, Replay.NextState);
+ var next = Replay.NextState;
+ BeforeApplyState?.Invoke((state, next));
+ _gameState.ApplyGameState(state, next);
ProcessMessages(Replay.CurMessages, skipEffectEvents);
// TODO REPLAYS block audio
diff --git a/Robust.Client/Replays/Playback/ReplayPlaybackManager.Update.cs b/Robust.Client/Replays/Playback/ReplayPlaybackManager.Update.cs
index b14a36b36..6fb60f36e 100644
--- a/Robust.Client/Replays/Playback/ReplayPlaybackManager.Update.cs
+++ b/Robust.Client/Replays/Playback/ReplayPlaybackManager.Update.cs
@@ -42,7 +42,9 @@ internal sealed partial class ReplayPlaybackManager
{
var state = Replay.CurState;
_gameState.UpdateFullRep(state, cloneDelta: true);
- _gameState.ApplyGameState(state, Replay.NextState);
+ var next = Replay.NextState;
+ BeforeApplyState?.Invoke((state, next));
+ _gameState.ApplyGameState(state, next);
DebugTools.Assert(Replay.LastApplied >= state.FromSequence);
DebugTools.Assert(Replay.LastApplied + 1 <= state.ToSequence);
Replay.LastApplied = state.ToSequence;
diff --git a/Robust.Client/Replays/Playback/ReplayPlaybackManager.cs b/Robust.Client/Replays/Playback/ReplayPlaybackManager.cs
index 22f9f1a24..a8df7fe91 100644
--- a/Robust.Client/Replays/Playback/ReplayPlaybackManager.cs
+++ b/Robust.Client/Replays/Playback/ReplayPlaybackManager.cs
@@ -12,6 +12,7 @@ using Robust.Client.Upload;
using Robust.Shared;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;
+using Robust.Shared.GameStates;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Network;
@@ -44,6 +45,7 @@ internal sealed partial class ReplayPlaybackManager : IReplayPlaybackManager
public event Action? ReplayPlaybackStopped;
public event Action? ReplayPaused;
public event Action? ReplayUnpaused;
+ public event Action<(GameState Current, GameState? Next)>? BeforeApplyState;
public ReplayData? Replay { get; private set; }
public NetUserId? Recorder => Replay?.Recorder;