UseDelay + ItemCooldown merge (#22502)

This commit is contained in:
AJCM-git
2024-01-03 21:33:09 -04:00
committed by GitHub
parent 42ec9b2967
commit 9c522c8b19
80 changed files with 324 additions and 589 deletions

View File

@@ -1,9 +1,7 @@
using Content.Client.Clothing; using Content.Client.Clothing;
using Content.Client.Examine; using Content.Client.Examine;
using Content.Client.Verbs.UI; using Content.Client.Verbs.UI;
using Content.Shared.Clothing.Components;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Interaction.Events;
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Content.Shared.Inventory.Events; using Content.Shared.Inventory.Events;
using Content.Shared.Storage; using Content.Shared.Storage;
@@ -48,8 +46,6 @@ namespace Content.Client.Inventory
_equipEventsQueue.Enqueue((comp, args))); _equipEventsQueue.Enqueue((comp, args)));
SubscribeLocalEvent<InventorySlotsComponent, DidUnequipEvent>((_, comp, args) => SubscribeLocalEvent<InventorySlotsComponent, DidUnequipEvent>((_, comp, args) =>
_equipEventsQueue.Enqueue((comp, args))); _equipEventsQueue.Enqueue((comp, args)));
SubscribeLocalEvent<ClothingComponent, UseInHandEvent>(OnUseInHand);
} }
public override void Update(float frameTime) 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) private void OnDidUnequip(InventorySlotsComponent component, DidUnequipEvent args)
{ {
UpdateSlot(args.Equipee, component, args.Slot); UpdateSlot(args.Equipee, component, args.Slot);

View File

@@ -3,10 +3,9 @@ using Content.Client.Hands.Systems;
using Content.Client.UserInterface.Controls; using Content.Client.UserInterface.Controls;
using Content.Client.UserInterface.Systems.Hands.Controls; using Content.Client.UserInterface.Systems.Hands.Controls;
using Content.Client.UserInterface.Systems.Hotbar.Widgets; using Content.Client.UserInterface.Systems.Hotbar.Widgets;
using Content.Shared.Cooldown;
using Content.Shared.Hands.Components; using Content.Shared.Hands.Components;
using Content.Shared.Input; using Content.Shared.Input;
using Robust.Client.GameObjects; using Content.Shared.Timing;
using Robust.Client.Player; using Robust.Client.Player;
using Robust.Client.UserInterface; using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controllers; using Robust.Client.UserInterface.Controllers;
@@ -247,7 +246,7 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
if (HandsGui != null && if (HandsGui != null &&
_playerHandsComponent != null && _playerHandsComponent != null &&
_player.LocalPlayer?.ControlledEntity is { } playerEntity && _player.LocalSession?.AttachedEntity is { } playerEntity &&
_handsSystem.TryGetHand(playerEntity, handName, out var hand, _playerHandsComponent)) _handsSystem.TryGetHand(playerEntity, handName, out var hand, _playerHandsComponent))
{ {
HandsGui.UpdatePanelEntity(hand.HeldEntity); HandsGui.UpdatePanelEntity(hand.HeldEntity);
@@ -329,7 +328,6 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
private bool RemoveHand(string handName, out HandButton? handButton) private bool RemoveHand(string handName, out HandButton? handButton)
{ {
handButton = null;
if (!_handLookup.TryGetValue(handName, out handButton)) if (!_handLookup.TryGetValue(handName, out handButton))
return false; return false;
if (handButton.Parent is HandsContainer handContainer) if (handButton.Parent is HandsContainer handContainer)
@@ -395,8 +393,9 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
{ {
foreach (var hand in container.GetButtons()) foreach (var hand in container.GetButtons())
{ {
if (!_entities.TryGetComponent(hand.Entity, out ItemCooldownComponent? cooldown) ||
cooldown is not { CooldownStart: { } start, CooldownEnd: { } end}) if (!_entities.TryGetComponent(hand.Entity, out UseDelayComponent? useDelay) ||
useDelay is not { DelayStartTime: var start, DelayEndTime: var end })
{ {
hand.CooldownDisplay.Visible = false; hand.CooldownDisplay.Visible = false;
return; return;

View File

@@ -1,6 +1,5 @@
using Content.Server.Administration.Logs; using Content.Server.Administration.Logs;
using Content.Server.Atmos.Components; using Content.Server.Atmos.Components;
using Content.Server.Explosion.EntitySystems;
using Content.Server.IgnitionSource; using Content.Server.IgnitionSource;
using Content.Server.Stunnable; using Content.Server.Stunnable;
using Content.Server.Temperature.Components; using Content.Server.Temperature.Components;
@@ -12,7 +11,6 @@ using Content.Shared.Atmos.Components;
using Content.Shared.Damage; using Content.Shared.Damage;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Interaction.Events;
using Content.Shared.Physics; using Content.Shared.Physics;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Rejuvenate; using Content.Shared.Rejuvenate;
@@ -22,7 +20,6 @@ using Content.Shared.Timing;
using Content.Shared.Toggleable; using Content.Shared.Toggleable;
using Content.Shared.Weapons.Melee.Events; using Content.Shared.Weapons.Melee.Events;
using Robust.Server.Audio; using Robust.Server.Audio;
using Robust.Server.GameObjects;
using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Events; using Robust.Shared.Physics.Events;
using Robust.Shared.Physics.Systems; using Robust.Shared.Physics.Systems;
@@ -39,9 +36,7 @@ namespace Content.Server.Atmos.EntitySystems
[Dependency] private readonly IgnitionSourceSystem _ignitionSourceSystem = default!; [Dependency] private readonly IgnitionSourceSystem _ignitionSourceSystem = default!;
[Dependency] private readonly DamageableSystem _damageableSystem = default!; [Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private readonly AlertsSystem _alertsSystem = default!; [Dependency] private readonly AlertsSystem _alertsSystem = default!;
[Dependency] private readonly TransformSystem _transformSystem = default!;
[Dependency] private readonly FixtureSystem _fixture = default!; [Dependency] private readonly FixtureSystem _fixture = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!; [Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly SharedPopupSystem _popup = default!;
@@ -59,7 +54,6 @@ namespace Content.Server.Atmos.EntitySystems
private float _timer; private float _timer;
private readonly Dictionary<Entity<FlammableComponent>, float> _fireEvents = new(); private readonly Dictionary<Entity<FlammableComponent>, float> _fireEvents = new();
private readonly List<EntityUid> _toRemove = new();
public override void Initialize() public override void Initialize()
{ {
@@ -157,10 +151,11 @@ namespace Content.Server.Atmos.EntitySystems
args.Handled = true; args.Handled = true;
if (!_useDelay.BeginDelay(uid)) if (!TryComp(uid, out UseDelayComponent? useDelay) || !_useDelay.TryResetDelay((uid, useDelay), true))
return; return;
_audio.PlayPvs(component.ExtinguishAttemptSound, uid); _audio.PlayPvs(component.ExtinguishAttemptSound, uid);
if (_random.Prob(component.Probability)) if (_random.Prob(component.Probability))
{ {
AdjustFireStacks(uid, component.StackDelta, flammable); AdjustFireStacks(uid, component.StackDelta, flammable);
@@ -170,6 +165,7 @@ namespace Content.Server.Atmos.EntitySystems
_popup.PopupEntity(Loc.GetString(component.ExtinguishFailed), uid); _popup.PopupEntity(Loc.GetString(component.ExtinguishFailed), uid);
} }
} }
private void OnCollide(EntityUid uid, FlammableComponent flammable, ref StartCollideEvent args) private void OnCollide(EntityUid uid, FlammableComponent flammable, ref StartCollideEvent args)
{ {
var otherUid = args.OtherEntity; 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. // TODO: This needs cleanup to take off the crust from TemperatureComponent and shit.
var query = EntityQueryEnumerator<FlammableComponent, TransformComponent>(); var query = EntityQueryEnumerator<FlammableComponent, TransformComponent>();
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. // Slowly dry ourselves off if wet.
if (flammable.FireStacks < 0) if (flammable.FireStacks < 0)
@@ -394,7 +390,7 @@ namespace Content.Server.Atmos.EntitySystems
EnsureComp<IgnitionSourceComponent>(uid); EnsureComp<IgnitionSourceComponent>(uid);
_ignitionSourceSystem.SetIgnited(uid); _ignitionSourceSystem.SetIgnited(uid);
var damageScale = MathF.Min(flammable.FireStacks, 5); var damageScale = MathF.Min( flammable.FireStacks, 5);
if (TryComp(uid, out TemperatureComponent? temp)) if (TryComp(uid, out TemperatureComponent? temp))
_temperatureSystem.ChangeHeat(uid, 12500 * damageScale, false, temp); _temperatureSystem.ChangeHeat(uid, 12500 * damageScale, false, temp);

View File

@@ -32,6 +32,7 @@ namespace Content.Server.Bible
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!; [Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly UseDelaySystem _delay = default!; [Dependency] private readonly UseDelaySystem _delay = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
public override void Initialize() public override void Initialize()
{ {
@@ -55,20 +56,20 @@ namespace Content.Server.Bible
{ {
base.Update(frameTime); base.Update(frameTime);
foreach(var entity in _addQueue) foreach (var entity in _addQueue)
{ {
EnsureComp<SummonableRespawningComponent>(entity); EnsureComp<SummonableRespawningComponent>(entity);
} }
_addQueue.Clear(); _addQueue.Clear();
foreach(var entity in _remQueue) foreach (var entity in _remQueue)
{ {
RemComp<SummonableRespawningComponent>(entity); RemComp<SummonableRespawningComponent>(entity);
} }
_remQueue.Clear(); _remQueue.Clear();
var query = EntityQueryEnumerator<SummonableRespawningComponent, SummonableComponent>(); var query = EntityQueryEnumerator<SummonableRespawningComponent, SummonableComponent>();
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; summonableComp.Accumulator += frameTime;
if (summonableComp.Accumulator < summonableComp.RespawnTime) if (summonableComp.Accumulator < summonableComp.RespawnTime)
@@ -82,8 +83,8 @@ namespace Content.Server.Bible
summonableComp.Summon = null; summonableComp.Summon = null;
} }
summonableComp.AlreadySummoned = false; summonableComp.AlreadySummoned = false;
_popupSystem.PopupEntity(Loc.GetString("bible-summon-respawn-ready", ("book", summonableComp.Owner)), summonableComp.Owner, PopupType.Medium); _popupSystem.PopupEntity(Loc.GetString("bible-summon-respawn-ready", ("book", uid)), uid, PopupType.Medium);
_audio.PlayPvs("/Audio/Effects/radpulse9.ogg", summonableComp.Owner, AudioParams.Default.WithVolume(-4f)); _audio.PlayPvs("/Audio/Effects/radpulse9.ogg", uid, AudioParams.Default.WithVolume(-4f));
// Clean up the accumulator and respawn tracking component // Clean up the accumulator and respawn tracking component
summonableComp.Accumulator = 0; summonableComp.Accumulator = 0;
_remQueue.Enqueue(uid); _remQueue.Enqueue(uid);
@@ -95,9 +96,7 @@ namespace Content.Server.Bible
if (!args.CanReach) if (!args.CanReach)
return; return;
UseDelayComponent? delay = null; if (!TryComp(uid, out UseDelayComponent? useDelay) || _delay.IsDelayed((uid, useDelay)))
if (_delay.ActiveDelay(uid, delay))
return; return;
if (args.Target == null || args.Target == args.User || !_mobStateSystem.IsAlive(args.Target.Value)) 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); _audio.PlayPvs(component.SizzleSoundPath, args.User);
_damageableSystem.TryChangeDamage(args.User, component.DamageOnUntrainedUse, true, origin: uid); _damageableSystem.TryChangeDamage(args.User, component.DamageOnUntrainedUse, true, origin: uid);
_delay.BeginDelay(uid, delay); _delay.TryResetDelay((uid, useDelay));
return; return;
} }
@@ -121,15 +120,15 @@ namespace Content.Server.Bible
{ {
if (_random.Prob(component.FailChance)) 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); _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); _popupSystem.PopupEntity(selfFailMessage, args.User, args.User, PopupType.MediumCaution);
_audio.PlayPvs("/Audio/Effects/hit_kick.ogg", args.User); _audio.PlayPvs("/Audio/Effects/hit_kick.ogg", args.User);
_damageableSystem.TryChangeDamage(args.Target.Value, component.DamageOnFail, true, origin: uid); _damageableSystem.TryChangeDamage(args.Target.Value, component.DamageOnFail, true, origin: uid);
_delay.BeginDelay(uid, delay); _delay.TryResetDelay((uid, useDelay));
return; return;
} }
} }
@@ -138,21 +137,21 @@ namespace Content.Server.Bible
if (damage == null || damage.Empty) 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); _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); _popupSystem.PopupEntity(selfMessage, args.User, args.User, PopupType.Large);
} }
else 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); _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); _popupSystem.PopupEntity(selfMessage, args.User, args.User, PopupType.Large);
_audio.PlayPvs(component.HealSoundPath, args.User); _audio.PlayPvs(component.HealSoundPath, args.User);
_delay.BeginDelay(uid, delay); _delay.TryResetDelay((uid, useDelay));
} }
} }
@@ -168,7 +167,8 @@ namespace Content.Server.Bible
{ {
Act = () => Act = () =>
{ {
if (!TryComp<TransformComponent>(args.User, out var userXform)) return; if (!TryComp<TransformComponent>(args.User, out var userXform))
return;
AttemptSummon((uid, component), args.User, userXform); AttemptSummon((uid, component), args.User, userXform);
}, },
@@ -236,13 +236,13 @@ namespace Content.Server.Bible
// Make this familiar the component's summon // Make this familiar the component's summon
var familiar = EntityManager.SpawnEntity(component.SpecialItemPrototype, position.Coordinates); 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 this is going to use a ghost role mob spawner, attach it to the bible.
if (HasComp<GhostRoleMobSpawnerComponent>(familiar)) if (HasComp<GhostRoleMobSpawnerComponent>(familiar))
{ {
_popupSystem.PopupEntity(Loc.GetString("bible-summon-requested"), user, PopupType.Medium); _popupSystem.PopupEntity(Loc.GetString("bible-summon-requested"), user, PopupType.Medium);
Transform(familiar).AttachParent(uid); _transform.SetParent(familiar, uid);
} }
component.AlreadySummoned = true; component.AlreadySummoned = true;
_actionsSystem.RemoveAction(user, component.SummonActionEntity); _actionsSystem.RemoveAction(user, component.SummonActionEntity);

View File

@@ -4,7 +4,6 @@ using Content.Shared.IdentityManagement;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Timing; using Content.Shared.Timing;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Robust.Shared.Player;
namespace Content.Server.Cargo.Systems; namespace Content.Server.Cargo.Systems;
@@ -26,11 +25,10 @@ public sealed class PriceGunSystem : EntitySystem
private void OnUtilityVerb(EntityUid uid, PriceGunComponent component, GetVerbsEvent<UtilityVerb> args) private void OnUtilityVerb(EntityUid uid, PriceGunComponent component, GetVerbsEvent<UtilityVerb> args)
{ {
if (!args.CanAccess || !args.CanInteract || args.Using == null)
if (!args.CanAccess || !args.CanInteract)
return; return;
if (TryComp(args.Using, out UseDelayComponent? useDelay) && useDelay.ActiveDelay) if (!TryComp(uid, out UseDelayComponent? useDelay) || _useDelay.IsDelayed((uid, useDelay)))
return; return;
var price = _pricingSystem.GetPrice(args.Target); var price = _pricingSystem.GetPrice(args.Target);
@@ -40,7 +38,7 @@ public sealed class PriceGunSystem : EntitySystem
Act = () => Act = () =>
{ {
_popupSystem.PopupEntity(Loc.GetString("price-gun-pricing-result", ("object", Identity.Entity(args.Target, EntityManager)), ("price", $"{price:F2}")), args.User, args.User); _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"), Text = Loc.GetString("price-gun-verb-text"),
Message = Loc.GetString("price-gun-verb-message", ("object", Identity.Entity(args.Target, EntityManager))) 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); args.Verbs.Add(verb);
} }
private void OnAfterInteract(EntityUid uid, PriceGunComponent component, AfterInteractEvent args) private void OnAfterInteract(EntityUid uid, PriceGunComponent component, AfterInteractEvent args)
{ {
if (!args.CanReach || args.Target == null || args.Handled) if (!args.CanReach || args.Target == null || args.Handled)
return; return;
if (TryComp(args.Used, out UseDelayComponent? useDelay) && useDelay.ActiveDelay) if (!TryComp(uid, out UseDelayComponent? useDelay) || _useDelay.IsDelayed((uid, useDelay)))
return; return;
var price = _pricingSystem.GetPrice(args.Target.Value); 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); _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; args.Handled = true;
} }
} }

View File

@@ -79,8 +79,12 @@ namespace Content.Server.Chemistry.EntitySystems
if (!EligibleEntity(target, _entMan, component)) if (!EligibleEntity(target, _entMan, component))
return false; return false;
if (TryComp(uid, out UseDelayComponent? delayComp) && _useDelay.ActiveDelay(uid, delayComp)) if (TryComp(uid, out UseDelayComponent? delayComp))
return false; {
if (_useDelay.IsDelayed((uid, delayComp)))
return false;
}
string? msgFormat = null; 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 // Medipens and such use this system and don't have a delay, requiring extra checks
// BeginDelay function returns if item is already on delay // BeginDelay function returns if item is already on delay
if (delayComp is not null) if (delayComp != null)
_useDelay.BeginDelay(uid, delayComp); _useDelay.TryResetDelay((uid, delayComp));
// Get transfer amount. May be smaller than component.TransferAmount if not enough room // Get transfer amount. May be smaller than component.TransferAmount if not enough room
var realTransferAmount = FixedPoint2.Min(component.TransferAmount, targetSolution.AvailableVolume); var realTransferAmount = FixedPoint2.Min(component.TransferAmount, targetSolution.AvailableVolume);

View File

@@ -1,32 +0,0 @@
using Content.Shared.Cooldown;
namespace Content.Server.Cooldown
{
public sealed class ItemCooldownSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ItemCooldownComponent, RefreshItemCooldownEvent>(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;
}
}
}

View File

@@ -5,9 +5,7 @@ using Content.Shared.Examine;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Timing; using Content.Shared.Timing;
using Content.Shared.Tools;
using Content.Shared.Tools.Systems; using Content.Shared.Tools.Systems;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using SignalReceivedEvent = Content.Server.DeviceLinking.Events.SignalReceivedEvent; using SignalReceivedEvent = Content.Server.DeviceLinking.Events.SignalReceivedEvent;
@@ -74,7 +72,8 @@ public sealed class LogicGateSystem : EntitySystem
return; return;
// no sound spamming // no sound spamming
if (TryComp<UseDelayComponent>(uid, out var useDelay) && _useDelay.ActiveDelay(uid, useDelay)) if (TryComp<UseDelayComponent>(uid, out var useDelay)
&& !_useDelay.TryResetDelay((uid, useDelay), true))
return; return;
// cycle through possible gates // 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())); var msg = Loc.GetString("logic-gate-cycle", ("gate", comp.Gate.ToString().ToUpper()));
_popup.PopupEntity(msg, uid, args.User); _popup.PopupEntity(msg, uid, args.User);
_appearance.SetData(uid, LogicGateVisuals.Gate, comp.Gate); _appearance.SetData(uid, LogicGateVisuals.Gate, comp.Gate);
_useDelay.BeginDelay(uid, useDelay);
} }
private void OnSignalReceived(EntityUid uid, LogicGateComponent comp, ref SignalReceivedEvent args) private void OnSignalReceived(EntityUid uid, LogicGateComponent comp, ref SignalReceivedEvent args)

