From d745a788ea33616f06f5301f780e5c7dba3ae6c6 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:58:06 +1000 Subject: [PATCH] Fix UseDelay issues (#27336) * Fix UseDelay issues - Fix it not predicting properly by deep-copying the classes (realistically they should be structs). - Fix the `z` path not applying UseDelay similarly to the `e` path. * click --- .../Interaction/SharedInteractionSystem.cs | 4 +-- Content.Shared/Timing/UseDelayComponent.cs | 10 ++++++-- Content.Shared/Timing/UseDelaySystem.cs | 25 +++++++++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/Content.Shared/Interaction/SharedInteractionSystem.cs b/Content.Shared/Interaction/SharedInteractionSystem.cs index 8d49ce31f0..2eabe14d23 100644 --- a/Content.Shared/Interaction/SharedInteractionSystem.cs +++ b/Content.Shared/Interaction/SharedInteractionSystem.cs @@ -973,8 +973,8 @@ namespace Content.Shared.Interaction return false; DoContactInteraction(user, used, activateMsg); - if (delayComponent != null) - _useDelay.TryResetDelay((used, delayComponent)); + // Still need to call this even without checkUseDelay in case this gets relayed from Activate. + _useDelay.TryResetDelay(used, component: delayComponent); if (!activateMsg.WasLogged) _adminLogger.Add(LogType.InteractActivate, LogImpact.Low, $"{ToPrettyString(user):user} activated {ToPrettyString(used):used}"); return true; diff --git a/Content.Shared/Timing/UseDelayComponent.cs b/Content.Shared/Timing/UseDelayComponent.cs index c7b21bd1fe..aa6c66eb81 100644 --- a/Content.Shared/Timing/UseDelayComponent.cs +++ b/Content.Shared/Timing/UseDelayComponent.cs @@ -8,11 +8,11 @@ namespace Content.Shared.Timing; /// Can support additional, separate cooldown timers on the object by passing a unique ID with the system methods. /// [RegisterComponent] -[NetworkedComponent, AutoGenerateComponentState] +[NetworkedComponent] [Access(typeof(UseDelaySystem))] public sealed partial class UseDelayComponent : Component { - [DataField, AutoNetworkedField] + [DataField] public Dictionary Delays = []; /// @@ -27,6 +27,12 @@ public sealed partial class UseDelayComponent : Component public TimeSpan Delay = TimeSpan.FromSeconds(1); } +[Serializable, NetSerializable] +public sealed class UseDelayComponentState : IComponentState +{ + public Dictionary Delays = new(); +} + [Serializable, NetSerializable] [DataDefinition] public sealed partial class UseDelayInfo diff --git a/Content.Shared/Timing/UseDelaySystem.cs b/Content.Shared/Timing/UseDelaySystem.cs index 3d2498203c..bc2a709175 100644 --- a/Content.Shared/Timing/UseDelaySystem.cs +++ b/Content.Shared/Timing/UseDelaySystem.cs @@ -1,4 +1,5 @@ using System.Diagnostics.CodeAnalysis; +using Robust.Shared.GameStates; using Robust.Shared.Timing; namespace Content.Shared.Timing; @@ -16,6 +17,30 @@ public sealed class UseDelaySystem : EntitySystem SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnUnpaused); + SubscribeLocalEvent(OnDelayGetState); + SubscribeLocalEvent(OnDelayHandleState); + } + + private void OnDelayHandleState(Entity ent, ref ComponentHandleState args) + { + if (args.Current is not UseDelayComponentState state) + return; + + ent.Comp.Delays.Clear(); + + // At time of writing sourcegen networking doesn't deep copy so this will mispredict if you try. + foreach (var (key, delay) in state.Delays) + { + ent.Comp.Delays[key] = new UseDelayInfo(delay.Length, delay.StartTime, delay.EndTime); + } + } + + private void OnDelayGetState(Entity ent, ref ComponentGetState args) + { + args.State = new UseDelayComponentState() + { + Delays = ent.Comp.Delays + }; } private void OnMapInit(Entity ent, ref MapInitEvent args)