From: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com> Date: Thu, 18 Dec 2025 19:41:08 +0000 (+0100) Subject: Make StaminaModifier into a status effect, apply to Hyperzine (#41902) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=bb95787af77cc9491998749a61806fa957d4cdcc;p=space-station-14.git Make StaminaModifier into a status effect, apply to Hyperzine (#41902) * Initial commit * Probably better this way. * Review fixes * cleanup --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- diff --git a/Content.Shared/Damage/Components/StaminaComponent.cs b/Content.Shared/Damage/Components/StaminaComponent.cs index 9875d31349..07429cbab7 100644 --- a/Content.Shared/Damage/Components/StaminaComponent.cs +++ b/Content.Shared/Damage/Components/StaminaComponent.cs @@ -39,9 +39,15 @@ public sealed partial class StaminaComponent : Component public float StaminaDamage; /// - /// How much stamina damage is required to enter stam crit. + /// The base stamina the entity requires to enter stam crit. Should rarely if ever be modified outside of yaml. /// - [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] + [DataField, AutoNetworkedField] + public float BaseCritThreshold = 100f; + + /// + /// Modified crit threshold for when an entity should enter stamcrit. + /// + [ViewVariables, AutoNetworkedField] public float CritThreshold = 100f; /// diff --git a/Content.Shared/Damage/Components/StaminaModifierComponent.cs b/Content.Shared/Damage/Components/StaminaModifierStatusEffectComponent.cs similarity index 90% rename from Content.Shared/Damage/Components/StaminaModifierComponent.cs rename to Content.Shared/Damage/Components/StaminaModifierStatusEffectComponent.cs index e492ea04ff..4ca888ffbe 100644 --- a/Content.Shared/Damage/Components/StaminaModifierComponent.cs +++ b/Content.Shared/Damage/Components/StaminaModifierStatusEffectComponent.cs @@ -7,7 +7,7 @@ namespace Content.Shared.Damage.Components; /// Multiplies the entity's by the . /// [RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SharedStaminaSystem))] -public sealed partial class StaminaModifierComponent : Component +public sealed partial class StaminaModifierStatusEffectComponent : Component { /// /// What to multiply max stamina by. diff --git a/Content.Shared/Damage/Events/RefreshStaminaCritThresholdEvent.cs b/Content.Shared/Damage/Events/RefreshStaminaCritThresholdEvent.cs new file mode 100644 index 0000000000..4ed86445e1 --- /dev/null +++ b/Content.Shared/Damage/Events/RefreshStaminaCritThresholdEvent.cs @@ -0,0 +1,18 @@ +using Content.Shared.Damage.Components; + +namespace Content.Shared.Damage.Events; + +/// +/// Raised whenever the needs to be refreshed. +/// +[ByRefEvent] +public record struct RefreshStaminaCritThresholdEvent +{ + public float ThresholdValue = 100f; + public float Modifier = 1f; + + public RefreshStaminaCritThresholdEvent(float thresholdValue) + { + ThresholdValue = thresholdValue; + } +} diff --git a/Content.Shared/Damage/Systems/SharedStaminaSystem.Modifier.cs b/Content.Shared/Damage/Systems/SharedStaminaSystem.Modifier.cs index c723d8cb94..8fcb4b8d1d 100644 --- a/Content.Shared/Damage/Systems/SharedStaminaSystem.Modifier.cs +++ b/Content.Shared/Damage/Systems/SharedStaminaSystem.Modifier.cs @@ -1,4 +1,6 @@ using Content.Shared.Damage.Components; +using Content.Shared.Damage.Events; +using Content.Shared.StatusEffectNew; namespace Content.Shared.Damage.Systems; @@ -6,47 +8,36 @@ public partial class SharedStaminaSystem { private void InitializeModifier() { - SubscribeLocalEvent(OnModifierStartup); - SubscribeLocalEvent(OnModifierShutdown); + SubscribeLocalEvent(OnEffectApplied); + SubscribeLocalEvent(OnEffectRemoved); + SubscribeLocalEvent>(OnRefreshCritThreshold); } - private void OnModifierStartup(EntityUid uid, StaminaModifierComponent comp, ComponentStartup args) + private void OnEffectApplied(Entity ent, ref StatusEffectAppliedEvent args) { - if (!TryComp(uid, out var stamina)) - return; - - stamina.CritThreshold *= comp.Modifier; + RefreshStaminaCritThreshold(args.Target); } - private void OnModifierShutdown(EntityUid uid, StaminaModifierComponent comp, ComponentShutdown args) + private void OnEffectRemoved(Entity ent, ref StatusEffectRemovedEvent args) { - if (!TryComp(uid, out var stamina)) - return; - - stamina.CritThreshold /= comp.Modifier; + RefreshStaminaCritThreshold(args.Target); } - /// - /// Change the stamina modifier for an entity. - /// If it has it will also be updated. - /// - public void SetModifier(EntityUid uid, float modifier, StaminaComponent? stamina = null, StaminaModifierComponent? comp = null) + private void OnRefreshCritThreshold(Entity ent, ref StatusEffectRelayedEvent args) { - if (!Resolve(uid, ref comp)) - return; - - var old = comp.Modifier; + var evArgs = args.Args; + evArgs.Modifier = Math.Max(ent.Comp.Modifier, evArgs.Modifier); // We only pick the highest value, to avoid stacking different status effects. + args.Args = evArgs; + } - if (old.Equals(modifier)) + public void RefreshStaminaCritThreshold(Entity entity) + { + if (!Resolve(entity, ref entity.Comp)) return; - comp.Modifier = modifier; - Dirty(uid, comp); + var ev = new RefreshStaminaCritThresholdEvent(entity.Comp.BaseCritThreshold); + RaiseLocalEvent(entity, ref ev); - if (Resolve(uid, ref stamina, false)) - { - // scale to the new threshold, act as if it was removed then added - stamina.CritThreshold *= modifier / old; - } + entity.Comp.CritThreshold = ev.ThresholdValue * ev.Modifier; } } diff --git a/Content.Shared/Damage/Systems/SharedStaminaSystem.cs b/Content.Shared/Damage/Systems/SharedStaminaSystem.cs index 045052d1fa..ca030d5e5d 100644 --- a/Content.Shared/Damage/Systems/SharedStaminaSystem.cs +++ b/Content.Shared/Damage/Systems/SharedStaminaSystem.cs @@ -99,6 +99,9 @@ public abstract partial class SharedStaminaSystem : EntitySystem private void OnStartup(Entity entity, ref ComponentStartup args) { + // Set the base threshold here since ModifiedCritThreshold can't be modified via yaml. + entity.Comp.CritThreshold = entity.Comp.BaseCritThreshold; + UpdateStaminaVisuals(entity); } diff --git a/Content.Shared/StatusEffectNew/StatusEffectSystem.Relay.cs b/Content.Shared/StatusEffectNew/StatusEffectSystem.Relay.cs index 30c5d9f67e..cafe5075c9 100644 --- a/Content.Shared/StatusEffectNew/StatusEffectSystem.Relay.cs +++ b/Content.Shared/StatusEffectNew/StatusEffectSystem.Relay.cs @@ -27,6 +27,7 @@ public sealed partial class StatusEffectsSystem SubscribeLocalEvent(RefRelayStatusEffectEvent); SubscribeLocalEvent(RefRelayStatusEffectEvent); + SubscribeLocalEvent(RefRelayStatusEffectEvent); SubscribeLocalEvent(RelayStatusEffectEvent); SubscribeLocalEvent(RelayStatusEffectEvent); diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 05a72b3b33..3685f891b6 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -115,7 +115,7 @@ 0: Alive 10: Dead - type: Stamina - critThreshold: 10 + baseCritThreshold: 10 animationThreshold: 1 - type: DamageStateVisuals states: @@ -1889,7 +1889,7 @@ types: Piercing: 0 - type: Bloodstream - bloodReferenceSolution: + bloodReferenceSolution: reagents: - ReagentId: Blood Quantity: 50 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml index c0ea417663..1547e36339 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml @@ -44,7 +44,7 @@ baseWalkSpeed: 2.5 baseSprintSpeed: 3.5 - type: Stamina - critThreshold: 100 + baseCritThreshold: 100 - type: DamageStateVisuals states: Alive: @@ -233,7 +233,7 @@ 0: Alive 82: Dead # Might seem random, but this brings up the hits to kill with a crusher mark to 3 - type: Stamina - critThreshold: 150 + baseCritThreshold: 150 - type: DamageStateVisuals states: Alive: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/elemental.yml b/Resources/Prototypes/Entities/Mobs/NPCs/elemental.yml index b430689361..e9f0c4a8ef 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/elemental.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/elemental.yml @@ -28,7 +28,7 @@ 0: Alive 120: Dead - type: Stamina - critThreshold: 120 + baseCritThreshold: 120 - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/flesh.yml b/Resources/Prototypes/Entities/Mobs/NPCs/flesh.yml index 75f0aa83b8..c32a9d3d0b 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/flesh.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/flesh.yml @@ -41,7 +41,7 @@ 0: Alive 75: Dead - type: Stamina - critThreshold: 50 + baseCritThreshold: 50 animationThreshold: 25 - type: Butcherable spawned: @@ -243,7 +243,7 @@ 0: Alive 75: Dead - type: Stamina - critThreshold: 50 + baseCritThreshold: 50 animationThreshold: 25 - type: Butcherable spawned: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/living_light.yml b/Resources/Prototypes/Entities/Mobs/NPCs/living_light.yml index 13eeb2b372..d080f8c45f 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/living_light.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/living_light.yml @@ -50,7 +50,6 @@ allowed: - Corporeal - Electrocution - - StaminaModifier - type: Fixtures fixtures: fix1: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml index 1de449a215..3e0edee084 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml @@ -241,7 +241,7 @@ - !type:GibBehavior recursive: false - type: Stamina - critThreshold: 60 + baseCritThreshold: 60 - type: MeleeWeapon soundHit: path: /Audio/Weapons/bladeslice.ogg diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml index a538243192..7c9f3ca95c 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml @@ -82,7 +82,7 @@ baseWalkSpeed : 3 baseSprintSpeed : 4 - type: Stamina - critThreshold: 120 + baseCritThreshold: 120 - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml index d0ea13f26e..906675045b 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml @@ -96,7 +96,6 @@ - Electrocution - TemporaryBlindness - Pacified - - StaminaModifier - Flashed - RadiationProtection - Adrenaline diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml index d052728379..7a51d257ef 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml @@ -36,7 +36,7 @@ 0: Alive 80: Dead - type: Stamina - critThreshold: 150 + baseCritThreshold: 150 - type: MovementAlwaysTouching - type: Bloodstream bloodReferenceSolution: @@ -157,7 +157,7 @@ Dead: Base: kangaroo-space-dead - type: Stamina - critThreshold: 180 + baseCritThreshold: 180 - type: Inventory speciesId: kangaroo templateId: spacekangaroo @@ -202,7 +202,7 @@ 0: Alive 45: Dead - type: Stamina - critThreshold: 150 + baseCritThreshold: 150 - type: DamageStateVisuals states: Alive: @@ -305,7 +305,7 @@ 0: Alive 45: Dead - type: Stamina - critThreshold: 150 + baseCritThreshold: 150 - type: DamageStateVisuals states: Alive: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml b/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml index 780c4b0330..653704cfbb 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml @@ -52,7 +52,7 @@ - !type:GibBehavior recursive: false - type: Stamina - critThreshold: 15 + baseCritThreshold: 15 animationThreshold: 5 - type: MovementAlwaysTouching - type: DamageStateVisuals diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml index 247d7636e5..58e0088828 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml @@ -65,7 +65,7 @@ speedModifierThresholds: 25: 0.5 - type: Stamina - critThreshold: 200 + baseCritThreshold: 200 - type: Bloodstream bloodReferenceSolution: reagents: @@ -138,7 +138,7 @@ 0: Alive 100: Dead - type: Stamina - critThreshold: 300 + baseCritThreshold: 300 - type: SlowOnDamage speedModifierThresholds: 50: 0.7 @@ -492,7 +492,7 @@ - type: ComplexInteraction - type: MobState - type: Stamina - critThreshold: 200 + baseCritThreshold: 200 - type: Bloodstream bloodReferenceSolution: reagents: diff --git a/Resources/Prototypes/Entities/Mobs/Species/base.yml b/Resources/Prototypes/Entities/Mobs/Species/base.yml index f33cee8b20..a0ace57c47 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/base.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/base.yml @@ -127,7 +127,6 @@ - Muted - TemporaryBlindness - Pacified - - StaminaModifier - Flashed - RadiationProtection - Adrenaline diff --git a/Resources/Prototypes/Entities/StatusEffects/body.yml b/Resources/Prototypes/Entities/StatusEffects/body.yml index 739c9c3b22..7c7d5fc68c 100644 --- a/Resources/Prototypes/Entities/StatusEffects/body.yml +++ b/Resources/Prototypes/Entities/StatusEffects/body.yml @@ -62,3 +62,26 @@ parent: [ PainNumbnessTraitStatusEffect, MobStatusEffectDebuff ] id: StatusEffectPainNumbness name: pain numbness + +- type: entity + parent: MobStatusEffectBase + id: StaminaModifierStatusEffect + components: + - type: StatusEffect + whitelist: + components: + - Stamina + - type: StaminaModifierStatusEffect + +- type: entity + parent: StaminaModifierStatusEffect + name: 2x max stamina + id: StatusEffectDesoxyStamina + +- type: entity + parent: StaminaModifierStatusEffect + id: StatusEffectStimulantsStamina + name: 1.5x max stamina + components: + - type: StaminaModifierStatusEffect + modifier: 1.5 diff --git a/Resources/Prototypes/Reagents/narcotics.yml b/Resources/Prototypes/Reagents/narcotics.yml index aaaa62916c..7ad463bfcc 100644 --- a/Resources/Prototypes/Reagents/narcotics.yml +++ b/Resources/Prototypes/Reagents/narcotics.yml @@ -34,9 +34,8 @@ - !type:MovementSpeedModifier walkSpeedModifier: 1.20 sprintSpeedModifier: 1.20 - - !type:GenericStatusEffect - key: StaminaModifier # You are on meth. You keep going. - component: StaminaModifier + - !type:ModifyStatusEffect + effectProto: StatusEffectDesoxyStamina # You are on meth. You keep going. time: 3 - !type:GenericStatusEffect key: Adrenaline @@ -145,6 +144,9 @@ - !type:MovementSpeedModifier walkSpeedModifier: 1.25 sprintSpeedModifier: 1.25 + - !type:ModifyStatusEffect + effectProto: StatusEffectStimulantsStamina # You are on meth. You keep going. + time: 3 - !type:ModifyStatusEffect effectProto: StatusEffectStunned time: 3.5 diff --git a/Resources/Prototypes/status_effects.yml b/Resources/Prototypes/status_effects.yml index 8ae32928a3..a48758716c 100644 --- a/Resources/Prototypes/status_effects.yml +++ b/Resources/Prototypes/status_effects.yml @@ -50,9 +50,6 @@ - type: statusEffect id: RatvarianLanguage #Praise him -- type: statusEffect - id: StaminaModifier - - type: statusEffect id: Flashed