View File

@@ -1,5 +1,4 @@
using Content.Server.DeviceLinking.Components; using Content.Server.DeviceLinking.Components;
using Content.Server.DeviceNetwork;
using Content.Server.NodeContainer; using Content.Server.NodeContainer;
using Content.Server.Power.EntitySystems; using Content.Server.Power.EntitySystems;
using Content.Server.Power.Nodes; using Content.Server.Power.Nodes;
@@ -9,10 +8,9 @@ using Content.Shared.Interaction;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Power.Generator; using Content.Shared.Power.Generator;
using Content.Shared.Timing; using Content.Shared.Timing;
using Content.Shared.Tools;
using Content.Shared.Tools.Systems; using Content.Shared.Tools.Systems;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using Robust.Shared.Map; using Robust.Shared.Map.Components;
using Robust.Shared.Timing; using Robust.Shared.Timing;
namespace Content.Server.DeviceLinking.Systems; namespace Content.Server.DeviceLinking.Systems;
@@ -21,7 +19,6 @@ public sealed class PowerSensorSystem : EntitySystem
{ {
[Dependency] private readonly DeviceLinkSystem _deviceLink = default!; [Dependency] private readonly DeviceLinkSystem _deviceLink = default!;
[Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly PowerNetSystem _powerNet = default!; [Dependency] private readonly PowerNetSystem _powerNet = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly SharedPopupSystem _popup = default!;
@@ -76,7 +73,8 @@ public sealed class PowerSensorSystem : EntitySystem
return; return;
// no sound spamming // no sound spamming
if (TryComp<UseDelayComponent>(uid, out var useDelay) && _useDelay.ActiveDelay(uid, useDelay)) if (TryComp<UseDelayComponent>(uid, out var useDelay)
&& !_useDelay.TryResetDelay((uid, useDelay), true))
return; return;
// switch between input and output mode. // switch between input and output mode.
@@ -89,8 +87,6 @@ public sealed class PowerSensorSystem : EntitySystem
_audio.PlayPvs(comp.SwitchSound, uid); _audio.PlayPvs(comp.SwitchSound, uid);
var msg = Loc.GetString("power-sensor-switch", ("output", comp.Output)); var msg = Loc.GetString("power-sensor-switch", ("output", comp.Output));
_popup.PopupEntity(msg, uid, args.User); _popup.PopupEntity(msg, uid, args.User);
_useDelay.BeginDelay(uid, useDelay);
} }
private void UpdateOutputs(EntityUid uid, PowerSensorComponent comp) 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 // update state based on the power stats retrieved from the selected power network
var xform = _xformQuery.GetComponent(uid); 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); var cables = deviceNode.GetReachableNodes(xform, _nodeQuery, _xformQuery, grid, EntityManager);
foreach (var node in cables) foreach (var node in cables)
{ {

View File

@@ -39,15 +39,12 @@ public sealed class SignallerSystem : EntitySystem
private void OnTrigger(EntityUid uid, SignallerComponent component, TriggerEvent args) private void OnTrigger(EntityUid uid, SignallerComponent component, TriggerEvent args)
{ {
// if on cooldown, do nothing if (!TryComp(uid, out UseDelayComponent? useDelay)
var hasUseDelay = TryComp<UseDelayComponent>(uid, out var useDelay); // if on cooldown, do nothing
if (hasUseDelay && _useDelay.ActiveDelay(uid, useDelay)) // and set cooldown to prevent clocks
|| !_useDelay.TryResetDelay((uid, useDelay), true))
return; return;
// set cooldown to prevent clocks
if (hasUseDelay)
_useDelay.BeginDelay(uid, useDelay);
_link.InvokePort(uid, component.Port); _link.InvokePort(uid, component.Port);
args.Handled = true; args.Handled = true;
} }

View File

@@ -9,7 +9,8 @@ using Content.Shared.Interaction;
using Content.Shared.Timing; using Content.Shared.Timing;
using Content.Shared.Weapons.Melee; using Content.Shared.Weapons.Melee;
using Robust.Server.Audio; using Robust.Server.Audio;
using Robust.Shared.Map; using Robust.Server.GameObjects;
using Robust.Shared.Map.Components;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -18,7 +19,6 @@ namespace Content.Server.Fluids.EntitySystems;
/// <inheritdoc/> /// <inheritdoc/>
public sealed class AbsorbentSystem : SharedAbsorbentSystem public sealed class AbsorbentSystem : SharedAbsorbentSystem
{ {
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly AudioSystem _audio = default!; [Dependency] private readonly AudioSystem _audio = default!;
[Dependency] private readonly PopupSystem _popups = 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 SharedTransformSystem _transform = default!;
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!; [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
[Dependency] private readonly UseDelaySystem _useDelay = default!; [Dependency] private readonly UseDelaySystem _useDelay = default!;
[Dependency] private readonly MapSystem _mapSystem = default!;
public override void Initialize() public override void Initialize()
{ {
@@ -106,14 +107,15 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem
if (!_solutionContainerSystem.TryGetSolution(used, AbsorbentComponent.SolutionName, out var absorberSoln)) if (!_solutionContainerSystem.TryGetSolution(used, AbsorbentComponent.SolutionName, out var absorberSoln))
return; return;
if (_useDelay.ActiveDelay(used)) if (TryComp<UseDelayComponent>(used, out var useDelay)
&& _useDelay.IsDelayed((used, useDelay)))
return; return;
// If it's a puddle try to grab from // 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 it's refillable try to transfer
if (!TryRefillableInteract(user, used, target, component, absorberSoln.Value)) if (!TryRefillableInteract(user, used, target, component, useDelay, absorberSoln.Value))
return; return;
} }
} }
@@ -121,7 +123,7 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem
/// <summary> /// <summary>
/// Logic for an absorbing entity interacting with a refillable. /// Logic for an absorbing entity interacting with a refillable.
/// </summary> /// </summary>
private bool TryRefillableInteract(EntityUid user, EntityUid used, EntityUid target, AbsorbentComponent component, Entity<SolutionComponent> absorbentSoln) private bool TryRefillableInteract(EntityUid user, EntityUid used, EntityUid target, AbsorbentComponent component, UseDelayComponent? useDelay, Entity<SolutionComponent> absorbentSoln)
{ {
if (!TryComp(target, out RefillableSolutionComponent? refillable)) if (!TryComp(target, out RefillableSolutionComponent? refillable))
return false; return false;
@@ -143,7 +145,8 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem
} }
_audio.PlayPvs(component.TransferSound, target); _audio.PlayPvs(component.TransferSound, target);
_useDelay.BeginDelay(used); if (useDelay != null)
_useDelay.TryResetDelay((used, useDelay));
return true; return true;
} }
@@ -264,7 +267,7 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem
/// <summary> /// <summary>
/// Logic for an absorbing entity interacting with a puddle. /// Logic for an absorbing entity interacting with a puddle.
/// </summary> /// </summary>
private bool TryPuddleInteract(EntityUid user, EntityUid used, EntityUid target, AbsorbentComponent absorber, Entity<SolutionComponent> absorberSoln) private bool TryPuddleInteract(EntityUid user, EntityUid used, EntityUid target, AbsorbentComponent absorber, UseDelayComponent? useDelay, Entity<SolutionComponent> absorberSoln)
{ {
if (!TryComp(target, out PuddleComponent? puddle)) if (!TryComp(target, out PuddleComponent? puddle))
return false; return false;
@@ -297,17 +300,20 @@ public sealed class AbsorbentSystem : SharedAbsorbentSystem
var absorberSplit = absorberSolution.SplitSolutionWithOnly(puddleSplit.Volume, PuddleSystem.EvaporationReagents); var absorberSplit = absorberSolution.SplitSolutionWithOnly(puddleSplit.Volume, PuddleSystem.EvaporationReagents);
// Do tile reactions first // Do tile reactions first
var coordinates = Transform(target).Coordinates; var transform = Transform(target);
if (_mapManager.TryGetGrid(coordinates.GetGridUid(EntityManager), out var mapGrid)) 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(puddle.Solution.Value, absorberSplit);
_solutionContainerSystem.AddSolution(absorberSoln, puddleSplit); _solutionContainerSystem.AddSolution(absorberSoln, puddleSplit);
_audio.PlayPvs(absorber.PickupSound, target); _audio.PlayPvs(absorber.PickupSound, target);
_useDelay.BeginDelay(used); if (useDelay != null)
_useDelay.TryResetDelay((used, useDelay));
var userXform = Transform(user); var userXform = Transform(user);
var targetPos = _transform.GetWorldPosition(target); var targetPos = _transform.GetWorldPosition(target);

View File

@@ -1,36 +1,34 @@
using Content.Server.Chemistry.Components; using Content.Server.Chemistry.Components;
using Content.Server.Chemistry.Containers.EntitySystems; using Content.Server.Chemistry.Containers.EntitySystems;
using Content.Server.Chemistry.EntitySystems; using Content.Server.Chemistry.EntitySystems;
using Content.Server.Cooldown;
using Content.Server.Extinguisher; using Content.Server.Extinguisher;
using Content.Server.Fluids.Components; using Content.Server.Fluids.Components;
using Content.Server.Gravity; using Content.Server.Gravity;
using Content.Server.Popups; using Content.Server.Popups;
using Content.Shared.Cooldown;
using Content.Shared.FixedPoint; using Content.Shared.FixedPoint;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Timing;
using Content.Shared.Vapor; using Content.Shared.Vapor;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Components;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using System.Numerics; using System.Numerics;
namespace Content.Server.Fluids.EntitySystems; namespace Content.Server.Fluids.EntitySystems;
public sealed class SpraySystem : EntitySystem public sealed class SpraySystem : EntitySystem
{ {
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IPrototypeManager _proto = default!; [Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly GravitySystem _gravity = default!; [Dependency] private readonly GravitySystem _gravity = default!;
[Dependency] private readonly PhysicsSystem _physics = default!; [Dependency] private readonly PhysicsSystem _physics = default!;
[Dependency] private readonly UseDelaySystem _useDelay = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!; [Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SolutionContainerSystem _solutionContainer = default!; [Dependency] private readonly SolutionContainerSystem _solutionContainer = default!;
[Dependency] private readonly VaporSystem _vapor = default!; [Dependency] private readonly VaporSystem _vapor = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly TransformSystem _transform = default!; [Dependency] private readonly SharedTransformSystem _transform = default!;
public override void Initialize() public override void Initialize()
{ {
@@ -54,12 +52,9 @@ public sealed class SpraySystem : EntitySystem
if (ev.Cancelled) if (ev.Cancelled)
return; return;
var curTime = _gameTiming.CurTime; if (!TryComp<UseDelayComponent>(entity, out var useDelay)
if (TryComp<ItemCooldownComponent>(entity, out var cooldown) || _useDelay.IsDelayed((entity, useDelay)))
&& curTime < cooldown.CooldownEnd)
{
return; return;
}
if (solution.Volume <= 0) if (solution.Volume <= 0)
{ {
@@ -70,7 +65,7 @@ public sealed class SpraySystem : EntitySystem
var xformQuery = GetEntityQuery<TransformComponent>(); var xformQuery = GetEntityQuery<TransformComponent>();
var userXform = xformQuery.GetComponent(args.User); var userXform = xformQuery.GetComponent(args.User);
var userMapPos = userXform.MapPosition; var userMapPos = _transform.GetMapCoordinates(userXform);
var clickMapPos = args.ClickLocation.ToMap(EntityManager, _transform); var clickMapPos = args.ClickLocation.ToMap(EntityManager, _transform);
var diffPos = clickMapPos.Position - userMapPos.Position; 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)); _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));
} }
} }

View File

@@ -1,6 +1,5 @@
using Content.Server.Explosion.EntitySystems; using Content.Server.Explosion.EntitySystems;
using Content.Shared.Timing; using Content.Shared.Timing;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using Robust.Shared.Timing; using Robust.Shared.Timing;
@@ -43,14 +42,13 @@ public sealed class IgniteOnTriggerSystem : EntitySystem
private void OnTrigger(Entity<IgniteOnTriggerComponent> ent, ref TriggerEvent args) private void OnTrigger(Entity<IgniteOnTriggerComponent> ent, ref TriggerEvent args)
{ {
// prevent spamming sound and ignition // prevent spamming sound and ignition
TryComp<UseDelayComponent>(ent, out var delay); if (!TryComp(ent.Owner, out UseDelayComponent? useDelay) || _useDelay.IsDelayed((ent.Owner, useDelay)))
if (_useDelay.ActiveDelay(ent, delay))
return; return;
_source.SetIgnited(ent.Owner); _source.SetIgnited(ent.Owner);
_audio.PlayPvs(ent.Comp.IgniteSound, ent); _audio.PlayPvs(ent.Comp.IgniteSound, ent);
_useDelay.BeginDelay(ent, delay); _useDelay.TryResetDelay((ent.Owner, useDelay));
ent.Comp.IgnitedUntil = _timing.CurTime + ent.Comp.IgnitedTime; ent.Comp.IgnitedUntil = _timing.CurTime + ent.Comp.IgnitedTime;
} }
} }

