diff --git a/Content.Shared/Movement/Components/SpeedModifierContactsComponent.cs b/Content.Shared/Movement/Components/SpeedModifierContactsComponent.cs
index 73bb0690fd..f288363a2d 100644
--- a/Content.Shared/Movement/Components/SpeedModifierContactsComponent.cs
+++ b/Content.Shared/Movement/Components/SpeedModifierContactsComponent.cs
@@ -4,19 +4,33 @@ using Robust.Shared.GameStates;
namespace Content.Shared.Movement.Components;
-[NetworkedComponent, RegisterComponent]
-[AutoGenerateComponentState]
-[Access(typeof(SpeedModifierContactsSystem))]
+///
+/// Component that modifies the movement speed of other entities that come into contact with the entity this component is added to.
+///
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SpeedModifierContactsSystem))]
public sealed partial class SpeedModifierContactsComponent : Component
{
- [DataField("walkSpeedModifier"), ViewVariables(VVAccess.ReadWrite)]
- [AutoNetworkedField]
+ ///
+ /// The modifier applied to the walk speed of entities that come into contact with the entity this component is added to.
+ ///
+ [DataField, AutoNetworkedField]
public float WalkSpeedModifier = 1.0f;
- [AutoNetworkedField]
- [DataField("sprintSpeedModifier"), ViewVariables(VVAccess.ReadWrite)]
+ ///
+ /// The modifier applied to the sprint speed of entities that come into contact with the entity this component is added to.
+ ///
+ [DataField, AutoNetworkedField]
public float SprintSpeedModifier = 1.0f;
- [DataField("ignoreWhitelist")]
+ ///
+ /// Indicates whether this component affects the movement speed of airborne entities that come into contact with the entity this component is added to.
+ ///
+ [DataField, AutoNetworkedField]
+ public bool AffectAirborne;
+
+ ///
+ /// A whitelist of entities that should be ignored by this component's speed modifiers.
+ ///
+ [DataField]
public EntityWhitelist? IgnoreWhitelist;
}
diff --git a/Content.Shared/Movement/Systems/SpeedModifierContactsSystem.cs b/Content.Shared/Movement/Systems/SpeedModifierContactsSystem.cs
index 089fbbf924..e53a4351d1 100644
--- a/Content.Shared/Movement/Systems/SpeedModifierContactsSystem.cs
+++ b/Content.Shared/Movement/Systems/SpeedModifierContactsSystem.cs
@@ -1,6 +1,7 @@
using Content.Shared.Inventory;
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Events;
+using Content.Shared.Gravity;
using Content.Shared.Slippery;
using Content.Shared.Whitelist;
using Robust.Shared.Physics.Components;
@@ -12,6 +13,7 @@ namespace Content.Shared.Movement.Systems;
public sealed class SpeedModifierContactsSystem : EntitySystem
{
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
+ [Dependency] private readonly SharedGravitySystem _gravity = default!;
[Dependency] private readonly MovementSpeedModifierSystem _speedModifierSystem = default!;
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
@@ -84,6 +86,9 @@ public sealed class SpeedModifierContactsSystem : EntitySystem
var walkSpeed = 0.0f;
var sprintSpeed = 0.0f;
+ // Cache the result of the airborne check, as it's expensive and independent of contacting entities, hence need only be done once.
+ var isAirborne = physicsComponent.BodyStatus == BodyStatus.InAir || _gravity.IsWeightless(uid, physicsComponent);
+
bool remove = true;
var entries = 0;
foreach (var ent in _physics.GetContactingEntities(uid, physicsComponent))
@@ -95,6 +100,10 @@ public sealed class SpeedModifierContactsSystem : EntitySystem
if (_whitelistSystem.IsWhitelistPass(slowContactsComponent.IgnoreWhitelist, uid))
continue;
+ // Entities that are airborne should not be affected by contact slowdowns that are specified to not affect airborne entities.
+ if (isAirborne && !slowContactsComponent.AffectAirborne)
+ continue;
+
walkSpeed += slowContactsComponent.WalkSpeedModifier;
sprintSpeed += slowContactsComponent.SprintSpeedModifier;
speedModified = true;
diff --git a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml
index c688c7cadc..e35e915b09 100644
--- a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml
+++ b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml
@@ -15,6 +15,8 @@
- type: ActiveEdgeSpreader
- type: EdgeSpreader
id: Kudzu
+ - type: SpeedModifierContacts
+ affectAirborne: true
- type: entity
id: Kudzu