diff --git a/Content.Client/TapeRecorder/TapeRecorderSystem.cs b/Content.Client/TapeRecorder/TapeRecorderSystem.cs new file mode 100644 index 00000000000..c228ea356c2 --- /dev/null +++ b/Content.Client/TapeRecorder/TapeRecorderSystem.cs @@ -0,0 +1,24 @@ +using Content.Shared.TapeRecorder; + +namespace Content.Client.TapeRecorder; + +/// +/// Required for client side prediction stuff +/// +public sealed class TapeRecorderSystem : SharedTapeRecorderSystem +{ + private TimeSpan _lastTickTime = TimeSpan.Zero; + + public override void Update(float frameTime) + { + if (!Timing.IsFirstTimePredicted) + return; + + //We need to know the exact time period that has passed since the last update to ensure the tape position is sync'd with the server + //Since the client can skip frames when lagging, we cannot use frameTime + var realTime = (float) (Timing.CurTime - _lastTickTime).TotalSeconds; + _lastTickTime = Timing.CurTime; + + base.Update(realTime); + } +} \ No newline at end of file diff --git a/Content.Client/TapeRecorder/Ui/TapeRecorderBoundUserInterface.cs b/Content.Client/TapeRecorder/Ui/TapeRecorderBoundUserInterface.cs new file mode 100644 index 00000000000..33df6267480 --- /dev/null +++ b/Content.Client/TapeRecorder/Ui/TapeRecorderBoundUserInterface.cs @@ -0,0 +1,64 @@ +using Content.Shared.TapeRecorder.Components; +using Content.Shared.TapeRecorder.Events; +using Robust.Shared.Prototypes; +using Robust.Shared.Timing; + +namespace Content.Client.TapeRecorder.Ui; + +public sealed class TapeRecorderBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey) +{ + [Dependency] private readonly IEntityManager _entMan = default!; + + [ViewVariables] + private TapeRecorderWindow? _window; + + [ViewVariables] + private TimeSpan _printCooldown; + + protected override void Open() + { + base.Open(); + + _window = new(_entMan, Owner); + _window.OnClose += Close; + _window.OnModeChanged += ChangeMode; + _window.OnPrintTranscript += PrintTranscript; + _window.OpenCentered(); + } + + private void ChangeMode(TapeRecorderMode mode) + { + SendMessage(new ChangeModeTapeRecorderMessage(mode)); + } + + private void PrintTranscript() + { + SendMessage(new PrintTapeRecorderMessage()); + + _window?.UpdatePrint(true); + + Timer.Spawn(_printCooldown, () => + { + _window?.UpdatePrint(false); + }); + } + + protected override void UpdateState(BoundUserInterfaceState state) + { + base.UpdateState(state); + + if (state is not TapeRecorderState cast) + return; + + _printCooldown = cast.PrintCooldown; + + _window?.UpdateState(cast); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (disposing) + _window?.Dispose(); + } +} diff --git a/Content.Client/TapeRecorder/Ui/TapeRecorderWindow.xaml b/Content.Client/TapeRecorder/Ui/TapeRecorderWindow.xaml new file mode 100644 index 00000000000..0e22a7815fe --- /dev/null +++ b/Content.Client/TapeRecorder/Ui/TapeRecorderWindow.xaml @@ -0,0 +1,23 @@ + + + + + + + + +