View File

@@ -1,7 +1,5 @@
using Content.Server.Storage.EntitySystems; using Content.Server.Storage.EntitySystems;
using Content.Shared.Clothing.Components;
using Content.Shared.Explosion; using Content.Shared.Explosion;
using Content.Shared.Interaction.Events;
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Content.Shared.Inventory.Events; using Content.Shared.Inventory.Events;
using Content.Shared.Storage; using Content.Shared.Storage;
@@ -17,9 +15,6 @@ namespace Content.Server.Inventory
base.Initialize(); base.Initialize();
SubscribeLocalEvent<InventoryComponent, BeforeExplodeEvent>(OnExploded); SubscribeLocalEvent<InventoryComponent, BeforeExplodeEvent>(OnExploded);
SubscribeLocalEvent<ClothingComponent, UseInHandEvent>(OnUseInHand);
SubscribeNetworkEvent<OpenSlotStorageNetworkMessage>(OnOpenSlotStorage); SubscribeNetworkEvent<OpenSlotStorageNetworkMessage>(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) private void OnOpenSlotStorage(OpenSlotStorageNetworkMessage ev, EntitySessionEventArgs args)
{ {
if (args.SenderSession.AttachedEntity is not { Valid: true } uid) if (args.SenderSession.AttachedEntity is not { Valid: true } uid)

View File

@@ -66,13 +66,14 @@ public sealed class DefibrillatorSystem : EntitySystem
private void OnUseInHand(EntityUid uid, DefibrillatorComponent component, UseInHandEvent args) 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; return;
if (!TryToggle(uid, component, args.User)) if (!TryToggle(uid, component, args.User))
return; return;
args.Handled = true; args.Handled = true;
_useDelay.BeginDelay(uid); _useDelay.TryResetDelay((uid, useDelay));
} }
private void OnPowerCellSlotEmpty(EntityUid uid, DefibrillatorComponent component, ref PowerCellSlotEmptyEvent args) private void OnPowerCellSlotEmpty(EntityUid uid, DefibrillatorComponent component, ref PowerCellSlotEmptyEvent args)

View File

@@ -11,14 +11,15 @@ public sealed partial class InteractWithOperator : HTNOperator
/// <summary> /// <summary>
/// Key that contains the target entity. /// Key that contains the target entity.
/// </summary> /// </summary>
[DataField("targetKey", required: true)] [DataField(required: true)]
public string TargetKey = default!; public string TargetKey = default!;
public override HTNOperatorStatus Update(NPCBlackboard blackboard, float frameTime) public override HTNOperatorStatus Update(NPCBlackboard blackboard, float frameTime)
{ {
var owner = blackboard.GetValue<EntityUid>(NPCBlackboard.Owner); var owner = blackboard.GetValue<EntityUid>(NPCBlackboard.Owner);
if (_entManager.System<UseDelaySystem>().ActiveDelay(owner) || if (!_entManager.TryGetComponent<UseDelayComponent>(owner, out var useDelay) ||
_entManager.System<UseDelaySystem>().IsDelayed((owner, useDelay)) ||
!blackboard.TryGetValue<EntityUid>(TargetKey, out var moveTarget, _entManager) || !blackboard.TryGetValue<EntityUid>(TargetKey, out var moveTarget, _entManager) ||
!_entManager.TryGetComponent<TransformComponent>(moveTarget, out var targetXform)) !_entManager.TryGetComponent<TransformComponent>(moveTarget, out var targetXform))
{ {

View File

@@ -3,13 +3,12 @@ using Content.Server.Ninja.Events;
using Content.Server.Popups; using Content.Server.Popups;
using Content.Server.Power.Components; using Content.Server.Power.Components;
using Content.Server.PowerCell; using Content.Server.PowerCell;
using Content.Shared.Actions;
using Content.Shared.Clothing.EntitySystems; using Content.Shared.Clothing.EntitySystems;
using Content.Shared.Hands.EntitySystems; using Content.Shared.Hands.EntitySystems;
using Content.Shared.Ninja.Components; using Content.Shared.Ninja.Components;
using Content.Shared.Ninja.Systems; using Content.Shared.Ninja.Systems;
using Content.Shared.Popups;
using Content.Shared.PowerCell.Components; using Content.Shared.PowerCell.Components;
using Content.Shared.Timing;
using Robust.Shared.Containers; using Robust.Shared.Containers;
namespace Content.Server.Ninja.Systems; namespace Content.Server.Ninja.Systems;
@@ -94,7 +93,8 @@ public sealed class NinjaSuitSystem : SharedNinjaSuitSystem
// need 1 second of charge to turn on stealth // need 1 second of charge to turn on stealth
var chargeNeeded = SuitWattage(uid, comp); var chargeNeeded = SuitWattage(uid, comp);
// being attacked while cloaked gives no power message since it overloads the power supply or something // 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); _popup.PopupEntity(Loc.GetString("ninja-no-power"), user, user);
args.Cancel(); args.Cancel();
@@ -108,7 +108,8 @@ public sealed class NinjaSuitSystem : SharedNinjaSuitSystem
{ {
args.Handled = true; args.Handled = true;
var user = args.Performer; 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); _popup.PopupEntity(Loc.GetString("ninja-no-power"), user, user);
return; return;
@@ -130,7 +131,8 @@ public sealed class NinjaSuitSystem : SharedNinjaSuitSystem
var coords = _transform.GetWorldPosition(katana); var coords = _transform.GetWorldPosition(katana);
var distance = (_transform.GetWorldPosition(user) - coords).Length(); var distance = (_transform.GetWorldPosition(user) - coords).Length();
var chargeNeeded = (float) distance * comp.RecallCharge; 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); _popup.PopupEntity(Loc.GetString("ninja-no-power"), user, user);
return; return;
@@ -147,14 +149,15 @@ public sealed class NinjaSuitSystem : SharedNinjaSuitSystem
{ {
args.Handled = true; args.Handled = true;
var user = args.Performer; 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); _popup.PopupEntity(Loc.GetString("ninja-no-power"), user, user);
return; return;
} }
// I don't think this affects the suit battery, but if it ever does in the future add a blacklist for it // 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); _emp.EmpPulse(coords, comp.EmpRange, comp.EmpConsumption, comp.EmpDuration);
} }
} }

View File

@@ -70,7 +70,7 @@ public sealed class PowerSwitchableSystem : SharedPowerSwitchableSystem
return; return;
// no sound spamming // no sound spamming
if (TryComp<UseDelayComponent>(uid, out var useDelay) && _useDelay.ActiveDelay(uid)) if (!TryComp(uid, out UseDelayComponent? useDelay) || _useDelay.IsDelayed((uid, useDelay)))
return; return;
comp.ActiveIndex = NextIndex(uid, comp); comp.ActiveIndex = NextIndex(uid, comp);
@@ -110,7 +110,7 @@ public sealed class PowerSwitchableSystem : SharedPowerSwitchableSystem
_audio.PlayPvs(comp.SwitchSound, uid); _audio.PlayPvs(comp.SwitchSound, uid);
_useDelay.BeginDelay(uid, useDelay); _useDelay.TryResetDelay((uid, useDelay));
} }
} }

View File

@@ -13,32 +13,21 @@ public sealed partial class RadiationCollectorComponent : Component
/// <summary> /// <summary>
/// How much joules will collector generate for each rad. /// How much joules will collector generate for each rad.
/// </summary> /// </summary>
[DataField("chargeModifier")] [DataField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public float ChargeModifier = 30000f; public float ChargeModifier = 30000f;
/// <summary> /// <summary>
/// Cooldown time between users interaction. /// Is the machine enabled.
/// </summary> /// </summary>
[DataField("cooldown")] [DataField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables]
public TimeSpan Cooldown = TimeSpan.FromSeconds(0.81f);
/// <summary>
/// Was machine activated by user?
/// </summary>
[ViewVariables(VVAccess.ReadOnly)]
public bool Enabled; public bool Enabled;
/// <summary>
/// Timestamp when machine can be deactivated again.
/// </summary>
public TimeSpan CoolDownEnd;
/// <summary> /// <summary>
/// List of gases that will react to the radiation passing through the collector /// List of gases that will react to the radiation passing through the collector
/// </summary> /// </summary>
[DataField("radiationReactiveGases")] [DataField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public List<RadiationReactiveGas>? RadiationReactiveGases; public List<RadiationReactiveGas>? RadiationReactiveGases;
} }
@@ -50,15 +39,15 @@ public sealed partial class RadiationCollectorComponent : Component
public sealed partial class RadiationReactiveGas public sealed partial class RadiationReactiveGas
{ {
/// <summary> /// <summary>
/// The reactant gas /// The reactant gas
/// </summary> /// </summary>
[DataField("reactantPrototype", required: true)] [DataField(required: true)]
public Gas Reactant = Gas.Plasma; public Gas ReactantPrototype;
/// <summary> /// <summary>
/// Multipier for the amount of power produced by the radiation collector when using this gas /// Multipier for the amount of power produced by the radiation collector when using this gas
/// </summary> /// </summary>
[DataField("powerGenerationEfficiency")] [DataField]
public float PowerGenerationEfficiency = 1f; public float PowerGenerationEfficiency = 1f;
/// <summary> /// <summary>
@@ -67,7 +56,7 @@ public sealed partial class RadiationReactiveGas
/// /// <remarks> /// /// <remarks>
/// Set to zero if the reactant does not deplete /// Set to zero if the reactant does not deplete
/// </remarks> /// </remarks>
[DataField("reactantBreakdownRate")] [DataField]
public float ReactantBreakdownRate = 1f; public float ReactantBreakdownRate = 1f;
/// <summary> /// <summary>
@@ -76,12 +65,12 @@ public sealed partial class RadiationReactiveGas
/// <remarks> /// <remarks>
/// Leave null if the reactant no byproduct gas is to be formed /// Leave null if the reactant no byproduct gas is to be formed
/// </remarks> /// </remarks>
[DataField("byproductPrototype")] [DataField]
public Gas? Byproduct = null; public Gas? Byproduct;
/// <summary> /// <summary>
/// The molar ratio of the byproduct gas generated from the reactant gas /// The molar ratio of the byproduct gas generated from the reactant gas
/// </summary> /// </summary>
[DataField("molarRatio")] [DataField]
public float MolarRatio = 1f; public float MolarRatio = 1f;
} }

View File

@@ -1,16 +1,19 @@
using Content.Server.Singularity.Components; using System.Diagnostics.CodeAnalysis;
using Content.Shared.Interaction; using System.Linq;
using Content.Shared.Singularity.Components; using Content.Server.Atmos;
using Content.Server.Atmos.Components;
using Content.Server.Popups; using Content.Server.Popups;
using Content.Server.Power.Components; using Content.Server.Power.Components;
using Content.Shared.Radiation.Events; using Content.Server.Power.EntitySystems;
using Robust.Shared.Timing; using Content.Server.Singularity.Components;
using Robust.Shared.Containers;
using Content.Server.Atmos.Components;
using Content.Shared.Examine;
using Content.Server.Atmos;
using System.Diagnostics.CodeAnalysis;
using Content.Shared.Atmos; 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; namespace Content.Server.Singularity.EntitySystems;
@@ -20,6 +23,10 @@ public sealed class RadiationCollectorSystem : EntitySystem
[Dependency] private readonly PopupSystem _popupSystem = default!; [Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedContainerSystem _containerSystem = 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() public override void Initialize()
{ {
@@ -36,12 +43,11 @@ public sealed class RadiationCollectorSystem : EntitySystem
private bool TryGetLoadedGasTank(EntityUid uid, [NotNullWhen(true)] out GasTankComponent? gasTankComponent) private bool TryGetLoadedGasTank(EntityUid uid, [NotNullWhen(true)] out GasTankComponent? gasTankComponent)
{ {
gasTankComponent = null; gasTankComponent = null;
var container = _containerSystem.EnsureContainer<ContainerSlot>(uid, "GasTank");
if (container.ContainedEntity == null) if (!_containerSystem.TryGetContainer(uid, GasTankContainer, out var container) || container.ContainedEntities.Count == 0)
return false; return false;
if (!EntityManager.TryGetComponent(container.ContainedEntity, out gasTankComponent)) if (!EntityManager.TryGetComponent(container.ContainedEntities.First(), out gasTankComponent))
return false; return false;
return true; return true;
@@ -61,13 +67,10 @@ public sealed class RadiationCollectorSystem : EntitySystem
private void OnInteractHand(EntityUid uid, RadiationCollectorComponent component, InteractHandEvent args) private void OnInteractHand(EntityUid uid, RadiationCollectorComponent component, InteractHandEvent args)
{ {
var curTime = _gameTiming.CurTime; if (TryComp(uid, out UseDelayComponent? useDelay) && !_useDelay.TryResetDelay((uid, useDelay), true))
if (curTime < component.CoolDownEnd)
return; return;
ToggleCollector(uid, args.User, component); ToggleCollector(uid, args.User, component);
component.CoolDownEnd = curTime + component.Cooldown;
} }
private void OnRadiation(EntityUid uid, RadiationCollectorComponent component, OnIrradiatedEvent args) private void OnRadiation(EntityUid uid, RadiationCollectorComponent component, OnIrradiatedEvent args)
@@ -82,7 +85,7 @@ public sealed class RadiationCollectorSystem : EntitySystem
foreach (var gas in component.RadiationReactiveGases) 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; float delta = args.TotalRads * reactantMol * gas.ReactantBreakdownRate;
// We need to offset the huge power gains possible when using very cold gases // 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) 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) if (gas.Byproduct != null)
@@ -111,7 +114,7 @@ public sealed class RadiationCollectorSystem : EntitySystem
// This still won't stop things being potentially hilariously unbalanced though. // This still won't stop things being potentially hilariously unbalanced though.
if (TryComp<BatteryComponent>(uid, out var batteryComponent)) if (TryComp<BatteryComponent>(uid, out var batteryComponent))
{ {
batteryComponent.CurrentCharge += charge; _batterySystem.SetCharge(uid, charge, batteryComponent);
} }
// Update appearance // Update appearance

View File

@@ -12,6 +12,7 @@ using Content.Shared.Storage.EntitySystems;
using Content.Shared.Timing; using Content.Shared.Timing;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Input.Binding; using Robust.Shared.Input.Binding;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Player; using Robust.Shared.Player;
@@ -26,6 +27,8 @@ public sealed partial class StorageSystem : SharedStorageSystem
[Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly InventorySystem _inventory = default!; [Dependency] private readonly InventorySystem _inventory = default!;
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!; [Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly UseDelaySystem _useDelay = default!;
public override void Initialize() public override void Initialize()
{ {
@@ -123,12 +126,12 @@ public sealed partial class StorageSystem : SharedStorageSystem
return; return;
// prevent spamming bag open / honkerton honk sound // prevent spamming bag open / honkerton honk sound
silent |= TryComp<UseDelayComponent>(uid, out var useDelay) && UseDelay.ActiveDelay(uid, useDelay); silent |= TryComp<UseDelayComponent>(uid, out var useDelay) && _useDelay.IsDelayed((uid, useDelay));
if (!silent) if (!silent)
{ {
Audio.PlayPvs(storageComp.StorageOpenSound, uid); _audio.PlayPvs(storageComp.StorageOpenSound, uid);
if (useDelay != null) if (useDelay != null)
UseDelay.BeginDelay(uid, useDelay); _useDelay.TryResetDelay((uid, useDelay));
} }
Log.Debug($"Storage (UID {uid}) \"used\" by player session (UID {player.PlayerSession.AttachedEntity})."); Log.Debug($"Storage (UID {uid}) \"used\" by player session (UID {player.PlayerSession.AttachedEntity}).");

View File

@@ -3,7 +3,6 @@ using Content.Server.Xenoarchaeology.Equipment.Components;
using Content.Server.Xenoarchaeology.XenoArtifacts; using Content.Server.Xenoarchaeology.XenoArtifacts;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Timing; using Content.Shared.Timing;
using Robust.Shared.Player;
namespace Content.Server.Xenoarchaeology.Equipment.Systems; namespace Content.Server.Xenoarchaeology.Equipment.Systems;
@@ -31,7 +30,11 @@ public sealed class NodeScannerSystem : EntitySystem
args.Handled = true; args.Handled = true;
var target = args.Target.Value; 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", _popupSystem.PopupEntity(Loc.GetString("node-scan-popup",
("id", $"{artifact.CurrentNodeId}")), target); ("id", $"{artifact.CurrentNodeId}")), target);
} }

View File

@@ -1,9 +1,13 @@
using Content.Shared.Clothing.Components; using Content.Shared.Clothing.Components;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Humanoid; using Content.Shared.Humanoid;
using Content.Shared.Interaction.Events;
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Content.Shared.Inventory.Events; using Content.Shared.Inventory.Events;
using Content.Shared.Item; using Content.Shared.Item;
using Content.Shared.Tag; using Content.Shared.Tag;
using Content.Shared.Timing;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
namespace Content.Shared.Clothing.EntitySystems; namespace Content.Shared.Clothing.EntitySystems;
@@ -13,6 +17,8 @@ public abstract class ClothingSystem : EntitySystem
[Dependency] private readonly SharedItemSystem _itemSys = default!; [Dependency] private readonly SharedItemSystem _itemSys = default!;
[Dependency] private readonly SharedHumanoidAppearanceSystem _humanoidSystem = default!; [Dependency] private readonly SharedHumanoidAppearanceSystem _humanoidSystem = default!;
[Dependency] private readonly TagSystem _tagSystem = default!; [Dependency] private readonly TagSystem _tagSystem = default!;
[Dependency] private readonly InventorySystem _invSystem = default!;
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
[ValidatePrototypeId<TagPrototype>] [ValidatePrototypeId<TagPrototype>]
private const string HairTag = "HidesHair"; private const string HairTag = "HidesHair";
@@ -21,12 +27,60 @@ public abstract class ClothingSystem : EntitySystem
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<ClothingComponent, UseInHandEvent>(OnUseInHand);
SubscribeLocalEvent<ClothingComponent, ComponentGetState>(OnGetState); SubscribeLocalEvent<ClothingComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<ClothingComponent, ComponentHandleState>(OnHandleState); SubscribeLocalEvent<ClothingComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<ClothingComponent, GotEquippedEvent>(OnGotEquipped); SubscribeLocalEvent<ClothingComponent, GotEquippedEvent>(OnGotEquipped);
SubscribeLocalEvent<ClothingComponent, GotUnequippedEvent>(OnGotUnequipped); SubscribeLocalEvent<ClothingComponent, GotUnequippedEvent>(OnGotUnequipped);
SubscribeLocalEvent<ClothingComponent, ItemMaskToggledEvent>(OnMaskToggled); SubscribeLocalEvent<ClothingComponent, ItemMaskToggledEvent>(OnMaskToggled);
} }
private void OnUseInHand(Entity<ClothingComponent> 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<ClothingComponent> toEquipEnt,
Entity<InventoryComponent, HandsComponent> 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) protected virtual void OnGotEquipped(EntityUid uid, ClothingComponent component, GotEquippedEvent args)
{ {
@@ -71,7 +125,7 @@ public abstract class ClothingSystem : EntitySystem
clothing.EquippedPrefix = prefix; clothing.EquippedPrefix = prefix;
_itemSys.VisualsChanged(uid); _itemSys.VisualsChanged(uid);
Dirty(clothing); Dirty(uid, clothing);
} }
public void SetSlots(EntityUid uid, SlotFlags slots, ClothingComponent? clothing = null) public void SetSlots(EntityUid uid, SlotFlags slots, ClothingComponent? clothing = null)
@@ -80,7 +134,7 @@ public abstract class ClothingSystem : EntitySystem
return; return;
clothing.Slots = slots; clothing.Slots = slots;
Dirty(clothing); Dirty(uid, clothing);
} }
/// <summary> /// <summary>
@@ -97,7 +151,7 @@ public abstract class ClothingSystem : EntitySystem
clothing.FemaleMask = otherClothing.FemaleMask; clothing.FemaleMask = otherClothing.FemaleMask;
_itemSys.VisualsChanged(uid); _itemSys.VisualsChanged(uid);
Dirty(clothing); Dirty(uid, clothing);
} }
#endregion #endregion

