diff --git a/Content.Server/Chemistry/ReagentEffects/ChemVomit.cs b/Content.Server/Chemistry/ReagentEffects/ChemVomit.cs new file mode 100644 index 0000000000..d53d14e782 --- /dev/null +++ b/Content.Server/Chemistry/ReagentEffects/ChemVomit.cs @@ -0,0 +1,27 @@ +using Content.Shared.Chemistry.Reagent; +using Content.Server.Medical; +using JetBrains.Annotations; + +namespace Content.Server.Chemistry.ReagentEffects +{ + /// + /// Forces you to vomit. + /// + [UsedImplicitly] + public sealed class ChemVomit : ReagentEffect + { + /// How many units of thirst to add each time we vomit + [DataField("thirstAmount")] + public float ThirstAmount = -40f; + /// How many units of hunger to add each time we vomit + [DataField("hungerAmount")] + public float HungerAmount = -40f; + + public override void Effect(ReagentEffectArgs args) + { + var vomitSys = args.EntityManager.EntitySysManager.GetEntitySystem(); + + vomitSys.Vomit(args.SolutionEntity, ThirstAmount, HungerAmount); + } + } +} diff --git a/Content.Server/Disease/Effects/DiseaseVomit.cs b/Content.Server/Disease/Effects/DiseaseVomit.cs new file mode 100644 index 0000000000..0c5645193b --- /dev/null +++ b/Content.Server/Disease/Effects/DiseaseVomit.cs @@ -0,0 +1,27 @@ +using JetBrains.Annotations; +using Content.Shared.Disease; +using Content.Server.Medical; + +namespace Content.Server.Disease.Effects +{ + /// + /// Forces you to vomit. + /// + [UsedImplicitly] + public sealed class DiseaseVomit : DiseaseEffect + { + /// How many units of thirst to add each time we vomit + [DataField("thirstAmount")] + public float ThirstAmount = -40f; + /// How many units of hunger to add each time we vomit + [DataField("hungerAmount")] + public float HungerAmount = -40f; + + public override void Effect(DiseaseEffectArgs args) + { + var vomitSys = args.EntityManager.EntitySysManager.GetEntitySystem(); + + vomitSys.Vomit(args.DiseasedEntity, ThirstAmount, HungerAmount); + } + } +} diff --git a/Content.Server/Medical/VomitSystem.cs b/Content.Server/Medical/VomitSystem.cs new file mode 100644 index 0000000000..c9a9d88c19 --- /dev/null +++ b/Content.Server/Medical/VomitSystem.cs @@ -0,0 +1,73 @@ +using Content.Server.Nutrition.Components; +using Content.Server.Stunnable; +using Content.Server.Nutrition.EntitySystems; +using Content.Server.Body.Components; +using Content.Server.Fluids.Components; +using Content.Server.Chemistry.EntitySystems; +using Content.Server.Popups; +using Content.Server.Body.Systems; +using Content.Shared.StatusEffect; +using Content.Shared.Audio; +using Robust.Shared.Audio; +using Robust.Shared.Player; + +namespace Content.Server.Medical +{ + public sealed class VomitSystem : EntitySystem + { + + [Dependency] private readonly StunSystem _stunSystem = default!; + [Dependency] private readonly SolutionContainerSystem _solutionSystem = default!; + [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly BodySystem _bodySystem = default!; + [Dependency] private readonly ThirstSystem _thirstSystem = default!; + + /// + /// Make an entity vomit, if they have a stomach. + /// + public void Vomit(EntityUid uid, float thirstAdded = -40f, float hungerAdded = -40f) + { + /// Main requirement: You have a stomach + var stomachList = _bodySystem.GetComponentsOnMechanisms(uid); + if (stomachList.Count == 0) + { + return; + } + /// Vomiting makes you hungrier and thirstier + if (TryComp(uid, out var hunger)) + hunger.UpdateFood(hungerAdded); + + if (TryComp(uid, out var thirst)) + _thirstSystem.UpdateThirst(thirst, thirstAdded); + + // It fully empties the stomach, this amount from the chem stream is relatively small + float solutionSize = (Math.Abs(thirstAdded) + Math.Abs(hungerAdded)) / 6; + // Apply a bit of slowdown + if (TryComp(uid, out var status)) + _stunSystem.TrySlowdown(uid, TimeSpan.FromSeconds(solutionSize), true, 0.5f, 0.5f, status); + + var puddle = EntityManager.SpawnEntity("PuddleVomit", Transform(uid).Coordinates); + + var puddleComp = Comp(puddle); + + SoundSystem.Play(Filter.Pvs(uid), "/Audio/Effects/Diseases/vomiting.ogg", uid, AudioHelpers.WithVariation(0.2f).WithVolume(-4f)); + + _popupSystem.PopupEntity(Loc.GetString("disease-vomit", ("person", uid)), uid, Filter.Pvs(uid)); + // Get the solution of the puddle we spawned + if (!_solutionSystem.TryGetSolution(puddle, puddleComp.SolutionName, out var puddleSolution)) + return; + // Empty the stomach out into it + foreach (var stomach in stomachList) + { + if (_solutionSystem.TryGetSolution(stomach.Comp.Owner, StomachSystem.DefaultSolutionName, out var sol)) + _solutionSystem.TryAddSolution(puddle, puddleSolution, sol); + } + // And the small bit of the chem stream from earlier + if (TryComp(uid, out var bloodStream)) + { + var temp = bloodStream.ChemicalSolution.SplitSolution(solutionSize); + _solutionSystem.TryAddSolution(puddle, puddleSolution, temp); + } + } + } +} diff --git a/Content.Server/StationEvents/Events/DiseaseOutbreak.cs b/Content.Server/StationEvents/Events/DiseaseOutbreak.cs index 00cdd281fe..ef46469aa9 100644 --- a/Content.Server/StationEvents/Events/DiseaseOutbreak.cs +++ b/Content.Server/StationEvents/Events/DiseaseOutbreak.cs @@ -27,7 +27,9 @@ public sealed class DiseaseOutbreak : StationEvent "SpaceCold", "VanAusdallsRobovirus", "VentCough", - "AMIV" + "AMIV", + "SpaceFlu", + "BirdFlew" }; public override string Name => "DiseaseOutbreak"; public override float Weight => WeightNormal; diff --git a/Resources/Audio/Effects/Diseases/license.txt b/Resources/Audio/Effects/Diseases/license.txt index 2252a0ed60..96816fdb83 100644 --- a/Resources/Audio/Effects/Diseases/license.txt +++ b/Resources/Audio/Effects/Diseases/license.txt @@ -5,3 +5,4 @@ beepboop.ogg taken from https://freesound.org/people/Fidjo20/sounds/503526/ monkey1.ogg taken from https://freesound.org/people/TRAVELcandies/sounds/423396/ monkey2.ogg taken from https://freesound.org/people/Archeos/sounds/325549/ sneeze2.ogg taken from https://freesound.org/people/InspectorJ/sounds/352177/ +vomiting.ogg taken from https://freesound.org/people/vikuserro/sounds/246308/ diff --git a/Resources/Audio/Effects/Diseases/vomiting.ogg b/Resources/Audio/Effects/Diseases/vomiting.ogg new file mode 100644 index 0000000000..64ee260f5c Binary files /dev/null and b/Resources/Audio/Effects/Diseases/vomiting.ogg differ diff --git a/Resources/Locale/en-US/disease/disease.ftl b/Resources/Locale/en-US/disease/disease.ftl index 81ec86c57b..674e1905fd 100644 --- a/Resources/Locale/en-US/disease/disease.ftl +++ b/Resources/Locale/en-US/disease/disease.ftl @@ -9,3 +9,4 @@ disease-beep= {CAPITALIZE($person)} beeps. disease-eaten-inside = You feel like you're being eaten from the inside. disease-banana-compulsion = You really want to eat some bananas. disease-beat-chest-compulsion = {CAPITALIZE(THE($person))} beats {POSS-ADJ($person)} chest. +disease-vomit = {CAPITALIZE(THE($person))} vomits. diff --git a/Resources/Prototypes/Catalog/Fills/Items/firstaidkits.yml b/Resources/Prototypes/Catalog/Fills/Items/firstaidkits.yml index 71f7c4b8ce..030053eb9b 100644 --- a/Resources/Prototypes/Catalog/Fills/Items/firstaidkits.yml +++ b/Resources/Prototypes/Catalog/Fills/Items/firstaidkits.yml @@ -52,6 +52,8 @@ contents: - id: SyringeSpaceacillin amount: 1 + - id: SyringeIpecac + amount: 1 - id: PillDylovene amount: 3 diff --git a/Resources/Prototypes/Diseases/infectious.yml b/Resources/Prototypes/Diseases/infectious.yml index 7112c69051..067ce166b6 100644 --- a/Resources/Prototypes/Diseases/infectious.yml +++ b/Resources/Prototypes/Diseases/infectious.yml @@ -48,6 +48,51 @@ - !type:DiseaseReagentCure reagent: SpaceCleaner +- type: disease + id: SpaceFlu + name: space flu + cureResist: 0.08 + effects: + - !type:DiseaseVomit + probability: 0.01 + - !type:DiseasePopUp + probability: 0.025 + - !type:DiseaseSnough + probability: 0.025 + snoughSound: + collection: Sneezes + - !type:DiseaseHealthChange + probability: 0.015 + damage: + types: + Heat: 1 + cures: + - !type:DiseaseBedrestCure + maxLength: 100 + +- type: disease + id: Bird Flew + name: bird flew + cureResist: 0.08 + effects: + - !type:DiseaseVomit + probability: 0.015 + - !type:DiseasePopUp + probability: 0.025 + - !type:DiseaseSnough + probability: 0.025 + snoughMessage: disease-cough + snoughSound: + collection: Coughs + - !type:DiseaseHealthChange + probability: 0.05 + damage: + groups: + Caustic: 1 + cures: + - !type:DiseaseBedrestCure + maxLength: 120 + - type: disease id: VanAusdallsRobovirus name: Van Ausdall's Robovirus diff --git a/Resources/Prototypes/Diseases/noninfectious.yml b/Resources/Prototypes/Diseases/noninfectious.yml index 27658a576e..ee0c3eb78d 100644 --- a/Resources/Prototypes/Diseases/noninfectious.yml +++ b/Resources/Prototypes/Diseases/noninfectious.yml @@ -5,10 +5,12 @@ cureResist: 0.15 effects: - !type:DiseaseHealthChange - probability: 0.35 + probability: 0.3 damage: types: Cellular: 1 + - !type:DiseaseVomit + probability: 0.01 - !type:DiseasePopUp probability: 0.03 cures: diff --git a/Resources/Prototypes/Entities/Effects/puddle.yml b/Resources/Prototypes/Entities/Effects/puddle.yml index 9860a7a47c..0a1cdbb214 100644 --- a/Resources/Prototypes/Entities/Effects/puddle.yml +++ b/Resources/Prototypes/Entities/Effects/puddle.yml @@ -118,10 +118,24 @@ - type: entity name: vomit - id: PuddleVomit - parent: PuddleBase + id: PuddleVomit # No parent because we don't want the visualizer description: Gross. components: + - type: Transform + anchored: true + - type: Clickable + - type: Evaporation + - type: Physics + - type: Fixtures + fixtures: + - shape: + !type:PhysShapeAabb + bounds: "-0.4,-0.4,0.4,0.4" + mask: + - ItemMask + layer: + - SlipLayer + hard: false - type: Sprite sprite: Fluids/vomit.rsi state: vomit-0 @@ -135,9 +149,6 @@ Quantity: 5 - ReagentId: Water Quantity: 5 - - type: Appearance - visuals: - - type: PuddleVisualizer - type: Slippery launchForwardsMultiplier: 2.0 - type: StepTrigger diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml index 54d23aa806..0c7df85dd0 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml @@ -268,6 +268,19 @@ - ReagentId: Spaceacillin Quantity: 15 +- type: entity + name: ipecac syringe + parent: Syringe + id: SyringeIpecac + components: + - type: SolutionContainerManager + solutions: + injector: + maxVol: 15 + reagents: + - ReagentId: Ipecac + Quantity: 15 + #this is where all the syringes are so i didn't know where to put it - type: entity name: corpium syringe diff --git a/Resources/Prototypes/Reagents/Consumable/Drink/alcohol.yml b/Resources/Prototypes/Reagents/Consumable/Drink/alcohol.yml index acbcac5813..4de2436549 100644 --- a/Resources/Prototypes/Reagents/Consumable/Drink/alcohol.yml +++ b/Resources/Prototypes/Reagents/Consumable/Drink/alcohol.yml @@ -108,6 +108,12 @@ damage: groups: Caustic: 1 + - !type:ChemVomit + probability: 0.04 + conditions: + - !type:ReagentThreshold + reagent: Ethanol + min: 3 - type: reagent id: Gin diff --git a/Resources/Prototypes/Reagents/medicine.yml b/Resources/Prototypes/Reagents/medicine.yml index 4fd9d9d553..953d53216f 100644 --- a/Resources/Prototypes/Reagents/medicine.yml +++ b/Resources/Prototypes/Reagents/medicine.yml @@ -249,6 +249,19 @@ types: Radiation: -1 +- type: reagent + id: Ipecac + name: ipecac + group: Medicine + desc: Induces vomiting. Useful for stopping a poisoning that isn't done metabolizing. + physicalDesc: inky + color: "#422912" + metabolisms: + Medicine: + effects: + - !type:ChemVomit + probability: 0.3 + - type: reagent id: Inaprovaline name: reagent-name-inaprovaline @@ -366,6 +379,8 @@ types: Cellular: -1 Radiation: 1 + - !type:ChemVomit + probability: 0.05 - type: reagent id: Romerol diff --git a/Resources/Prototypes/Reagents/toxins.yml b/Resources/Prototypes/Reagents/toxins.yml index 6aad5a0fd2..fef7ffc2ec 100644 --- a/Resources/Prototypes/Reagents/toxins.yml +++ b/Resources/Prototypes/Reagents/toxins.yml @@ -254,6 +254,13 @@ damage: types: Poison: 4 + - !type:ChemVomit + probability: 0.025 + conditions: + - !type:ReagentThreshold + min: 3 + - !type:OrganType + type: Animal - type: reagent id: Amatoxin diff --git a/Resources/Prototypes/Recipes/Reactions/medicine.yml b/Resources/Prototypes/Recipes/Reactions/medicine.yml index 649d3e1efc..60aed98ec4 100644 --- a/Resources/Prototypes/Recipes/Reactions/medicine.yml +++ b/Resources/Prototypes/Recipes/Reactions/medicine.yml @@ -142,6 +142,16 @@ products: Inaprovaline: 3 +- type: reaction + id: Ipecac + reactants: + Dylovene: + amount: 1 + Ammonia: + amount: 1 + products: + Ipecac: 2 + - type: reaction id: TranexamicAcid reactants: