From: Mora <46364955+TrixxedHeart@users.noreply.github.com> Date: Thu, 21 Aug 2025 00:43:06 +0000 (-0800) Subject: Impaired Mobility Disability (#39398) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=cd0cc721576a6db7905b1c25709c002f9f1bc7ef;p=space-station-14.git Impaired Mobility Disability (#39398) * Implements mobility impairment * Implements mobility impairment * Implements mobility impairment * Removed white cane related stuff (impaired cane replacement and removed mobility aid component) * fix development.toml * Implements slower standing * Prevent speed stacking by checking if the entity is already holding a mobility aid * Move all speed handling into ImpairedMobilitySystem, added comments, made it so wielding a mobility aid doesn't grant the recovery benefit * Move all speed handling into ImpairedMobilitySystem, added comments, made it so wielding a mobility aid doesn't grant the recovery benefit * remove unused file * Shorten description * Apply suggestions Co-authored-by: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> * Suggestion cleanup * formatting fix and removed extra datafield stuff * added comment, fixed slashes, yadda yadda * summary comments * removed a word * Add trait to clone whitelist * Fix clone.yml * my own review --------- Co-authored-by: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Co-authored-by: ScarKy0 --- diff --git a/Content.Shared/Traits/Assorted/ImpairedMobilityComponent.cs b/Content.Shared/Traits/Assorted/ImpairedMobilityComponent.cs new file mode 100644 index 0000000000..50f7281ff8 --- /dev/null +++ b/Content.Shared/Traits/Assorted/ImpairedMobilityComponent.cs @@ -0,0 +1,25 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Traits.Assorted; + +/// +/// Used for the Impaired Mobility disability trait. +/// Applies a base movement speed reduction as determined by the SpeedModifier field. +/// Also increases the time it takes to stand up after falling, as determined by the StandUpTimeModifier field. +/// When an entity holds an item with the MobilityAidComponent, the speed penalty is nullified. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class ImpairedMobilityComponent : Component +{ + /// + /// The movement speed modifier applied to the player (0.4 is 40% slower) + /// + [DataField, AutoNetworkedField] + public float SpeedModifier = 0.4f; + + /// + /// The doAfter modifier when getting up after falling (1.4 is 40% slower) + /// + [DataField, AutoNetworkedField] + public float StandUpTimeModifier = 1.4f; +} diff --git a/Content.Shared/Traits/Assorted/ImpairedMobilitySystem.cs b/Content.Shared/Traits/Assorted/ImpairedMobilitySystem.cs new file mode 100644 index 0000000000..678fc85344 --- /dev/null +++ b/Content.Shared/Traits/Assorted/ImpairedMobilitySystem.cs @@ -0,0 +1,70 @@ +using Content.Shared.Movement.Systems; +using Content.Shared.Stunnable; +using Content.Shared.Hands.EntitySystems; +using Content.Shared.Hands.Components; +using Content.Shared.Wieldable.Components; + +namespace Content.Shared.Traits.Assorted; + +/// +/// Handles +/// +public sealed class ImpairedMobilitySystem : EntitySystem +{ + [Dependency] private readonly SharedHandsSystem _hands = default!; + [Dependency] private readonly MovementSpeedModifierSystem _speedModifier = default!; + public override void Initialize() + { + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnShutdown); + SubscribeLocalEvent(OnRefreshMovementSpeed); + SubscribeLocalEvent(OnGetStandUpTime); + } + + private void OnInit(Entity ent, ref ComponentInit args) + { + _speedModifier.RefreshMovementSpeedModifiers(ent); + } + + private void OnShutdown(Entity ent, ref ComponentShutdown args) + { + _speedModifier.RefreshMovementSpeedModifiers(ent); + } + + // Handles movement speed for entities with impaired mobility. + // Applies a speed penalty, but counteracts it if the entity is holding a non-wielded mobility aid. + private void OnRefreshMovementSpeed(Entity ent, ref RefreshMovementSpeedModifiersEvent args) + { + if (HasMobilityAid(ent.Owner)) + return; + + args.ModifySpeed(ent.Comp.SpeedModifier); + } + + // Increases the time it takes for entities to stand up from being knocked down. + private void OnGetStandUpTime(Entity ent, ref GetStandUpTimeEvent args) + { + args.DoAfterTime *= ent.Comp.StandUpTimeModifier; + } + + // Checks if the entity is holding any non-wielded mobility aids. + private bool HasMobilityAid(Entity entity) + { + if (!Resolve(entity, ref entity.Comp, false)) + return false; + + foreach (var held in _hands.EnumerateHeld(entity)) + { + if (!HasComp(held)) + continue; + + // Makes sure it's not wielded yet + if (TryComp(held, out var wieldable) && wieldable.Wielded) + continue; + + return true; + } + + return false; + } +} diff --git a/Content.Shared/Traits/Assorted/MobilityAidComponent.cs b/Content.Shared/Traits/Assorted/MobilityAidComponent.cs new file mode 100644 index 0000000000..6623c8217a --- /dev/null +++ b/Content.Shared/Traits/Assorted/MobilityAidComponent.cs @@ -0,0 +1,11 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Traits.Assorted; + +/// +/// Component to mark items that restore normal movement speed when held in-hand for entities with the impaired mobility trait. +/// The speed is automatically calculated to nullify the entity's speed penalty. +/// Should be used on items that act as mobility aids, such as canes. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class MobilityAidComponent : Component; diff --git a/Content.Shared/Traits/Assorted/MobilityAidSystem.cs b/Content.Shared/Traits/Assorted/MobilityAidSystem.cs new file mode 100644 index 0000000000..7df47ca750 --- /dev/null +++ b/Content.Shared/Traits/Assorted/MobilityAidSystem.cs @@ -0,0 +1,42 @@ +using Content.Shared.Hands; +using Content.Shared.Movement.Systems; +using Content.Shared.Wieldable; + +namespace Content.Shared.Traits.Assorted; + +/// +/// Handles +/// +public sealed class MobilityAidSystem : EntitySystem +{ + [Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifier = default!; + + /// + public override void Initialize() + { + SubscribeLocalEvent(OnGotEquippedHand); + SubscribeLocalEvent(OnGotUnequippedHand); + SubscribeLocalEvent(OnMobilityAidWielded); + SubscribeLocalEvent(OnMobilityAidUnwielded); + } + + private void OnGotEquippedHand(Entity ent, ref GotEquippedHandEvent args) + { + _movementSpeedModifier.RefreshMovementSpeedModifiers(args.User); + } + + private void OnGotUnequippedHand(Entity ent, ref GotUnequippedHandEvent args) + { + _movementSpeedModifier.RefreshMovementSpeedModifiers(args.User); + } + + private void OnMobilityAidWielded(Entity ent, ref ItemWieldedEvent args) + { + _movementSpeedModifier.RefreshMovementSpeedModifiers(args.User); + } + + private void OnMobilityAidUnwielded(Entity ent, ref ItemUnwieldedEvent args) + { + _movementSpeedModifier.RefreshMovementSpeedModifiers(args.User); + } +} diff --git a/Resources/Locale/en-US/traits/traits.ftl b/Resources/Locale/en-US/traits/traits.ftl index d7ab6ca76a..f4c51d863e 100644 --- a/Resources/Locale/en-US/traits/traits.ftl +++ b/Resources/Locale/en-US/traits/traits.ftl @@ -65,3 +65,6 @@ trait-spanish-desc = Hola señor, donde esta la biblioteca. trait-painnumbness-name = Numb trait-painnumbness-desc = You lack any sense of feeling pain, being unaware of how hurt you may be. + +trait-impaired-mobility-name = Impaired Mobility +trait-impaired-mobility-desc = You have difficulty moving without a mobility aid. diff --git a/Resources/Prototypes/Entities/Mobs/Player/clone.yml b/Resources/Prototypes/Entities/Mobs/Player/clone.yml index 43174cfffe..98d99d7321 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/clone.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/clone.yml @@ -16,6 +16,7 @@ # traits - BlackAndWhiteOverlay - Clumsy + - ImpairedMobility # - LegsParalyzed (you get healed) - LightweightDrunk - Muted diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/cane.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/cane.yml index 29ce5fa8c8..96ad8b233d 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/cane.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/cane.yml @@ -11,6 +11,7 @@ size: Normal sprite: Objects/Weapons/Melee/cane.rsi - type: Appearance + - type: MobilityAid - type: MeleeWeapon wideAnimationRotation: 45 damage: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/offset_cane.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/offset_cane.yml index 1d2081fe93..12e2e9ae70 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/offset_cane.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/offset_cane.yml @@ -10,6 +10,7 @@ - type: Item size: Normal sprite: Objects/Weapons/Melee/offset_canes/standard.rsi + - type: MobilityAid # - type: RandomSprite # Ideally I'd rather these be their own selectable item instead of randomly picked. # available: # - color: "#91949C" # standard gray diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/white_cane.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/white_cane.yml index 997c3771d5..bba4085295 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/white_cane.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/white_cane.yml @@ -24,4 +24,3 @@ Blunt: 3 - type: UseDelay delay: 1 - diff --git a/Resources/Prototypes/Traits/disabilities.yml b/Resources/Prototypes/Traits/disabilities.yml index a5c1f54d6b..0bb6f0da3c 100644 --- a/Resources/Prototypes/Traits/disabilities.yml +++ b/Resources/Prototypes/Traits/disabilities.yml @@ -83,3 +83,12 @@ category: Disabilities components: - type: PainNumbness + +- type: trait + id: ImpairedMobility + name: trait-impaired-mobility-name + description: trait-impaired-mobility-desc + traitGear: OffsetCane + category: Disabilities + components: + - type: ImpairedMobility