View File

@@ -1,26 +0,0 @@
using Robust.Shared.Timing;
namespace Content.Shared.Cooldown
{
/// <summary>
/// Utilities for working with cooldowns.
/// </summary>
public static class Cooldowns
{
/// <param name="gameTiming">game timing to use, otherwise will resolve using IoCManager.</param>
/// <returns>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.</returns>
public static (TimeSpan start, TimeSpan end) FromNow(TimeSpan offset, IGameTiming? gameTiming = null)
{
var now = (gameTiming ?? IoCManager.Resolve<IGameTiming>()).CurTime;
return (now, now + offset);
}
/// <see cref="FromNow"/>
public static (TimeSpan start, TimeSpan end) SecondsFromNow(double seconds, IGameTiming? gameTiming = null)
{
return FromNow(TimeSpan.FromSeconds(seconds), gameTiming);
}
}
}

View File

@@ -1,51 +0,0 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Cooldown
{
/// <summary>
/// Stores a visual "cooldown" for items, that gets displayed in the hands GUI.
/// </summary>
[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;
/// <summary>
/// The time when this cooldown ends.
/// </summary>
/// <remarks>
/// If null, no cooldown is displayed.
/// </remarks>
[ViewVariables, AutoNetworkedField]
public TimeSpan? CooldownEnd
{
get => _cooldownEnd;
set
{
_cooldownEnd = value;
Dirty();
}
}
/// <summary>
/// The time when this cooldown started.
/// </summary>
/// <remarks>
/// If null, no cooldown is displayed.
/// </remarks>
[ViewVariables, AutoNetworkedField]
public TimeSpan? CooldownStart
{
get => _cooldownStart;
set
{
_cooldownStart = value;
Dirty();
}
}
}
}

View File

@@ -1,3 +1,5 @@
using Content.Shared.Clothing.EntitySystems;
using Content.Shared.Timing;
using JetBrains.Annotations; using JetBrains.Annotations;
namespace Content.Shared.Interaction.Events; namespace Content.Shared.Interaction.Events;
@@ -11,7 +13,13 @@ public sealed class UseInHandEvent : HandledEntityEventArgs
/// <summary> /// <summary>
/// Entity holding the item in their hand. /// Entity holding the item in their hand.
/// </summary> /// </summary>
public EntityUid User { get; } public EntityUid User;
/// <summary>
/// Whether or not to apply a UseDelay when used.
/// Mostly used by the <see cref="ClothingSystem"/> quick-equip to not apply the delay to entities that have the <see cref="UseDelayComponent"/>.
/// </summary>
public bool ApplyDelay = true;
public UseInHandEvent(EntityUid user) public UseInHandEvent(EntityUid user)
{ {

View File

@@ -6,7 +6,6 @@ using Content.Shared.Administration.Logs;
using Content.Shared.Administration.Managers; using Content.Shared.Administration.Managers;
using Content.Shared.CombatMode; using Content.Shared.CombatMode;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.DragDrop;
using Content.Shared.Hands; using Content.Shared.Hands;
using Content.Shared.Hands.Components; using Content.Shared.Hands.Components;
using Content.Shared.Input; using Content.Shared.Input;
@@ -21,7 +20,6 @@ using Content.Shared.Popups;
using Content.Shared.Pulling; using Content.Shared.Pulling;
using Content.Shared.Pulling.Components; using Content.Shared.Pulling.Components;
using Content.Shared.Tag; using Content.Shared.Tag;
using Content.Shared.Throwing;
using Content.Shared.Timing; using Content.Shared.Timing;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Content.Shared.Wall; using Content.Shared.Wall;
@@ -67,8 +65,7 @@ namespace Content.Shared.Interaction
[Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly TagSystem _tagSystem = default!; [Dependency] private readonly TagSystem _tagSystem = default!;
private const CollisionGroup InRangeUnobstructedMask private const CollisionGroup InRangeUnobstructedMask = CollisionGroup.Impassable | CollisionGroup.InteractImpassable;
= CollisionGroup.Impassable | CollisionGroup.InteractImpassable;
public const float InteractionRange = 1.5f; public const float InteractionRange = 1.5f;
public const float InteractionRangeSquared = InteractionRange * InteractionRange; public const float InteractionRangeSquared = InteractionRange * InteractionRange;
@@ -170,7 +167,6 @@ namespace Content.Shared.Interaction
QueueDel(uid); QueueDel(uid);
} }
private bool HandleTryPullObject(ICommonSession? session, EntityCoordinates coords, EntityUid uid) private bool HandleTryPullObject(ICommonSession? session, EntityCoordinates coords, EntityUid uid)
{ {
if (!ValidateClientInput(session, coords, uid, out var userEntity)) if (!ValidateClientInput(session, coords, uid, out var userEntity))
@@ -953,7 +949,7 @@ namespace Content.Shared.Interaction
UseDelayComponent? delayComponent = null; UseDelayComponent? delayComponent = null;
if (checkUseDelay if (checkUseDelay
&& TryComp(used, out delayComponent) && TryComp(used, out delayComponent)
&& delayComponent.ActiveDelay) && _useDelay.IsDelayed((used, delayComponent)))
return false; return false;
if (checkCanInteract && !_actionBlockerSystem.CanInteract(user, used)) if (checkCanInteract && !_actionBlockerSystem.CanInteract(user, used))
@@ -977,7 +973,8 @@ namespace Content.Shared.Interaction
return false; return false;
DoContactInteraction(user, used, activateMsg); DoContactInteraction(user, used, activateMsg);
_useDelay.BeginDelay(used, delayComponent); if (delayComponent != null)
_useDelay.TryResetDelay((used, delayComponent));
if (!activateMsg.WasLogged) if (!activateMsg.WasLogged)
_adminLogger.Add(LogType.InteractActivate, LogImpact.Low, $"{ToPrettyString(user):user} activated {ToPrettyString(used):used}"); _adminLogger.Add(LogType.InteractActivate, LogImpact.Low, $"{ToPrettyString(user):user} activated {ToPrettyString(used):used}");
return true; return true;
@@ -1002,7 +999,7 @@ namespace Content.Shared.Interaction
if (checkUseDelay if (checkUseDelay
&& TryComp(used, out delayComponent) && TryComp(used, out delayComponent)
&& delayComponent.ActiveDelay) && _useDelay.IsDelayed((used, delayComponent)))
return true; // if the item is on cooldown, we consider this handled. return true; // if the item is on cooldown, we consider this handled.
if (checkCanInteract && !_actionBlockerSystem.CanInteract(user, used)) if (checkCanInteract && !_actionBlockerSystem.CanInteract(user, used))
@@ -1016,7 +1013,8 @@ namespace Content.Shared.Interaction
if (useMsg.Handled) if (useMsg.Handled)
{ {
DoContactInteraction(user, used, useMsg); DoContactInteraction(user, used, useMsg);
_useDelay.BeginDelay(used, delayComponent); if (delayComponent != null && useMsg.ApplyDelay)
_useDelay.TryResetDelay((used, delayComponent));
return true; return true;
} }

View File

@@ -4,18 +4,13 @@ using Content.Shared.Hands;
using Content.Shared.Hands.Components; using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems; using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Interaction.Events;
using Content.Shared.Inventory.Events; using Content.Shared.Inventory.Events;
using Content.Shared.Item; using Content.Shared.Item;
using Content.Shared.Movement.Systems; using Content.Shared.Movement.Systems;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Strip.Components; using Content.Shared.Strip.Components;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -31,7 +26,6 @@ public abstract partial class InventorySystem
[Dependency] private readonly SharedContainerSystem _containerSystem = default!; [Dependency] private readonly SharedContainerSystem _containerSystem = default!;
[Dependency] private readonly SharedHandsSystem _handsSystem = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly INetManager _netMan = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly SharedTransformSystem _transform = default!;
[ValidatePrototypeId<ItemSizePrototype>] [ValidatePrototypeId<ItemSizePrototype>]
@@ -46,41 +40,6 @@ public abstract partial class InventorySystem
SubscribeAllEvent<UseSlotNetworkMessage>(OnUseSlot); SubscribeAllEvent<UseSlotNetworkMessage>(OnUseSlot);
} }
protected void QuickEquip(EntityUid uid, ClothingComponent component, UseInHandEvent args)
{
if (!TryComp(args.User, out InventoryComponent? inv) || !HasComp<HandsComponent>(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) private void OnEntRemoved(EntityUid uid, InventoryComponent component, EntRemovedFromContainerMessage args)
{ {
if(!TryGetSlot(uid, args.Container.ID, out var slotDef, inventory: component)) if(!TryGetSlot(uid, args.Container.ID, out var slotDef, inventory: component))

View File

@@ -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 System.Linq;
using Content.Shared.Mech.Equipment.Components;
using Content.Shared.Timing;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
namespace Content.Shared.Mech.Equipment.Systems; namespace Content.Shared.Mech.Equipment.Systems;
@@ -47,12 +44,11 @@ public sealed class MechSoundboardSystem : EntitySystem
if (msg.Sound >= comp.Sounds.Count) if (msg.Sound >= comp.Sounds.Count)
return; return;
if (_useDelay.ActiveDelay(uid)) if (TryComp(uid, out UseDelayComponent? useDelay)
&& !_useDelay.TryResetDelay((uid, useDelay), true))
return; return;
// honk!!!!! // honk!!!!!
var mech = equipment.EquipmentOwner.Value;
_useDelay.BeginDelay(uid);
_audio.PlayPvs(comp.Sounds[msg.Sound], uid); _audio.PlayPvs(comp.Sounds[msg.Sound], uid);
} }
} }

View File

@@ -8,7 +8,6 @@ using Content.Shared.Inventory.Events;
using Content.Shared.Ninja.Components; using Content.Shared.Ninja.Components;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Research.Components; using Content.Shared.Research.Components;
using Content.Shared.Timing;
using Content.Shared.Toggleable; using Content.Shared.Toggleable;
using Robust.Shared.Timing; using Robust.Shared.Timing;
@@ -24,7 +23,6 @@ public abstract class SharedNinjaGlovesSystem : EntitySystem
[Dependency] private readonly SharedCombatModeSystem _combatMode = default!; [Dependency] private readonly SharedCombatModeSystem _combatMode = default!;
[Dependency] protected readonly SharedInteractionSystem Interaction = default!; [Dependency] protected readonly SharedInteractionSystem Interaction = default!;
[Dependency] protected readonly SharedPopupSystem Popup = default!; [Dependency] protected readonly SharedPopupSystem Popup = default!;
[Dependency] private readonly UseDelaySystem _useDelay = default!;
[Dependency] private readonly ActionContainerSystem _actionContainer = default!; [Dependency] private readonly ActionContainerSystem _actionContainer = default!;
public override void Initialize() public override void Initialize()
@@ -110,7 +108,6 @@ public abstract class SharedNinjaGlovesSystem : EntitySystem
target = args.Target; target = args.Target;
return _timing.IsFirstTimePredicted return _timing.IsFirstTimePredicted
&& !_combatMode.IsInCombatMode(uid) && !_combatMode.IsInCombatMode(uid)
&& !_useDelay.ActiveDelay(uid)
&& TryComp<HandsComponent>(uid, out var hands) && TryComp<HandsComponent>(uid, out var hands)
&& hands.ActiveHandEntity == null && hands.ActiveHandEntity == null
&& Interaction.InRangeUnobstructed(uid, target); && Interaction.InRangeUnobstructed(uid, target);

View File

@@ -15,7 +15,7 @@ public abstract class SharedNinjaSuitSystem : EntitySystem
{ {
[Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedNinjaGlovesSystem _gloves = 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 StealthClothingSystem StealthClothing = default!;
[Dependency] protected readonly UseDelaySystem UseDelay = default!; [Dependency] protected readonly UseDelaySystem UseDelay = default!;
[Dependency] private readonly ActionContainerSystem _actionContainer = default!; [Dependency] private readonly ActionContainerSystem _actionContainer = default!;
@@ -112,8 +112,8 @@ public abstract class SharedNinjaSuitSystem : EntitySystem
_audio.PlayPredicted(comp.RevealSound, uid, user); _audio.PlayPredicted(comp.RevealSound, uid, user);
// all abilities check for a usedelay on the ninja // all abilities check for a usedelay on the ninja
var useDelay = EnsureComp<UseDelayComponent>(user); var useDelay = EnsureComp<UseDelayComponent>(user);
useDelay.Delay = comp.DisableTime; UseDelay.SetDelay((user, useDelay), comp.DisableTime);
UseDelay.BeginDelay(user, useDelay); UseDelay.TryResetDelay((user, useDelay));
} }
// TODO: modify PowerCellDrain // TODO: modify PowerCellDrain

View File

@@ -1,28 +1,36 @@
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared.Timing; namespace Content.Shared.Timing;
/// <summary> /// <summary>
/// Timer that creates a cooldown each time an object is activated/used /// Timer that creates a cooldown each time an object is activated/used
/// </summary> /// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] /// <remarks>
/// 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.
/// </remarks>
[RegisterComponent]
[NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(UseDelaySystem))]
public sealed partial class UseDelayComponent : Component public sealed partial class UseDelayComponent : Component
{ {
[AutoNetworkedField] /// <summary>
public TimeSpan LastUseTime; /// When the delay starts.
/// </summary>
[AutoNetworkedField] [ViewVariables(VVAccess.ReadWrite), DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField]
public TimeSpan? DelayEndTime; public TimeSpan DelayStartTime;
[DataField, AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)]
public TimeSpan Delay = TimeSpan.FromSeconds(1);
/// <summary> /// <summary>
/// Stores remaining delay pausing (and eventually, serialization). /// When the delay ends.
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField]
public TimeSpan DelayEndTime;
/// <summary>
/// Default delay time
/// </summary> /// </summary>
[DataField] [DataField]
public TimeSpan? RemainingDelay; [ViewVariables(VVAccess.ReadWrite)]
[AutoNetworkedField]
public bool ActiveDelay => DelayEndTime != null; public TimeSpan Delay = TimeSpan.FromSeconds(1);
} }

