diff --git a/Content.Shared/Movement/Systems/MovementModStatusSystem.cs b/Content.Shared/Movement/Systems/MovementModStatusSystem.cs
index 37039fa6d4..99ac22e330 100644
--- a/Content.Shared/Movement/Systems/MovementModStatusSystem.cs
+++ b/Content.Shared/Movement/Systems/MovementModStatusSystem.cs
@@ -194,6 +194,16 @@ public sealed class MovementModStatusSystem : EntitySystem
return TryUpdateMovementStatus(uid, status, speedModifier, speedModifier);
}
+ ///
+ public bool TryAddFrictionModDuration(
+ EntityUid uid,
+ TimeSpan duration,
+ float friction
+ )
+ {
+ return TryAddFrictionModDuration(uid, duration, friction, friction);
+ }
+
///
/// Apply friction modifier with provided duration,
/// or incrementing duration of existing.
@@ -210,8 +220,18 @@ public sealed class MovementModStatusSystem : EntitySystem
float acceleration
)
{
- return _status.TryAddStatusEffectDuration(uid, StatusEffectFriction, out var status, duration)
- && TrySetFrictionStatus(status.Value, friction, acceleration, uid);
+ return _status.TryAddStatusEffectDuration(uid, StatusEffectFriction, out var status, duration)
+ && TrySetFrictionStatus(status.Value, friction, acceleration, uid);
+ }
+
+ ///
+ public bool TryUpdateFrictionModDuration(
+ EntityUid uid,
+ TimeSpan duration,
+ float friction
+ )
+ {
+ return TryUpdateFrictionModDuration(uid,duration, friction, friction);
}
///
diff --git a/Content.Shared/Slippery/SlipperySystem.cs b/Content.Shared/Slippery/SlipperySystem.cs
index 58a0ec06d5..6a0e96888a 100644
--- a/Content.Shared/Slippery/SlipperySystem.cs
+++ b/Content.Shared/Slippery/SlipperySystem.cs
@@ -30,10 +30,18 @@ public sealed class SlipperySystem : EntitySystem
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly SpeedModifierContactsSystem _speedModifier = default!;
+ private EntityQuery _knockedDownQuery;
+ private EntityQuery _physicsQuery;
+ private EntityQuery _slidingQuery;
+
public override void Initialize()
{
base.Initialize();
+ _knockedDownQuery = GetEntityQuery();
+ _physicsQuery = GetEntityQuery();
+ _slidingQuery = GetEntityQuery();
+
SubscribeLocalEvent(HandleAttemptCollide);
SubscribeLocalEvent(HandleStepTrigger);
SubscribeLocalEvent(OnNoSlipAttempt);
@@ -92,7 +100,8 @@ public sealed class SlipperySystem : EntitySystem
public void TrySlip(EntityUid uid, SlipperyComponent component, EntityUid other, bool requiresContact = true)
{
- if (HasComp(other) && !component.SlipData.SuperSlippery)
+ var knockedDown = _knockedDownQuery.HasComp(other);
+ if (knockedDown && !component.SlipData.SuperSlippery)
return;
var attemptEv = new SlipAttemptEvent(uid);
@@ -111,7 +120,7 @@ public sealed class SlipperySystem : EntitySystem
var ev = new SlipEvent(other);
RaiseLocalEvent(uid, ref ev);
- if (TryComp(other, out PhysicsComponent? physics) && !HasComp(other))
+ if (_physicsQuery.TryComp(other, out var physics) && !_slidingQuery.HasComp(other))
{
_physics.SetLinearVelocity(other, physics.LinearVelocity * component.SlipData.LaunchForwardsMultiplier, body: physics);
@@ -120,16 +129,23 @@ public sealed class SlipperySystem : EntitySystem
}
// Preventing from playing the slip sound and stunning when you are already knocked down.
- if (!HasComp(other))
+ if (!knockedDown)
{
+ // Status effects should handle a TimeSpan of 0 properly...
_stun.TryUpdateStunDuration(other, component.SlipData.StunTime);
- _stamina.TakeStaminaDamage(other, component.StaminaDamage); // Note that this can stamCrit
- _movementMod.TryUpdateFrictionModDuration(
- other,
- component.FrictionStatusTime,
- component.SlipData.SlipFriction,
- component.SlipData.SlipFriction
- );
+
+ // Don't make a new status effect entity if the entity wouldn't do anything
+ if (!MathHelper.CloseTo(component.SlipData.SlipFriction, 1f))
+ {
+ _movementMod.TryUpdateFrictionModDuration(
+ other,
+ component.FrictionStatusTime,
+ component.SlipData.SlipFriction
+ );
+ }
+
+ _stamina.TakeStaminaDamage(other, component.StaminaDamage); // Note that this can StamCrit
+
_audio.PlayPredicted(component.SlipSound, other, other);
}
diff --git a/Content.Shared/StatusEffectNew/StatusEffectSystem.API.cs b/Content.Shared/StatusEffectNew/StatusEffectSystem.API.cs
index d30ab79c2b..2144b5a0c1 100644
--- a/Content.Shared/StatusEffectNew/StatusEffectSystem.API.cs
+++ b/Content.Shared/StatusEffectNew/StatusEffectSystem.API.cs
@@ -22,6 +22,13 @@ public sealed partial class StatusEffectsSystem
TimeSpan duration
)
{
+ if (duration == TimeSpan.Zero)
+ {
+ statusEffect = null;
+ return false;
+ }
+
+ // We check to make sure time is greater than zero here because sometimes you want to use TryAddStatusEffect to remove duration instead...
if (!TryGetStatusEffect(target, effectProto, out statusEffect))
return TryAddStatusEffect(target, effectProto, out statusEffect, duration);
@@ -53,6 +60,12 @@ public sealed partial class StatusEffectsSystem
TimeSpan? duration = null
)
{
+ if (duration <= TimeSpan.Zero)
+ {
+ statusEffect = null;
+ return false;
+ }
+
if (!TryGetStatusEffect(target, effectProto, out statusEffect))
return TryAddStatusEffect(target, effectProto, out statusEffect, duration);
@@ -83,6 +96,12 @@ public sealed partial class StatusEffectsSystem
TimeSpan? duration = null
)
{
+ if (duration <= TimeSpan.Zero)
+ {
+ statusEffect = null;
+ return false;
+ }
+
if (!TryGetStatusEffect(target, effectProto, out statusEffect))
return TryAddStatusEffect(target, effectProto, out statusEffect, duration);
diff --git a/Content.Shared/StatusEffectNew/StatusEffectsSystem.cs b/Content.Shared/StatusEffectNew/StatusEffectsSystem.cs
index f1edcfe819..1ffb74570a 100644
--- a/Content.Shared/StatusEffectNew/StatusEffectsSystem.cs
+++ b/Content.Shared/StatusEffectNew/StatusEffectsSystem.cs
@@ -202,6 +202,10 @@ public sealed partial class StatusEffectsSystem : EntitySystem
)
{
statusEffect = null;
+
+ if (duration <= TimeSpan.Zero)
+ return false;
+
if (!CanAddStatusEffect(target, effectProto))
return false;
diff --git a/Resources/Prototypes/Entities/Objects/Fun/toys.yml b/Resources/Prototypes/Entities/Objects/Fun/toys.yml
index 81b09be659..230669874b 100644
--- a/Resources/Prototypes/Entities/Objects/Fun/toys.yml
+++ b/Resources/Prototypes/Entities/Objects/Fun/toys.yml
@@ -911,6 +911,7 @@
delay: 0.8
- type: Slippery
staminaDamage: 0
+ frictionStatusTime: 0
slipData:
stunTime: 0
knockdownTime: 0