From cf14cb3eb519a2d9f2cd7a64f102a7984f05dc08 Mon Sep 17 00:00:00 2001 From: BramvanZijp <56019239+BramvanZijp@users.noreply.github.com> Date: Mon, 14 Apr 2025 17:27:26 +0200 Subject: [PATCH] The long overdue downfall of stun meta - Stamina resists on Nukie & ERT Suits. (#35580) * Add stamina damage resistance * Probably starting a civil war within the community. * Tweak some values, my chart was outdated. * Tone down the values * Allow a way to bypass the resistances, which forks downstream can use. * Apply suggestions from code review Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Comment out the changes to non-deathsquad suits. * minor text fix e * review --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Co-authored-by: SlamBamActionman Co-authored-by: Milon --- .../Components/StaminaResistanceComponent.cs | 38 +++++++++++++++++++ .../Damage/Events/BeforeStaminaDamageEvent.cs | 12 ++++++ .../Damage/Systems/SharedGodmodeSystem.cs | 1 + .../Systems/StaminaSystem.Resistance.cs | 38 +++++++++++++++++++ .../Damage/Systems/StaminaSystem.cs | 15 ++++---- .../Inventory/InventorySystem.Relay.cs | 2 + Resources/Locale/en-US/damage/stamina.ftl | 1 + .../Entities/Clothing/OuterClothing/armor.yml | 2 + .../Clothing/OuterClothing/hardsuits.yml | 10 +++++ 9 files changed, 112 insertions(+), 7 deletions(-) create mode 100644 Content.Shared/Damage/Components/StaminaResistanceComponent.cs create mode 100644 Content.Shared/Damage/Events/BeforeStaminaDamageEvent.cs create mode 100644 Content.Shared/Damage/Systems/StaminaSystem.Resistance.cs diff --git a/Content.Shared/Damage/Components/StaminaResistanceComponent.cs b/Content.Shared/Damage/Components/StaminaResistanceComponent.cs new file mode 100644 index 0000000000..1a0db54492 --- /dev/null +++ b/Content.Shared/Damage/Components/StaminaResistanceComponent.cs @@ -0,0 +1,38 @@ +using Content.Shared.Damage.Systems; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary; +using Robust.Shared.GameStates; + +namespace Content.Shared.Damage.Components; + +/// +/// Component that provides entities with stamina resistance. +/// By default this is applied when worn, but to solely protect the entity itself and +/// not the wearer use worn: false. +/// +/// +/// This is desirable over just using damage modifier sets, given that equipment like bomb-suits need to +/// significantly reduce the damage, but shouldn't be silly overpowered in regular combat. +/// +[NetworkedComponent, RegisterComponent, AutoGenerateComponentState] +public sealed partial class StaminaResistanceComponent : Component +{ + /// + /// The stamina resistance coefficient, This fraction is multiplied into the total resistance. + /// + [DataField, AutoNetworkedField] + public float DamageCoefficient = 1; + + /// + /// When true, resistances will be applied to the entity wearing this item. + /// When false, only this entity will get the resistance. + /// + [DataField] + public bool Worn = true; + + /// + /// Examine string for stamina resistance. + /// Passed value from 0 to 100. + /// + [DataField] + public LocId Examine = "stamina-resistance-coefficient-value"; +} diff --git a/Content.Shared/Damage/Events/BeforeStaminaDamageEvent.cs b/Content.Shared/Damage/Events/BeforeStaminaDamageEvent.cs new file mode 100644 index 0000000000..6992ad83a5 --- /dev/null +++ b/Content.Shared/Damage/Events/BeforeStaminaDamageEvent.cs @@ -0,0 +1,12 @@ +using Content.Shared.Inventory; + +namespace Content.Shared.Damage.Events; + +/// +/// Raised before stamina damage is dealt to allow other systems to cancel or modify it. +/// +[ByRefEvent] +public record struct BeforeStaminaDamageEvent(float Value, bool Cancelled = false) : IInventoryRelayEvent +{ + SlotFlags IInventoryRelayEvent.TargetSlots => ~SlotFlags.POCKET; +} diff --git a/Content.Shared/Damage/Systems/SharedGodmodeSystem.cs b/Content.Shared/Damage/Systems/SharedGodmodeSystem.cs index 20e29ef434..4ccc56dcb8 100644 --- a/Content.Shared/Damage/Systems/SharedGodmodeSystem.cs +++ b/Content.Shared/Damage/Systems/SharedGodmodeSystem.cs @@ -1,4 +1,5 @@ using Content.Shared.Damage.Components; +using Content.Shared.Damage.Events; using Content.Shared.Rejuvenate; using Content.Shared.Slippery; using Content.Shared.StatusEffect; diff --git a/Content.Shared/Damage/Systems/StaminaSystem.Resistance.cs b/Content.Shared/Damage/Systems/StaminaSystem.Resistance.cs new file mode 100644 index 0000000000..9ad09b8f2f --- /dev/null +++ b/Content.Shared/Damage/Systems/StaminaSystem.Resistance.cs @@ -0,0 +1,38 @@ +using Content.Shared.Armor; +using Content.Shared.Damage.Components; +using Content.Shared.Damage.Events; +using Content.Shared.Inventory; + +namespace Content.Shared.Damage.Systems; + +public sealed partial class StaminaSystem +{ + private void InitializeResistance() + { + SubscribeLocalEvent(OnGetResistance); + SubscribeLocalEvent>(RelayedResistance); + SubscribeLocalEvent(OnArmorExamine); + } + + private void OnGetResistance(Entity ent, ref BeforeStaminaDamageEvent args) + { + args.Value *= ent.Comp.DamageCoefficient; + } + + private void RelayedResistance(Entity ent, ref InventoryRelayedEvent args) + { + if (ent.Comp.Worn) + OnGetResistance(ent, ref args.Args); + } + + private void OnArmorExamine(Entity ent, ref ArmorExamineEvent args) + { + var value = MathF.Round((1f - ent.Comp.DamageCoefficient) * 100, 1); + + if (value == 0) + return; + + args.Msg.PushNewline(); + args.Msg.AddMarkupOrThrow(Loc.GetString(ent.Comp.Examine, ("value", value))); + } +} diff --git a/Content.Shared/Damage/Systems/StaminaSystem.cs b/Content.Shared/Damage/Systems/StaminaSystem.cs index d897a363d4..bd84b711e3 100644 --- a/Content.Shared/Damage/Systems/StaminaSystem.cs +++ b/Content.Shared/Damage/Systems/StaminaSystem.cs @@ -50,6 +50,7 @@ public sealed partial class StaminaSystem : EntitySystem base.Initialize(); InitializeModifier(); + InitializeResistance(); SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnShutdown); @@ -240,7 +241,7 @@ public sealed partial class StaminaSystem : EntitySystem } public void TakeStaminaDamage(EntityUid uid, float value, StaminaComponent? component = null, - EntityUid? source = null, EntityUid? with = null, bool visual = true, SoundSpecifier? sound = null) + EntityUid? source = null, EntityUid? with = null, bool visual = true, SoundSpecifier? sound = null, bool ignoreResist = false) { if (!Resolve(uid, ref component, false)) return; @@ -250,6 +251,12 @@ public sealed partial class StaminaSystem : EntitySystem if (ev.Cancelled) return; + // Allow stamina resistance to be applied. + if (!ignoreResist) + { + value = ev.Value; + } + value = UniversalStaminaDamageModifier * value; // Have we already reached the point of max stamina damage? @@ -399,9 +406,3 @@ public sealed partial class StaminaSystem : EntitySystem _adminLogger.Add(LogType.Stamina, LogImpact.Low, $"{ToPrettyString(uid):user} recovered from stamina crit"); } } - -/// -/// Raised before stamina damage is dealt to allow other systems to cancel it. -/// -[ByRefEvent] -public record struct BeforeStaminaDamageEvent(float Value, bool Cancelled = false); diff --git a/Content.Shared/Inventory/InventorySystem.Relay.cs b/Content.Shared/Inventory/InventorySystem.Relay.cs index 8fac406eb5..efa88fb23a 100644 --- a/Content.Shared/Inventory/InventorySystem.Relay.cs +++ b/Content.Shared/Inventory/InventorySystem.Relay.cs @@ -5,6 +5,7 @@ using Content.Shared.Chemistry; using Content.Shared.Chemistry.Hypospray.Events; using Content.Shared.Climbing.Events; using Content.Shared.Damage; +using Content.Shared.Damage.Events; using Content.Shared.Electrocution; using Content.Shared.Explosion; using Content.Shared.Eye.Blinding.Systems; @@ -45,6 +46,7 @@ public partial class InventorySystem SubscribeLocalEvent(RelayInventoryEvent); // by-ref events + SubscribeLocalEvent(RefRelayInventoryEvent); SubscribeLocalEvent(RefRelayInventoryEvent); SubscribeLocalEvent(RefRelayInventoryEvent); SubscribeLocalEvent(RefRelayInventoryEvent); diff --git a/Resources/Locale/en-US/damage/stamina.ftl b/Resources/Locale/en-US/damage/stamina.ftl index da817824aa..cbda507865 100644 --- a/Resources/Locale/en-US/damage/stamina.ftl +++ b/Resources/Locale/en-US/damage/stamina.ftl @@ -1,2 +1,3 @@ melee-stamina = Not enough stamina slow-on-damage-modifier-examine = Slowness from injuries is reduced by [color=yellow]{$mod}%[/color] +stamina-resistance-coefficient-value = - [color=lightyellow]Stamina[/color] damage reduced by [color=lightblue]{$value}%[/color]. diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml index 7835ace80f..acb44c8ad8 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml @@ -130,6 +130,8 @@ Caustic: 0.5 - type: ExplosionResistance damageCoefficient: 0.35 + #- type: StaminaResistance + # damageCoefficient: 0.45 - type: ClothingSpeedModifier walkModifier: 0.9 sprintModifier: 0.9 diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml index 6c2a671446..71eef999cf 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml @@ -533,6 +533,8 @@ lowPressureMultiplier: 1000 - type: ExplosionResistance damageCoefficient: 0.5 + #- type: StaminaResistance + # damageCoefficient: 0.75 - type: Armor modifiers: coefficients: @@ -593,6 +595,8 @@ damageCoefficient: 0.2 - type: FireProtection reduction: 0.8 + #- type: StaminaResistance + # damageCoefficient: 0.6 - type: Armor modifiers: coefficients: @@ -627,6 +631,8 @@ lowPressureMultiplier: 1000 - type: ExplosionResistance damageCoefficient: 0.5 + #- type: StaminaResistance + # damageCoefficient: 0.6 - type: Armor modifiers: coefficients: @@ -659,6 +665,8 @@ lowPressureMultiplier: 1000 - type: ExplosionResistance damageCoefficient: 0.3 + #- type: StaminaResistance # Should not have stamina resistance, this is purely so people know it was not forgotten. + # damageCoefficient: 0.99 - type: Armor modifiers: coefficients: @@ -912,6 +920,8 @@ damageCoefficient: 0.2 - type: FireProtection reduction: 0.8 + - type: StaminaResistance + damageCoefficient: 0.15 # Needs 21 hits with a disabler to stun :godo: - type: Armor modifiers: coefficients: -- 2.51.2