View File

@@ -1,125 +1,64 @@
using Content.Shared.Cooldown;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using Robust.Shared.Utility;
namespace Content.Shared.Timing; namespace Content.Shared.Timing;
public sealed class UseDelaySystem : EntitySystem public sealed class UseDelaySystem : EntitySystem
{ {
[Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly MetaDataSystem _metadata = default!;
private HashSet<UseDelayComponent> _activeDelays = new();
public override void Initialize() public override void Initialize()
{ {
base.Initialize();
SubscribeLocalEvent<UseDelayComponent, AfterAutoHandleStateEvent>(OnHandleState);
SubscribeLocalEvent<UseDelayComponent, EntityPausedEvent>(OnPaused);
SubscribeLocalEvent<UseDelayComponent, EntityUnpausedEvent>(OnUnpaused); SubscribeLocalEvent<UseDelayComponent, EntityUnpausedEvent>(OnUnpaused);
} }
private void OnPaused(EntityUid uid, UseDelayComponent component, ref EntityPausedEvent args) private void OnUnpaused(Entity<UseDelayComponent> ent, ref EntityUnpausedEvent args)
{ {
// This entity just got paused, but wasn't before // We got unpaused, resume the delay
if (component.DelayEndTime != null) ent.Comp.DelayStartTime += args.PausedTime;
component.RemainingDelay = _gameTiming.CurTime - component.DelayEndTime; ent.Comp.DelayEndTime += args.PausedTime;
Dirty(ent);
_activeDelays.Remove(component);
Dirty(component);
} }
private void OnUnpaused(EntityUid uid, UseDelayComponent component, ref EntityUnpausedEvent args) public void SetDelay(Entity<UseDelayComponent> ent, TimeSpan delay)
{ {
if (component.RemainingDelay == null) if (ent.Comp.Delay == delay)
return; return;
// We got unpaused, resume the delay/cooldown. Currently this takes for granted that ItemCooldownComponent ent.Comp.Delay += delay;
// handles the pausing on its own. I'm not even gonna check, because I CBF fixing it if it doesn't. Dirty(ent);
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<UseDelayComponent>();
var curTime = _gameTiming.CurTime;
var mQuery = EntityManager.GetEntityQuery<MetaDataComponent>();
// 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);
}
} }
/// <summary> /// <summary>
/// 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.
/// </summary> /// </summary>
/// <remarks> public bool IsDelayed(Entity<UseDelayComponent> ent)
/// 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.
/// </remarks>
public bool BeginDelay(EntityUid uid, UseDelayComponent? component = null)
{ {
if (!Resolve(uid, ref component, false)) return ent.Comp.DelayEndTime >= _gameTiming.CurTime;
return true; }
if (component.ActiveDelay) /// <summary>
/// Cancels the current delay.
/// </summary>
public void CancelDelay(Entity<UseDelayComponent> ent)
{
ent.Comp.DelayEndTime = _gameTiming.CurTime;
Dirty(ent);
}
/// <summary>
/// Resets the UseDelay entirely for this entity if possible.
/// </summary>
/// <param name="checkDelayed">Check if the entity has an ongoing delay, return false if it does, return true if it does not.</param>
public bool TryResetDelay(Entity<UseDelayComponent> ent, bool checkDelayed = false)
{
if (checkDelayed && IsDelayed(ent))
return false; return false;
DebugTools.Assert(!_activeDelays.Contains(component)); var curTime = _gameTiming.CurTime;
_activeDelays.Add(component); ent.Comp.DelayStartTime = curTime;
ent.Comp.DelayEndTime = curTime - _metadata.GetPauseTime(ent) + ent.Comp.Delay;
var currentTime = _gameTiming.CurTime; Dirty(ent);
component.LastUseTime = currentTime;
component.DelayEndTime = currentTime + component.Delay;
Dirty(uid, component);
var cooldown = EnsureComp<ItemCooldownComponent>(uid);
cooldown.CooldownStart = currentTime;
cooldown.CooldownEnd = component.DelayEndTime;
return true; 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<ItemCooldownComponent>(component.Owner, out var cooldown))
{
cooldown.CooldownEnd = _gameTiming.CurTime;
}
}
} }

View File

@@ -6,10 +6,8 @@ using Content.Shared.Interaction;
using Content.Shared.Movement.Events; using Content.Shared.Movement.Events;
using Content.Shared.Physics; using Content.Shared.Physics;
using Content.Shared.Projectiles; using Content.Shared.Projectiles;
using Content.Shared.Timing;
using Content.Shared.Weapons.Ranged.Components; using Content.Shared.Weapons.Ranged.Components;
using Content.Shared.Weapons.Ranged.Systems; using Content.Shared.Weapons.Ranged.Systems;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using Robust.Shared.Network; using Robust.Shared.Network;
using Robust.Shared.Physics; using Robust.Shared.Physics;
@@ -30,7 +28,6 @@ public abstract class SharedGrapplingGunSystem : EntitySystem
[Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedJointSystem _joints = default!; [Dependency] private readonly SharedJointSystem _joints = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly UseDelaySystem _delay = default!;
public const string GrapplingJoint = "grappling"; public const string GrapplingJoint = "grappling";
@@ -117,10 +114,9 @@ public abstract class SharedGrapplingGunSystem : EntitySystem
private void OnGunActivate(EntityUid uid, GrapplingGunComponent component, ActivateInWorldEvent args) private void OnGunActivate(EntityUid uid, GrapplingGunComponent component, ActivateInWorldEvent args)
{ {
if (!Timing.IsFirstTimePredicted || _delay.ActiveDelay(uid)) if (!Timing.IsFirstTimePredicted || args.Handled)
return; return;
_delay.BeginDelay(uid);
_audio.PlayPredicted(component.CycleSound, uid, args.User); _audio.PlayPredicted(component.CycleSound, uid, args.User);
TryComp<AppearanceComponent>(uid, out var appearance); TryComp<AppearanceComponent>(uid, out var appearance);
@@ -137,6 +133,8 @@ public abstract class SharedGrapplingGunSystem : EntitySystem
component.Projectile = null; component.Projectile = null;
Dirty(uid, component); Dirty(uid, component);
} }
args.Handled = true;
} }
private void SetReeling(EntityUid uid, GrapplingGunComponent component, bool value, EntityUid? user) private void SetReeling(EntityUid uid, GrapplingGunComponent component, bool value, EntityUid? user)

View File

@@ -15,6 +15,7 @@ public sealed class UseDelayOnShootSystem : EntitySystem
private void OnUseShoot(EntityUid uid, UseDelayOnShootComponent component, ref GunShotEvent args) private void OnUseShoot(EntityUid uid, UseDelayOnShootComponent component, ref GunShotEvent args)
{ {
_delay.BeginDelay(uid); if (TryComp(uid, out UseDelayComponent? useDelay))
_delay.TryResetDelay((uid, useDelay));
} }
} }

View File

