From: āda Date: Mon, 19 May 2025 18:23:38 +0000 (-0500) Subject: Pepper makes you cough (#36358) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=41a129e74919fe67fbb6529a13359328cf6884ef;p=space-station-14.git Pepper makes you cough (#36358) --- diff --git a/Content.Server/Body/Systems/RespiratorSystem.cs b/Content.Server/Body/Systems/RespiratorSystem.cs index 6209f00419..bebf92f977 100644 --- a/Content.Server/Body/Systems/RespiratorSystem.cs +++ b/Content.Server/Body/Systems/RespiratorSystem.cs @@ -173,6 +173,20 @@ public sealed class RespiratorSystem : EntitySystem _atmosSys.Merge(ev.Gas, outGas); } + /// + /// Returns true if the entity is above their SuffocationThreshold and alive. + /// + public bool IsBreathing(Entity ent) + { + if (_mobState.IsIncapacitated(ent)) + return false; + + if (!Resolve(ent, ref ent.Comp)) + return false; + + return (ent.Comp.Saturation > ent.Comp.SuffocationThreshold); + } + /// /// Check whether or not an entity can metabolize inhaled air without suffocating or taking damage (i.e., no toxic /// gasses). diff --git a/Content.Server/EntityEffects/EffectConditions/BreathingCondition.cs b/Content.Server/EntityEffects/EffectConditions/BreathingCondition.cs new file mode 100644 index 0000000000..d87e686f2b --- /dev/null +++ b/Content.Server/EntityEffects/EffectConditions/BreathingCondition.cs @@ -0,0 +1,33 @@ +using Content.Server.Body.Components; +using Content.Server.Body.Systems; +using Content.Shared.EntityEffects; +using Robust.Shared.Prototypes; + +namespace Content.Server.EntityEffects.EffectConditions; + +/// +/// Condition for if the entity is successfully breathing. +/// +public sealed partial class Breathing : EntityEffectCondition +{ + /// + /// If true, the entity must not have trouble breathing to pass. + /// + [DataField] + public bool IsBreathing = true; + + public override bool Condition(EntityEffectBaseArgs args) + { + if (!args.EntityManager.TryGetComponent(args.TargetEntity, out RespiratorComponent? respiratorComp)) + return !IsBreathing; // They do not breathe. + + var breathingState = args.EntityManager.System().IsBreathing((args.TargetEntity, respiratorComp)); + return IsBreathing == breathingState; + } + + public override string GuidebookExplanation(IPrototypeManager prototype) + { + return Loc.GetString("reagent-effect-condition-guidebook-breathing", + ("isBreathing", IsBreathing)); + } +} diff --git a/Content.Server/EntityEffects/EffectConditions/InternalsCondition.cs b/Content.Server/EntityEffects/EffectConditions/InternalsCondition.cs new file mode 100644 index 0000000000..1bc5b26cfb --- /dev/null +++ b/Content.Server/EntityEffects/EffectConditions/InternalsCondition.cs @@ -0,0 +1,31 @@ +using Content.Shared.Body.Components; +using Content.Shared.EntityEffects; +using Robust.Shared.Prototypes; + +namespace Content.Server.EntityEffects.EffectConditions; + +/// +/// Condition for if the entity is or isn't wearing internals. +/// +public sealed partial class Internals : EntityEffectCondition +{ + /// + /// To pass, the entity's internals must have this same state. + /// + [DataField] + public bool UsingInternals = true; + + public override bool Condition(EntityEffectBaseArgs args) + { + if (!args.EntityManager.TryGetComponent(args.TargetEntity, out InternalsComponent? internalsComp)) + return !UsingInternals; // They have no internals to wear. + + var internalsState = internalsComp.GasTankEntity == null; + return UsingInternals == internalsState; + } + + public override string GuidebookExplanation(IPrototypeManager prototype) + { + return Loc.GetString("reagent-effect-condition-guidebook-internals", ("usingInternals", UsingInternals)); + } +} diff --git a/Content.Server/EntityEffects/Effects/Emote.cs b/Content.Server/EntityEffects/Effects/Emote.cs index 00bdaec455..227e60a175 100644 --- a/Content.Server/EntityEffects/Effects/Emote.cs +++ b/Content.Server/EntityEffects/Effects/Emote.cs @@ -8,34 +8,49 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototy namespace Content.Server.EntityEffects.Effects; /// -/// Tries to force someone to emote (scream, laugh, etc). Still respects whitelists/blacklists and other limits of the specified emote unless forced. +/// Tries to force someone to emote (scream, laugh, etc). Still respects whitelists/blacklists and other limits unless specially forced. /// [UsedImplicitly] public sealed partial class Emote : EntityEffect { - [DataField("emote", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string? EmoteId; - + /// + /// The emote the entity will preform. + /// + [DataField("emote", required: true, customTypeSerializer: typeof(PrototypeIdSerializer))] + public string EmoteId; + + /// + /// If the emote should be recorded in chat. + /// [DataField] public bool ShowInChat; + /// + /// If the forced emote will be listed in the guidebook. + /// + [DataField] + public bool ShowInGuidebook; + + /// + /// If true, the entity will preform the emote even if they normally can't. + /// [DataField] public bool Force = false; - // JUSTIFICATION: Emoting is flavor, so same reason popup messages are not in here. protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) - => null; + { + if (!ShowInGuidebook) + return null; // JUSTIFICATION: Emoting is mostly flavor, so same reason popup messages are not in here. + + return Loc.GetString("reagent-effect-guidebook-emote", ("chance", Probability), ("emote", EmoteId)); + } public override void Effect(EntityEffectBaseArgs args) { - if (EmoteId == null) - return; - var chatSys = args.EntityManager.System(); if (ShowInChat) chatSys.TryEmoteWithChat(args.TargetEntity, EmoteId, ChatTransmitRange.GhostRangeLimit, forceEmote: Force); else chatSys.TryEmoteWithoutChat(args.TargetEntity, EmoteId); - } } diff --git a/Resources/Locale/en-US/guidebook/chemistry/conditions.ftl b/Resources/Locale/en-US/guidebook/chemistry/conditions.ftl index 95aaf9126d..fe31dd62f8 100644 --- a/Resources/Locale/en-US/guidebook/chemistry/conditions.ftl +++ b/Resources/Locale/en-US/guidebook/chemistry/conditions.ftl @@ -62,3 +62,15 @@ reagent-effect-condition-guidebook-has-tag = } the tag {$tag} reagent-effect-condition-guidebook-this-reagent = this reagent + +reagent-effect-condition-guidebook-breathing = + the metabolizer is { $isBreathing -> + [true] breathing normally + *[false] suffocating + } + +reagent-effect-condition-guidebook-internals = + the metabolizer is { $usingInternals -> + [true] using internals + *[false] breathing atmospheric air + } diff --git a/Resources/Locale/en-US/guidebook/chemistry/effects.ftl b/Resources/Locale/en-US/guidebook/chemistry/effects.ftl index ba6ae96c82..a5ddb03f0a 100644 --- a/Resources/Locale/en-US/guidebook/chemistry/effects.ftl +++ b/Resources/Locale/en-US/guidebook/chemistry/effects.ftl @@ -258,6 +258,12 @@ reagent-effect-guidebook-electrocute = *[other] electrocute } the metabolizer for {NATURALFIXED($time, 3)} {MANY("second", $time)} +reagent-effect-guidebook-emote = + { $chance -> + [1] Will force + *[other] force + } the metabolizer to [bold][color=white]{$emote}[/color][/bold] + reagent-effect-guidebook-extinguish-reaction = { $chance -> [1] Extinguishes diff --git a/Resources/Prototypes/Reagents/Consumable/Food/ingredients.yml b/Resources/Prototypes/Reagents/Consumable/Food/ingredients.yml index d2cf44e6d6..6e4114cecf 100644 --- a/Resources/Prototypes/Reagents/Consumable/Food/ingredients.yml +++ b/Resources/Prototypes/Reagents/Consumable/Food/ingredients.yml @@ -104,6 +104,25 @@ flavor: peppery color: black recognizable: true + metabolisms: + Food: + effects: + - !type:Emote + emote: Cough + showInChat: true + showInGuidebook: true + probability: 0.05 + reactiveEffects: + Acidic: + methods: [ Touch ] + effects: + - !type:Emote + emote: Cough + showInGuidebook: true + conditions: + - !type:Breathing + - !type:Internals + usingInternals: false - type: reagent id: Vinegar diff --git a/Resources/Prototypes/Reagents/fun.yml b/Resources/Prototypes/Reagents/fun.yml index adbf202c7e..df02839940 100644 --- a/Resources/Prototypes/Reagents/fun.yml +++ b/Resources/Prototypes/Reagents/fun.yml @@ -314,6 +314,7 @@ effects: - !type:Emote emote: Laugh + showInGuidebook: true probability: 0.3 - !type:PopupMessage type: Local @@ -336,6 +337,7 @@ - !type:Emote emote: Weh showInChat: true + showInGuidebook: true force: true probability: 0.5 - !type:Polymorph @@ -368,6 +370,7 @@ - !type:Emote emote: Hew showInChat: true + showInGuidebook: true force: true probability: 0.5 - !type:Polymorph diff --git a/Resources/Prototypes/Reagents/toxins.yml b/Resources/Prototypes/Reagents/toxins.yml index 27057cb715..a06224e9dd 100644 --- a/Resources/Prototypes/Reagents/toxins.yml +++ b/Resources/Prototypes/Reagents/toxins.yml @@ -570,6 +570,7 @@ - !type:Emote emote: Honk showInChat: true + showInGuidebook: true force: true probability: 0.2 - !type:HealthChange