Remove Contact Slowdown when Weightless or in the Air (#33299)

* removed contact slowdowns from entities that are weightless or in the air

* fixed kudzu not applying contact slowdown to airbone entities

* revert kudzu fix

* reimplemented kudzu fix with bool datafield

* update variable serialization format

Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>

* empty commit

* cleaned up and added documentation

* cached airborne check

* rerun tests

* minor review

---------

Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
Co-authored-by: Milon <milonpl.git@proton.me>
This commit is contained in:
Victor Shen
2025-04-28 17:24:12 -07:00
committed by GitHub
parent f7a8a1779e
commit 4671382419
3 changed files with 33 additions and 8 deletions

View File

@@ -4,19 +4,33 @@ using Robust.Shared.GameStates;
namespace Content.Shared.Movement.Components; namespace Content.Shared.Movement.Components;
[NetworkedComponent, RegisterComponent] /// <summary>
[AutoGenerateComponentState] /// Component that modifies the movement speed of other entities that come into contact with the entity this component is added to.
[Access(typeof(SpeedModifierContactsSystem))] /// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SpeedModifierContactsSystem))]
public sealed partial class SpeedModifierContactsComponent : Component public sealed partial class SpeedModifierContactsComponent : Component
{ {
[DataField("walkSpeedModifier"), ViewVariables(VVAccess.ReadWrite)] /// <summary>
[AutoNetworkedField] /// The modifier applied to the walk speed of entities that come into contact with the entity this component is added to.
/// </summary>
[DataField, AutoNetworkedField]
public float WalkSpeedModifier = 1.0f; public float WalkSpeedModifier = 1.0f;
[AutoNetworkedField] /// <summary>
[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.
/// </summary>
[DataField, AutoNetworkedField]
public float SprintSpeedModifier = 1.0f; public float SprintSpeedModifier = 1.0f;
[DataField("ignoreWhitelist")] /// <summary>
/// Indicates whether this component affects the movement speed of airborne entities that come into contact with the entity this component is added to.
/// </summary>
[DataField, AutoNetworkedField]
public bool AffectAirborne;
/// <summary>
/// A whitelist of entities that should be ignored by this component's speed modifiers.
/// </summary>
[DataField]
public EntityWhitelist? IgnoreWhitelist; public EntityWhitelist? IgnoreWhitelist;
} }

View File

@@ -1,6 +1,7 @@
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Content.Shared.Movement.Components; using Content.Shared.Movement.Components;
using Content.Shared.Movement.Events; using Content.Shared.Movement.Events;
using Content.Shared.Gravity;
using Content.Shared.Slippery; using Content.Shared.Slippery;
using Content.Shared.Whitelist; using Content.Shared.Whitelist;
using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Components;
@@ -12,6 +13,7 @@ namespace Content.Shared.Movement.Systems;
public sealed class SpeedModifierContactsSystem : EntitySystem public sealed class SpeedModifierContactsSystem : EntitySystem
{ {
[Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly SharedGravitySystem _gravity = default!;
[Dependency] private readonly MovementSpeedModifierSystem _speedModifierSystem = default!; [Dependency] private readonly MovementSpeedModifierSystem _speedModifierSystem = default!;
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
@@ -84,6 +86,9 @@ public sealed class SpeedModifierContactsSystem : EntitySystem
var walkSpeed = 0.0f; var walkSpeed = 0.0f;
var sprintSpeed = 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; bool remove = true;
var entries = 0; var entries = 0;
foreach (var ent in _physics.GetContactingEntities(uid, physicsComponent)) foreach (var ent in _physics.GetContactingEntities(uid, physicsComponent))
@@ -95,6 +100,10 @@ public sealed class SpeedModifierContactsSystem : EntitySystem
if (_whitelistSystem.IsWhitelistPass(slowContactsComponent.IgnoreWhitelist, uid)) if (_whitelistSystem.IsWhitelistPass(slowContactsComponent.IgnoreWhitelist, uid))
continue; 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; walkSpeed += slowContactsComponent.WalkSpeedModifier;
sprintSpeed += slowContactsComponent.SprintSpeedModifier; sprintSpeed += slowContactsComponent.SprintSpeedModifier;
speedModified = true; speedModified = true;

View File

@@ -15,6 +15,8 @@
- type: ActiveEdgeSpreader - type: ActiveEdgeSpreader
- type: EdgeSpreader - type: EdgeSpreader
id: Kudzu id: Kudzu
- type: SpeedModifierContacts
affectAirborne: true
- type: entity - type: entity
id: Kudzu id: Kudzu