@@ -1,27 +1,24 @@
using Content.Shared.DoAfter;
using Content.Shared.Hands; using Content.Shared.Hands;
using Content.Shared.Hands.Components; using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems; using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction.Events; using Content.Shared.Interaction.Events;
using Content.Shared.Item; using Content.Shared.Item;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Timing;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Content.Shared.Weapons.Melee; using Content.Shared.Weapons.Melee;
using Content.Shared.Weapons.Melee.Events;
using Content.Shared.Weapons.Melee.Components; using Content.Shared.Weapons.Melee.Components;
using Content.Shared.Weapons.Melee.Events;
using Content.Shared.Weapons.Ranged.Components; using Content.Shared.Weapons.Ranged.Components;
using Content.Shared.Weapons.Ranged.Systems; using Content.Shared.Weapons.Ranged.Systems;
using Content.Shared.Wieldable.Components; using Content.Shared.Wieldable.Components;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using Robust.Shared.Player; using Robust.Shared.Player;
using Content.Shared.Timing;
namespace Content.Shared.Wieldable; namespace Content.Shared.Wieldable;
public sealed class WieldableSystem : EntitySystem public sealed class WieldableSystem : EntitySystem
{ {
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
[Dependency] private readonly SharedHandVirtualItemSystem _virtualItemSystem = default!; [Dependency] private readonly SharedHandVirtualItemSystem _virtualItemSystem = default!;
[Dependency] private readonly SharedHandsSystem _handsSystem = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!;
[Dependency] private readonly SharedItemSystem _itemSystem = default!; [Dependency] private readonly SharedItemSystem _itemSystem = default!;
@@ -120,18 +117,18 @@ public sealed class WieldableSystem : EntitySystem
if (args.Handled) if (args.Handled)
return; return;
if(!component.Wielded) if (!component.Wielded)
args.Handled = TryWield(uid, component, args.User); args.Handled = TryWield(uid, component, args.User);
else else
args.Handled = TryUnwield(uid, component, args.User); 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? // Do they have enough hands free?
if (!EntityManager.TryGetComponent<HandsComponent>(user, out var hands)) if (!EntityManager.TryGetComponent<HandsComponent>(user, out var hands))
{ {
if(!quiet) if (!quiet)
_popupSystem.PopupClient(Loc.GetString("wieldable-component-no-hands"), user, user); _popupSystem.PopupClient(Loc.GetString("wieldable-component-no-hands"), user, user);
return false; return false;
} }
@@ -190,10 +187,12 @@ public sealed class WieldableSystem : EntitySystem
_virtualItemSystem.TrySpawnVirtualItemInHand(used, user); _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.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(); var targEv = new ItemWieldedEvent();
RaiseLocalEvent(used, ref targEv); RaiseLocalEvent(used, ref targEv);
@@ -224,6 +223,7 @@ public sealed class WieldableSystem : EntitySystem
{ {
if (args.User == null) if (args.User == null)
return; return;
if (!component.Wielded) if (!component.Wielded)
return; return;
@@ -255,6 +255,7 @@ public sealed class WieldableSystem : EntitySystem
{ {
if (!component.Wielded || uid != args.Unequipped) if (!component.Wielded || uid != args.Unequipped)
return; return;
RaiseLocalEvent(uid, new ItemUnwieldedEvent(args.User, force: true), true); RaiseLocalEvent(uid, new ItemUnwieldedEvent(args.User, force: true), true);
} }
@@ -268,6 +269,7 @@ public sealed class WieldableSystem : EntitySystem
{ {
if (!TryComp<WieldableComponent>(uid, out var wield)) if (!TryComp<WieldableComponent>(uid, out var wield))
return; return;
if (!wield.Wielded) if (!wield.Wielded)
return; return;

View File

@@ -100405,7 +100405,6 @@ entities:
- Pressed: Toggle - Pressed: Toggle
1065: 1065:
- Pressed: Toggle - Pressed: Toggle
- type: ItemCooldown
- uid: 7826 - uid: 7826
components: components:
- type: Transform - type: Transform
@@ -100451,7 +100450,6 @@ entities:
- Pressed: Toggle - Pressed: Toggle
2822: 2822:
- Pressed: Toggle - Pressed: Toggle
- type: ItemCooldown
- uid: 8749 - uid: 8749
components: components:
- type: Transform - type: Transform
@@ -100550,7 +100548,6 @@ entities:
linkedPorts: linkedPorts:
4205: 4205:
- Pressed: Toggle - Pressed: Toggle
- type: ItemCooldown
- uid: 17649 - uid: 17649
components: components:
- type: Transform - type: Transform
@@ -100563,7 +100560,6 @@ entities:
linkedPorts: linkedPorts:
3066: 3066:
- Pressed: Toggle - Pressed: Toggle
- type: ItemCooldown
- proto: SignalButtonBridge - proto: SignalButtonBridge
entities: entities:
- uid: 4305 - uid: 4305

View File

@@ -67091,7 +67091,7 @@ entities:
3218: 3218:
- Pressed: Toggle - Pressed: Toggle
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown - type: UseDelay
- uid: 5389 - uid: 5389
components: components:
- rot: 1.5707963267948966 rad - rot: 1.5707963267948966 rad
@@ -67104,7 +67104,7 @@ entities:
3218: 3218:
- Pressed: Toggle - Pressed: Toggle
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown - type: UseDelay
- uid: 5447 - uid: 5447
components: components:
- rot: 3.141592653589793 rad - rot: 3.141592653589793 rad

View File

@@ -74740,7 +74740,7 @@ entities:
1663: 1663:
- Pressed: Toggle - Pressed: Toggle
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown - type: UseDelay
- uid: 9640 - uid: 9640
components: components:
- pos: -20.5,-1.5 - pos: -20.5,-1.5

View File

@@ -142471,7 +142471,6 @@ entities:
- Pressed: Toggle - Pressed: Toggle
20499: 20499:
- Pressed: Toggle - Pressed: Toggle
- type: ItemCooldown
- uid: 20513 - uid: 20513
components: components:
- type: Transform - type: Transform
@@ -142704,7 +142703,6 @@ entities:
- Pressed: Toggle - Pressed: Toggle
20423: 20423:
- Pressed: Toggle - Pressed: Toggle
- type: ItemCooldown
- uid: 20528 - uid: 20528
components: components:
- type: Transform - type: Transform

View File

@@ -118234,7 +118234,6 @@ entities:
- Pressed: Toggle - Pressed: Toggle
9404: 9404:
- Pressed: Toggle - Pressed: Toggle
- type: ItemCooldown
- uid: 8610 - uid: 8610
components: components:
- type: Transform - type: Transform

View File

@@ -135841,7 +135841,6 @@ entities:
- Pressed: Toggle - Pressed: Toggle
19434: 19434:
- Pressed: Toggle - Pressed: Toggle
- type: ItemCooldown
- uid: 19438 - uid: 19438
components: components:
- type: MetaData - type: MetaData

View File

@@ -79806,7 +79806,6 @@ entities:
- pos: -46.5,62.5 - pos: -46.5,62.5
parent: 2 parent: 2
type: Transform type: Transform
- type: ItemCooldown
- proto: ClothingBackpackMedical - proto: ClothingBackpackMedical
entities: entities:
- uid: 12350 - uid: 12350
@@ -163449,7 +163448,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24195 - uid: 24195
components: components:
- rot: -1.5707963267948966 rad - rot: -1.5707963267948966 rad
@@ -163481,7 +163479,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24196 - uid: 24196
components: components:
- name: shutters switch - name: shutters switch
@@ -163514,7 +163511,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24197 - uid: 24197
components: components:
- name: blast door switch - name: blast door switch
@@ -163528,7 +163524,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24198 - uid: 24198
components: components:
- rot: -1.5707963267948966 rad - rot: -1.5707963267948966 rad
@@ -163557,7 +163552,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24199 - uid: 24199
components: components:
- rot: 1.5707963267948966 rad - rot: 1.5707963267948966 rad
@@ -163572,7 +163566,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24200 - uid: 24200
components: components:
- rot: 3.141592653589793 rad - rot: 3.141592653589793 rad
@@ -163624,7 +163617,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24204 - uid: 24204
components: components:
- rot: 3.141592653589793 rad - rot: 3.141592653589793 rad
@@ -163671,7 +163663,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24207 - uid: 24207
components: components:
- pos: -52.5,-11.5 - pos: -52.5,-11.5
@@ -163728,7 +163719,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24210 - uid: 24210
components: components:
- pos: -49.5,24.5 - pos: -49.5,24.5
@@ -163793,7 +163783,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24214 - uid: 24214
components: components:
- pos: 58.5,48.5 - pos: 58.5,48.5
@@ -164016,7 +164005,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24228 - uid: 24228
components: components:
- pos: 54.5,51.5 - pos: 54.5,51.5
@@ -164033,7 +164021,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24229 - uid: 24229
components: components:
- pos: 5.5,49.5 - pos: 5.5,49.5
@@ -164229,7 +164216,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24238 - uid: 24238
components: components:
- rot: 3.141592653589793 rad - rot: 3.141592653589793 rad
@@ -164273,7 +164259,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24239 - uid: 24239
components: components:
- name: shutters switch - name: shutters switch
@@ -164294,7 +164279,6 @@ entities:
- Off: Close - Off: Close
- Status: Toggle - Status: Toggle
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24240 - uid: 24240
components: components:
- pos: -51.5,36.5 - pos: -51.5,36.5
@@ -164305,7 +164289,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24241 - uid: 24241
components: components:
- name: shutters switch - name: shutters switch
@@ -164342,7 +164325,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24242 - uid: 24242
components: components:
- name: visitation switch - name: visitation switch
@@ -164363,7 +164345,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24243 - uid: 24243
components: components:
- name: shutters switch - name: shutters switch
@@ -164402,7 +164383,6 @@ entities:
- On: Open - On: Open
- Off: Close - Off: Close
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24245 - uid: 24245
components: components:
- name: shutters switch - name: shutters switch
@@ -164521,7 +164501,6 @@ entities:
- Off: Close - Off: Close
- Status: Toggle - Status: Toggle
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 24248 - uid: 24248
components: components:
- pos: -74.5,-43.5 - pos: -74.5,-43.5
@@ -175048,7 +175027,6 @@ entities:
- Right: Reverse - Right: Reverse
- Middle: Off - Middle: Off
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 25925 - uid: 25925
components: components:
- pos: -41.5,17.5 - pos: -41.5,17.5
@@ -175351,7 +175329,6 @@ entities:
- Right: Reverse - Right: Reverse
- Middle: Off - Middle: Off
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 25933 - uid: 25933
components: components:
- pos: 47.5,39.5 - pos: 47.5,39.5
@@ -175551,7 +175528,6 @@ entities:
- Right: Forward - Right: Forward
- Middle: Off - Middle: Off
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- proto: UnfinishedMachineFrame - proto: UnfinishedMachineFrame
entities: entities:
- uid: 25938 - uid: 25938

View File

@@ -56927,7 +56927,6 @@ entities:
260: 260:
- Pressed: Toggle - Pressed: Toggle
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 8766 - uid: 8766
components: components:
- pos: -13.5,12.5 - pos: -13.5,12.5
@@ -56965,7 +56964,6 @@ entities:
7588: 7588:
- Pressed: Toggle - Pressed: Toggle
type: DeviceLinkSource type: DeviceLinkSource
- type: ItemCooldown
- uid: 10449 - uid: 10449
components: components:
- pos: 51.5,18.5 - pos: 51.5,18.5

View File

@@ -53,7 +53,6 @@
qualities: qualities:
- Rolling - Rolling
speed: 0.25 # its small so takes longer to roll the entire dough flat speed: 0.25 # its small so takes longer to roll the entire dough flat
- type: ItemCooldown
- type: SpaceGarbage - type: SpaceGarbage
- type: TrashOnSolutionEmpty - type: TrashOnSolutionEmpty
solution: drink solution: drink

View File

@@ -37,7 +37,6 @@
damage: damage:
types: types:
Blunt: 0 Blunt: 0
- type: ItemCooldown
- type: entity - type: entity
parent: DrinkBaseCup parent: DrinkBaseCup

View File

@@ -16,7 +16,6 @@
prototype: MobHumanSyndicateAgent prototype: MobHumanSyndicateAgent
- type: EmitSoundOnUse - type: EmitSoundOnUse
sound: /Audio/Effects/Emotes/parp1.ogg sound: /Audio/Effects/Emotes/parp1.ogg
- type: ItemCooldown
- type: UseDelay - type: UseDelay
delay: 300 delay: 300

View File

@@ -5,9 +5,7 @@
description: A handy-dandy holographic projector that displays a janitorial sign. description: A handy-dandy holographic projector that displays a janitorial sign.
components: components:
- type: HolosignProjector - type: HolosignProjector
- type: ItemCooldown
- type: UseDelay - type: UseDelay
delay: 1.0
- type: ContainerContainer - type: ContainerContainer
containers: containers:
cell_slot: !type:ContainerSlot {} cell_slot: !type:ContainerSlot {}

View File

@@ -14,7 +14,6 @@
sprite: Objects/Fun/bikehorn.rsi sprite: Objects/Fun/bikehorn.rsi
slots: [Belt] slots: [Belt]
quickEquip: false quickEquip: false
- type: ItemCooldown
- type: EmitSoundOnUse - type: EmitSoundOnUse
sound: sound:
collection: BikeHorn collection: BikeHorn
@@ -52,7 +51,7 @@
name: broken bike horn name: broken bike horn
description: A broken horn off of a bicycle. description: A broken horn off of a bicycle.
components: components:
- type: ItemCooldown - type: UseDelay
- type: Sprite - type: Sprite
sprite: Objects/Fun/cluwnehorn.rsi sprite: Objects/Fun/cluwnehorn.rsi
state: icon state: icon

View File

@@ -42,7 +42,6 @@
- type: Item - type: Item
size: Tiny size: Tiny
sprite: Objects/Fun/Darts/dart_red.rsi sprite: Objects/Fun/Darts/dart_red.rsi
- type: ItemCooldown
- type: SolutionContainerManager - type: SolutionContainerManager
solutions: solutions:
melee: melee:
@@ -204,4 +203,4 @@
items: items:
- id: HypoDart - id: HypoDart
sound: sound:
path: /Audio/Effects/unwrap.ogg path: /Audio/Effects/unwrap.ogg

View File

@@ -4,7 +4,6 @@
id: BaseDice id: BaseDice
components: components:
- type: Dice - type: Dice
- type: ItemCooldown
- type: UseDelay - type: UseDelay
- type: Sprite - type: Sprite
sprite: Objects/Fun/dice.rsi sprite: Objects/Fun/dice.rsi

View File

@@ -9,7 +9,6 @@
state: icon state: icon
- type: Item - type: Item
sprite: Objects/Misc/skub.rsi sprite: Objects/Misc/skub.rsi
- type: ItemCooldown
- type: EmitSoundOnUse - type: EmitSoundOnUse
sound: sound:
collection: Skub collection: Skub

View File

@@ -19,7 +19,6 @@
- type: EmitSoundOnLand - type: EmitSoundOnLand
sound: sound:
collection: ToyFall collection: ToyFall
- type: ItemCooldown
- type: UseDelay - type: UseDelay
delay: 1.0 delay: 1.0
- type: MeleeWeapon - type: MeleeWeapon
@@ -709,7 +708,7 @@
size: Small size: Small
sprite: Objects/Fun/toys.rsi sprite: Objects/Fun/toys.rsi
heldPrefix: foamblade heldPrefix: foamblade
- type: ItemCooldown - type: UseDelay
# MISC # MISC
@@ -1020,7 +1019,6 @@
sprite: Objects/Fun/whoopie.rsi sprite: Objects/Fun/whoopie.rsi
state: icon state: icon
quickEquip: false quickEquip: false
- type: ItemCooldown
- type: EmitSoundOnUse - type: EmitSoundOnUse
sound: sound:
collection: Parp collection: Parp

View File

@@ -20,7 +20,6 @@
- enum.DamageStateVisualLayers.Base: - enum.DamageStateVisualLayers.Base:
shard3: "" shard3: ""
- type: SpaceGarbage - type: SpaceGarbage
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
attackRate: 1.5 attackRate: 1.5
damage: damage:

View File

@@ -18,7 +18,6 @@
shard2: "" shard2: ""
- enum.DamageStateVisualLayers.Base: - enum.DamageStateVisualLayers.Base:
shard3: "" shard3: ""
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
attackRate: 1.5 attackRate: 1.5
damage: damage:

View File

@@ -5,7 +5,6 @@
description: In Space Glasgow this is called a conversation starter. description: In Space Glasgow this is called a conversation starter.
components: components:
- type: Sharp - type: Sharp
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
attackRate: 1.5 attackRate: 1.5
damage: damage:
@@ -27,4 +26,3 @@
materialComposition: materialComposition:
Glass: 50 Glass: 50
- type: SpaceGarbage - type: SpaceGarbage

View File

@@ -32,7 +32,6 @@
params: params:
variation: 0.03 variation: 0.03
volume: 3 volume: 3
- type: ItemCooldown
- type: UseDelay - type: UseDelay
delay: 0.5 delay: 0.5
- type: MeleeWeapon - type: MeleeWeapon

View File

@@ -24,7 +24,7 @@
- type: DrainableSolution - type: DrainableSolution
solution: spray solution: spray
- type: SolutionTransfer - type: SolutionTransfer
- type: ItemCooldown - type: UseDelay
- type: Spray - type: Spray
transferAmount: 10 transferAmount: 10
pushbackAmount: 60 pushbackAmount: 60

View File

@@ -287,7 +287,6 @@
- type: Sprite - type: Sprite
sprite: Objects/Misc/bureaucracy.rsi sprite: Objects/Misc/bureaucracy.rsi
state: overpriced_pen state: overpriced_pen
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
wideAnimationRotation: -45 wideAnimationRotation: -45
damage: damage:

View File

@@ -26,7 +26,6 @@
mixMessage: "bible-mixing-success" mixMessage: "bible-mixing-success"
reactionTypes: reactionTypes:
- Holy - Holy
- type: ItemCooldown
- type: Sprite - type: Sprite
sprite: Objects/Specific/Chapel/bible.rsi sprite: Objects/Specific/Chapel/bible.rsi
state: icon state: icon

View File

@@ -45,7 +45,6 @@
solution: spray solution: spray
- type: Spillable - type: Spillable
solution: spray solution: spray
- type: ItemCooldown
- type: Tag - type: Tag
tags: tags:
- Spray - Spray

View File

@@ -11,7 +11,6 @@
- type: Sprite - type: Sprite
sprite: Objects/Tools/Hydroponics/hoe.rsi sprite: Objects/Tools/Hydroponics/hoe.rsi
state: icon state: icon
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
wideAnimationRotation: 135 wideAnimationRotation: 135
swingLeft: true swingLeft: true
@@ -33,7 +32,6 @@
- type: Sprite - type: Sprite
sprite: Objects/Tools/Hydroponics/clippers.rsi sprite: Objects/Tools/Hydroponics/clippers.rsi
state: icon state: icon
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
wideAnimationRotation: 90 wideAnimationRotation: 90
damage: damage:
@@ -53,7 +51,6 @@
- type: Sprite - type: Sprite
sprite: Objects/Tools/Hydroponics/scythe.rsi sprite: Objects/Tools/Hydroponics/scythe.rsi
state: icon state: icon
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
wideAnimationRotation: 135 wideAnimationRotation: 135
damage: damage:
@@ -81,7 +78,6 @@
- type: Sprite - type: Sprite
sprite: Objects/Tools/Hydroponics/hatchet.rsi sprite: Objects/Tools/Hydroponics/hatchet.rsi
state: icon state: icon
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
wideAnimationRotation: 135 wideAnimationRotation: 135
swingLeft: true swingLeft: true
@@ -105,7 +101,6 @@
- type: Sprite - type: Sprite
sprite: Objects/Tools/Hydroponics/spade.rsi sprite: Objects/Tools/Hydroponics/spade.rsi
state: icon state: icon
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
wideAnimationRotation: 45 wideAnimationRotation: 45
damage: damage:

View File

@@ -562,7 +562,6 @@
- type: Item - type: Item
sprite: Objects/Specific/Janitorial/plunger.rsi sprite: Objects/Specific/Janitorial/plunger.rsi
heldPrefix: plunger heldPrefix: plunger
- type: ItemCooldown
- type: GuideHelp - type: GuideHelp
guides: guides:
- Janitorial - Janitorial

View File

@@ -24,7 +24,7 @@
solution: spray solution: spray
- type: SolutionTransfer - type: SolutionTransfer
canChangeTransferAmount: true canChangeTransferAmount: true
- type: ItemCooldown - type: UseDelay
- type: Spray - type: Spray
transferAmount: 10 transferAmount: 10
sprayVelocity: 2 sprayVelocity: 2

View File

@@ -29,7 +29,6 @@
False: { visible: false } False: { visible: false }
- type: Item - type: Item
size: Large size: Large
- type: ItemCooldown
- type: Speech - type: Speech
speechVerb: Robotic speechVerb: Robotic
- type: Defibrillator - type: Defibrillator

View File

@@ -22,7 +22,6 @@
state: cautery state: cautery
- type: Item - type: Item
sprite: Objects/Specific/Medical/Surgery/cautery.rsi sprite: Objects/Specific/Medical/Surgery/cautery.rsi
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
damage: damage:
types: types:
@@ -43,7 +42,6 @@
state: drill state: drill
- type: Item - type: Item
sprite: Objects/Specific/Medical/Surgery/drill.rsi sprite: Objects/Specific/Medical/Surgery/drill.rsi
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
damage: damage:
types: types:
@@ -69,7 +67,6 @@
state: scalpel state: scalpel
- type: Item - type: Item
sprite: Objects/Specific/Medical/Surgery/scalpel.rsi sprite: Objects/Specific/Medical/Surgery/scalpel.rsi
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
attackRate: 1.5 attackRate: 1.5
damage: damage:
@@ -128,7 +125,6 @@
state: retractor state: retractor
- type: Item - type: Item
sprite: Objects/Specific/Medical/Surgery/scissors.rsi sprite: Objects/Specific/Medical/Surgery/scissors.rsi
- type: ItemCooldown
- type: entity - type: entity
name: hemostat name: hemostat
@@ -164,7 +160,6 @@
state: saw state: saw
- type: Item - type: Item
sprite: Objects/Specific/Medical/Surgery/saw.rsi sprite: Objects/Specific/Medical/Surgery/saw.rsi
- type: ItemCooldown
- type: Tool - type: Tool
qualities: qualities:
- Sawing - Sawing

View File

@@ -12,7 +12,6 @@
- state: base - state: base
- state: green_bit - state: green_bit
shader: unshaded shader: unshaded
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
damage: damage:
types: types:

View File

@@ -10,7 +10,6 @@
- type: Sprite - type: Sprite
sprite: Objects/Tools/Cowtools/haycutters.rsi sprite: Objects/Tools/Cowtools/haycutters.rsi
state: haycutters state: haycutters
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
damage: damage:
types: types:
@@ -36,7 +35,6 @@
state: moodriver state: moodriver
- type: Item - type: Item
sprite: Objects/Tools/Cowtools/moodriver.rsi sprite: Objects/Tools/Cowtools/moodriver.rsi
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
attackRate: 1.5 attackRate: 1.5
damage: damage:
@@ -60,7 +58,6 @@
state: wronch state: wronch
- type: Item - type: Item
sprite: Objects/Tools/Cowtools/wronch.rsi sprite: Objects/Tools/Cowtools/wronch.rsi
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
attackRate: 1.5 attackRate: 1.5
damage: damage:
@@ -84,7 +81,6 @@
state: cowbar state: cowbar
- type: Item - type: Item
sprite: Objects/Tools/Cowtools/cowbar.rsi sprite: Objects/Tools/Cowtools/cowbar.rsi
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
damage: damage:
types: types:
@@ -185,4 +181,3 @@
- id: Mooltitool - id: Mooltitool
- id: Cowelder - id: Cowelder
- id: Milkalyzer - id: Milkalyzer

View File

@@ -71,7 +71,7 @@
- type: Item - type: Item
size: Tiny size: Tiny
sprite: Objects/Tools/lighters.rsi sprite: Objects/Tools/lighters.rsi
- type: ItemCooldown - type: UseDelay
- type: RefillableSolution - type: RefillableSolution
solution: Welder solution: Welder
- type: SolutionContainerManager - type: SolutionContainerManager

View File

@@ -13,7 +13,6 @@
- 0,0,6,3 - 0,0,6,3
- type: Item - type: Item
size: Ginormous size: Ginormous
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
damage: damage:
types: types:

View File

@@ -17,7 +17,6 @@
- state: cutters - state: cutters
map: [ "enum.DamageStateVisualLayers.Base" ] map: [ "enum.DamageStateVisualLayers.Base" ]
- state: cutters-cutty-thingy - state: cutters-cutty-thingy
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
wideAnimationRotation: -90 wideAnimationRotation: -90
damage: damage:
@@ -66,7 +65,6 @@
- type: Item - type: Item
sprite: Objects/Tools/screwdriver.rsi sprite: Objects/Tools/screwdriver.rsi
storedRotation: -90 storedRotation: -90
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
wideAnimationRotation: -90 wideAnimationRotation: -90
attackRate: 1 attackRate: 1
@@ -110,7 +108,6 @@
storedSprite: storedSprite:
sprite: Objects/Tools/wrench.rsi sprite: Objects/Tools/wrench.rsi
state: storage state: storage
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
wideAnimationRotation: 135 wideAnimationRotation: 135
attackRate: 1.5 attackRate: 1.5
@@ -149,7 +146,6 @@
storedSprite: storedSprite:
sprite: Objects/Tools/crowbar.rsi sprite: Objects/Tools/crowbar.rsi
state: storage state: storage
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
wideAnimationRotation: -135 wideAnimationRotation: -135
damage: damage:
@@ -351,7 +347,6 @@
maxCharges: 5 maxCharges: 5
charges: 5 charges: 5
- type: UseDelay - type: UseDelay
delay: 1.0
- type: Sprite - type: Sprite
sprite: Objects/Tools/rcd.rsi sprite: Objects/Tools/rcd.rsi
state: icon state: icon
@@ -500,7 +495,6 @@
- type: Sprite - type: Sprite
sprite: Objects/Tools/shovel.rsi sprite: Objects/Tools/shovel.rsi
state: icon state: icon
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
wideAnimationRotation: -135 wideAnimationRotation: -135
damage: damage:
@@ -533,7 +527,6 @@
quickEquip: false quickEquip: false
slots: slots:
- Belt - Belt
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
wideAnimationRotation: -135 wideAnimationRotation: -135
damage: damage:

View File

@@ -64,7 +64,7 @@
right: right:
- state: inhand-right-flame - state: inhand-right-flame
shader: unshaded shader: unshaded
- type: ItemCooldown - type: UseDelay
- type: MeleeWeapon - type: MeleeWeapon
wideAnimationRotation: -90 wideAnimationRotation: -90
damage: damage:

View File

@@ -10,7 +10,6 @@
- type: Utensil - type: Utensil
types: types:
- Knife - Knife
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
wideAnimationRotation: -135 wideAnimationRotation: -135
damage: damage:

View File

@@ -10,7 +10,6 @@
- type: Sprite - type: Sprite
sprite: Objects/Weapons/Melee/pickaxe.rsi sprite: Objects/Weapons/Melee/pickaxe.rsi
state: pickaxe state: pickaxe
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
wideAnimationRotation: -135 wideAnimationRotation: -135
damage: damage:
@@ -31,7 +30,6 @@
sprite: Objects/Weapons/Melee/pickaxe.rsi sprite: Objects/Weapons/Melee/pickaxe.rsi
storedRotation: -45 storedRotation: -45
- type: UseDelay - type: UseDelay
delay: 1
- type: entity - type: entity
name: mining drill name: mining drill
@@ -45,7 +43,6 @@
- type: Sprite - type: Sprite
sprite: Objects/Tools/handdrill.rsi sprite: Objects/Tools/handdrill.rsi
state: handdrill state: handdrill
- type: ItemCooldown
- type: MeleeWeapon - type: MeleeWeapon
attackRate: 1.5 attackRate: 1.5
damage: damage:

View File

@@ -55,7 +55,6 @@
- type: Construction - type: Construction
graph: Spear graph: Spear
node: spear node: spear
- type: ItemCooldown
- type: SolutionContainerManager - type: SolutionContainerManager
solutions: solutions:
melee: melee:
@@ -107,7 +106,6 @@
types: types:
Blunt: 5 Blunt: 5
- type: UseDelay - type: UseDelay
delay: 1
- type: Appearance - type: Appearance
- type: SolutionContainerVisuals - type: SolutionContainerVisuals
maxFillLevels: 1 maxFillLevels: 1

View File

@@ -44,7 +44,7 @@
- type: Battery - type: Battery
maxCharge: 360 maxCharge: 360
startingCharge: 360 startingCharge: 360
- type: ItemCooldown - type: UseDelay
- type: Item - type: Item
heldPrefix: off heldPrefix: off
size: Normal size: Normal

View File

@@ -46,7 +46,7 @@
- type: Battery - type: Battery
maxCharge: 1000 maxCharge: 1000
startingCharge: 1000 startingCharge: 1000
- type: ItemCooldown - type: UseDelay
- type: Item - type: Item
heldPrefix: off heldPrefix: off
size: Normal size: Normal
@@ -142,7 +142,7 @@
- type: Item - type: Item
size: Small size: Small
sprite: Objects/Weapons/Melee/flash.rsi sprite: Objects/Weapons/Melee/flash.rsi
- type: ItemCooldown - type: UseDelay
- type: StaticPrice - type: StaticPrice
price: 40 price: 40
- type: Appearance - type: Appearance

View File

@@ -81,14 +81,16 @@
guides: [ Singularity, Power ] guides: [ Singularity, Power ]
- type: ContainerContainer - type: ContainerContainer
containers: containers:
GasTank: !type:ContainerSlot {} gas_tank: !type:ContainerSlot {}
- type: ItemSlots - type: ItemSlots
slots: slots:
GasTank: gas_tank:
startingItem: PlasmaTank startingItem: PlasmaTank
whitelist: whitelist:
components: components:
- GasTank - GasTank
- type: UseDelay
delay: 1
- type: entity - type: entity
id: RadiationCollectorNoTank id: RadiationCollectorNoTank
@@ -97,11 +99,11 @@
components: components:
- type: ItemSlots - type: ItemSlots
slots: slots:
GasTank: gas_tank:
whitelist: whitelist:
components: components:
- GasTank - GasTank
- type: entity - type: entity
id: RadiationCollectorFullTank id: RadiationCollectorFullTank
suffix: Filled tank suffix: Filled tank
@@ -109,8 +111,8 @@
components: components:
- type: ItemSlots - type: ItemSlots
slots: slots:
GasTank: gas_tank:
startingItem: PlasmaTankFilled startingItem: PlasmaTankFilled
whitelist: whitelist:
components: components:
- GasTank - GasTank

View File

@@ -20,7 +20,6 @@
False: { visible: false } False: { visible: false }
- type: Item - type: Item
size: Normal size: Normal
- type: ItemCooldown
- type: EmitSoundOnUse #placeholder for future unical mechanic - type: EmitSoundOnUse #placeholder for future unical mechanic
sound: sound:
collection: RadiationPulse collection: RadiationPulse

View File

@@ -127,7 +127,7 @@
components: components:
- Item - Item
permanentComponents: permanentComponents:
- type: ItemCooldown - type: UseDelay
- type: MeleeWeapon - type: MeleeWeapon
damage: damage:
types: types: