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