diff --git a/Content.Server/GameObjects/Components/Timing/UseDelayComponent.cs b/Content.Server/GameObjects/Components/Timing/UseDelayComponent.cs new file mode 100644 index 0000000000..66d79c8d5a --- /dev/null +++ b/Content.Server/GameObjects/Components/Timing/UseDelayComponent.cs @@ -0,0 +1,79 @@ +using System; +using CancellationTokenSource = System.Threading.CancellationTokenSource; +using Content.Shared.GameObjects.Components.Items; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization; +using Robust.Shared.Timers; +using Robust.Shared.IoC; +using Robust.Shared.Interfaces.Timing; + +namespace Content.Server.GameObjects.Components.Timing +{ + /// + /// Timer that creates a cooldown each time an object is activated/used + /// + [RegisterComponent] + public class UseDelayComponent : Component + { + public override string Name => "UseDelay"; + + private TimeSpan _lastUseTime; + + private float _delay; + /// + /// The time, in seconds, between an object's use and when it can be used again + /// + public float Delay { get => _delay; set => _delay = value; } + + public bool ActiveDelay{ get; private set; } + + private CancellationTokenSource cancellationTokenSource; + + public override void ExposeData(ObjectSerializer serializer) + { + base.ExposeData(serializer); + serializer.DataField(ref _delay, "delay", 1); + } + + public void BeginDelay() + { + if (ActiveDelay) + { + return; + } + + ActiveDelay = true; + + cancellationTokenSource = new CancellationTokenSource(); + + Timer.Spawn(TimeSpan.FromSeconds(Delay), () => ActiveDelay = false, cancellationTokenSource.Token); + + _lastUseTime = IoCManager.Resolve().CurTime; + + if (Owner.TryGetComponent(out ItemCooldownComponent cooldown)) + { + cooldown.CooldownStart = _lastUseTime; + cooldown.CooldownEnd = _lastUseTime + TimeSpan.FromSeconds(Delay); + } + + } + + public void Cancel() + { + cancellationTokenSource.Cancel(); + ActiveDelay = false; + + if (Owner.TryGetComponent(out ItemCooldownComponent cooldown)) + { + cooldown.CooldownEnd = IoCManager.Resolve().CurTime; + } + } + + public void Restart() + { + cancellationTokenSource.Cancel(); + ActiveDelay = false; + BeginDelay(); + } + } +} diff --git a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs index b522a2f9c7..bcc6405590 100644 --- a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using Content.Server.GameObjects.Components.Mobs; +using Content.Server.GameObjects.Components.Timing; using Content.Server.Interfaces.GameObjects; using Content.Shared.Input; using JetBrains.Annotations; @@ -560,6 +561,12 @@ namespace Content.Server.GameObjects.EntitySystems /// public void UseInteraction(IEntity user, IEntity used) { + + if (used.TryGetComponent(out var delayComponent)) + { + delayComponent.BeginDelay(); + } + var useMsg = new UseInHandMessage(user, used); RaiseEvent(useMsg); if (useMsg.Handled) diff --git a/Resources/Prototypes/Entities/items/bike_horn.yml b/Resources/Prototypes/Entities/items/bike_horn.yml index 1320f2b012..ff80d83b81 100644 --- a/Resources/Prototypes/Entities/items/bike_horn.yml +++ b/Resources/Prototypes/Entities/items/bike_horn.yml @@ -15,7 +15,12 @@ - type: Item Size: 5 sprite: Objects/Fun/bikehorn.rsi + - type: ItemCooldown - type: Sound - type: EmitSoundOnUse sound: /Audio/items/bikehorn.ogg + + - type: Timing + - type: UseDelay + delay: 0.5