diff --git a/Content.Shared/Damage/Components/StaminaModifierComponent.cs b/Content.Shared/Damage/Components/StaminaModifierComponent.cs new file mode 100644 index 0000000000..f054c77f7b --- /dev/null +++ b/Content.Shared/Damage/Components/StaminaModifierComponent.cs @@ -0,0 +1,19 @@ +using Content.Shared.Damage.Systems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Damage.Components; + +/// +/// Multiplies the entity's by the . +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(StaminaSystem))] +public sealed partial class StaminaModifierComponent : Component +{ + /// + /// What to multiply max stamina by. + /// When added this scales max stamina, but not stamina damags to give you an extra boost of survability. + /// If you have too much damage when the modifier is removed, you suffer "withdrawl" and instantly stamcrit. + /// + [ViewVariables(VVAccess.ReadWrite), DataField("modifier"), AutoNetworkedField] + public float Modifier = 2f; +} diff --git a/Content.Shared/Damage/Systems/StaminaSystem.Modifier.cs b/Content.Shared/Damage/Systems/StaminaSystem.Modifier.cs new file mode 100644 index 0000000000..aadf5a9dee --- /dev/null +++ b/Content.Shared/Damage/Systems/StaminaSystem.Modifier.cs @@ -0,0 +1,52 @@ +using Content.Shared.Damage.Components; + +namespace Content.Shared.Damage.Systems; + +public sealed partial class StaminaSystem +{ + private void InitializeModifier() + { + SubscribeLocalEvent(OnModifierStartup); + SubscribeLocalEvent(OnModifierShutdown); + } + + private void OnModifierStartup(EntityUid uid, StaminaModifierComponent comp, ComponentStartup args) + { + if (!TryComp(uid, out var stamina)) + return; + + stamina.CritThreshold *= comp.Modifier; + } + + private void OnModifierShutdown(EntityUid uid, StaminaModifierComponent comp, ComponentShutdown args) + { + if (!TryComp(uid, out var stamina)) + return; + + stamina.CritThreshold /= comp.Modifier; + } + + /// + /// 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) + { + if (!Resolve(uid, ref comp)) + return; + + var old = comp.Modifier; + + if (old.Equals(modifier)) + return; + + comp.Modifier = modifier; + Dirty(uid, comp); + + if (Resolve(uid, ref stamina, false)) + { + // scale to the new threshold, act as if it was removed then added + stamina.CritThreshold *= modifier / old; + } + } +} diff --git a/Content.Shared/Damage/Systems/StaminaSystem.cs b/Content.Shared/Damage/Systems/StaminaSystem.cs index c0fa7a0bf6..439876d4cd 100644 --- a/Content.Shared/Damage/Systems/StaminaSystem.cs +++ b/Content.Shared/Damage/Systems/StaminaSystem.cs @@ -21,7 +21,7 @@ using Robust.Shared.Timing; namespace Content.Shared.Damage.Systems; -public sealed class StaminaSystem : EntitySystem +public sealed partial class StaminaSystem : EntitySystem { [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IRobustRandom _random = default!; @@ -41,6 +41,9 @@ public sealed class StaminaSystem : EntitySystem public override void Initialize() { base.Initialize(); + + InitializeModifier(); + SubscribeLocalEvent(OnStamUnpaused); SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnShutdown); @@ -48,6 +51,7 @@ public sealed class StaminaSystem : EntitySystem SubscribeLocalEvent(OnStamHandleState); SubscribeLocalEvent(OnDisarmed); SubscribeLocalEvent(OnRejuvenate); + SubscribeLocalEvent(OnCollide); SubscribeLocalEvent(OnHit); } diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml index 5939413208..110e17bae0 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml @@ -194,6 +194,7 @@ - ForcedSleep - TemporaryBlindness - Pacified + - StaminaModifier - type: ThermalRegulator metabolismHeat: 800 radiatedHeat: 100 diff --git a/Resources/Prototypes/Entities/Mobs/Species/base.yml b/Resources/Prototypes/Entities/Mobs/Species/base.yml index 3768718536..0fff8903ba 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/base.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/base.yml @@ -84,6 +84,7 @@ - ForcedSleep - TemporaryBlindness - Pacified + - StaminaModifier - type: Blindable # Other - type: Inventory diff --git a/Resources/Prototypes/Reagents/narcotics.yml b/Resources/Prototypes/Reagents/narcotics.yml index 2a4d304da7..77caafb647 100644 --- a/Resources/Prototypes/Reagents/narcotics.yml +++ b/Resources/Prototypes/Reagents/narcotics.yml @@ -124,6 +124,11 @@ key: KnockedDown time: 3 type: Remove + - !type:GenericStatusEffect + key: StaminaModifier + component: StaminaModifier + time: 3 + type: Add Medicine: metabolismRate: 1.0 effects: diff --git a/Resources/Prototypes/status_effects.yml b/Resources/Prototypes/status_effects.yml index b909baa0eb..a991bf4035 100644 --- a/Resources/Prototypes/status_effects.yml +++ b/Resources/Prototypes/status_effects.yml @@ -56,3 +56,6 @@ - type: statusEffect id: RatvarianLanguage #Praise him + +- type: statusEffect + id: StaminaModifier