From 9c522c8b19f7a6f6b396c66342413572a22d7845 Mon Sep 17 00:00:00 2001 From: AJCM-git <60196617+AJCM-git@users.noreply.github.com> Date: Wed, 3 Jan 2024 21:33:09 -0400 Subject: [PATCH] UseDelay + ItemCooldown merge (#22502) --- .../Inventory/ClientInventorySystem.cs | 12 -- .../Systems/Hands/HandsUIController.cs | 11 +- .../Atmos/EntitySystems/FlammableSystem.cs | 14 +- Content.Server/Bible/BibleSystem.cs | 40 +++--- .../Cargo/Systems/PriceGunSystem.cs | 13 +- .../EntitySystems/ChemistrySystemHypospray.cs | 12 +- Content.Server/Cooldown/ItemCooldownSystem.cs | 32 ----- .../DeviceLinking/Systems/LogicGateSystem.cs | 7 +- .../Systems/PowerSensorSystem.cs | 14 +- .../DeviceLinking/Systems/SignallerSystem.cs | 11 +- .../Fluids/EntitySystems/AbsorbentSystem.cs | 30 ++-- .../Fluids/EntitySystems/SpraySystem.cs | 20 ++- .../IgnitionSource/IgniteOnTriggerSystem.cs | 6 +- .../Inventory/ServerInventorySystem.cs | 13 -- Content.Server/Medical/DefibrillatorSystem.cs | 5 +- .../Interactions/InteractWithOperator.cs | 5 +- .../Ninja/Systems/NinjaSuitSystem.cs | 17 ++- .../Power/Generator/PowerSwitchableSystem.cs | 4 +- .../Components/RadiationCollectorComponent.cs | 37 ++--- .../EntitySystems/RadiationCollectorSystem.cs | 43 +++--- .../Storage/EntitySystems/StorageSystem.cs | 9 +- .../Equipment/Systems/NodeScannerSystem.cs | 7 +- .../Clothing/EntitySystems/ClothingSystem.cs | 60 +++++++- Content.Shared/Cooldown/Cooldowns.cs | 26 ---- .../Cooldown/ItemCooldownComponent.cs | 51 ------- .../Interaction/Events/UseInHandEvent.cs | 10 +- .../Interaction/SharedInteractionSystem.cs | 16 +-- .../Inventory/InventorySystem.Equip.cs | 41 ------ .../Equipment/Systems/MechSoundboardSystem.cs | 12 +- .../Ninja/Systems/SharedNinjaGlovesSystem.cs | 3 - .../Ninja/Systems/SharedNinjaSuitSystem.cs | 6 +- Content.Shared/Timing/UseDelayComponent.cs | 36 +++-- Content.Shared/Timing/UseDelaySystem.cs | 129 +++++------------- .../Weapons/Misc/SharedGrapplingGunSystem.cs | 8 +- .../Ranged/Systems/UseDelayOnShootSystem.cs | 3 +- Content.Shared/Wieldable/WieldableSystem.cs | 22 +-- Resources/Maps/aspid.yml | 4 - Resources/Maps/cluster.yml | 4 +- Resources/Maps/europa.yml | 2 +- Resources/Maps/gemini.yml | 2 - Resources/Maps/marathon.yml | 1 - Resources/Maps/meta.yml | 1 - Resources/Maps/origin.yml | 24 ---- Resources/Maps/saltern.yml | 2 - .../Objects/Consumable/Drinks/drinks_cans.yml | 1 - .../Objects/Consumable/Drinks/drinks_cups.yml | 1 - .../reinforcement_teleporter.yml | 1 - .../Objects/Devices/holoprojectors.yml | 2 - .../Entities/Objects/Fun/bike_horn.yml | 3 +- .../Prototypes/Entities/Objects/Fun/darts.yml | 3 +- .../Prototypes/Entities/Objects/Fun/dice.yml | 1 - .../Prototypes/Entities/Objects/Fun/skub.yml | 1 - .../Prototypes/Entities/Objects/Fun/toys.yml | 4 +- .../Objects/Materials/crystal_shard.yml | 1 - .../Entities/Objects/Materials/shards.yml | 1 - .../Entities/Objects/Misc/broken_bottle.yml | 2 - .../Entities/Objects/Misc/desk_bell.yml | 1 - .../Objects/Misc/fire_extinguisher.yml | 2 +- .../Entities/Objects/Misc/paper.yml | 1 - .../Objects/Specific/Chapel/bibles.yml | 1 - .../Objects/Specific/Hydroponics/sprays.yml | 1 - .../Objects/Specific/Hydroponics/tools.yml | 5 - .../Objects/Specific/Janitorial/janitor.yml | 1 - .../Objects/Specific/Janitorial/spray.yml | 2 +- .../Objects/Specific/Medical/defib.yml | 1 - .../Objects/Specific/Medical/surgery.yml | 5 - .../Service/vending_machine_restock.yml | 1 - .../Entities/Objects/Tools/cowtools.yml | 5 - .../Entities/Objects/Tools/lighters.yml | 2 +- .../Entities/Objects/Tools/toolbox.yml | 1 - .../Entities/Objects/Tools/tools.yml | 7 - .../Entities/Objects/Tools/welders.yml | 2 +- .../Entities/Objects/Weapons/Melee/knife.yml | 1 - .../Objects/Weapons/Melee/pickaxe.yml | 3 - .../Entities/Objects/Weapons/Melee/spear.yml | 2 - .../Objects/Weapons/Melee/stunprod.yml | 2 +- .../Entities/Objects/Weapons/security.yml | 4 +- .../Generation/Singularity/collector.yml | 14 +- .../Structures/Specific/Anomaly/cores.yml | 1 - .../XenoArch/Effects/utility_effects.yml | 2 +- 80 files changed, 324 insertions(+), 589 deletions(-) delete mode 100644 Content.Server/Cooldown/ItemCooldownSystem.cs delete mode 100644 Content.Shared/Cooldown/Cooldowns.cs delete mode 100644 Content.Shared/Cooldown/ItemCooldownComponent.cs diff --git a/Content.Client/Inventory/ClientInventorySystem.cs b/Content.Client/Inventory/ClientInventorySystem.cs index d4615210f2..7b98513a92 100644 --- a/Content.Client/Inventory/ClientInventorySystem.cs +++ b/Content.Client/Inventory/ClientInventorySystem.cs @@ -1,9 +1,7 @@ using Content.Client.Clothing; using Content.Client.Examine; using Content.Client.Verbs.UI; -using Content.Shared.Clothing.Components; using Content.Shared.Interaction; -using Content.Shared.Interaction.Events; using Content.Shared.Inventory; using Content.Shared.Inventory.Events; using Content.Shared.Storage; @@ -48,8 +46,6 @@ namespace Content.Client.Inventory _equipEventsQueue.Enqueue((comp, args))); SubscribeLocalEvent((_, comp, args) => _equipEventsQueue.Enqueue((comp, args))); - - SubscribeLocalEvent(OnUseInHand); } public override void Update(float frameTime) @@ -74,14 +70,6 @@ namespace Content.Client.Inventory } } - private void OnUseInHand(EntityUid uid, ClothingComponent component, UseInHandEvent args) - { - if (args.Handled || !component.QuickEquip) - return; - - QuickEquip(uid, component, args); - } - private void OnDidUnequip(InventorySlotsComponent component, DidUnequipEvent args) { UpdateSlot(args.Equipee, component, args.Slot); diff --git a/Content.Client/UserInterface/Systems/Hands/HandsUIController.cs b/Content.Client/UserInterface/Systems/Hands/HandsUIController.cs index 09d6a080ef..a15f1cbb76 100644 --- a/Content.Client/UserInterface/Systems/Hands/HandsUIController.cs +++ b/Content.Client/UserInterface/Systems/Hands/HandsUIController.cs @@ -3,10 +3,9 @@ using Content.Client.Hands.Systems; using Content.Client.UserInterface.Controls; using Content.Client.UserInterface.Systems.Hands.Controls; using Content.Client.UserInterface.Systems.Hotbar.Widgets; -using Content.Shared.Cooldown; using Content.Shared.Hands.Components; using Content.Shared.Input; -using Robust.Client.GameObjects; +using Content.Shared.Timing; using Robust.Client.Player; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controllers; @@ -247,7 +246,7 @@ public sealed class HandsUIController : UIController, IOnStateEntered, float> _fireEvents = new(); - private readonly List _toRemove = new(); public override void Initialize() { @@ -157,10 +151,11 @@ namespace Content.Server.Atmos.EntitySystems args.Handled = true; - if (!_useDelay.BeginDelay(uid)) + if (!TryComp(uid, out UseDelayComponent? useDelay) || !_useDelay.TryResetDelay((uid, useDelay), true)) return; _audio.PlayPvs(component.ExtinguishAttemptSound, uid); + if (_random.Prob(component.Probability)) { AdjustFireStacks(uid, component.StackDelta, flammable); @@ -170,6 +165,7 @@ namespace Content.Server.Atmos.EntitySystems _popup.PopupEntity(Loc.GetString(component.ExtinguishFailed), uid); } } + private void OnCollide(EntityUid uid, FlammableComponent flammable, ref StartCollideEvent args) { var otherUid = args.OtherEntity; @@ -364,7 +360,7 @@ namespace Content.Server.Atmos.EntitySystems // TODO: This needs cleanup to take off the crust from TemperatureComponent and shit. var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var flammable, out var transform)) + while (query.MoveNext(out var uid, out var flammable, out _)) { // Slowly dry ourselves off if wet. if (flammable.FireStacks < 0) @@ -394,7 +390,7 @@ namespace Content.Server.Atmos.EntitySystems EnsureComp(uid); _ignitionSourceSystem.SetIgnited(uid); - var damageScale = MathF.Min(flammable.FireStacks, 5); + var damageScale = MathF.Min( flammable.FireStacks, 5); if (TryComp(uid, out TemperatureComponent? temp)) _temperatureSystem.ChangeHeat(uid, 12500 * damageScale, false, temp); diff --git a/Content.Server/Bible/BibleSystem.cs b/Content.Server/Bible/BibleSystem.cs index 5c153bb464..c845b17230 100644 --- a/Content.Server/Bible/BibleSystem.cs +++ b/Content.Server/Bible/BibleSystem.cs @@ -32,6 +32,7 @@ namespace Content.Server.Bible [Dependency] private readonly SharedActionsSystem _actionsSystem = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly UseDelaySystem _delay = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; public override void Initialize() { @@ -55,20 +56,20 @@ namespace Content.Server.Bible { base.Update(frameTime); - foreach(var entity in _addQueue) + foreach (var entity in _addQueue) { EnsureComp(entity); } _addQueue.Clear(); - foreach(var entity in _remQueue) + foreach (var entity in _remQueue) { RemComp(entity); } _remQueue.Clear(); var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var respawning, out var summonableComp)) + while (query.MoveNext(out var uid, out var _, out var summonableComp)) { summonableComp.Accumulator += frameTime; if (summonableComp.Accumulator < summonableComp.RespawnTime) @@ -82,8 +83,8 @@ namespace Content.Server.Bible summonableComp.Summon = null; } summonableComp.AlreadySummoned = false; - _popupSystem.PopupEntity(Loc.GetString("bible-summon-respawn-ready", ("book", summonableComp.Owner)), summonableComp.Owner, PopupType.Medium); - _audio.PlayPvs("/Audio/Effects/radpulse9.ogg", summonableComp.Owner, AudioParams.Default.WithVolume(-4f)); + _popupSystem.PopupEntity(Loc.GetString("bible-summon-respawn-ready", ("book", uid)), uid, PopupType.Medium); + _audio.PlayPvs("/Audio/Effects/radpulse9.ogg", uid, AudioParams.Default.WithVolume(-4f)); // Clean up the accumulator and respawn tracking component summonableComp.Accumulator = 0; _remQueue.Enqueue(uid); @@ -95,9 +96,7 @@ namespace Content.Server.Bible if (!args.CanReach) return; - UseDelayComponent? delay = null; - - if (_delay.ActiveDelay(uid, delay)) + if (!TryComp(uid, out UseDelayComponent? useDelay) || _delay.IsDelayed((uid, useDelay))) return; if (args.Target == null || args.Target == args.User || !_mobStateSystem.IsAlive(args.Target.Value)) @@ -111,7 +110,7 @@ namespace Content.Server.Bible _audio.PlayPvs(component.SizzleSoundPath, args.User); _damageableSystem.TryChangeDamage(args.User, component.DamageOnUntrainedUse, true, origin: uid); - _delay.BeginDelay(uid, delay); + _delay.TryResetDelay((uid, useDelay)); return; } @@ -121,15 +120,15 @@ namespace Content.Server.Bible { if (_random.Prob(component.FailChance)) { - var othersFailMessage = Loc.GetString(component.LocPrefix + "-heal-fail-others", ("user", Identity.Entity(args.User, EntityManager)),("target", Identity.Entity(args.Target.Value, EntityManager)),("bible", uid)); + var othersFailMessage = Loc.GetString(component.LocPrefix + "-heal-fail-others", ("user", Identity.Entity(args.User, EntityManager)), ("target", Identity.Entity(args.Target.Value, EntityManager)), ("bible", uid)); _popupSystem.PopupEntity(othersFailMessage, args.User, Filter.PvsExcept(args.User), true, PopupType.SmallCaution); - var selfFailMessage = Loc.GetString(component.LocPrefix + "-heal-fail-self", ("target", Identity.Entity(args.Target.Value, EntityManager)),("bible", uid)); + var selfFailMessage = Loc.GetString(component.LocPrefix + "-heal-fail-self", ("target", Identity.Entity(args.Target.Value, EntityManager)), ("bible", uid)); _popupSystem.PopupEntity(selfFailMessage, args.User, args.User, PopupType.MediumCaution); _audio.PlayPvs("/Audio/Effects/hit_kick.ogg", args.User); _damageableSystem.TryChangeDamage(args.Target.Value, component.DamageOnFail, true, origin: uid); - _delay.BeginDelay(uid, delay); + _delay.TryResetDelay((uid, useDelay)); return; } } @@ -138,21 +137,21 @@ namespace Content.Server.Bible if (damage == null || damage.Empty) { - var othersMessage = Loc.GetString(component.LocPrefix + "-heal-success-none-others", ("user", Identity.Entity(args.User, EntityManager)),("target", Identity.Entity(args.Target.Value, EntityManager)),("bible", uid)); + var othersMessage = Loc.GetString(component.LocPrefix + "-heal-success-none-others", ("user", Identity.Entity(args.User, EntityManager)), ("target", Identity.Entity(args.Target.Value, EntityManager)), ("bible", uid)); _popupSystem.PopupEntity(othersMessage, args.User, Filter.PvsExcept(args.User), true, PopupType.Medium); - var selfMessage = Loc.GetString(component.LocPrefix + "-heal-success-none-self", ("target", Identity.Entity(args.Target.Value, EntityManager)),("bible", uid)); + var selfMessage = Loc.GetString(component.LocPrefix + "-heal-success-none-self", ("target", Identity.Entity(args.Target.Value, EntityManager)), ("bible", uid)); _popupSystem.PopupEntity(selfMessage, args.User, args.User, PopupType.Large); } else { - var othersMessage = Loc.GetString(component.LocPrefix + "-heal-success-others", ("user", Identity.Entity(args.User, EntityManager)),("target", Identity.Entity(args.Target.Value, EntityManager)),("bible", uid)); + var othersMessage = Loc.GetString(component.LocPrefix + "-heal-success-others", ("user", Identity.Entity(args.User, EntityManager)), ("target", Identity.Entity(args.Target.Value, EntityManager)), ("bible", uid)); _popupSystem.PopupEntity(othersMessage, args.User, Filter.PvsExcept(args.User), true, PopupType.Medium); - var selfMessage = Loc.GetString(component.LocPrefix + "-heal-success-self", ("target", Identity.Entity(args.Target.Value, EntityManager)),("bible", uid)); + var selfMessage = Loc.GetString(component.LocPrefix + "-heal-success-self", ("target", Identity.Entity(args.Target.Value, EntityManager)), ("bible", uid)); _popupSystem.PopupEntity(selfMessage, args.User, args.User, PopupType.Large); _audio.PlayPvs(component.HealSoundPath, args.User); - _delay.BeginDelay(uid, delay); + _delay.TryResetDelay((uid, useDelay)); } } @@ -168,7 +167,8 @@ namespace Content.Server.Bible { Act = () => { - if (!TryComp(args.User, out var userXform)) return; + if (!TryComp(args.User, out var userXform)) + return; AttemptSummon((uid, component), args.User, userXform); }, @@ -236,13 +236,13 @@ namespace Content.Server.Bible // Make this familiar the component's summon var familiar = EntityManager.SpawnEntity(component.SpecialItemPrototype, position.Coordinates); - component.Summon = familiar; + component.Summon = familiar; // If this is going to use a ghost role mob spawner, attach it to the bible. if (HasComp(familiar)) { _popupSystem.PopupEntity(Loc.GetString("bible-summon-requested"), user, PopupType.Medium); - Transform(familiar).AttachParent(uid); + _transform.SetParent(familiar, uid); } component.AlreadySummoned = true; _actionsSystem.RemoveAction(user, component.SummonActionEntity); diff --git a/Content.Server/Cargo/Systems/PriceGunSystem.cs b/Content.Server/Cargo/Systems/PriceGunSystem.cs index 23bded1d42..d7d708821c 100644 --- a/Content.Server/Cargo/Systems/PriceGunSystem.cs +++ b/Content.Server/Cargo/Systems/PriceGunSystem.cs @@ -4,7 +4,6 @@ using Content.Shared.IdentityManagement; using Content.Shared.Interaction; using Content.Shared.Timing; using Content.Shared.Verbs; -using Robust.Shared.Player; namespace Content.Server.Cargo.Systems; @@ -26,11 +25,10 @@ public sealed class PriceGunSystem : EntitySystem private void OnUtilityVerb(EntityUid uid, PriceGunComponent component, GetVerbsEvent args) { - - if (!args.CanAccess || !args.CanInteract) + if (!args.CanAccess || !args.CanInteract || args.Using == null) return; - if (TryComp(args.Using, out UseDelayComponent? useDelay) && useDelay.ActiveDelay) + if (!TryComp(uid, out UseDelayComponent? useDelay) || _useDelay.IsDelayed((uid, useDelay))) return; var price = _pricingSystem.GetPrice(args.Target); @@ -40,7 +38,7 @@ public sealed class PriceGunSystem : EntitySystem Act = () => { _popupSystem.PopupEntity(Loc.GetString("price-gun-pricing-result", ("object", Identity.Entity(args.Target, EntityManager)), ("price", $"{price:F2}")), args.User, args.User); - _useDelay.BeginDelay(uid, useDelay); + _useDelay.TryResetDelay((uid, useDelay)); }, Text = Loc.GetString("price-gun-verb-text"), Message = Loc.GetString("price-gun-verb-message", ("object", Identity.Entity(args.Target, EntityManager))) @@ -48,18 +46,19 @@ public sealed class PriceGunSystem : EntitySystem args.Verbs.Add(verb); } + private void OnAfterInteract(EntityUid uid, PriceGunComponent component, AfterInteractEvent args) { if (!args.CanReach || args.Target == null || args.Handled) return; - if (TryComp(args.Used, out UseDelayComponent? useDelay) && useDelay.ActiveDelay) + if (!TryComp(uid, out UseDelayComponent? useDelay) || _useDelay.IsDelayed((uid, useDelay))) return; var price = _pricingSystem.GetPrice(args.Target.Value); _popupSystem.PopupEntity(Loc.GetString("price-gun-pricing-result", ("object", Identity.Entity(args.Target.Value, EntityManager)), ("price", $"{price:F2}")), args.User, args.User); - _useDelay.BeginDelay(uid, useDelay); + _useDelay.TryResetDelay((uid, useDelay)); args.Handled = true; } } diff --git a/Content.Server/Chemistry/EntitySystems/ChemistrySystemHypospray.cs b/Content.Server/Chemistry/EntitySystems/ChemistrySystemHypospray.cs index 9c1b5130a2..be8faec984 100644 --- a/Content.Server/Chemistry/EntitySystems/ChemistrySystemHypospray.cs +++ b/Content.Server/Chemistry/EntitySystems/ChemistrySystemHypospray.cs @@ -79,8 +79,12 @@ namespace Content.Server.Chemistry.EntitySystems if (!EligibleEntity(target, _entMan, component)) return false; - if (TryComp(uid, out UseDelayComponent? delayComp) && _useDelay.ActiveDelay(uid, delayComp)) - return false; + if (TryComp(uid, out UseDelayComponent? delayComp)) + { + if (_useDelay.IsDelayed((uid, delayComp))) + return false; + } + string? msgFormat = null; @@ -117,8 +121,8 @@ namespace Content.Server.Chemistry.EntitySystems // Medipens and such use this system and don't have a delay, requiring extra checks // BeginDelay function returns if item is already on delay - if (delayComp is not null) - _useDelay.BeginDelay(uid, delayComp); + if (delayComp != null) + _useDelay.TryResetDelay((uid, delayComp)); // Get transfer amount. May be smaller than component.TransferAmount if not enough room var realTransferAmount = FixedPoint2.Min(component.TransferAmount, targetSolution.AvailableVolume); diff --git a/Content.Server/Cooldown/ItemCooldownSystem.cs b/Content.Server/Cooldown/ItemCooldownSystem.cs deleted file mode 100644 index 77d2dd1873..0000000000 --- a/Content.Server/Cooldown/ItemCooldownSystem.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Content.Shared.Cooldown; - -namespace Content.Server.Cooldown -{ - public sealed class ItemCooldownSystem : EntitySystem - { - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnItemCooldownRefreshed); - } - - public void OnItemCooldownRefreshed(EntityUid uid, ItemCooldownComponent comp, RefreshItemCooldownEvent args) - { - comp.CooldownStart = args.LastAttackTime; - comp.CooldownEnd = args.CooldownEnd; - } - } - - public sealed class RefreshItemCooldownEvent : EntityEventArgs - { - public TimeSpan LastAttackTime { get; } - public TimeSpan CooldownEnd { get; } - - public RefreshItemCooldownEvent(TimeSpan lastAttackTime, TimeSpan cooldownEnd) - { - LastAttackTime = lastAttackTime; - CooldownEnd = cooldownEnd; - } - } -} diff --git a/Content.Server/DeviceLinking/Systems/LogicGateSystem.cs b/Content.Server/DeviceLinking/Systems/LogicGateSystem.cs index 115285413f..598d5a2725 100644 --- a/Content.Server/DeviceLinking/Systems/LogicGateSystem.cs +++ b/Content.Server/DeviceLinking/Systems/LogicGateSystem.cs @@ -5,9 +5,7 @@ using Content.Shared.Examine; using Content.Shared.Interaction; using Content.Shared.Popups; using Content.Shared.Timing; -using Content.Shared.Tools; using Content.Shared.Tools.Systems; -using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using SignalReceivedEvent = Content.Server.DeviceLinking.Events.SignalReceivedEvent; @@ -74,7 +72,8 @@ public sealed class LogicGateSystem : EntitySystem return; // no sound spamming - if (TryComp(uid, out var useDelay) && _useDelay.ActiveDelay(uid, useDelay)) + if (TryComp(uid, out var useDelay) + && !_useDelay.TryResetDelay((uid, useDelay), true)) return; // cycle through possible gates @@ -90,8 +89,6 @@ public sealed class LogicGateSystem : EntitySystem var msg = Loc.GetString("logic-gate-cycle", ("gate", comp.Gate.ToString().ToUpper())); _popup.PopupEntity(msg, uid, args.User); _appearance.SetData(uid, LogicGateVisuals.Gate, comp.Gate); - - _useDelay.BeginDelay(uid, useDelay); } private void OnSignalReceived(EntityUid uid, LogicGateComponent comp, ref SignalReceivedEvent args) diff --git a/Content.Server/DeviceLinking/Systems/PowerSensorSystem.cs b/Content.Server/DeviceLinking/Systems/PowerSensorSystem.cs index cabcabe1ae..9975f04bbb 100644 --- a/Content.Server/DeviceLinking/Systems/PowerSensorSystem.cs +++ b/Content.Server/DeviceLinking/Systems/PowerSensorSystem.cs @@ -1,5 +1,4 @@ using Content.Server.DeviceLinking.Components; -using Content.Server.DeviceNetwork; using Content.Server.NodeContainer; using Content.Server.Power.EntitySystems; using Content.Server.Power.Nodes; @@ -9,10 +8,9 @@ using Content.Shared.Interaction; using Content.Shared.Popups; using Content.Shared.Power.Generator; using Content.Shared.Timing; -using Content.Shared.Tools; using Content.Shared.Tools.Systems; using Robust.Shared.Audio.Systems; -using Robust.Shared.Map; +using Robust.Shared.Map.Components; using Robust.Shared.Timing; namespace Content.Server.DeviceLinking.Systems; @@ -21,7 +19,6 @@ public sealed class PowerSensorSystem : EntitySystem { [Dependency] private readonly DeviceLinkSystem _deviceLink = default!; [Dependency] private readonly IGameTiming _timing = default!; - [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly PowerNetSystem _powerNet = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; @@ -76,7 +73,8 @@ public sealed class PowerSensorSystem : EntitySystem return; // no sound spamming - if (TryComp(uid, out var useDelay) && _useDelay.ActiveDelay(uid, useDelay)) + if (TryComp(uid, out var useDelay) + && !_useDelay.TryResetDelay((uid, useDelay), true)) return; // switch between input and output mode. @@ -89,8 +87,6 @@ public sealed class PowerSensorSystem : EntitySystem _audio.PlayPvs(comp.SwitchSound, uid); var msg = Loc.GetString("power-sensor-switch", ("output", comp.Output)); _popup.PopupEntity(msg, uid, args.User); - - _useDelay.BeginDelay(uid, useDelay); } private void UpdateOutputs(EntityUid uid, PowerSensorComponent comp) @@ -107,7 +103,9 @@ public sealed class PowerSensorSystem : EntitySystem // update state based on the power stats retrieved from the selected power network var xform = _xformQuery.GetComponent(uid); - _mapManager.TryGetGrid(xform.GridUid, out var grid); + if (!TryComp(xform.GridUid, out MapGridComponent? grid)) + return; + var cables = deviceNode.GetReachableNodes(xform, _nodeQuery, _xformQuery, grid, EntityManager); foreach (var node in cables) { diff --git a/Content.Server/DeviceLinking/Systems/SignallerSystem.cs b/Content.Server/DeviceLinking/Systems/SignallerSystem.cs index 44a2385055..a5091508ed 100644 --- a/Content.Server/DeviceLinking/Systems/SignallerSystem.cs +++ b/Content.Server/DeviceLinking/Systems/SignallerSystem.cs @@ -39,15 +39,12 @@ public sealed class SignallerSystem : EntitySystem private void OnTrigger(EntityUid uid, SignallerComponent component, TriggerEvent args) { - // if on cooldown, do nothing - var hasUseDelay = TryComp(uid, out var useDelay); - if (hasUseDelay && _useDelay.ActiveDelay(uid, useDelay)) + if (!TryComp(uid, out UseDelayComponent? useDelay) + // if on cooldown, do nothing + // and set cooldown to prevent clocks + || !_useDelay.TryResetDelay((uid, useDelay), true)) return; - // set cooldown to prevent clocks - if (hasUseDelay) - _useDelay.BeginDelay(uid, useDelay); - _link.InvokePort(uid, component.Port); args.Handled = true; } diff --git a/Content.Server/Fluids/EntitySystems/AbsorbentSystem.cs b/Content.Server/Fluids/EntitySystems/AbsorbentSystem.cs index 3fd2ca00e2..d88f46968a 100644 --- a/Content.Server/Fluids/EntitySystems/AbsorbentSystem.cs +++ b/Content.Server/Fluids/EntitySystems/AbsorbentSystem.cs @@ -9,7 +9,8 @@ using Content.Shared.Interaction; using Content.Shared.Timing; using Content.Shared.Weapons.Melee; using Robust.Server.Audio; -using Robust.Shared.Map; +using Robust.Server.GameObjects; +using Robust.Shared.Map.Components; using Robust.Shared.Prototypes; using Robust.Shared.Utility; @@ -18,7 +19,6 @@ namespace Content.Server.Fluids.EntitySystems; /// public sealed class AbsorbentSystem : SharedAbsorbentSystem { - [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly AudioSystem _audio = default!; [Dependency] private readonly PopupSystem _popups = default!; @@ -27,6 +27,7 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!; [Dependency] private readonly UseDelaySystem _useDelay = default!; + [Dependency] private readonly MapSystem _mapSystem = default!; public override void Initialize() { @@ -106,14 +107,15 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem if (!_solutionContainerSystem.TryGetSolution(used, AbsorbentComponent.SolutionName, out var absorberSoln)) return; - if (_useDelay.ActiveDelay(used)) + if (TryComp(used, out var useDelay) + && _useDelay.IsDelayed((used, useDelay))) return; // If it's a puddle try to grab from - if (!TryPuddleInteract(user, used, target, component, absorberSoln.Value)) + if (!TryPuddleInteract(user, used, target, component, useDelay, absorberSoln.Value)) { // If it's refillable try to transfer - if (!TryRefillableInteract(user, used, target, component, absorberSoln.Value)) + if (!TryRefillableInteract(user, used, target, component, useDelay, absorberSoln.Value)) return; } } @@ -121,7 +123,7 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem /// /// Logic for an absorbing entity interacting with a refillable. /// - private bool TryRefillableInteract(EntityUid user, EntityUid used, EntityUid target, AbsorbentComponent component, Entity absorbentSoln) + private bool TryRefillableInteract(EntityUid user, EntityUid used, EntityUid target, AbsorbentComponent component, UseDelayComponent? useDelay, Entity absorbentSoln) { if (!TryComp(target, out RefillableSolutionComponent? refillable)) return false; @@ -143,7 +145,8 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem } _audio.PlayPvs(component.TransferSound, target); - _useDelay.BeginDelay(used); + if (useDelay != null) + _useDelay.TryResetDelay((used, useDelay)); return true; } @@ -264,7 +267,7 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem /// /// Logic for an absorbing entity interacting with a puddle. /// - private bool TryPuddleInteract(EntityUid user, EntityUid used, EntityUid target, AbsorbentComponent absorber, Entity absorberSoln) + private bool TryPuddleInteract(EntityUid user, EntityUid used, EntityUid target, AbsorbentComponent absorber, UseDelayComponent? useDelay, Entity absorberSoln) { if (!TryComp(target, out PuddleComponent? puddle)) return false; @@ -297,17 +300,20 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem var absorberSplit = absorberSolution.SplitSolutionWithOnly(puddleSplit.Volume, PuddleSystem.EvaporationReagents); // Do tile reactions first - var coordinates = Transform(target).Coordinates; - if (_mapManager.TryGetGrid(coordinates.GetGridUid(EntityManager), out var mapGrid)) + var transform = Transform(target); + var gridUid = transform.GridUid; + if (TryComp(gridUid, out MapGridComponent? mapGrid)) { - _puddleSystem.DoTileReactions(mapGrid.GetTileRef(coordinates), absorberSplit); + var tileRef = _mapSystem.GetTileRef(gridUid.Value, mapGrid, transform.Coordinates); + _puddleSystem.DoTileReactions(tileRef, absorberSplit); } _solutionContainerSystem.AddSolution(puddle.Solution.Value, absorberSplit); _solutionContainerSystem.AddSolution(absorberSoln, puddleSplit); _audio.PlayPvs(absorber.PickupSound, target); - _useDelay.BeginDelay(used); + if (useDelay != null) + _useDelay.TryResetDelay((used, useDelay)); var userXform = Transform(user); var targetPos = _transform.GetWorldPosition(target); diff --git a/Content.Server/Fluids/EntitySystems/SpraySystem.cs b/Content.Server/Fluids/EntitySystems/SpraySystem.cs index 5acd2c9118..f7621aec62 100644 --- a/Content.Server/Fluids/EntitySystems/SpraySystem.cs +++ b/Content.Server/Fluids/EntitySystems/SpraySystem.cs @@ -1,36 +1,34 @@ using Content.Server.Chemistry.Components; using Content.Server.Chemistry.Containers.EntitySystems; using Content.Server.Chemistry.EntitySystems; -using Content.Server.Cooldown; using Content.Server.Extinguisher; using Content.Server.Fluids.Components; using Content.Server.Gravity; using Content.Server.Popups; -using Content.Shared.Cooldown; using Content.Shared.FixedPoint; using Content.Shared.Interaction; +using Content.Shared.Timing; using Content.Shared.Vapor; using Robust.Server.GameObjects; using Robust.Shared.Audio.Systems; using Robust.Shared.Physics.Components; using Robust.Shared.Prototypes; -using Robust.Shared.Timing; using System.Numerics; namespace Content.Server.Fluids.EntitySystems; public sealed class SpraySystem : EntitySystem { - [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IPrototypeManager _proto = default!; [Dependency] private readonly GravitySystem _gravity = default!; [Dependency] private readonly PhysicsSystem _physics = default!; + [Dependency] private readonly UseDelaySystem _useDelay = default!; [Dependency] private readonly PopupSystem _popupSystem = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SolutionContainerSystem _solutionContainer = default!; [Dependency] private readonly VaporSystem _vapor = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; - [Dependency] private readonly TransformSystem _transform = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; public override void Initialize() { @@ -54,12 +52,9 @@ public sealed class SpraySystem : EntitySystem if (ev.Cancelled) return; - var curTime = _gameTiming.CurTime; - if (TryComp(entity, out var cooldown) - && curTime < cooldown.CooldownEnd) - { + if (!TryComp(entity, out var useDelay) + || _useDelay.IsDelayed((entity, useDelay))) return; - } if (solution.Volume <= 0) { @@ -70,7 +65,7 @@ public sealed class SpraySystem : EntitySystem var xformQuery = GetEntityQuery(); var userXform = xformQuery.GetComponent(args.User); - var userMapPos = userXform.MapPosition; + var userMapPos = _transform.GetMapCoordinates(userXform); var clickMapPos = args.ClickLocation.ToMap(EntityManager, _transform); var diffPos = clickMapPos.Position - userMapPos.Position; @@ -149,7 +144,8 @@ public sealed class SpraySystem : EntitySystem _audio.PlayPvs(entity.Comp.SpraySound, entity, entity.Comp.SpraySound.Params.WithVariation(0.125f)); - RaiseLocalEvent(entity, new RefreshItemCooldownEvent(curTime, curTime + TimeSpan.FromSeconds(cooldownTime)), true); + _useDelay.SetDelay((entity, useDelay), TimeSpan.FromSeconds(cooldownTime)); + _useDelay.TryResetDelay((entity, useDelay)); } } diff --git a/Content.Server/IgnitionSource/IgniteOnTriggerSystem.cs b/Content.Server/IgnitionSource/IgniteOnTriggerSystem.cs index d80d7ecbfc..a1c288e225 100644 --- a/Content.Server/IgnitionSource/IgniteOnTriggerSystem.cs +++ b/Content.Server/IgnitionSource/IgniteOnTriggerSystem.cs @@ -1,6 +1,5 @@ using Content.Server.Explosion.EntitySystems; using Content.Shared.Timing; -using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Timing; @@ -43,14 +42,13 @@ public sealed class IgniteOnTriggerSystem : EntitySystem private void OnTrigger(Entity ent, ref TriggerEvent args) { // prevent spamming sound and ignition - TryComp(ent, out var delay); - if (_useDelay.ActiveDelay(ent, delay)) + if (!TryComp(ent.Owner, out UseDelayComponent? useDelay) || _useDelay.IsDelayed((ent.Owner, useDelay))) return; _source.SetIgnited(ent.Owner); _audio.PlayPvs(ent.Comp.IgniteSound, ent); - _useDelay.BeginDelay(ent, delay); + _useDelay.TryResetDelay((ent.Owner, useDelay)); ent.Comp.IgnitedUntil = _timing.CurTime + ent.Comp.IgnitedTime; } } diff --git a/Content.Server/Inventory/ServerInventorySystem.cs b/Content.Server/Inventory/ServerInventorySystem.cs index 7e3d9b3c7d..29d39f3723 100644 --- a/Content.Server/Inventory/ServerInventorySystem.cs +++ b/Content.Server/Inventory/ServerInventorySystem.cs @@ -1,7 +1,5 @@ using Content.Server.Storage.EntitySystems; -using Content.Shared.Clothing.Components; using Content.Shared.Explosion; -using Content.Shared.Interaction.Events; using Content.Shared.Inventory; using Content.Shared.Inventory.Events; using Content.Shared.Storage; @@ -17,9 +15,6 @@ namespace Content.Server.Inventory base.Initialize(); SubscribeLocalEvent(OnExploded); - - SubscribeLocalEvent(OnUseInHand); - SubscribeNetworkEvent(OnOpenSlotStorage); } @@ -34,14 +29,6 @@ namespace Content.Server.Inventory } } - private void OnUseInHand(EntityUid uid, ClothingComponent component, UseInHandEvent args) - { - if (args.Handled || !component.QuickEquip) - return; - - QuickEquip(uid, component, args); - } - private void OnOpenSlotStorage(OpenSlotStorageNetworkMessage ev, EntitySessionEventArgs args) { if (args.SenderSession.AttachedEntity is not { Valid: true } uid) diff --git a/Content.Server/Medical/DefibrillatorSystem.cs b/Content.Server/Medical/DefibrillatorSystem.cs index d3374bd775..9b96cb7fcb 100644 --- a/Content.Server/Medical/DefibrillatorSystem.cs +++ b/Content.Server/Medical/DefibrillatorSystem.cs @@ -66,13 +66,14 @@ public sealed class DefibrillatorSystem : EntitySystem private void OnUseInHand(EntityUid uid, DefibrillatorComponent component, UseInHandEvent args) { - if (args.Handled || _useDelay.ActiveDelay(uid)) + if (args.Handled || !TryComp(uid, out UseDelayComponent? useDelay) || _useDelay.IsDelayed((uid, useDelay))) return; if (!TryToggle(uid, component, args.User)) return; + args.Handled = true; - _useDelay.BeginDelay(uid); + _useDelay.TryResetDelay((uid, useDelay)); } private void OnPowerCellSlotEmpty(EntityUid uid, DefibrillatorComponent component, ref PowerCellSlotEmptyEvent args) diff --git a/Content.Server/NPC/HTN/PrimitiveTasks/Operators/Interactions/InteractWithOperator.cs b/Content.Server/NPC/HTN/PrimitiveTasks/Operators/Interactions/InteractWithOperator.cs index d3f4f2ea8d..a8abb5ac4c 100644 --- a/Content.Server/NPC/HTN/PrimitiveTasks/Operators/Interactions/InteractWithOperator.cs +++ b/Content.Server/NPC/HTN/PrimitiveTasks/Operators/Interactions/InteractWithOperator.cs @@ -11,14 +11,15 @@ public sealed partial class InteractWithOperator : HTNOperator /// /// Key that contains the target entity. /// - [DataField("targetKey", required: true)] + [DataField(required: true)] public string TargetKey = default!; public override HTNOperatorStatus Update(NPCBlackboard blackboard, float frameTime) { var owner = blackboard.GetValue(NPCBlackboard.Owner); - if (_entManager.System().ActiveDelay(owner) || + if (!_entManager.TryGetComponent(owner, out var useDelay) || + _entManager.System().IsDelayed((owner, useDelay)) || !blackboard.TryGetValue(TargetKey, out var moveTarget, _entManager) || !_entManager.TryGetComponent(moveTarget, out var targetXform)) { diff --git a/Content.Server/Ninja/Systems/NinjaSuitSystem.cs b/Content.Server/Ninja/Systems/NinjaSuitSystem.cs index 61beed9481..2aa08e0492 100644 --- a/Content.Server/Ninja/Systems/NinjaSuitSystem.cs +++ b/Content.Server/Ninja/Systems/NinjaSuitSystem.cs @@ -3,13 +3,12 @@ using Content.Server.Ninja.Events; using Content.Server.Popups; using Content.Server.Power.Components; using Content.Server.PowerCell; -using Content.Shared.Actions; using Content.Shared.Clothing.EntitySystems; using Content.Shared.Hands.EntitySystems; using Content.Shared.Ninja.Components; using Content.Shared.Ninja.Systems; -using Content.Shared.Popups; using Content.Shared.PowerCell.Components; +using Content.Shared.Timing; using Robust.Shared.Containers; namespace Content.Server.Ninja.Systems; @@ -94,7 +93,8 @@ public sealed class NinjaSuitSystem : SharedNinjaSuitSystem // need 1 second of charge to turn on stealth var chargeNeeded = SuitWattage(uid, comp); // being attacked while cloaked gives no power message since it overloads the power supply or something - if (!_ninja.GetNinjaBattery(user, out var _, out var battery) || battery.CurrentCharge < chargeNeeded || UseDelay.ActiveDelay(user)) + if (!_ninja.GetNinjaBattery(user, out var _, out var battery) || battery.CurrentCharge < chargeNeeded + || !TryComp(user, out UseDelayComponent? useDelay) || UseDelay.IsDelayed((user, useDelay))) { _popup.PopupEntity(Loc.GetString("ninja-no-power"), user, user); args.Cancel(); @@ -108,7 +108,8 @@ public sealed class NinjaSuitSystem : SharedNinjaSuitSystem { args.Handled = true; var user = args.Performer; - if (!_ninja.TryUseCharge(user, comp.ThrowingStarCharge) || UseDelay.ActiveDelay(user)) + if (!_ninja.TryUseCharge(user, comp.ThrowingStarCharge) + || !TryComp(user, out UseDelayComponent? useDelay) || UseDelay.IsDelayed((user, useDelay))) { _popup.PopupEntity(Loc.GetString("ninja-no-power"), user, user); return; @@ -130,7 +131,8 @@ public sealed class NinjaSuitSystem : SharedNinjaSuitSystem var coords = _transform.GetWorldPosition(katana); var distance = (_transform.GetWorldPosition(user) - coords).Length(); var chargeNeeded = (float) distance * comp.RecallCharge; - if (!_ninja.TryUseCharge(user, chargeNeeded) || UseDelay.ActiveDelay(user)) + if (!_ninja.TryUseCharge(user, chargeNeeded) + || !TryComp(user, out UseDelayComponent? useDelay) || UseDelay.IsDelayed((user, useDelay))) { _popup.PopupEntity(Loc.GetString("ninja-no-power"), user, user); return; @@ -147,14 +149,15 @@ public sealed class NinjaSuitSystem : SharedNinjaSuitSystem { args.Handled = true; var user = args.Performer; - if (!_ninja.TryUseCharge(user, comp.EmpCharge) || UseDelay.ActiveDelay(user)) + if (!_ninja.TryUseCharge(user, comp.EmpCharge) + || !TryComp(user, out UseDelayComponent? useDelay) || UseDelay.IsDelayed((user, useDelay))) { _popup.PopupEntity(Loc.GetString("ninja-no-power"), user, user); return; } // I don't think this affects the suit battery, but if it ever does in the future add a blacklist for it - var coords = Transform(user).MapPosition; + var coords = _transform.GetMapCoordinates(user); _emp.EmpPulse(coords, comp.EmpRange, comp.EmpConsumption, comp.EmpDuration); } } diff --git a/Content.Server/Power/Generator/PowerSwitchableSystem.cs b/Content.Server/Power/Generator/PowerSwitchableSystem.cs index 7c377ef66e..61892f23f8 100644 --- a/Content.Server/Power/Generator/PowerSwitchableSystem.cs +++ b/Content.Server/Power/Generator/PowerSwitchableSystem.cs @@ -70,7 +70,7 @@ public sealed class PowerSwitchableSystem : SharedPowerSwitchableSystem return; // no sound spamming - if (TryComp(uid, out var useDelay) && _useDelay.ActiveDelay(uid)) + if (!TryComp(uid, out UseDelayComponent? useDelay) || _useDelay.IsDelayed((uid, useDelay))) return; comp.ActiveIndex = NextIndex(uid, comp); @@ -110,7 +110,7 @@ public sealed class PowerSwitchableSystem : SharedPowerSwitchableSystem _audio.PlayPvs(comp.SwitchSound, uid); - _useDelay.BeginDelay(uid, useDelay); + _useDelay.TryResetDelay((uid, useDelay)); } } diff --git a/Content.Server/Singularity/Components/RadiationCollectorComponent.cs b/Content.Server/Singularity/Components/RadiationCollectorComponent.cs index 649514ed42..30522c28f3 100644 --- a/Content.Server/Singularity/Components/RadiationCollectorComponent.cs +++ b/Content.Server/Singularity/Components/RadiationCollectorComponent.cs @@ -13,32 +13,21 @@ public sealed partial class RadiationCollectorComponent : Component /// /// How much joules will collector generate for each rad. /// - [DataField("chargeModifier")] + [DataField] [ViewVariables(VVAccess.ReadWrite)] public float ChargeModifier = 30000f; /// - /// Cooldown time between users interaction. + /// Is the machine enabled. /// - [DataField("cooldown")] - [ViewVariables(VVAccess.ReadWrite)] - public TimeSpan Cooldown = TimeSpan.FromSeconds(0.81f); - - /// - /// Was machine activated by user? - /// - [ViewVariables(VVAccess.ReadOnly)] + [DataField] + [ViewVariables] public bool Enabled; - /// - /// Timestamp when machine can be deactivated again. - /// - public TimeSpan CoolDownEnd; - /// /// List of gases that will react to the radiation passing through the collector /// - [DataField("radiationReactiveGases")] + [DataField] [ViewVariables(VVAccess.ReadWrite)] public List? RadiationReactiveGases; } @@ -50,15 +39,15 @@ public sealed partial class RadiationCollectorComponent : Component public sealed partial class RadiationReactiveGas { /// - /// The reactant gas + /// The reactant gas /// - [DataField("reactantPrototype", required: true)] - public Gas Reactant = Gas.Plasma; + [DataField(required: true)] + public Gas ReactantPrototype; /// /// Multipier for the amount of power produced by the radiation collector when using this gas /// - [DataField("powerGenerationEfficiency")] + [DataField] public float PowerGenerationEfficiency = 1f; /// @@ -67,7 +56,7 @@ public sealed partial class RadiationReactiveGas /// /// /// Set to zero if the reactant does not deplete /// - [DataField("reactantBreakdownRate")] + [DataField] public float ReactantBreakdownRate = 1f; /// @@ -76,12 +65,12 @@ public sealed partial class RadiationReactiveGas /// /// Leave null if the reactant no byproduct gas is to be formed /// - [DataField("byproductPrototype")] - public Gas? Byproduct = null; + [DataField] + public Gas? Byproduct; /// /// The molar ratio of the byproduct gas generated from the reactant gas /// - [DataField("molarRatio")] + [DataField] public float MolarRatio = 1f; } diff --git a/Content.Server/Singularity/EntitySystems/RadiationCollectorSystem.cs b/Content.Server/Singularity/EntitySystems/RadiationCollectorSystem.cs index 27219bb183..83666776a0 100644 --- a/Content.Server/Singularity/EntitySystems/RadiationCollectorSystem.cs +++ b/Content.Server/Singularity/EntitySystems/RadiationCollectorSystem.cs @@ -1,16 +1,19 @@ -using Content.Server.Singularity.Components; -using Content.Shared.Interaction; -using Content.Shared.Singularity.Components; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using Content.Server.Atmos; +using Content.Server.Atmos.Components; using Content.Server.Popups; using Content.Server.Power.Components; -using Content.Shared.Radiation.Events; -using Robust.Shared.Timing; -using Robust.Shared.Containers; -using Content.Server.Atmos.Components; -using Content.Shared.Examine; -using Content.Server.Atmos; -using System.Diagnostics.CodeAnalysis; +using Content.Server.Power.EntitySystems; +using Content.Server.Singularity.Components; using Content.Shared.Atmos; +using Content.Shared.Examine; +using Content.Shared.Interaction; +using Content.Shared.Radiation.Events; +using Content.Shared.Singularity.Components; +using Content.Shared.Timing; +using Robust.Shared.Containers; +using Robust.Shared.Timing; namespace Content.Server.Singularity.EntitySystems; @@ -20,6 +23,10 @@ public sealed class RadiationCollectorSystem : EntitySystem [Dependency] private readonly PopupSystem _popupSystem = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedContainerSystem _containerSystem = default!; + [Dependency] private readonly UseDelaySystem _useDelay = default!; + [Dependency] private readonly BatterySystem _batterySystem = default!; + + private const string GasTankContainer = "gas_tank"; public override void Initialize() { @@ -36,12 +43,11 @@ public sealed class RadiationCollectorSystem : EntitySystem private bool TryGetLoadedGasTank(EntityUid uid, [NotNullWhen(true)] out GasTankComponent? gasTankComponent) { gasTankComponent = null; - var container = _containerSystem.EnsureContainer(uid, "GasTank"); - if (container.ContainedEntity == null) + if (!_containerSystem.TryGetContainer(uid, GasTankContainer, out var container) || container.ContainedEntities.Count == 0) return false; - if (!EntityManager.TryGetComponent(container.ContainedEntity, out gasTankComponent)) + if (!EntityManager.TryGetComponent(container.ContainedEntities.First(), out gasTankComponent)) return false; return true; @@ -61,13 +67,10 @@ public sealed class RadiationCollectorSystem : EntitySystem private void OnInteractHand(EntityUid uid, RadiationCollectorComponent component, InteractHandEvent args) { - var curTime = _gameTiming.CurTime; - - if (curTime < component.CoolDownEnd) + if (TryComp(uid, out UseDelayComponent? useDelay) && !_useDelay.TryResetDelay((uid, useDelay), true)) return; ToggleCollector(uid, args.User, component); - component.CoolDownEnd = curTime + component.Cooldown; } private void OnRadiation(EntityUid uid, RadiationCollectorComponent component, OnIrradiatedEvent args) @@ -82,7 +85,7 @@ public sealed class RadiationCollectorSystem : EntitySystem foreach (var gas in component.RadiationReactiveGases) { - float reactantMol = gasTankComponent.Air.GetMoles(gas.Reactant); + float reactantMol = gasTankComponent.Air.GetMoles(gas.ReactantPrototype); float delta = args.TotalRads * reactantMol * gas.ReactantBreakdownRate; // We need to offset the huge power gains possible when using very cold gases @@ -95,7 +98,7 @@ public sealed class RadiationCollectorSystem : EntitySystem if (delta > 0) { - gasTankComponent.Air.AdjustMoles(gas.Reactant, -Math.Min(delta, reactantMol)); + gasTankComponent.Air.AdjustMoles(gas.ReactantPrototype, -Math.Min(delta, reactantMol)); } if (gas.Byproduct != null) @@ -111,7 +114,7 @@ public sealed class RadiationCollectorSystem : EntitySystem // This still won't stop things being potentially hilariously unbalanced though. if (TryComp(uid, out var batteryComponent)) { - batteryComponent.CurrentCharge += charge; + _batterySystem.SetCharge(uid, charge, batteryComponent); } // Update appearance diff --git a/Content.Server/Storage/EntitySystems/StorageSystem.cs b/Content.Server/Storage/EntitySystems/StorageSystem.cs index 3223cbf60c..b1da3cf30e 100644 --- a/Content.Server/Storage/EntitySystems/StorageSystem.cs +++ b/Content.Server/Storage/EntitySystems/StorageSystem.cs @@ -12,6 +12,7 @@ using Content.Shared.Storage.EntitySystems; using Content.Shared.Timing; using Content.Shared.Verbs; using Robust.Server.GameObjects; +using Robust.Shared.Audio.Systems; using Robust.Shared.Input.Binding; using Robust.Shared.Map; using Robust.Shared.Player; @@ -26,6 +27,8 @@ public sealed partial class StorageSystem : SharedStorageSystem [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly InventorySystem _inventory = default!; [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly UseDelaySystem _useDelay = default!; public override void Initialize() { @@ -123,12 +126,12 @@ public sealed partial class StorageSystem : SharedStorageSystem return; // prevent spamming bag open / honkerton honk sound - silent |= TryComp(uid, out var useDelay) && UseDelay.ActiveDelay(uid, useDelay); + silent |= TryComp(uid, out var useDelay) && _useDelay.IsDelayed((uid, useDelay)); if (!silent) { - Audio.PlayPvs(storageComp.StorageOpenSound, uid); + _audio.PlayPvs(storageComp.StorageOpenSound, uid); if (useDelay != null) - UseDelay.BeginDelay(uid, useDelay); + _useDelay.TryResetDelay((uid, useDelay)); } Log.Debug($"Storage (UID {uid}) \"used\" by player session (UID {player.PlayerSession.AttachedEntity})."); diff --git a/Content.Server/Xenoarchaeology/Equipment/Systems/NodeScannerSystem.cs b/Content.Server/Xenoarchaeology/Equipment/Systems/NodeScannerSystem.cs index 928de35711..fc9ab28942 100644 --- a/Content.Server/Xenoarchaeology/Equipment/Systems/NodeScannerSystem.cs +++ b/Content.Server/Xenoarchaeology/Equipment/Systems/NodeScannerSystem.cs @@ -3,7 +3,6 @@ using Content.Server.Xenoarchaeology.Equipment.Components; using Content.Server.Xenoarchaeology.XenoArtifacts; using Content.Shared.Interaction; using Content.Shared.Timing; -using Robust.Shared.Player; namespace Content.Server.Xenoarchaeology.Equipment.Systems; @@ -31,7 +30,11 @@ public sealed class NodeScannerSystem : EntitySystem args.Handled = true; var target = args.Target.Value; - _useDelay.BeginDelay(uid); + + if (TryComp(uid, out UseDelayComponent? useDelay) + && !_useDelay.TryResetDelay((uid, useDelay), true)) + return; + _popupSystem.PopupEntity(Loc.GetString("node-scan-popup", ("id", $"{artifact.CurrentNodeId}")), target); } diff --git a/Content.Shared/Clothing/EntitySystems/ClothingSystem.cs b/Content.Shared/Clothing/EntitySystems/ClothingSystem.cs index 9aa0158088..da2a09313a 100644 --- a/Content.Shared/Clothing/EntitySystems/ClothingSystem.cs +++ b/Content.Shared/Clothing/EntitySystems/ClothingSystem.cs @@ -1,9 +1,13 @@ using Content.Shared.Clothing.Components; +using Content.Shared.Hands.Components; +using Content.Shared.Hands.EntitySystems; using Content.Shared.Humanoid; +using Content.Shared.Interaction.Events; using Content.Shared.Inventory; using Content.Shared.Inventory.Events; using Content.Shared.Item; using Content.Shared.Tag; +using Content.Shared.Timing; using Robust.Shared.GameStates; namespace Content.Shared.Clothing.EntitySystems; @@ -13,6 +17,8 @@ public abstract class ClothingSystem : EntitySystem [Dependency] private readonly SharedItemSystem _itemSys = default!; [Dependency] private readonly SharedHumanoidAppearanceSystem _humanoidSystem = default!; [Dependency] private readonly TagSystem _tagSystem = default!; + [Dependency] private readonly InventorySystem _invSystem = default!; + [Dependency] private readonly SharedHandsSystem _handsSystem = default!; [ValidatePrototypeId] private const string HairTag = "HidesHair"; @@ -21,12 +27,60 @@ public abstract class ClothingSystem : EntitySystem { base.Initialize(); + SubscribeLocalEvent(OnUseInHand); SubscribeLocalEvent(OnGetState); SubscribeLocalEvent(OnHandleState); SubscribeLocalEvent(OnGotEquipped); SubscribeLocalEvent(OnGotUnequipped); SubscribeLocalEvent(OnMaskToggled); } + private void OnUseInHand(Entity ent, ref UseInHandEvent args) + { + if (args.Handled || !ent.Comp.QuickEquip) + return; + + var user = args.User; + if (!TryComp(user, out InventoryComponent? inv) || + !TryComp(user, out HandsComponent? hands)) + return; + + QuickEquip(ent, (user, inv, hands)); + args.Handled = true; + args.ApplyDelay = false; + } + + private void QuickEquip( + Entity toEquipEnt, + Entity userEnt) + { + foreach (var slotDef in userEnt.Comp1.Slots) + { + if (!_invSystem.CanEquip(userEnt, toEquipEnt, slotDef.Name, out _, slotDef, userEnt, toEquipEnt)) + continue; + + if (_invSystem.TryGetSlotEntity(userEnt, slotDef.Name, out var slotEntity, userEnt)) + { + // Item in slot has to be quick equipable as well + if (TryComp(slotEntity, out ClothingComponent? item) && !item.QuickEquip) + continue; + + if (!_invSystem.TryUnequip(userEnt, slotDef.Name, true, inventory: userEnt, clothing: toEquipEnt)) + continue; + + if (!_invSystem.TryEquip(userEnt, toEquipEnt, slotDef.Name, true, inventory: userEnt, clothing: toEquipEnt)) + continue; + + _handsSystem.PickupOrDrop(userEnt, slotEntity.Value, handsComp: userEnt); + } + else + { + if (!_invSystem.TryEquip(userEnt, toEquipEnt, slotDef.Name, true, inventory: userEnt, clothing: toEquipEnt)) + continue; + } + + break; + } + } protected virtual void OnGotEquipped(EntityUid uid, ClothingComponent component, GotEquippedEvent args) { @@ -71,7 +125,7 @@ public abstract class ClothingSystem : EntitySystem clothing.EquippedPrefix = prefix; _itemSys.VisualsChanged(uid); - Dirty(clothing); + Dirty(uid, clothing); } public void SetSlots(EntityUid uid, SlotFlags slots, ClothingComponent? clothing = null) @@ -80,7 +134,7 @@ public abstract class ClothingSystem : EntitySystem return; clothing.Slots = slots; - Dirty(clothing); + Dirty(uid, clothing); } /// @@ -97,7 +151,7 @@ public abstract class ClothingSystem : EntitySystem clothing.FemaleMask = otherClothing.FemaleMask; _itemSys.VisualsChanged(uid); - Dirty(clothing); + Dirty(uid, clothing); } #endregion diff --git a/Content.Shared/Cooldown/Cooldowns.cs b/Content.Shared/Cooldown/Cooldowns.cs deleted file mode 100644 index f56c78028f..0000000000 --- a/Content.Shared/Cooldown/Cooldowns.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Robust.Shared.Timing; - -namespace Content.Shared.Cooldown -{ - /// - /// Utilities for working with cooldowns. - /// - public static class Cooldowns - { - /// game timing to use, otherwise will resolve using IoCManager. - /// a cooldown interval starting at GameTiming.Curtime and ending at (offset) from CurTime. - /// For example, passing TimeSpan.FromSeconds(5) will create an interval - /// from now to 5 seconds from now. - public static (TimeSpan start, TimeSpan end) FromNow(TimeSpan offset, IGameTiming? gameTiming = null) - { - var now = (gameTiming ?? IoCManager.Resolve()).CurTime; - return (now, now + offset); - } - - /// - public static (TimeSpan start, TimeSpan end) SecondsFromNow(double seconds, IGameTiming? gameTiming = null) - { - return FromNow(TimeSpan.FromSeconds(seconds), gameTiming); - } - } -} diff --git a/Content.Shared/Cooldown/ItemCooldownComponent.cs b/Content.Shared/Cooldown/ItemCooldownComponent.cs deleted file mode 100644 index 32560ec6cb..0000000000 --- a/Content.Shared/Cooldown/ItemCooldownComponent.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Robust.Shared.GameStates; -using Robust.Shared.Serialization; - -namespace Content.Shared.Cooldown -{ - /// - /// Stores a visual "cooldown" for items, that gets displayed in the hands GUI. - /// - [RegisterComponent, NetworkedComponent] - [AutoGenerateComponentState] - public sealed partial class ItemCooldownComponent : Component - { - // TODO: access and system setting and dirtying not this funny stuff - private TimeSpan? _cooldownEnd; - private TimeSpan? _cooldownStart; - - /// - /// The time when this cooldown ends. - /// - /// - /// If null, no cooldown is displayed. - /// - [ViewVariables, AutoNetworkedField] - public TimeSpan? CooldownEnd - { - get => _cooldownEnd; - set - { - _cooldownEnd = value; - Dirty(); - } - } - - /// - /// The time when this cooldown started. - /// - /// - /// If null, no cooldown is displayed. - /// - [ViewVariables, AutoNetworkedField] - public TimeSpan? CooldownStart - { - get => _cooldownStart; - set - { - _cooldownStart = value; - Dirty(); - } - } - } -} diff --git a/Content.Shared/Interaction/Events/UseInHandEvent.cs b/Content.Shared/Interaction/Events/UseInHandEvent.cs index 0a0b0406d5..24a841c2d8 100644 --- a/Content.Shared/Interaction/Events/UseInHandEvent.cs +++ b/Content.Shared/Interaction/Events/UseInHandEvent.cs @@ -1,3 +1,5 @@ +using Content.Shared.Clothing.EntitySystems; +using Content.Shared.Timing; using JetBrains.Annotations; namespace Content.Shared.Interaction.Events; @@ -11,7 +13,13 @@ public sealed class UseInHandEvent : HandledEntityEventArgs /// /// Entity holding the item in their hand. /// - public EntityUid User { get; } + public EntityUid User; + + /// + /// Whether or not to apply a UseDelay when used. + /// Mostly used by the quick-equip to not apply the delay to entities that have the . + /// + public bool ApplyDelay = true; public UseInHandEvent(EntityUid user) { diff --git a/Content.Shared/Interaction/SharedInteractionSystem.cs b/Content.Shared/Interaction/SharedInteractionSystem.cs index 44cf325567..75063c5550 100644 --- a/Content.Shared/Interaction/SharedInteractionSystem.cs +++ b/Content.Shared/Interaction/SharedInteractionSystem.cs @@ -6,7 +6,6 @@ using Content.Shared.Administration.Logs; using Content.Shared.Administration.Managers; using Content.Shared.CombatMode; using Content.Shared.Database; -using Content.Shared.DragDrop; using Content.Shared.Hands; using Content.Shared.Hands.Components; using Content.Shared.Input; @@ -21,7 +20,6 @@ using Content.Shared.Popups; using Content.Shared.Pulling; using Content.Shared.Pulling.Components; using Content.Shared.Tag; -using Content.Shared.Throwing; using Content.Shared.Timing; using Content.Shared.Verbs; using Content.Shared.Wall; @@ -67,8 +65,7 @@ namespace Content.Shared.Interaction [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly TagSystem _tagSystem = default!; - private const CollisionGroup InRangeUnobstructedMask - = CollisionGroup.Impassable | CollisionGroup.InteractImpassable; + private const CollisionGroup InRangeUnobstructedMask = CollisionGroup.Impassable | CollisionGroup.InteractImpassable; public const float InteractionRange = 1.5f; public const float InteractionRangeSquared = InteractionRange * InteractionRange; @@ -170,7 +167,6 @@ namespace Content.Shared.Interaction QueueDel(uid); } - private bool HandleTryPullObject(ICommonSession? session, EntityCoordinates coords, EntityUid uid) { if (!ValidateClientInput(session, coords, uid, out var userEntity)) @@ -953,7 +949,7 @@ namespace Content.Shared.Interaction UseDelayComponent? delayComponent = null; if (checkUseDelay && TryComp(used, out delayComponent) - && delayComponent.ActiveDelay) + && _useDelay.IsDelayed((used, delayComponent))) return false; if (checkCanInteract && !_actionBlockerSystem.CanInteract(user, used)) @@ -977,7 +973,8 @@ namespace Content.Shared.Interaction return false; DoContactInteraction(user, used, activateMsg); - _useDelay.BeginDelay(used, delayComponent); + if (delayComponent != null) + _useDelay.TryResetDelay((used, delayComponent)); if (!activateMsg.WasLogged) _adminLogger.Add(LogType.InteractActivate, LogImpact.Low, $"{ToPrettyString(user):user} activated {ToPrettyString(used):used}"); return true; @@ -1002,7 +999,7 @@ namespace Content.Shared.Interaction if (checkUseDelay && TryComp(used, out delayComponent) - && delayComponent.ActiveDelay) + && _useDelay.IsDelayed((used, delayComponent))) return true; // if the item is on cooldown, we consider this handled. if (checkCanInteract && !_actionBlockerSystem.CanInteract(user, used)) @@ -1016,7 +1013,8 @@ namespace Content.Shared.Interaction if (useMsg.Handled) { DoContactInteraction(user, used, useMsg); - _useDelay.BeginDelay(used, delayComponent); + if (delayComponent != null && useMsg.ApplyDelay) + _useDelay.TryResetDelay((used, delayComponent)); return true; } diff --git a/Content.Shared/Inventory/InventorySystem.Equip.cs b/Content.Shared/Inventory/InventorySystem.Equip.cs index bad36098c0..848c8c3558 100644 --- a/Content.Shared/Inventory/InventorySystem.Equip.cs +++ b/Content.Shared/Inventory/InventorySystem.Equip.cs @@ -4,18 +4,13 @@ using Content.Shared.Hands; using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; -using Content.Shared.Interaction.Events; using Content.Shared.Inventory.Events; using Content.Shared.Item; using Content.Shared.Movement.Systems; using Content.Shared.Popups; using Content.Shared.Strip.Components; -using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Containers; -using Robust.Shared.Network; -using Robust.Shared.Player; -using Robust.Shared.Prototypes; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -31,7 +26,6 @@ public abstract partial class InventorySystem [Dependency] private readonly SharedContainerSystem _containerSystem = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly INetManager _netMan = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; [ValidatePrototypeId] @@ -46,41 +40,6 @@ public abstract partial class InventorySystem SubscribeAllEvent(OnUseSlot); } - protected void QuickEquip(EntityUid uid, ClothingComponent component, UseInHandEvent args) - { - if (!TryComp(args.User, out InventoryComponent? inv) || !HasComp(args.User)) - return; - - foreach (var slotDef in inv.Slots) - { - if (!CanEquip(args.User, uid, slotDef.Name, out _, slotDef, inv)) - continue; - - if (TryGetSlotEntity(args.User, slotDef.Name, out var slotEntity, inv)) - { - // Item in slot has to be quick equipable as well - if (TryComp(slotEntity, out ClothingComponent? item) && !item.QuickEquip) - continue; - - if (!TryUnequip(args.User, slotDef.Name, true, inventory: inv)) - continue; - - if (!TryEquip(args.User, uid, slotDef.Name, true, inventory: inv)) - continue; - - _handsSystem.PickupOrDrop(args.User, slotEntity.Value); - } - else - { - if (!TryEquip(args.User, uid, slotDef.Name, true, inventory: inv)) - continue; - } - - args.Handled = true; - break; - } - } - private void OnEntRemoved(EntityUid uid, InventoryComponent component, EntRemovedFromContainerMessage args) { if(!TryGetSlot(uid, args.Container.ID, out var slotDef, inventory: component)) diff --git a/Content.Shared/Mech/Equipment/Systems/MechSoundboardSystem.cs b/Content.Shared/Mech/Equipment/Systems/MechSoundboardSystem.cs index 1440a6ef1f..a2a6a94488 100644 --- a/Content.Shared/Mech/Equipment/Systems/MechSoundboardSystem.cs +++ b/Content.Shared/Mech/Equipment/Systems/MechSoundboardSystem.cs @@ -1,9 +1,6 @@ -using Content.Shared.Mech; -using Content.Shared.Mech.Equipment.Components; -using Content.Shared.Mech.Equipment.Systems; -using Content.Shared.Timing; -using Robust.Shared.Audio; using System.Linq; +using Content.Shared.Mech.Equipment.Components; +using Content.Shared.Timing; using Robust.Shared.Audio.Systems; namespace Content.Shared.Mech.Equipment.Systems; @@ -47,12 +44,11 @@ public sealed class MechSoundboardSystem : EntitySystem if (msg.Sound >= comp.Sounds.Count) return; - if (_useDelay.ActiveDelay(uid)) + if (TryComp(uid, out UseDelayComponent? useDelay) + && !_useDelay.TryResetDelay((uid, useDelay), true)) return; // honk!!!!! - var mech = equipment.EquipmentOwner.Value; - _useDelay.BeginDelay(uid); _audio.PlayPvs(comp.Sounds[msg.Sound], uid); } } diff --git a/Content.Shared/Ninja/Systems/SharedNinjaGlovesSystem.cs b/Content.Shared/Ninja/Systems/SharedNinjaGlovesSystem.cs index 639d3f1346..815464bf7a 100644 --- a/Content.Shared/Ninja/Systems/SharedNinjaGlovesSystem.cs +++ b/Content.Shared/Ninja/Systems/SharedNinjaGlovesSystem.cs @@ -8,7 +8,6 @@ using Content.Shared.Inventory.Events; using Content.Shared.Ninja.Components; using Content.Shared.Popups; using Content.Shared.Research.Components; -using Content.Shared.Timing; using Content.Shared.Toggleable; using Robust.Shared.Timing; @@ -24,7 +23,6 @@ public abstract class SharedNinjaGlovesSystem : EntitySystem [Dependency] private readonly SharedCombatModeSystem _combatMode = default!; [Dependency] protected readonly SharedInteractionSystem Interaction = default!; [Dependency] protected readonly SharedPopupSystem Popup = default!; - [Dependency] private readonly UseDelaySystem _useDelay = default!; [Dependency] private readonly ActionContainerSystem _actionContainer = default!; public override void Initialize() @@ -110,7 +108,6 @@ public abstract class SharedNinjaGlovesSystem : EntitySystem target = args.Target; return _timing.IsFirstTimePredicted && !_combatMode.IsInCombatMode(uid) - && !_useDelay.ActiveDelay(uid) && TryComp(uid, out var hands) && hands.ActiveHandEntity == null && Interaction.InRangeUnobstructed(uid, target); diff --git a/Content.Shared/Ninja/Systems/SharedNinjaSuitSystem.cs b/Content.Shared/Ninja/Systems/SharedNinjaSuitSystem.cs index 224152a402..20d003a61b 100644 --- a/Content.Shared/Ninja/Systems/SharedNinjaSuitSystem.cs +++ b/Content.Shared/Ninja/Systems/SharedNinjaSuitSystem.cs @@ -15,7 +15,7 @@ public abstract class SharedNinjaSuitSystem : EntitySystem { [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedNinjaGlovesSystem _gloves = default!; - [Dependency] protected readonly SharedSpaceNinjaSystem _ninja = default!; + [Dependency] private readonly SharedSpaceNinjaSystem _ninja = default!; [Dependency] protected readonly StealthClothingSystem StealthClothing = default!; [Dependency] protected readonly UseDelaySystem UseDelay = default!; [Dependency] private readonly ActionContainerSystem _actionContainer = default!; @@ -112,8 +112,8 @@ public abstract class SharedNinjaSuitSystem : EntitySystem _audio.PlayPredicted(comp.RevealSound, uid, user); // all abilities check for a usedelay on the ninja var useDelay = EnsureComp(user); - useDelay.Delay = comp.DisableTime; - UseDelay.BeginDelay(user, useDelay); + UseDelay.SetDelay((user, useDelay), comp.DisableTime); + UseDelay.TryResetDelay((user, useDelay)); } // TODO: modify PowerCellDrain diff --git a/Content.Shared/Timing/UseDelayComponent.cs b/Content.Shared/Timing/UseDelayComponent.cs index 4135bf26fe..784fd6632f 100644 --- a/Content.Shared/Timing/UseDelayComponent.cs +++ b/Content.Shared/Timing/UseDelayComponent.cs @@ -1,28 +1,36 @@ using Robust.Shared.GameStates; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Shared.Timing; /// /// Timer that creates a cooldown each time an object is activated/used /// -[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] +/// +/// Currently it only supports a single delay per entity, this means that for things that have two delay interactions they will share one timer, so this can cause issues. For example, the bible has a delay when opening the storage UI and when applying it's interaction effect, and they share the same delay. +/// +[RegisterComponent] +[NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(UseDelaySystem))] public sealed partial class UseDelayComponent : Component { - [AutoNetworkedField] - public TimeSpan LastUseTime; - - [AutoNetworkedField] - public TimeSpan? DelayEndTime; - - [DataField, AutoNetworkedField] - [ViewVariables(VVAccess.ReadWrite)] - public TimeSpan Delay = TimeSpan.FromSeconds(1); + /// + /// When the delay starts. + /// + [ViewVariables(VVAccess.ReadWrite), DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField] + public TimeSpan DelayStartTime; /// - /// Stores remaining delay pausing (and eventually, serialization). + /// When the delay ends. + /// + [ViewVariables(VVAccess.ReadWrite), DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField] + public TimeSpan DelayEndTime; + + /// + /// Default delay time /// [DataField] - public TimeSpan? RemainingDelay; - - public bool ActiveDelay => DelayEndTime != null; + [ViewVariables(VVAccess.ReadWrite)] + [AutoNetworkedField] + public TimeSpan Delay = TimeSpan.FromSeconds(1); } diff --git a/Content.Shared/Timing/UseDelaySystem.cs b/Content.Shared/Timing/UseDelaySystem.cs index 17a806f094..a263778cef 100644 --- a/Content.Shared/Timing/UseDelaySystem.cs +++ b/Content.Shared/Timing/UseDelaySystem.cs @@ -1,125 +1,64 @@ -using Content.Shared.Cooldown; using Robust.Shared.Timing; -using Robust.Shared.Utility; namespace Content.Shared.Timing; public sealed class UseDelaySystem : EntitySystem { [Dependency] private readonly IGameTiming _gameTiming = default!; - - private HashSet _activeDelays = new(); + [Dependency] private readonly MetaDataSystem _metadata = default!; public override void Initialize() { - base.Initialize(); - - SubscribeLocalEvent(OnHandleState); - - SubscribeLocalEvent(OnPaused); SubscribeLocalEvent(OnUnpaused); } - private void OnPaused(EntityUid uid, UseDelayComponent component, ref EntityPausedEvent args) + private void OnUnpaused(Entity ent, ref EntityUnpausedEvent args) { - // This entity just got paused, but wasn't before - if (component.DelayEndTime != null) - component.RemainingDelay = _gameTiming.CurTime - component.DelayEndTime; - - _activeDelays.Remove(component); - Dirty(component); + // We got unpaused, resume the delay + ent.Comp.DelayStartTime += args.PausedTime; + ent.Comp.DelayEndTime += args.PausedTime; + Dirty(ent); } - private void OnUnpaused(EntityUid uid, UseDelayComponent component, ref EntityUnpausedEvent args) + public void SetDelay(Entity ent, TimeSpan delay) { - if (component.RemainingDelay == null) + if (ent.Comp.Delay == delay) return; - // We got unpaused, resume the delay/cooldown. Currently this takes for granted that ItemCooldownComponent - // handles the pausing on its own. I'm not even gonna check, because I CBF fixing it if it doesn't. - component.DelayEndTime = _gameTiming.CurTime + component.RemainingDelay; - Dirty(component); - _activeDelays.Add(component); - } - - private void OnHandleState(EntityUid uid, UseDelayComponent component, ref AfterAutoHandleStateEvent args) - { - if (component.DelayEndTime == null) - _activeDelays.Remove(component); - else - _activeDelays.Add(component); - } - - public override void Update(float frameTime) - { - base.Update(frameTime); - - var toRemove = new RemQueue(); - var curTime = _gameTiming.CurTime; - var mQuery = EntityManager.GetEntityQuery(); - - // TODO refactor this to use active components - foreach (var delay in _activeDelays) - { - if (delay.DelayEndTime == null || - curTime > delay.DelayEndTime || - Deleted(delay.Owner, mQuery)) - { - toRemove.Add(delay); - } - } - - foreach (var delay in toRemove) - { - delay.DelayEndTime = null; - _activeDelays.Remove(delay); - Dirty(delay); - } + ent.Comp.Delay += delay; + Dirty(ent); } /// - /// Attempts tp start a use-delay for some entity. Returns true unless there is already an active delay. + /// Returns true if the entity has a currently active UseDelay. /// - /// - /// Note that this will always return true if the entity does not have a use delay component, as in that case there - /// is no reason to block/prevent an interaction. - /// - public bool BeginDelay(EntityUid uid, UseDelayComponent? component = null) + public bool IsDelayed(Entity ent) { - if (!Resolve(uid, ref component, false)) - return true; + return ent.Comp.DelayEndTime >= _gameTiming.CurTime; + } - if (component.ActiveDelay) + /// + /// Cancels the current delay. + /// + public void CancelDelay(Entity ent) + { + ent.Comp.DelayEndTime = _gameTiming.CurTime; + Dirty(ent); + } + + /// + /// Resets the UseDelay entirely for this entity if possible. + /// + /// Check if the entity has an ongoing delay, return false if it does, return true if it does not. + public bool TryResetDelay(Entity ent, bool checkDelayed = false) + { + if (checkDelayed && IsDelayed(ent)) return false; - DebugTools.Assert(!_activeDelays.Contains(component)); - _activeDelays.Add(component); - - var currentTime = _gameTiming.CurTime; - component.LastUseTime = currentTime; - component.DelayEndTime = currentTime + component.Delay; - Dirty(uid, component); - - var cooldown = EnsureComp(uid); - cooldown.CooldownStart = currentTime; - cooldown.CooldownEnd = component.DelayEndTime; + var curTime = _gameTiming.CurTime; + ent.Comp.DelayStartTime = curTime; + ent.Comp.DelayEndTime = curTime - _metadata.GetPauseTime(ent) + ent.Comp.Delay; + Dirty(ent); return true; } - - public bool ActiveDelay(EntityUid uid, UseDelayComponent? component = null) - { - return Resolve(uid, ref component, false) && component.ActiveDelay; - } - - public void Cancel(UseDelayComponent component) - { - component.DelayEndTime = null; - _activeDelays.Remove(component); - Dirty(component); - - if (TryComp(component.Owner, out var cooldown)) - { - cooldown.CooldownEnd = _gameTiming.CurTime; - } - } } diff --git a/Content.Shared/Weapons/Misc/SharedGrapplingGunSystem.cs b/Content.Shared/Weapons/Misc/SharedGrapplingGunSystem.cs index 3aa82c411c..eb02dd06f8 100644 --- a/Content.Shared/Weapons/Misc/SharedGrapplingGunSystem.cs +++ b/Content.Shared/Weapons/Misc/SharedGrapplingGunSystem.cs @@ -6,10 +6,8 @@ using Content.Shared.Interaction; using Content.Shared.Movement.Events; using Content.Shared.Physics; using Content.Shared.Projectiles; -using Content.Shared.Timing; using Content.Shared.Weapons.Ranged.Components; using Content.Shared.Weapons.Ranged.Systems; -using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Network; using Robust.Shared.Physics; @@ -30,7 +28,6 @@ public abstract class SharedGrapplingGunSystem : EntitySystem [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedJointSystem _joints = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; - [Dependency] private readonly UseDelaySystem _delay = default!; public const string GrapplingJoint = "grappling"; @@ -117,10 +114,9 @@ public abstract class SharedGrapplingGunSystem : EntitySystem private void OnGunActivate(EntityUid uid, GrapplingGunComponent component, ActivateInWorldEvent args) { - if (!Timing.IsFirstTimePredicted || _delay.ActiveDelay(uid)) + if (!Timing.IsFirstTimePredicted || args.Handled) return; - _delay.BeginDelay(uid); _audio.PlayPredicted(component.CycleSound, uid, args.User); TryComp(uid, out var appearance); @@ -137,6 +133,8 @@ public abstract class SharedGrapplingGunSystem : EntitySystem component.Projectile = null; Dirty(uid, component); } + + args.Handled = true; } private void SetReeling(EntityUid uid, GrapplingGunComponent component, bool value, EntityUid? user) diff --git a/Content.Shared/Weapons/Ranged/Systems/UseDelayOnShootSystem.cs b/Content.Shared/Weapons/Ranged/Systems/UseDelayOnShootSystem.cs index 10593f56df..260f08c40a 100644 --- a/Content.Shared/Weapons/Ranged/Systems/UseDelayOnShootSystem.cs +++ b/Content.Shared/Weapons/Ranged/Systems/UseDelayOnShootSystem.cs @@ -15,6 +15,7 @@ public sealed class UseDelayOnShootSystem : EntitySystem private void OnUseShoot(EntityUid uid, UseDelayOnShootComponent component, ref GunShotEvent args) { - _delay.BeginDelay(uid); + if (TryComp(uid, out UseDelayComponent? useDelay)) + _delay.TryResetDelay((uid, useDelay)); } } diff --git a/Content.Shared/Wieldable/WieldableSystem.cs b/Content.Shared/Wieldable/WieldableSystem.cs index 72db0c4a3a..0f6422241c 100644 --- a/Content.Shared/Wieldable/WieldableSystem.cs +++ b/Content.Shared/Wieldable/WieldableSystem.cs @@ -1,27 +1,24 @@ -using Content.Shared.DoAfter; using Content.Shared.Hands; using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction.Events; using Content.Shared.Item; using Content.Shared.Popups; +using Content.Shared.Timing; using Content.Shared.Verbs; using Content.Shared.Weapons.Melee; -using Content.Shared.Weapons.Melee.Events; using Content.Shared.Weapons.Melee.Components; +using Content.Shared.Weapons.Melee.Events; using Content.Shared.Weapons.Ranged.Components; using Content.Shared.Weapons.Ranged.Systems; using Content.Shared.Wieldable.Components; -using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Player; -using Content.Shared.Timing; namespace Content.Shared.Wieldable; public sealed class WieldableSystem : EntitySystem { - [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; [Dependency] private readonly SharedHandVirtualItemSystem _virtualItemSystem = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!; [Dependency] private readonly SharedItemSystem _itemSystem = default!; @@ -120,18 +117,18 @@ public sealed class WieldableSystem : EntitySystem if (args.Handled) return; - if(!component.Wielded) + if (!component.Wielded) args.Handled = TryWield(uid, component, args.User); else args.Handled = TryUnwield(uid, component, args.User); } - public bool CanWield(EntityUid uid, WieldableComponent component, EntityUid user, bool quiet=false) + public bool CanWield(EntityUid uid, WieldableComponent component, EntityUid user, bool quiet = false) { // Do they have enough hands free? if (!EntityManager.TryGetComponent(user, out var hands)) { - if(!quiet) + if (!quiet) _popupSystem.PopupClient(Loc.GetString("wieldable-component-no-hands"), user, user); return false; } @@ -190,10 +187,12 @@ public sealed class WieldableSystem : EntitySystem _virtualItemSystem.TrySpawnVirtualItemInHand(used, user); } - _delay.BeginDelay(used); + if (TryComp(used, out UseDelayComponent? useDelay) + && !_delay.TryResetDelay((used, useDelay), true)) + return false; _popupSystem.PopupClient(Loc.GetString("wieldable-component-successful-wield", ("item", used)), user, user); - _popupSystem.PopupEntity(Loc.GetString("wieldable-component-successful-wield-other", ("user", user),("item", used)), user, Filter.PvsExcept(user), true); + _popupSystem.PopupEntity(Loc.GetString("wieldable-component-successful-wield-other", ("user", user), ("item", used)), user, Filter.PvsExcept(user), true); var targEv = new ItemWieldedEvent(); RaiseLocalEvent(used, ref targEv); @@ -224,6 +223,7 @@ public sealed class WieldableSystem : EntitySystem { if (args.User == null) return; + if (!component.Wielded) return; @@ -255,6 +255,7 @@ public sealed class WieldableSystem : EntitySystem { if (!component.Wielded || uid != args.Unequipped) return; + RaiseLocalEvent(uid, new ItemUnwieldedEvent(args.User, force: true), true); } @@ -268,6 +269,7 @@ public sealed class WieldableSystem : EntitySystem { if (!TryComp(uid, out var wield)) return; + if (!wield.Wielded) return; diff --git a/Resources/Maps/aspid.yml b/Resources/Maps/aspid.yml index 00f3ef4c98..bfcb3bc227 100644 --- a/Resources/Maps/aspid.yml +++ b/Resources/Maps/aspid.yml @@ -100405,7 +100405,6 @@ entities: - Pressed: Toggle 1065: - Pressed: Toggle - - type: ItemCooldown - uid: 7826 components: - type: Transform @@ -100451,7 +100450,6 @@ entities: - Pressed: Toggle 2822: - Pressed: Toggle - - type: ItemCooldown - uid: 8749 components: - type: Transform @@ -100550,7 +100548,6 @@ entities: linkedPorts: 4205: - Pressed: Toggle - - type: ItemCooldown - uid: 17649 components: - type: Transform @@ -100563,7 +100560,6 @@ entities: linkedPorts: 3066: - Pressed: Toggle - - type: ItemCooldown - proto: SignalButtonBridge entities: - uid: 4305 diff --git a/Resources/Maps/cluster.yml b/Resources/Maps/cluster.yml index 3dab4f1e19..db00d2d62f 100644 --- a/Resources/Maps/cluster.yml +++ b/Resources/Maps/cluster.yml @@ -67091,7 +67091,7 @@ entities: 3218: - Pressed: Toggle type: DeviceLinkSource - - type: ItemCooldown + - type: UseDelay - uid: 5389 components: - rot: 1.5707963267948966 rad @@ -67104,7 +67104,7 @@ entities: 3218: - Pressed: Toggle type: DeviceLinkSource - - type: ItemCooldown + - type: UseDelay - uid: 5447 components: - rot: 3.141592653589793 rad diff --git a/Resources/Maps/europa.yml b/Resources/Maps/europa.yml index 14636c1096..653721d1ce 100644 --- a/Resources/Maps/europa.yml +++ b/Resources/Maps/europa.yml @@ -74740,7 +74740,7 @@ entities: 1663: - Pressed: Toggle type: DeviceLinkSource - - type: ItemCooldown + - type: UseDelay - uid: 9640 components: - pos: -20.5,-1.5 diff --git a/Resources/Maps/gemini.yml b/Resources/Maps/gemini.yml index de01876acb..d26f4ac59b 100644 --- a/Resources/Maps/gemini.yml +++ b/Resources/Maps/gemini.yml @@ -142471,7 +142471,6 @@ entities: - Pressed: Toggle 20499: - Pressed: Toggle - - type: ItemCooldown - uid: 20513 components: - type: Transform @@ -142704,7 +142703,6 @@ entities: - Pressed: Toggle 20423: - Pressed: Toggle - - type: ItemCooldown - uid: 20528 components: - type: Transform diff --git a/Resources/Maps/marathon.yml b/Resources/Maps/marathon.yml index 6b77eb7525..c7e6486c53 100644 --- a/Resources/Maps/marathon.yml +++ b/Resources/Maps/marathon.yml @@ -118234,7 +118234,6 @@ entities: - Pressed: Toggle 9404: - Pressed: Toggle - - type: ItemCooldown - uid: 8610 components: - type: Transform diff --git a/Resources/Maps/meta.yml b/Resources/Maps/meta.yml index 15a11add3f..93d8d49f60 100644 --- a/Resources/Maps/meta.yml +++ b/Resources/Maps/meta.yml @@ -135841,7 +135841,6 @@ entities: - Pressed: Toggle 19434: - Pressed: Toggle - - type: ItemCooldown - uid: 19438 components: - type: MetaData diff --git a/Resources/Maps/origin.yml b/Resources/Maps/origin.yml index 35db1567da..3a6f173e91 100644 --- a/Resources/Maps/origin.yml +++ b/Resources/Maps/origin.yml @@ -79806,7 +79806,6 @@ entities: - pos: -46.5,62.5 parent: 2 type: Transform - - type: ItemCooldown - proto: ClothingBackpackMedical entities: - uid: 12350 @@ -163449,7 +163448,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24195 components: - rot: -1.5707963267948966 rad @@ -163481,7 +163479,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24196 components: - name: shutters switch @@ -163514,7 +163511,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24197 components: - name: blast door switch @@ -163528,7 +163524,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24198 components: - rot: -1.5707963267948966 rad @@ -163557,7 +163552,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24199 components: - rot: 1.5707963267948966 rad @@ -163572,7 +163566,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24200 components: - rot: 3.141592653589793 rad @@ -163624,7 +163617,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24204 components: - rot: 3.141592653589793 rad @@ -163671,7 +163663,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24207 components: - pos: -52.5,-11.5 @@ -163728,7 +163719,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24210 components: - pos: -49.5,24.5 @@ -163793,7 +163783,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24214 components: - pos: 58.5,48.5 @@ -164016,7 +164005,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24228 components: - pos: 54.5,51.5 @@ -164033,7 +164021,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24229 components: - pos: 5.5,49.5 @@ -164229,7 +164216,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24238 components: - rot: 3.141592653589793 rad @@ -164273,7 +164259,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24239 components: - name: shutters switch @@ -164294,7 +164279,6 @@ entities: - Off: Close - Status: Toggle type: DeviceLinkSource - - type: ItemCooldown - uid: 24240 components: - pos: -51.5,36.5 @@ -164305,7 +164289,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24241 components: - name: shutters switch @@ -164342,7 +164325,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24242 components: - name: visitation switch @@ -164363,7 +164345,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24243 components: - name: shutters switch @@ -164402,7 +164383,6 @@ entities: - On: Open - Off: Close type: DeviceLinkSource - - type: ItemCooldown - uid: 24245 components: - name: shutters switch @@ -164521,7 +164501,6 @@ entities: - Off: Close - Status: Toggle type: DeviceLinkSource - - type: ItemCooldown - uid: 24248 components: - pos: -74.5,-43.5 @@ -175048,7 +175027,6 @@ entities: - Right: Reverse - Middle: Off type: DeviceLinkSource - - type: ItemCooldown - uid: 25925 components: - pos: -41.5,17.5 @@ -175351,7 +175329,6 @@ entities: - Right: Reverse - Middle: Off type: DeviceLinkSource - - type: ItemCooldown - uid: 25933 components: - pos: 47.5,39.5 @@ -175551,7 +175528,6 @@ entities: - Right: Forward - Middle: Off type: DeviceLinkSource - - type: ItemCooldown - proto: UnfinishedMachineFrame entities: - uid: 25938 diff --git a/Resources/Maps/saltern.yml b/Resources/Maps/saltern.yml index 7a955f62a7..c3f158b985 100644 --- a/Resources/Maps/saltern.yml +++ b/Resources/Maps/saltern.yml @@ -56927,7 +56927,6 @@ entities: 260: - Pressed: Toggle type: DeviceLinkSource - - type: ItemCooldown - uid: 8766 components: - pos: -13.5,12.5 @@ -56965,7 +56964,6 @@ entities: 7588: - Pressed: Toggle type: DeviceLinkSource - - type: ItemCooldown - uid: 10449 components: - pos: 51.5,18.5 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml index f651254c9b..4b8628213b 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml @@ -53,7 +53,6 @@ qualities: - Rolling speed: 0.25 # its small so takes longer to roll the entire dough flat - - type: ItemCooldown - type: SpaceGarbage - type: TrashOnSolutionEmpty solution: drink diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml index e626e21cb8..1fbc53c922 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml @@ -37,7 +37,6 @@ damage: types: Blunt: 0 - - type: ItemCooldown - type: entity parent: DrinkBaseCup diff --git a/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/reinforcement_teleporter.yml b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/reinforcement_teleporter.yml index f4bc48a241..6d324b6bed 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/reinforcement_teleporter.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/reinforcement_teleporter.yml @@ -16,7 +16,6 @@ prototype: MobHumanSyndicateAgent - type: EmitSoundOnUse sound: /Audio/Effects/Emotes/parp1.ogg - - type: ItemCooldown - type: UseDelay delay: 300 diff --git a/Resources/Prototypes/Entities/Objects/Devices/holoprojectors.yml b/Resources/Prototypes/Entities/Objects/Devices/holoprojectors.yml index e1137d7b8c..c347a91180 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/holoprojectors.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/holoprojectors.yml @@ -5,9 +5,7 @@ description: A handy-dandy holographic projector that displays a janitorial sign. components: - type: HolosignProjector - - type: ItemCooldown - type: UseDelay - delay: 1.0 - type: ContainerContainer containers: cell_slot: !type:ContainerSlot {} diff --git a/Resources/Prototypes/Entities/Objects/Fun/bike_horn.yml b/Resources/Prototypes/Entities/Objects/Fun/bike_horn.yml index caf2b909c6..e3fe9d8949 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/bike_horn.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/bike_horn.yml @@ -14,7 +14,6 @@ sprite: Objects/Fun/bikehorn.rsi slots: [Belt] quickEquip: false - - type: ItemCooldown - type: EmitSoundOnUse sound: collection: BikeHorn @@ -52,7 +51,7 @@ name: broken bike horn description: A broken horn off of a bicycle. components: - - type: ItemCooldown + - type: UseDelay - type: Sprite sprite: Objects/Fun/cluwnehorn.rsi state: icon diff --git a/Resources/Prototypes/Entities/Objects/Fun/darts.yml b/Resources/Prototypes/Entities/Objects/Fun/darts.yml index 8d8565361d..a4e86e1b11 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/darts.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/darts.yml @@ -42,7 +42,6 @@ - type: Item size: Tiny sprite: Objects/Fun/Darts/dart_red.rsi - - type: ItemCooldown - type: SolutionContainerManager solutions: melee: @@ -204,4 +203,4 @@ items: - id: HypoDart sound: - path: /Audio/Effects/unwrap.ogg \ No newline at end of file + path: /Audio/Effects/unwrap.ogg diff --git a/Resources/Prototypes/Entities/Objects/Fun/dice.yml b/Resources/Prototypes/Entities/Objects/Fun/dice.yml index d5f28d09b6..090245cb50 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/dice.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/dice.yml @@ -4,7 +4,6 @@ id: BaseDice components: - type: Dice - - type: ItemCooldown - type: UseDelay - type: Sprite sprite: Objects/Fun/dice.rsi diff --git a/Resources/Prototypes/Entities/Objects/Fun/skub.yml b/Resources/Prototypes/Entities/Objects/Fun/skub.yml index 037f9ec80d..0061270df2 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/skub.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/skub.yml @@ -9,7 +9,6 @@ state: icon - type: Item sprite: Objects/Misc/skub.rsi - - type: ItemCooldown - type: EmitSoundOnUse sound: collection: Skub diff --git a/Resources/Prototypes/Entities/Objects/Fun/toys.yml b/Resources/Prototypes/Entities/Objects/Fun/toys.yml index ae6d37b554..41233ffecd 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/toys.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/toys.yml @@ -19,7 +19,6 @@ - type: EmitSoundOnLand sound: collection: ToyFall - - type: ItemCooldown - type: UseDelay delay: 1.0 - type: MeleeWeapon @@ -709,7 +708,7 @@ size: Small sprite: Objects/Fun/toys.rsi heldPrefix: foamblade - - type: ItemCooldown + - type: UseDelay # MISC @@ -1020,7 +1019,6 @@ sprite: Objects/Fun/whoopie.rsi state: icon quickEquip: false - - type: ItemCooldown - type: EmitSoundOnUse sound: collection: Parp diff --git a/Resources/Prototypes/Entities/Objects/Materials/crystal_shard.yml b/Resources/Prototypes/Entities/Objects/Materials/crystal_shard.yml index 797cee6b4f..d880d9d181 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/crystal_shard.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/crystal_shard.yml @@ -20,7 +20,6 @@ - enum.DamageStateVisualLayers.Base: shard3: "" - type: SpaceGarbage - - type: ItemCooldown - type: MeleeWeapon attackRate: 1.5 damage: diff --git a/Resources/Prototypes/Entities/Objects/Materials/shards.yml b/Resources/Prototypes/Entities/Objects/Materials/shards.yml index c5abc9d8cc..3dd254b0c4 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/shards.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/shards.yml @@ -18,7 +18,6 @@ shard2: "" - enum.DamageStateVisualLayers.Base: shard3: "" - - type: ItemCooldown - type: MeleeWeapon attackRate: 1.5 damage: diff --git a/Resources/Prototypes/Entities/Objects/Misc/broken_bottle.yml b/Resources/Prototypes/Entities/Objects/Misc/broken_bottle.yml index e7f2088b64..c5d970af50 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/broken_bottle.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/broken_bottle.yml @@ -5,7 +5,6 @@ description: In Space Glasgow this is called a conversation starter. components: - type: Sharp - - type: ItemCooldown - type: MeleeWeapon attackRate: 1.5 damage: @@ -27,4 +26,3 @@ materialComposition: Glass: 50 - type: SpaceGarbage - diff --git a/Resources/Prototypes/Entities/Objects/Misc/desk_bell.yml b/Resources/Prototypes/Entities/Objects/Misc/desk_bell.yml index 12406f2890..092722ec17 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/desk_bell.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/desk_bell.yml @@ -32,7 +32,6 @@ params: variation: 0.03 volume: 3 - - type: ItemCooldown - type: UseDelay delay: 0.5 - type: MeleeWeapon diff --git a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml index 1deafac00b..bae33f27f1 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml @@ -24,7 +24,7 @@ - type: DrainableSolution solution: spray - type: SolutionTransfer - - type: ItemCooldown + - type: UseDelay - type: Spray transferAmount: 10 pushbackAmount: 60 diff --git a/Resources/Prototypes/Entities/Objects/Misc/paper.yml b/Resources/Prototypes/Entities/Objects/Misc/paper.yml index e66829c7d4..16966a4e4d 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/paper.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/paper.yml @@ -287,7 +287,6 @@ - type: Sprite sprite: Objects/Misc/bureaucracy.rsi state: overpriced_pen - - type: ItemCooldown - type: MeleeWeapon wideAnimationRotation: -45 damage: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Chapel/bibles.yml b/Resources/Prototypes/Entities/Objects/Specific/Chapel/bibles.yml index 75ce118d9f..fef4d47be0 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Chapel/bibles.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Chapel/bibles.yml @@ -26,7 +26,6 @@ mixMessage: "bible-mixing-success" reactionTypes: - Holy - - type: ItemCooldown - type: Sprite sprite: Objects/Specific/Chapel/bible.rsi state: icon diff --git a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/sprays.yml b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/sprays.yml index e54dedb066..9d9f3b7324 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/sprays.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/sprays.yml @@ -45,7 +45,6 @@ solution: spray - type: Spillable solution: spray - - type: ItemCooldown - type: Tag tags: - Spray diff --git a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/tools.yml b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/tools.yml index 1209d2a3f9..d389a35fe0 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/tools.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/tools.yml @@ -11,7 +11,6 @@ - type: Sprite sprite: Objects/Tools/Hydroponics/hoe.rsi state: icon - - type: ItemCooldown - type: MeleeWeapon wideAnimationRotation: 135 swingLeft: true @@ -33,7 +32,6 @@ - type: Sprite sprite: Objects/Tools/Hydroponics/clippers.rsi state: icon - - type: ItemCooldown - type: MeleeWeapon wideAnimationRotation: 90 damage: @@ -53,7 +51,6 @@ - type: Sprite sprite: Objects/Tools/Hydroponics/scythe.rsi state: icon - - type: ItemCooldown - type: MeleeWeapon wideAnimationRotation: 135 damage: @@ -81,7 +78,6 @@ - type: Sprite sprite: Objects/Tools/Hydroponics/hatchet.rsi state: icon - - type: ItemCooldown - type: MeleeWeapon wideAnimationRotation: 135 swingLeft: true @@ -105,7 +101,6 @@ - type: Sprite sprite: Objects/Tools/Hydroponics/spade.rsi state: icon - - type: ItemCooldown - type: MeleeWeapon wideAnimationRotation: 45 damage: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml index e819d6c39f..e284944a53 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml @@ -562,7 +562,6 @@ - type: Item sprite: Objects/Specific/Janitorial/plunger.rsi heldPrefix: plunger - - type: ItemCooldown - type: GuideHelp guides: - Janitorial diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml index ed55afea1d..dbbea70746 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/spray.yml @@ -24,7 +24,7 @@ solution: spray - type: SolutionTransfer canChangeTransferAmount: true - - type: ItemCooldown + - type: UseDelay - type: Spray transferAmount: 10 sprayVelocity: 2 diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/defib.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/defib.yml index 2d1af8f246..3c93a0a876 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/defib.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/defib.yml @@ -29,7 +29,6 @@ False: { visible: false } - type: Item size: Large - - type: ItemCooldown - type: Speech speechVerb: Robotic - type: Defibrillator diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/surgery.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/surgery.yml index 354cee2f99..e157817ec4 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/surgery.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/surgery.yml @@ -22,7 +22,6 @@ state: cautery - type: Item sprite: Objects/Specific/Medical/Surgery/cautery.rsi - - type: ItemCooldown - type: MeleeWeapon damage: types: @@ -43,7 +42,6 @@ state: drill - type: Item sprite: Objects/Specific/Medical/Surgery/drill.rsi - - type: ItemCooldown - type: MeleeWeapon damage: types: @@ -69,7 +67,6 @@ state: scalpel - type: Item sprite: Objects/Specific/Medical/Surgery/scalpel.rsi - - type: ItemCooldown - type: MeleeWeapon attackRate: 1.5 damage: @@ -128,7 +125,6 @@ state: retractor - type: Item sprite: Objects/Specific/Medical/Surgery/scissors.rsi - - type: ItemCooldown - type: entity name: hemostat @@ -164,7 +160,6 @@ state: saw - type: Item sprite: Objects/Specific/Medical/Surgery/saw.rsi - - type: ItemCooldown - type: Tool qualities: - Sawing diff --git a/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml b/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml index 6abdd790c9..f3be016724 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml @@ -12,7 +12,6 @@ - state: base - state: green_bit shader: unshaded - - type: ItemCooldown - type: MeleeWeapon damage: types: diff --git a/Resources/Prototypes/Entities/Objects/Tools/cowtools.yml b/Resources/Prototypes/Entities/Objects/Tools/cowtools.yml index e6a7a43fa4..05a80043e8 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/cowtools.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/cowtools.yml @@ -10,7 +10,6 @@ - type: Sprite sprite: Objects/Tools/Cowtools/haycutters.rsi state: haycutters - - type: ItemCooldown - type: MeleeWeapon damage: types: @@ -36,7 +35,6 @@ state: moodriver - type: Item sprite: Objects/Tools/Cowtools/moodriver.rsi - - type: ItemCooldown - type: MeleeWeapon attackRate: 1.5 damage: @@ -60,7 +58,6 @@ state: wronch - type: Item sprite: Objects/Tools/Cowtools/wronch.rsi - - type: ItemCooldown - type: MeleeWeapon attackRate: 1.5 damage: @@ -84,7 +81,6 @@ state: cowbar - type: Item sprite: Objects/Tools/Cowtools/cowbar.rsi - - type: ItemCooldown - type: MeleeWeapon damage: types: @@ -185,4 +181,3 @@ - id: Mooltitool - id: Cowelder - id: Milkalyzer - diff --git a/Resources/Prototypes/Entities/Objects/Tools/lighters.yml b/Resources/Prototypes/Entities/Objects/Tools/lighters.yml index e9315a6418..ab11fb65b6 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/lighters.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/lighters.yml @@ -71,7 +71,7 @@ - type: Item size: Tiny sprite: Objects/Tools/lighters.rsi - - type: ItemCooldown + - type: UseDelay - type: RefillableSolution solution: Welder - type: SolutionContainerManager diff --git a/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml b/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml index 2627bbeeda..64efe53f43 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml @@ -13,7 +13,6 @@ - 0,0,6,3 - type: Item size: Ginormous - - type: ItemCooldown - type: MeleeWeapon damage: types: diff --git a/Resources/Prototypes/Entities/Objects/Tools/tools.yml b/Resources/Prototypes/Entities/Objects/Tools/tools.yml index c173eb7e76..8d85a13429 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/tools.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/tools.yml @@ -17,7 +17,6 @@ - state: cutters map: [ "enum.DamageStateVisualLayers.Base" ] - state: cutters-cutty-thingy - - type: ItemCooldown - type: MeleeWeapon wideAnimationRotation: -90 damage: @@ -66,7 +65,6 @@ - type: Item sprite: Objects/Tools/screwdriver.rsi storedRotation: -90 - - type: ItemCooldown - type: MeleeWeapon wideAnimationRotation: -90 attackRate: 1 @@ -110,7 +108,6 @@ storedSprite: sprite: Objects/Tools/wrench.rsi state: storage - - type: ItemCooldown - type: MeleeWeapon wideAnimationRotation: 135 attackRate: 1.5 @@ -149,7 +146,6 @@ storedSprite: sprite: Objects/Tools/crowbar.rsi state: storage - - type: ItemCooldown - type: MeleeWeapon wideAnimationRotation: -135 damage: @@ -351,7 +347,6 @@ maxCharges: 5 charges: 5 - type: UseDelay - delay: 1.0 - type: Sprite sprite: Objects/Tools/rcd.rsi state: icon @@ -500,7 +495,6 @@ - type: Sprite sprite: Objects/Tools/shovel.rsi state: icon - - type: ItemCooldown - type: MeleeWeapon wideAnimationRotation: -135 damage: @@ -533,7 +527,6 @@ quickEquip: false slots: - Belt - - type: ItemCooldown - type: MeleeWeapon wideAnimationRotation: -135 damage: diff --git a/Resources/Prototypes/Entities/Objects/Tools/welders.yml b/Resources/Prototypes/Entities/Objects/Tools/welders.yml index eeb2f11179..60dfe0f136 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/welders.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/welders.yml @@ -64,7 +64,7 @@ right: - state: inhand-right-flame shader: unshaded - - type: ItemCooldown + - type: UseDelay - type: MeleeWeapon wideAnimationRotation: -90 damage: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml index 3c7c1a7865..106e8bf440 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml @@ -10,7 +10,6 @@ - type: Utensil types: - Knife - - type: ItemCooldown - type: MeleeWeapon wideAnimationRotation: -135 damage: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/pickaxe.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/pickaxe.yml index d8809389a7..4368f162a2 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/pickaxe.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/pickaxe.yml @@ -10,7 +10,6 @@ - type: Sprite sprite: Objects/Weapons/Melee/pickaxe.rsi state: pickaxe - - type: ItemCooldown - type: MeleeWeapon wideAnimationRotation: -135 damage: @@ -31,7 +30,6 @@ sprite: Objects/Weapons/Melee/pickaxe.rsi storedRotation: -45 - type: UseDelay - delay: 1 - type: entity name: mining drill @@ -45,7 +43,6 @@ - type: Sprite sprite: Objects/Tools/handdrill.rsi state: handdrill - - type: ItemCooldown - type: MeleeWeapon attackRate: 1.5 damage: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml index e704fc90a4..4dff7f3ee1 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml @@ -55,7 +55,6 @@ - type: Construction graph: Spear node: spear - - type: ItemCooldown - type: SolutionContainerManager solutions: melee: @@ -107,7 +106,6 @@ types: Blunt: 5 - type: UseDelay - delay: 1 - type: Appearance - type: SolutionContainerVisuals maxFillLevels: 1 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml index 6a566927db..b0b166f6ce 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/stunprod.yml @@ -44,7 +44,7 @@ - type: Battery maxCharge: 360 startingCharge: 360 - - type: ItemCooldown + - type: UseDelay - type: Item heldPrefix: off size: Normal diff --git a/Resources/Prototypes/Entities/Objects/Weapons/security.yml b/Resources/Prototypes/Entities/Objects/Weapons/security.yml index d55a396164..93bc0a2dd3 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/security.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/security.yml @@ -46,7 +46,7 @@ - type: Battery maxCharge: 1000 startingCharge: 1000 - - type: ItemCooldown + - type: UseDelay - type: Item heldPrefix: off size: Normal @@ -142,7 +142,7 @@ - type: Item size: Small sprite: Objects/Weapons/Melee/flash.rsi - - type: ItemCooldown + - type: UseDelay - type: StaticPrice price: 40 - type: Appearance diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/collector.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/collector.yml index e43c80400e..73ce221787 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/collector.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/collector.yml @@ -81,14 +81,16 @@ guides: [ Singularity, Power ] - type: ContainerContainer containers: - GasTank: !type:ContainerSlot {} + gas_tank: !type:ContainerSlot {} - type: ItemSlots slots: - GasTank: + gas_tank: startingItem: PlasmaTank whitelist: components: - GasTank + - type: UseDelay + delay: 1 - type: entity id: RadiationCollectorNoTank @@ -97,11 +99,11 @@ components: - type: ItemSlots slots: - GasTank: + gas_tank: whitelist: components: - GasTank - + - type: entity id: RadiationCollectorFullTank suffix: Filled tank @@ -109,8 +111,8 @@ components: - type: ItemSlots slots: - GasTank: + gas_tank: startingItem: PlasmaTankFilled whitelist: components: - - GasTank \ No newline at end of file + - GasTank diff --git a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/cores.yml b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/cores.yml index 06e08beb75..6679b2d533 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/cores.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/cores.yml @@ -20,7 +20,6 @@ False: { visible: false } - type: Item size: Normal - - type: ItemCooldown - type: EmitSoundOnUse #placeholder for future unical mechanic sound: collection: RadiationPulse diff --git a/Resources/Prototypes/XenoArch/Effects/utility_effects.yml b/Resources/Prototypes/XenoArch/Effects/utility_effects.yml index edfd64b06c..65ebcab944 100644 --- a/Resources/Prototypes/XenoArch/Effects/utility_effects.yml +++ b/Resources/Prototypes/XenoArch/Effects/utility_effects.yml @@ -127,7 +127,7 @@ components: - Item permanentComponents: - - type: ItemCooldown + - type: UseDelay - type: MeleeWeapon damage: types: