Files
OldThink/Content.Client/Replay/Spectator/ReplaySpectatorSystem.cs

90 lines
3.5 KiB
C#
Raw Permalink Normal View History

2023-06-05 16:44:09 +12:00
using Content.Shared.Movement.Systems;
using Content.Shared.Verbs;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Client.Replays.Playback;
using Robust.Client.State;
using Robust.Shared.Console;
2023-11-11 17:45:46 +11:00
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Serialization.Markdown.Mapping;
2023-06-05 16:44:09 +12:00
namespace Content.Client.Replay.Spectator;
/// <summary>
/// This system handles spawning replay observer ghosts and maintaining their positions when traveling through time.
/// It also blocks most normal interactions, just in case.
/// </summary>
/// <remarks>
/// E.g., if an observer is on a grid, and then jumps forward or backward in time to a point where the grid does not
/// exist, where should the observer go? This attempts to maintain their position and eye rotation or just re-spawns
/// them as needed.
/// </remarks>
public sealed partial class ReplaySpectatorSystem : EntitySystem
{
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IConsoleHost _conHost = default!;
[Dependency] private readonly IStateManager _stateMan = default!;
[Dependency] private readonly TransformSystem _transform = default!;
[Dependency] private readonly SharedMoverController _mover = default!;
[Dependency] private readonly SharedContentEyeSystem _eye = default!;
[Dependency] private readonly IReplayPlaybackManager _replayPlayback = default!;
private SpectatorData? _spectatorData;
2023-06-06 13:01:38 +12:00
public const string SpectateCmd = "replay_spectate";
2023-06-05 16:44:09 +12:00
2023-11-11 17:45:46 +11:00
/// <summary>
/// User Id that corresponds to the local user in a single-player game.
/// </summary>
public static readonly NetUserId DefaultUser = default;
2023-06-05 16:44:09 +12:00
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<GetVerbsEvent<AlternativeVerb>>(OnGetAlternativeVerbs);
SubscribeLocalEvent<ReplaySpectatorComponent, EntityTerminatingEvent>(OnTerminating);
SubscribeLocalEvent<ReplaySpectatorComponent, LocalPlayerDetachedEvent>(OnDetached);
2023-06-06 13:01:38 +12:00
SubscribeLocalEvent<ReplaySpectatorComponent, EntParentChangedMessage>(OnParentChanged);
2023-06-05 16:44:09 +12:00
InitializeBlockers();
_replayPlayback.BeforeSetTick += OnBeforeSetTick;
_replayPlayback.AfterSetTick += OnAfterSetTick;
_replayPlayback.ReplayPlaybackStarted += OnPlaybackStarted;
_replayPlayback.ReplayPlaybackStopped += OnPlaybackStopped;
2023-11-11 17:45:46 +11:00
_replayPlayback.BeforeApplyState += OnBeforeApplyState;
2023-06-05 16:44:09 +12:00
}
public override void Shutdown()
{
base.Shutdown();
_replayPlayback.BeforeSetTick -= OnBeforeSetTick;
_replayPlayback.AfterSetTick -= OnAfterSetTick;
_replayPlayback.ReplayPlaybackStarted -= OnPlaybackStarted;
_replayPlayback.ReplayPlaybackStopped -= OnPlaybackStopped;
2023-11-11 17:45:46 +11:00
_replayPlayback.BeforeApplyState -= OnBeforeApplyState;
2023-06-05 16:44:09 +12:00
}
private void OnPlaybackStarted(MappingDataNode yamlMappingNode, List<object> objects)
2023-06-05 16:44:09 +12:00
{
2023-06-06 13:01:38 +12:00
InitializeMovement();
_conHost.RegisterCommand(SpectateCmd,
Loc.GetString("cmd-replay-spectate-desc"),
Loc.GetString("cmd-replay-spectate-help"),
SpectateCommand,
SpectateCompletions);
if (_replayPlayback.TryGetRecorderEntity(out var recorder))
SpectateEntity(recorder.Value);
else
SetSpectatorPosition(default);
2023-06-05 16:44:09 +12:00
}
2023-06-06 13:01:38 +12:00
private void OnPlaybackStopped()
2023-06-05 16:44:09 +12:00
{
2023-06-06 13:01:38 +12:00
ShutdownMovement();
_conHost.UnregisterCommand(SpectateCmd);
2023-06-05 16:44:09 +12:00
}
}