diff --git a/Content.Client/Entry/IgnoredComponents.cs b/Content.Client/Entry/IgnoredComponents.cs index f5d976796d..388c56ae43 100644 --- a/Content.Client/Entry/IgnoredComponents.cs +++ b/Content.Client/Entry/IgnoredComponents.cs @@ -154,7 +154,8 @@ namespace Content.Client.Entry "GasPassiveGate", "GasValve", "GasThermoMachine", - "Metabolism", + "Respirator", + "Metabolizer", "AiFactionTag", "PressureProtection", "AMEPart", diff --git a/Content.IntegrationTests/Tests/Body/LungTest.cs b/Content.IntegrationTests/Tests/Body/LungTest.cs index 580984374b..d1ac590adf 100644 --- a/Content.IntegrationTests/Tests/Body/LungTest.cs +++ b/Content.IntegrationTests/Tests/Body/LungTest.cs @@ -5,7 +5,7 @@ using System.Threading.Tasks; using Content.Server.Atmos; using Content.Server.Body.Behavior; using Content.Server.Body.Circulatory; -using Content.Server.Metabolism; +using Content.Server.Body.Respiratory; using Content.Shared.Atmos; using Content.Shared.Body.Components; using NUnit.Framework; @@ -32,7 +32,7 @@ namespace Content.IntegrationTests.Tests.Body template: HumanoidTemplate preset: HumanPreset centerSlot: torso - - type: Metabolism + - type: Respirator metabolismHeat: 5000 radiatedHeat: 400 implicitHeatRegulation: 5000 @@ -148,7 +148,7 @@ namespace Content.IntegrationTests.Tests.Body MapId mapId; IMapGrid grid = null; - MetabolismComponent metabolism = null; + RespiratorComponent respirator = null; IEntity human = null; var testMapName = "Maps/Test/Breathing/3by3-20oxy-80nit.yml"; @@ -169,8 +169,8 @@ namespace Content.IntegrationTests.Tests.Body Assert.True(human.TryGetComponent(out SharedBodyComponent body)); Assert.True(body.HasMechanismBehavior()); - Assert.True(human.TryGetComponent(out metabolism)); - Assert.False(metabolism.Suffocating); + Assert.True(human.TryGetComponent(out respirator)); + Assert.False(respirator.Suffocating); }); var increment = 10; @@ -178,7 +178,7 @@ namespace Content.IntegrationTests.Tests.Body for (var tick = 0; tick < 600; tick += increment) { await server.WaitRunTicks(increment); - Assert.False(metabolism.Suffocating, $"Entity {human.Name} is suffocating on tick {tick}"); + Assert.False(respirator.Suffocating, $"Entity {human.Name} is suffocating on tick {tick}"); } await server.WaitIdleAsync(); diff --git a/Content.Server/Body/Behavior/LiverBehavior.cs b/Content.Server/Body/Behavior/LiverBehavior.cs index 95897b320a..aa40d1b142 100644 --- a/Content.Server/Body/Behavior/LiverBehavior.cs +++ b/Content.Server/Body/Behavior/LiverBehavior.cs @@ -1,7 +1,6 @@ using System.Linq; using Content.Server.Body.Circulatory; using Content.Shared.Body.Networks; -using Content.Shared.Chemistry.Metabolizable; using Content.Shared.Chemistry.Reagent; using Robust.Shared.IoC; using Robust.Shared.Prototypes; @@ -13,52 +12,8 @@ namespace Content.Server.Body.Behavior /// public class LiverBehavior : MechanismBehavior { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - private float _accumulatedFrameTime; - /// - /// Delay time that determines how often to metabolise blood contents (in seconds). - /// - private float _updateIntervalSeconds = 1.0f; - - /// - /// Whether the liver is functional. - /// - //[ViewVariables] private bool _liverFailing = false; - - /// - /// Modifier for alcohol damage. - /// - //[DataField("alcoholLethality")] - //[ViewVariables] private float _alcoholLethality = 0.005f; - - /// - /// Modifier for alcohol damage. - /// - //[DataField("alcoholExponent")] - //[ViewVariables] private float _alcoholExponent = 1.6f; - - /// - /// Toxin volume that can be purged without damage. - /// - //[DataField("toxinTolerance")] - //[ViewVariables] private float _toxinTolerance = 3f; - - /// - /// Toxin damage modifier. - /// - //[DataField("toxinLethality")] - //[ViewVariables] private float _toxinLethality = 0.01f; - - /// - /// Loops through each reagent in _internalSolution, - /// and calls for each of them. - /// Also handles toxins and alcohol. - /// - /// - /// The time since the last update in seconds. - /// public override void Update(float frameTime) { if (Body == null) @@ -68,51 +23,13 @@ namespace Content.Server.Body.Behavior _accumulatedFrameTime += frameTime; - // Update at most once every _updateIntervalSeconds - if (_accumulatedFrameTime < _updateIntervalSeconds) + // Update at most once per second + if (_accumulatedFrameTime < 1) { return; } - _accumulatedFrameTime -= _updateIntervalSeconds; - - if (!Body.Owner.TryGetComponent(out BloodstreamComponent? bloodstream)) - { - return; - } - - if (bloodstream.Solution.CurrentVolume <= ReagentUnit.Zero) - { - return; - } - - // Run metabolism for each reagent, remove metabolized reagents - // Using ToList here lets us edit reagents while iterating - foreach (var reagent in bloodstream.Solution.ReagentList.ToList()) - { - if (!_prototypeManager.TryIndex(reagent.ReagentId, out ReagentPrototype? prototype)) - { - continue; - } - - // How much reagent is available to metabolise? - // This needs to be passed to other functions that have metabolism rate information, such that they don't "overmetabolise" a reagent. - var availableReagent = bloodstream.Solution.Solution.GetReagentQuantity(reagent.ReagentId); - - //TODO BODY Check if it's a Toxin. If volume < _toxinTolerance, just remove it. If greater, add damage = volume * _toxinLethality - //TODO BODY Check if it has BoozePower > 0. Affect drunkenness, apply damage. Proposed formula (SS13-derived): damage = sqrt(volume) * BoozePower^_alcoholExponent * _alcoholLethality / 10 - //TODO BODY Liver failure. - - //TODO Make sure reagent prototypes actually have the toxin and boozepower vars set. - - // Run metabolism code for each reagent - foreach (var metabolizable in prototype.Metabolism) - { - var reagentDelta = metabolizable.Metabolize(Body.Owner, reagent.ReagentId, _updateIntervalSeconds, availableReagent); - bloodstream.Solution.TryRemoveReagent(reagent.ReagentId, reagentDelta); - availableReagent -= reagentDelta; - } - } + _accumulatedFrameTime -= 1; } } } diff --git a/Content.Server/Body/Circulatory/BloodstreamComponent.cs b/Content.Server/Body/Circulatory/BloodstreamComponent.cs index df90cd6fc6..998e3d97bb 100644 --- a/Content.Server/Body/Circulatory/BloodstreamComponent.cs +++ b/Content.Server/Body/Circulatory/BloodstreamComponent.cs @@ -2,8 +2,8 @@ using System; using System.Linq; using Content.Server.Atmos; using Content.Server.Atmos.EntitySystems; +using Content.Server.Body.Respiratory; using Content.Server.Chemistry.Components; -using Content.Server.Metabolism; using Content.Shared.Atmos; using Content.Shared.Body.Networks; using Content.Shared.Chemistry.Reagent; @@ -72,7 +72,7 @@ namespace Content.Server.Body.Circulatory { var atmosphereSystem = EntitySystem.Get(); - if (!Owner.TryGetComponent(out MetabolismComponent? metabolism)) + if (!Owner.TryGetComponent(out RespiratorComponent? metabolism)) { atmosphereSystem.Merge(to, Air); Air.Clear(); diff --git a/Content.Server/Body/Metabolism/MetabolizerComponent.cs b/Content.Server/Body/Metabolism/MetabolizerComponent.cs new file mode 100644 index 0000000000..b74926ff57 --- /dev/null +++ b/Content.Server/Body/Metabolism/MetabolizerComponent.cs @@ -0,0 +1,57 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Content.Shared.Chemistry.Reagent; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary; + +namespace Content.Server.Body.Metabolism +{ + /// + /// Handles metabolizing various reagents with given effects. + /// + [RegisterComponent] + public class MetabolizerComponent : Component + { + public override string Name => "Metabolizer"; + + public float AccumulatedFrametime = 0.0f; + + /// + /// How often to metabolize reagents, in seconds. + /// + /// + [DataField("updateFrequency")] + public float UpdateFrequency = 1.0f; + + /// + /// Whether this metabolizer should attempt to metabolize chemicals in its parent bodies' bloodstream, + /// as opposed to a solution container on the metabolizing entity itself. + /// + [DataField("takeFromBloodstream")] + public bool TakeFromBloodstream = true; + + /// + /// A dictionary mapping reagent string IDs to a list of effects & associated metabolism rate. + /// + /// + [DataField("metabolisms", required: true, customTypeSerializer:typeof(PrototypeIdDictionarySerializer))] + public Dictionary Metabolisms = default!; + } + + [DataDefinition] + public class ReagentEffectsEntry + { + /// + /// Amount of reagent to metabolize, per metabolism cycle. + /// + [DataField("metabolismRate")] + public ReagentUnit MetabolismRate = ReagentUnit.New(1.0f); + + /// + /// A list of effects to apply when these reagents are metabolized. + /// + [DataField("effects", required: true)] + public ReagentEffect[] Effects = default!; + } +} diff --git a/Content.Server/Body/Metabolism/MetabolizerSystem.cs b/Content.Server/Body/Metabolism/MetabolizerSystem.cs new file mode 100644 index 0000000000..249ca13391 --- /dev/null +++ b/Content.Server/Body/Metabolism/MetabolizerSystem.cs @@ -0,0 +1,107 @@ +using System.Collections.Generic; +using System.Linq; +using Content.Server.Body.Circulatory; +using Content.Server.Chemistry.Components; +using Content.Shared.Body.Components; +using Content.Shared.Body.Mechanism; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.Chemistry.Solution; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Prototypes; + +namespace Content.Server.Body.Metabolism +{ + // TODO mirror in the future working on mechanisms move updating here to BodySystem so it can be ordered? + public class MetabolizerSystem : EntitySystem + { + public override void Update(float frameTime) + { + base.Update(frameTime); + + foreach (var metab in ComponentManager.EntityQuery(false)) + { + metab.AccumulatedFrametime += frameTime; + + // Only update as frequently as it should + if (metab.AccumulatedFrametime >= metab.UpdateFrequency) + { + metab.AccumulatedFrametime = 0.0f; + TryMetabolize(metab); + } + } + } + + private void TryMetabolize(MetabolizerComponent comp) + { + var owner = comp.Owner; + var reagentList = new List(); + SolutionContainerComponent? solution = null; + SharedBodyComponent? body = null; + + // if this field is passed we should try and take from the bloodstream over anything else + if (comp.TakeFromBloodstream && owner.TryGetComponent(out var mech)) + { + body = mech.Body; + if (body != null) + { + if (body.Owner.TryGetComponent(out var bloodstream) + && bloodstream.Solution.CurrentVolume >= ReagentUnit.Zero) + { + solution = bloodstream.Solution; + reagentList = bloodstream.Solution.ReagentList.ToList(); + } + } + } + else if (owner.TryGetComponent(out var sol)) + { + // if we have no mechanism/body but a solution container instead, + // we'll just use that to metabolize from + solution = sol; + reagentList = sol.ReagentList.ToList(); + } + if (solution == null || reagentList.Count == 0) + { + // We're all outta ideas on where to metabolize from + return; + } + + // Run metabolism for each reagent, remove metabolized reagents + foreach (var reagent in reagentList) + { + if (!comp.Metabolisms.ContainsKey(reagent.ReagentId)) + continue; + + var metabolism = comp.Metabolisms[reagent.ReagentId]; + // Run metabolism code for each reagent + foreach (var effect in metabolism.Effects) + { + var ent = body != null ? body.Owner : owner; + var conditionsMet = true; + if (effect.Conditions != null) + { + // yes this is 3 nested for loops, but all of these lists are + // basically guaranteed to be small or empty + foreach (var condition in effect.Conditions) + { + if (!condition.Condition(ent, reagent)) + { + conditionsMet = false; + break; + } + } + } + + if (!conditionsMet) + return; + + // If we're part of a body, pass that entity to Metabolize + // Otherwise, just pass our owner entity, maybe we're a plant or something + effect.Metabolize(ent, reagent); + } + + solution.TryRemoveReagent(reagent.ReagentId, metabolism.MetabolismRate); + } + } + } +} diff --git a/Content.Server/Metabolism/MetabolismComponent.cs b/Content.Server/Body/Respiratory/RespiratorComponent.cs similarity index 98% rename from Content.Server/Metabolism/MetabolismComponent.cs rename to Content.Server/Body/Respiratory/RespiratorComponent.cs index 4898692ab9..2aec76e351 100644 --- a/Content.Server/Metabolism/MetabolismComponent.cs +++ b/Content.Server/Body/Respiratory/RespiratorComponent.cs @@ -13,7 +13,6 @@ using Content.Shared.Atmos; using Content.Shared.Body.Components; using Content.Shared.Damage; using Content.Shared.Damage.Components; -using Content.Shared.Metabolism.Events; using Content.Shared.MobState; using Content.Shared.Notification.Managers; using Robust.Shared.GameObjects; @@ -21,14 +20,14 @@ using Robust.Shared.Localization; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; -namespace Content.Server.Metabolism +namespace Content.Server.Body.Respiratory { [RegisterComponent] - public class MetabolismComponent : Component + public class RespiratorComponent : Component { [ComponentDependency] private readonly SharedBodyComponent? _body = default!; - public override string Name => "Metabolism"; + public override string Name => "Respirator"; private float _accumulatedFrameTime; diff --git a/Content.Server/Metabolism/MetabolismSystem.cs b/Content.Server/Body/Respiratory/RespiratorSystem.cs similarity index 50% rename from Content.Server/Metabolism/MetabolismSystem.cs rename to Content.Server/Body/Respiratory/RespiratorSystem.cs index 6616d013d5..424b1e4dce 100644 --- a/Content.Server/Metabolism/MetabolismSystem.cs +++ b/Content.Server/Body/Respiratory/RespiratorSystem.cs @@ -1,18 +1,18 @@ using JetBrains.Annotations; using Robust.Shared.GameObjects; -namespace Content.Server.Metabolism +namespace Content.Server.Body.Respiratory { [UsedImplicitly] - public class MetabolismSystem : EntitySystem + public class RespiratorSystem : EntitySystem { public override void Update(float frameTime) { base.Update(frameTime); - foreach (var metabolism in ComponentManager.EntityQuery(true)) + foreach (var respirator in ComponentManager.EntityQuery(false)) { - metabolism.Update(frameTime); + respirator.Update(frameTime); } } } diff --git a/Content.Server/Chemistry/Metabolism/DefaultDrink.cs b/Content.Server/Chemistry/Metabolism/DefaultDrink.cs deleted file mode 100644 index 255200f103..0000000000 --- a/Content.Server/Chemistry/Metabolism/DefaultDrink.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Content.Server.Nutrition.Components; -using Content.Shared.Chemistry; -using Content.Shared.Chemistry.Metabolizable; -using Content.Shared.Chemistry.Reagent; -using Robust.Shared.GameObjects; -using Robust.Shared.Serialization.Manager.Attributes; - -namespace Content.Server.Chemistry.Metabolism -{ - /// - /// Default metabolism for drink reagents. Attempts to find a ThirstComponent on the target, - /// and to update it's thirst values. Inherits metabolisation rate logic from DefaultMetabolizable. - /// - [DataDefinition] - public class DefaultDrink : DefaultMetabolizable - { - //How much thirst is satiated when 1u of the reagent is metabolized - [DataField("hydrationFactor")] - public float HydrationFactor { get; set; } = 30.0f; - - //Remove reagent at set rate, satiate thirst if a ThirstComponent can be found - public override ReagentUnit Metabolize(IEntity solutionEntity, string reagentId, float tickTime, ReagentUnit availableReagent) - { - // use DefaultMetabolism to determine how much reagent we should metabolize - var amountMetabolized = base.Metabolize(solutionEntity, reagentId, tickTime, availableReagent); - - // If metabolizing entity has a ThirstComponent, hydrate them. - if (solutionEntity.TryGetComponent(out ThirstComponent? thirst)) - thirst.UpdateThirst(amountMetabolized.Float() * HydrationFactor); - - //Return amount of reagent to be removed, remove reagent regardless of ThirstComponent presence - return amountMetabolized; - } - } -} diff --git a/Content.Server/Chemistry/Metabolism/DefaultFood.cs b/Content.Server/Chemistry/Metabolism/DefaultFood.cs deleted file mode 100644 index fafcf58dd1..0000000000 --- a/Content.Server/Chemistry/Metabolism/DefaultFood.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Content.Server.Nutrition.Components; -using Content.Shared.Chemistry; -using Content.Shared.Chemistry.Metabolizable; -using Content.Shared.Chemistry.Reagent; -using Robust.Shared.GameObjects; -using Robust.Shared.Serialization.Manager.Attributes; - -namespace Content.Server.Chemistry.Metabolism -{ - /// - /// Default metabolism for food reagents. Attempts to find a HungerComponent on the target, - /// and to update it's hunger values. Inherits metabolisation rate logic from DefaultMetabolizable. - /// - [DataDefinition] - public class DefaultFood : DefaultMetabolizable - { - - /// - /// How much hunger is satiated when 1u of the reagent is metabolized - /// - [DataField("nutritionFactor")] public float NutritionFactor { get; set; } = 30.0f; - - - //Remove reagent at set rate, satiate hunger if a HungerComponent can be found - public override ReagentUnit Metabolize(IEntity solutionEntity, string reagentId, float tickTime, ReagentUnit availableReagent) - { - // use DefaultMetabolism to determine how much reagent we should metabolize - var amountMetabolized = base.Metabolize(solutionEntity, reagentId, tickTime, availableReagent); - - // If metabolizing entity has a HungerComponent, feed them. - if (solutionEntity.TryGetComponent(out HungerComponent? hunger)) - hunger.UpdateFood(amountMetabolized.Float() * NutritionFactor); - - //Return amount of reagent to be removed. Reagent is removed regardless of HungerComponent presence - return amountMetabolized; - } - } -} diff --git a/Content.Server/Chemistry/Metabolism/HealthChangeMetabolism.cs b/Content.Server/Chemistry/Metabolism/HealthChangeMetabolism.cs deleted file mode 100644 index bbf2534505..0000000000 --- a/Content.Server/Chemistry/Metabolism/HealthChangeMetabolism.cs +++ /dev/null @@ -1,72 +0,0 @@ -using Content.Shared.Chemistry; -using Content.Shared.Chemistry.Metabolizable; -using Content.Shared.Chemistry.Reagent; -using Robust.Shared.GameObjects; -using Robust.Shared.Serialization.Manager.Attributes; -using Content.Shared.Damage; -using Content.Shared.Damage.Components; - -namespace Content.Server.Chemistry.Metabolism -{ - /// - /// Default metabolism for medicine reagents. Attempts to find a DamageableComponent on the target, - /// and to update its damage values. Inherits metabolisation rate logic from DefaultMetabolizable. - /// - [DataDefinition] - public class HealthChangeMetabolism : DefaultMetabolizable - { - - /// - /// How much damage is changed when 1u of the reagent is metabolized. - /// - [DataField("healthChange")] - public float HealthChange { get; set; } = 1.0f; - - /// - /// Class of damage changed, Brute, Burn, Toxin, Airloss. - /// - [DataField("damageClass")] - public DamageClass DamageType { get; set; } = DamageClass.Brute; - - private float _accumulatedHealth; - - /// - /// Remove reagent at set rate, changes damage if a DamageableComponent can be found. - /// - /// - /// - /// - /// Reagent available to be metabolized. - /// - public override ReagentUnit Metabolize(IEntity solutionEntity, string reagentId, float tickTime, ReagentUnit availableReagent) - { - // use DefaultMetabolism to determine how much reagent we should metabolize - var amountMetabolized = base.Metabolize(solutionEntity, reagentId, tickTime, availableReagent); - - // how much does this much reagent heal for - var healthChangeAmount = HealthChange * amountMetabolized.Float(); - - if (solutionEntity.TryGetComponent(out IDamageableComponent? health)) - { - // Heal damage by healthChangeAmmount, rounding down to nearest integer - health.ChangeDamage(DamageType, (int) healthChangeAmount, true); - - // Store decimal remainder of healthChangeAmmount in _accumulatedHealth - _accumulatedHealth += (healthChangeAmount - (int) healthChangeAmount); - - if (_accumulatedHealth >= 1) - { - health.ChangeDamage(DamageType, 1, true); - _accumulatedHealth -= 1; - } - - else if(_accumulatedHealth <= -1) - { - health.ChangeDamage(DamageType, -1, true); - _accumulatedHealth += 1; - } - } - return amountMetabolized; - } - } -} diff --git a/Content.Server/Chemistry/ReagentEffectConditions/ReagentThreshold.cs b/Content.Server/Chemistry/ReagentEffectConditions/ReagentThreshold.cs new file mode 100644 index 0000000000..cfc0177d41 --- /dev/null +++ b/Content.Server/Chemistry/ReagentEffectConditions/ReagentThreshold.cs @@ -0,0 +1,26 @@ +using Content.Shared.Body.Components; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.Chemistry.Solution; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Server.Chemistry.ReagentEffectConditions +{ + /// + /// Used for implementing reagent effects that require a certain amount of reagent before it should be applied. + /// For instance, overdoses. + /// + public class ReagentThreshold : ReagentEffectCondition + { + [DataField("min")] + public ReagentUnit Min = ReagentUnit.Zero; + + [DataField("max")] + public ReagentUnit Max = ReagentUnit.MaxValue; + + public override bool Condition(IEntity solutionEntity, Solution.ReagentQuantity reagent) + { + return reagent.Quantity >= Min && reagent.Quantity < Max; + } + } +} diff --git a/Content.Server/Chemistry/ReagentEffects/HealthChange.cs b/Content.Server/Chemistry/ReagentEffects/HealthChange.cs new file mode 100644 index 0000000000..47b640cdfc --- /dev/null +++ b/Content.Server/Chemistry/ReagentEffects/HealthChange.cs @@ -0,0 +1,56 @@ +using Content.Shared.Chemistry; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.Chemistry.Solution; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; +using Content.Shared.Damage; +using Content.Shared.Damage.Components; + +namespace Content.Server.Chemistry.ReagentEffects +{ + /// + /// Default metabolism for medicine reagents. Attempts to find a DamageableComponent on the target, + /// and to update its damage values. + /// + public class HealthChange : ReagentEffect + { + /// + /// How much damage is changed when 1u of the reagent is metabolized. + /// + [DataField("healthChange")] + public float AmountToChange { get; set; } = 1.0f; + + /// + /// Class of damage changed, Brute, Burn, Toxin, Airloss. + /// + [DataField("damageClass")] + public DamageClass DamageType { get; set; } = DamageClass.Brute; + + private float _accumulatedHealth; + + /// + /// Changes damage if a DamageableComponent can be found. + /// + public override void Metabolize(IEntity solutionEntity, Solution.ReagentQuantity amount) + { + if (solutionEntity.TryGetComponent(out IDamageableComponent? health)) + { + health.ChangeDamage(DamageType, (int)AmountToChange, true); + float decHealthChange = (float) (AmountToChange - (int) AmountToChange); + _accumulatedHealth += decHealthChange; + + if (_accumulatedHealth >= 1) + { + health.ChangeDamage(DamageType, 1, true); + _accumulatedHealth -= 1; + } + + else if(_accumulatedHealth <= -1) + { + health.ChangeDamage(DamageType, -1, true); + _accumulatedHealth += 1; + } + } + } + } +} diff --git a/Content.Server/Chemistry/ReagentEffects/SatiateHunger.cs b/Content.Server/Chemistry/ReagentEffects/SatiateHunger.cs new file mode 100644 index 0000000000..983d30b565 --- /dev/null +++ b/Content.Server/Chemistry/ReagentEffects/SatiateHunger.cs @@ -0,0 +1,28 @@ +using Content.Server.Nutrition.Components; +using Content.Shared.Chemistry; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.Chemistry.Solution; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Server.Chemistry.ReagentEffects +{ + /// + /// Attempts to find a HungerComponent on the target, + /// and to update it's hunger values. + /// + public class SatiateHunger : ReagentEffect + { + /// + /// How much hunger is satiated when 1u of the reagent is metabolized + /// + [DataField("nutritionFactor")] public float NutritionFactor { get; set; } = 3.0f; + + //Remove reagent at set rate, satiate hunger if a HungerComponent can be found + public override void Metabolize(IEntity solutionEntity, Solution.ReagentQuantity amount) + { + if (solutionEntity.TryGetComponent(out HungerComponent? hunger)) + hunger.UpdateFood(NutritionFactor); + } + } +} diff --git a/Content.Server/Chemistry/ReagentEffects/SatiateThirst.cs b/Content.Server/Chemistry/ReagentEffects/SatiateThirst.cs new file mode 100644 index 0000000000..637c56f235 --- /dev/null +++ b/Content.Server/Chemistry/ReagentEffects/SatiateThirst.cs @@ -0,0 +1,28 @@ +using Content.Server.Nutrition.Components; +using Content.Shared.Chemistry; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.Chemistry.Solution; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Server.Chemistry.ReagentEffects +{ + /// + /// Default metabolism for drink reagents. Attempts to find a ThirstComponent on the target, + /// and to update it's thirst values. + /// + public class SatiateThirst : ReagentEffect + { + /// How much thirst is satiated each metabolism tick. Not currently tied to + /// rate or anything. + [DataField("hydrationFactor")] + public float HydrationFactor { get; set; } = 3.0f; + + /// Satiate thirst if a ThirstComponent can be found + public override void Metabolize(IEntity solutionEntity, Solution.ReagentQuantity amount) + { + if (solutionEntity.TryGetComponent(out ThirstComponent? thirst)) + thirst.UpdateThirst(HydrationFactor); + } + } +} diff --git a/Content.Shared/ActionBlocker/ActionBlockerSystem.cs b/Content.Shared/ActionBlocker/ActionBlockerSystem.cs index a4f3080583..253475235b 100644 --- a/Content.Shared/ActionBlocker/ActionBlockerSystem.cs +++ b/Content.Shared/ActionBlocker/ActionBlockerSystem.cs @@ -4,7 +4,7 @@ using Content.Shared.Emoting; using Content.Shared.Interaction.Events; using Content.Shared.Inventory.Events; using Content.Shared.Item; -using Content.Shared.Metabolism.Events; +using Content.Shared.Body.Metabolism; using Content.Shared.Movement; using Content.Shared.Speech; using Content.Shared.Throwing; diff --git a/Content.Shared/Metabolism/Events/ShiverAttemptEvent.cs b/Content.Shared/Body/Metabolism/ShiverAttemptEvent.cs similarity index 85% rename from Content.Shared/Metabolism/Events/ShiverAttemptEvent.cs rename to Content.Shared/Body/Metabolism/ShiverAttemptEvent.cs index da05d74ffd..d84630fa3c 100644 --- a/Content.Shared/Metabolism/Events/ShiverAttemptEvent.cs +++ b/Content.Shared/Body/Metabolism/ShiverAttemptEvent.cs @@ -1,6 +1,6 @@ using Robust.Shared.GameObjects; -namespace Content.Shared.Metabolism.Events +namespace Content.Shared.Body.Metabolism { public class ShiverAttemptEvent : CancellableEntityEventArgs { diff --git a/Content.Shared/Metabolism/Events/SweatAttemptEvent.cs b/Content.Shared/Body/Metabolism/SweatAttemptEvent.cs similarity index 85% rename from Content.Shared/Metabolism/Events/SweatAttemptEvent.cs rename to Content.Shared/Body/Metabolism/SweatAttemptEvent.cs index b920639aff..6c6180eb00 100644 --- a/Content.Shared/Metabolism/Events/SweatAttemptEvent.cs +++ b/Content.Shared/Body/Metabolism/SweatAttemptEvent.cs @@ -1,6 +1,6 @@ using Robust.Shared.GameObjects; -namespace Content.Shared.Metabolism.Events +namespace Content.Shared.Body.Metabolism { public class SweatAttemptEvent : CancellableEntityEventArgs { diff --git a/Content.Shared/Chemistry/Metabolizable/DefaultMetabolizable.cs b/Content.Shared/Chemistry/Metabolizable/DefaultMetabolizable.cs deleted file mode 100644 index 939acdd21a..0000000000 --- a/Content.Shared/Chemistry/Metabolizable/DefaultMetabolizable.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Content.Shared.Chemistry.Reagent; -using Robust.Shared.GameObjects; -using Robust.Shared.Serialization.Manager.Attributes; - -namespace Content.Shared.Chemistry.Metabolizable -{ - /// - /// Default metabolization for reagents. Returns the amount of reagents metabolized without applying effects. - /// Metabolizes reagents at a constant rate, limited by how much is available. Other classes are derived from - /// this class, so that they do not need their own metabolization quantity calculation. - /// - [DataDefinition] - public class DefaultMetabolizable : IMetabolizable - { - /// - /// Rate of metabolism in units / second - /// - [DataField("rate")] public ReagentUnit MetabolismRate { get; set; } = ReagentUnit.New(1); - - public virtual ReagentUnit Metabolize(IEntity solutionEntity, string reagentId, float tickTime, ReagentUnit availableReagent) - { - - // How much reagent should we metabolize - // The default behaviour is to metabolize at a constant rate, independent of the quantity of reagents. - var amountMetabolized = MetabolismRate * tickTime; - - // is that much reagent actually available? - if (availableReagent < amountMetabolized) - { - return availableReagent; - } - - return amountMetabolized; - } - } -} diff --git a/Content.Shared/Chemistry/Metabolizable/IMetabolizable.cs b/Content.Shared/Chemistry/Metabolizable/IMetabolizable.cs deleted file mode 100644 index f8b2a888cc..0000000000 --- a/Content.Shared/Chemistry/Metabolizable/IMetabolizable.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Content.Shared.Chemistry.Reagent; -using Robust.Shared.GameObjects; - -namespace Content.Shared.Chemistry.Metabolizable -{ - /// - /// Metabolism behavior for a reagent. - /// - public interface IMetabolizable - { - /// - /// Metabolize the attached reagent. Return the amount of reagent to be removed from the solution. - /// You shouldn't remove the reagent yourself to avoid invalidating the iterator of the metabolism - /// organ that is processing it's reagents. - /// - /// The entity containing the solution. - /// The reagent id - /// The time since the last metabolism tick in seconds. - /// Reagent available to be metabolized. - /// The amount of reagent to be removed. The metabolizing organ should handle removing the reagent. - ReagentUnit Metabolize(IEntity solutionEntity, string reagentId, float tickTime, ReagentUnit availableReagent); - } -} diff --git a/Content.Shared/Chemistry/Reagent/ReagentEffect.cs b/Content.Shared/Chemistry/Reagent/ReagentEffect.cs new file mode 100644 index 0000000000..78ca370df0 --- /dev/null +++ b/Content.Shared/Chemistry/Reagent/ReagentEffect.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using Content.Shared.Chemistry.Reagent; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Shared.Chemistry.Reagent +{ + /// + /// Reagent effects describe behavior that occurs when a reagent is ingested and metabolized by some + /// organ. They only trigger when their conditions ( + /// + [ImplicitDataDefinitionForInheritors] + public abstract class ReagentEffect + { + /// + /// The list of conditions required for the effect to activate. Not required. + /// + [DataField("conditions")] + public ReagentEffectCondition[]? Conditions; + + public abstract void Metabolize(IEntity solutionEntity, Solution.Solution.ReagentQuantity amount); + } +} diff --git a/Content.Shared/Chemistry/Reagent/ReagentEffectCondition.cs b/Content.Shared/Chemistry/Reagent/ReagentEffectCondition.cs new file mode 100644 index 0000000000..54253d1c6d --- /dev/null +++ b/Content.Shared/Chemistry/Reagent/ReagentEffectCondition.cs @@ -0,0 +1,13 @@ +using Content.Shared.Body.Components; +using Content.Shared.Chemistry.Solution; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Shared.Chemistry.Reagent +{ + [ImplicitDataDefinitionForInheritors] + public abstract class ReagentEffectCondition + { + public abstract bool Condition(IEntity solutionEntity, Solution.Solution.ReagentQuantity reagent); + } +} diff --git a/Content.Shared/Chemistry/Reagent/ReagentPrototype.cs b/Content.Shared/Chemistry/Reagent/ReagentPrototype.cs index 30de264604..321dacd497 100644 --- a/Content.Shared/Chemistry/Reagent/ReagentPrototype.cs +++ b/Content.Shared/Chemistry/Reagent/ReagentPrototype.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using Content.Shared.Botany; -using Content.Shared.Chemistry.Metabolizable; using Content.Shared.Chemistry.Reaction; using Robust.Shared.GameObjects; using Robust.Shared.Map; @@ -16,9 +15,6 @@ namespace Content.Shared.Chemistry.Reagent [DataDefinition] public class ReagentPrototype : IPrototype { - [DataField("metabolism", serverOnly: true)] - private readonly List _metabolism = new() {new DefaultMetabolizable()}; - [DataField("tileReactions", serverOnly: true)] private readonly List _tileReactions = new(0); @@ -60,7 +56,6 @@ namespace Content.Shared.Chemistry.Reagent public string SpriteReplacementPath { get; } = string.Empty; //List of metabolism effects this reagent has, should really only be used server-side. - public IReadOnlyList Metabolism => _metabolism; public IReadOnlyList TileReactions => _tileReactions; public IReadOnlyList PlantMetabolism => _plantMetabolism; diff --git a/Resources/Prototypes/Body/Mechanisms/human.yml b/Resources/Prototypes/Body/Mechanisms/human.yml index aec9769c51..8de6180529 100644 --- a/Resources/Prototypes/Body/Mechanisms/human.yml +++ b/Resources/Prototypes/Body/Mechanisms/human.yml @@ -50,18 +50,30 @@ compatibility: Biological - type: entity - id: OrganHumanHeart + id: OrganHumanTongue parent: BaseHumanOrgan - name: heart - description: "I feel bad for the heartless bastard who lost this." + name: tongue + description: "A fleshy muscle mostly used for lying." components: - type: Sprite - state: heart-on + state: tongue + - type: Mechanism + size: 1 + compatibility: Biological + +- type: entity + id: OrganHumanAppendix + parent: BaseHumanOrgan + name: appendix + components: + - type: Sprite + layers: + - state: appendix + - state: appendix-inflamed + visible: false - type: Mechanism size: 1 compatibility: Biological - behaviors: - - !type:HeartBehavior {} - type: entity id: OrganHumanEars @@ -91,6 +103,92 @@ behaviors: - !type:LungBehavior {} +- type: entity + id: OrganHumanHeart + parent: BaseHumanOrgan + name: heart + description: "I feel bad for the heartless bastard who lost this." + components: + - type: Sprite + state: heart-on + - type: Mechanism + size: 1 + compatibility: Biological + behaviors: + - !type:HeartBehavior {} + # The heart 'metabolizes' medicines and poisons that aren't filtered out by other organs. + # This is done because these chemicals need to have some effect even if they aren't being filtered out of your body. + # You're technically 'immune to poison' without a heart, but.. uhh, you'll have bigger problems on your hands. + - type: Metabolizer + metabolisms: + Dylovene: + effects: + - !type:HealthChange + damageClass: Toxin + healthChange: -1 + Arithrazine: + effects: + - !type:HealthChange + damageClass: Toxin + healthChange: -1 + - !type:HealthChange + damageClass: Brute + healthChange: 0.5 + Bicaridine: + effects: + - !type:HealthChange + damageClass: Brute + healthChange: -2 + Dermaline: + effects: + - !type:HealthChange + damageClass: Burn + healthChange: -3 + Dexalin: + effects: + - !type:HealthChange + damageClass: Airloss + healthChange: -1 + DexalinPlus: + effects: + - !type:HealthChange + damageClass: Airloss + healthChange: -3 + Kelotane: + effects: + - !type:HealthChange + damageClass: Burn + healthChange: -1 + Synaptizine: + effects: + - !type:HealthChange + damageClass: Toxin + healthChange: 0.5 + HeartbreakerToxin: + effects: + - !type:HealthChange + damageClass: Airloss + healthChange: 4 + Lexorin: + effects: + - !type:HealthChange + damageClass: Airloss + healthChange: 7 + Omnizine: + effects: + - !type:HealthChange + healthChange: -2 + damageClass: Burn + - !type:HealthChange + healthChange: -2 + damageClass: Toxin + - !type:HealthChange + healthChange: -2 + damageClass: Airloss + - !type:HealthChange + healthChange: -2 + damageClass: Brute + - type: entity id: OrganHumanStomach parent: BaseHumanOrgan @@ -108,6 +206,93 @@ digestionDelay: 20 - type: SolutionContainer maxVol: 250 + # The stomach metabolizes stuff like foods and drinks. + # TODO: Have it work off of the ent's solution container, and move this + # to intestines instead. + - type: Metabolizer # Release me from this hell called 1 reagent for every drink + # TODO please make every drink their own base thing + metabolisms: + Flour: + effects: + - !type:SatiateHunger + JuiceApple: + effects: + - !type:SatiateThirst + JuiceBerry: + effects: + - !type:SatiateThirst + JuiceBanana: + effects: + - !type:SatiateThirst + JuiceCarrot: + effects: + - !type:SatiateThirst + JuiceLime: + effects: + - !type:SatiateThirst + JuiceLemon: + effects: + - !type:SatiateThirst + JuiceGrape: + effects: + - !type:SatiateThirst + JuiceOrange: + effects: + - !type:SatiateThirst + JuiceTomato: + effects: + - !type:SatiateThirst + JuiceBerryPoison: + effects: + - !type:SatiateThirst + - !type:HealthChange + damageClass: Toxin + healthChange: 1 + JuiceWatermelon: + effects: + - !type:SatiateThirst + JuicePineapple: + effects: + - !type:SatiateThirst + Nutriment: + effects: + - !type:SatiateHunger + Water: + effects: + - !type:SatiateThirst + hydrationFactor: 2 + Coffee: + effects: + - !type:SatiateThirst + Tea: + effects: + - !type:SatiateThirst + Milk: + effects: + - !type:SatiateThirst + SpoiledMilk: + effects: + - !type:SatiateThirst + hydrationFactor: -2 + MilkSoy: + effects: + - !type:SatiateThirst + hydrationFactor: 2 # soyboys stay winning + MilkOat: + effects: + - !type:SatiateThirst + hydrationFactor: 2 # oatboys stay winning + Cola: + effects: + - !type:SatiateThirst + hydrationFactor: 0.5 # sodaboys stay losing + ThirteenLoko: + effects: + - !type:SatiateThirst + hydrationFactor: 2 + - !type:HealthChange + damageClass: Toxin + healthChange: 1 - type: entity id: OrganHumanLiver @@ -120,12 +305,17 @@ - type: Mechanism size: 1 compatibility: Biological - behaviors: - - !type:LiverBehavior - alcoholLethality: 0.005 - alcoholExponent: 1.6 - toxinTolerance: 3 - toxinLethality: 0.01 + - type: Metabolizer # The liver metabolizes certain chemicals only, like alcohol. + metabolisms: # TODO add the rest of alcohol + CreamyDelight: + effects: + - !type:SatiateThirst + Lean: + effects: + - !type:SatiateThirst + LeanShine: # who added this? + effects: + - !type:SatiateThirst - type: entity id: OrganHumanKidneys @@ -141,28 +331,4 @@ size: 1 compatibility: Biological -- type: entity - id: OrganHumanTongue - parent: BaseHumanOrgan - name: tongue - description: "A fleshy muscle mostly used for lying." - components: - - type: Sprite - state: tongue - - type: Mechanism - size: 1 - compatibility: Biological -- type: entity - id: OrganHumanAppendix - parent: BaseHumanOrgan - name: appendix - components: - - type: Sprite - layers: - - state: appendix - - state: appendix-inflamed - visible: false - - type: Mechanism - size: 1 - compatibility: Biological diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml index cef117e5da..8ca13d7725 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml @@ -67,7 +67,7 @@ currentTemperature: 310.15 specificHeat: 42 tempDamageCoefficient: 0.1 - - type: Metabolism + - type: Respirator metabolismHeat: 5000 radiatedHeat: 400 implicitHeatRegulation: 5000 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml index 7b5b7dfcab..cbbabdf716 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml @@ -38,7 +38,7 @@ 0: !type:NormalMobState {} 150: !type:CriticalMobState {} 200: !type:DeadMobState {} - - type: Metabolism + - type: Respirator - type: UnarmedCombat range: 1.5 arcwidth: 0 diff --git a/Resources/Prototypes/Entities/Mobs/Species/human.yml b/Resources/Prototypes/Entities/Mobs/Species/human.yml index 915d97340a..a3b82f223e 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/human.yml @@ -167,7 +167,7 @@ preset: HumanPreset - type: Damageable damageContainer: biologicalDamageContainer - - type: Metabolism + - type: Respirator metabolismHeat: 5000 radiatedHeat: 400 implicitHeatRegulation: 5000 diff --git a/Resources/Prototypes/Entities/Mobs/Species/vox.yml b/Resources/Prototypes/Entities/Mobs/Species/vox.yml index dd9f5119c7..1f097c19a2 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/vox.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/vox.yml @@ -84,7 +84,7 @@ - type: Body template: HumanoidTemplate preset: VoxPreset - - type: Metabolism + - type: Respirator needsGases: Nitrogen: 0.00060763888 producesGases: diff --git a/Resources/Prototypes/Reagents/Consumable/Drink/alcohol.yml b/Resources/Prototypes/Reagents/Consumable/Drink/alcohol.yml index b31d59a19d..bff9a06605 100644 --- a/Resources/Prototypes/Reagents/Consumable/Drink/alcohol.yml +++ b/Resources/Prototypes/Reagents/Consumable/Drink/alcohol.yml @@ -183,9 +183,6 @@ desc: A combination of cream, wine and moonshine. Why would you do this? physicalDesc: foul color: "#a6969a" - metabolism: - - !type:DefaultDrink - rate: 1 - type: reagent id: Lean @@ -193,9 +190,6 @@ desc: Turn up for days. physicalDesc: bubbly color: "#9400D3" - metabolism: - - !type:DefaultDrink - rate: 1 - type: reagent id: LeanShine @@ -203,8 +197,3 @@ desc: Lean mixed with moonshine. Turn up for months. physicalDesc: bubbly color: "#9d5fb8" - metabolism: - - !type:DefaultDrink - rate: 1 - - diff --git a/Resources/Prototypes/Reagents/Consumable/Drink/drinks.yml b/Resources/Prototypes/Reagents/Consumable/Drink/drinks.yml index b4c5009d35..baa8792dd2 100644 --- a/Resources/Prototypes/Reagents/Consumable/Drink/drinks.yml +++ b/Resources/Prototypes/Reagents/Consumable/Drink/drinks.yml @@ -4,9 +4,6 @@ desc: A drink made from brewed coffee beans. Contains a moderate amount of caffeine. physicalDesc: aromatic color: "#664300" - metabolism: - - !type:DefaultDrink - rate: 1 - type: reagent id: Tea @@ -14,9 +11,6 @@ desc: A drink made by boiling leaves of the tea tree, Camellia sinensis. physicalDesc: aromatic color: "#8a5a3a" - metabolism: - - !type:DefaultDrink - rate: 1 - type: reagent id: Cream @@ -24,9 +18,6 @@ desc: The fatty, still liquid part of milk. Why don't you mix this with sum scotch, eh? physicalDesc: creamy color: "#DFD7AF" - metabolism: - - !type:DefaultDrink - rate: 1 - type: reagent id: Milk @@ -34,9 +25,6 @@ desc: An opaque white liquid produced by the mammary glands of mammals. physicalDesc: opaque color: "#DFDFDF" - metabolism: - - !type:DefaultDrink - rate: 1 plantMetabolism: - !type:AdjustNutrition amount: 0.1 @@ -49,9 +37,6 @@ desc: This milk has gone rancid. physicalDesc: putrid color: "#faffba" - metabolism: - - !type:DefaultDrink - rate: 1 - type: reagent id: MilkSoy @@ -59,9 +44,6 @@ desc: Surprisingly tasty. physicalDesc: refreshing color: "#302000" - metabolism: - - !type:DefaultDrink - rate: 1 - type: reagent id: MilkOat @@ -69,6 +51,3 @@ desc: Surprisingly tasty. physicalDesc: refreshing color: "#302000" - metabolism: - - !type:DefaultDrink - rate: 1 diff --git a/Resources/Prototypes/Reagents/Consumable/Drink/juice.yml b/Resources/Prototypes/Reagents/Consumable/Drink/juice.yml index 44a75bbd1d..ac4a65a2f5 100644 --- a/Resources/Prototypes/Reagents/Consumable/Drink/juice.yml +++ b/Resources/Prototypes/Reagents/Consumable/Drink/juice.yml @@ -4,9 +4,6 @@ desc: It's a little piece of Eden. physicalDesc: crisp color: "#FDAD01" - metabolism: - - !type:DefaultDrink - rate: 1 - type: reagent id: JuiceBerry @@ -14,9 +11,6 @@ desc: A delicious blend of several different kinds of berries. physicalDesc: sweet color: "#660099" - metabolism: - - !type:DefaultDrink - rate: 1 - type: reagent id: JuiceBanana @@ -24,9 +18,6 @@ desc: The raw essence of a banana. HONK. physicalDesc: crisp color: "#FFE777" - metabolism: - - !type:DefaultDrink - rate: 1 #TODO: port on_mob_life: restore eyesight #if(..()) @@ -45,9 +36,6 @@ desc: It's like a carrot, but less crunchy. physicalDesc: crisp color: "#FF8820" - metabolism: - - !type:DefaultDrink - rate: 1 - type: reagent id: JuiceLime @@ -55,9 +43,6 @@ desc: The sweet-sour juice of limes. physicalDesc: citric color: "#99bb43" - metabolism: - - !type:DefaultDrink - rate: 1 - type: reagent id: JuiceLemon @@ -65,9 +50,6 @@ desc: This juice is VERY sour. physicalDesc: citric color: "#fff690" - metabolism: - - !type:DefaultDrink - rate: 1 - type: reagent id: JuiceGrape @@ -75,9 +57,6 @@ desc: Freshly squeezed juice from red grapes. Quite sweet. physicalDesc: crisp color: "#512284" - metabolism: - - !type:DefaultDrink - rate: 1 # /datum/reagent/drink/orangejuice/on_mob_life(var/mob/living/M) @@ -93,9 +72,6 @@ desc: Both delicious AND rich in Vitamin C. What more do you need? physicalDesc: citric color: "#E78108" - metabolism: - - !type:DefaultDrink - rate: 1 - type: reagent id: JuiceTomato @@ -103,9 +79,6 @@ desc: Tomatoes made into juice. What a waste of good tomatoes, huh? physicalDesc: saucey color: "#731008" - metabolism: - - !type:DefaultDrink - rate: 1 # /datum/reagent/drink/poisonberryjuice/on_mob_life(var/mob/living/M) @@ -120,9 +93,6 @@ desc: A surprisingly tasty juice blended from various kinds of very deadly and toxic berries. physicalDesc: aromatic #maybe should be 'sickly'? color: "#6600CC" - metabolism: - - !type:DefaultDrink - rate: 1 - type: reagent id: JuiceWatermelon @@ -130,9 +100,6 @@ desc: The delicious juice of a watermelon. physicalDesc: sweet color: "#EF3520" - metabolism: - - !type:DefaultDrink - rate: 1 - type: reagent id: JuicePineapple @@ -140,9 +107,6 @@ desc: The delicious juice of a pineapple. physicalDesc: tropical color: yellow - metabolism: - - !type:DefaultDrink - rate: 1 # - type: reagent # id: PotatoJuice @@ -150,6 +114,3 @@ # desc: Juice of the potato. Bleh. # physicalDesc: starchy # color: "#302000" -# metabolism: -# - !type:DefaultDrink -# rate: 1 diff --git a/Resources/Prototypes/Reagents/Consumable/Drink/soda.yml b/Resources/Prototypes/Reagents/Consumable/Drink/soda.yml index eb2b34041b..b28baa70f1 100644 --- a/Resources/Prototypes/Reagents/Consumable/Drink/soda.yml +++ b/Resources/Prototypes/Reagents/Consumable/Drink/soda.yml @@ -4,9 +4,6 @@ desc: A sweet, carbonated soft drink. Caffeine free. physicalDesc: fizzy color: "#422912" - metabolism: - - !type:DefaultDrink - rate: 1 plantMetabolism: - !type:AdjustNutrition amount: 0.1 @@ -21,12 +18,6 @@ desc: A highly processed liquid substance barely-passing intergalatic health standarts for a soft drink. physicalDesc: fizzy color: "#deb928" - metabolism: - - !type:DefaultDrink - rate: 1 - - !type:HealthChangeMetabolism - healthChange: 2 - damageClass: Toxin plantMetabolism: - !type:AdjustNutrition amount: 0.1 diff --git a/Resources/Prototypes/Reagents/Consumable/Food/condiments.yml b/Resources/Prototypes/Reagents/Consumable/Food/condiments.yml index 88183dbfb6..8cdcb5903a 100644 --- a/Resources/Prototypes/Reagents/Consumable/Food/condiments.yml +++ b/Resources/Prototypes/Reagents/Consumable/Food/condiments.yml @@ -4,9 +4,6 @@ desc: The sweetness of a thousand sugars but none of the calories. # physicalDesc: color: aquamarine - metabolism: - - !type:DefaultFood - rate: 1 - type: reagent id: BbqSauce @@ -14,9 +11,6 @@ desc: Hand wipes not included. physicalDesc: Gloopy. color: darkred - metabolism: - - !type:DefaultFood - rate: 1 - type: reagent id: Cornoil @@ -24,9 +18,6 @@ desc: Corn oil, A delicious oil used in cooking. Made from corn. # physicalDesc: color: yellow - metabolism: - - !type:DefaultFood - rate: 1 - type: reagent id: Frostoil @@ -34,9 +25,6 @@ desc: Leaves the tongue numb in its passage. # physicalDesc: color: skyblue - metabolism: - - !type:DefaultFood - rate: 1 - type: reagent id: HorseradishSauce @@ -44,9 +32,6 @@ desc: Smelly horseradish sauce. physicalDesc: Overpowering. color: gray - metabolism: - - !type:DefaultFood - rate: 1 - type: reagent id: Hotsauce @@ -54,9 +39,6 @@ desc: Burns so good. # physicalDesc: color: red - metabolism: - - !type:DefaultFood - rate: 1 - type: reagent id: Ketchup @@ -64,9 +46,6 @@ desc: Made from pureed tomatoes and flavored with spices. # physicalDesc: color: red - metabolism: - - !type:DefaultFood - rate: 1 - type: reagent id: Soysauce @@ -74,6 +53,3 @@ desc: A salty soy-based flavoring. # physicalDesc: color: saddlebrown - metabolism: - - !type:DefaultFood - rate: 1 diff --git a/Resources/Prototypes/Reagents/Consumable/Food/ingredients.yml b/Resources/Prototypes/Reagents/Consumable/Food/ingredients.yml index ee13427ec1..bfeed21bb5 100644 --- a/Resources/Prototypes/Reagents/Consumable/Food/ingredients.yml +++ b/Resources/Prototypes/Reagents/Consumable/Food/ingredients.yml @@ -4,9 +4,6 @@ desc: Used for baking. physicalDesc: powdery color: white - metabolism: - - !type:DefaultFood - rate: 1 - type: reagent id: Oats @@ -14,18 +11,12 @@ desc: Used for a variety of tasty purposes. physicalDesc: coarse color: tan - metabolism: - - !type:DefaultFood - rate: 1 - type: reagent id: Enzyme name: universal enzyme desc: Used in cooking various dishes. color: "#009900" - metabolism: - - !type:DefaultFood - rate: 1 - type: reagent id: Egg @@ -33,9 +24,6 @@ desc: Used for baking. physicalDesc: mucus-like color: white - metabolism: - - !type:DefaultFood - rate: 1 - type: reagent id: Sugar @@ -43,9 +31,6 @@ desc: Tasty spacey sugar! physicalDesc: color: white - metabolism: - - !type:DefaultFood - rate: 1 - type: reagent id: Salt @@ -53,9 +38,6 @@ desc: Salt. From space oceans, presumably. physicalDesc: Coarse. color: white - metabolism: - - !type:DefaultFood - rate: 1 - type: reagent id: Blackpepper @@ -63,33 +45,21 @@ desc: Often used to flavor food or make people sneeze. physicalDesc: Grainy. color: black - metabolism: - - !type:DefaultFood - rate: 1 - type: reagent id: Vinegar name: vinegar desc: Often used to flavor food. color: tan - metabolism: - - !type:DefaultFood - rate: 1 - type: reagent id: Rice name: rice desc: Hard, small white grains. color: white - metabolism: - - !type:DefaultFood - rate: 1 - type: reagent id: OilOlive name: olive oil desc: Viscous and fragrant. color: olive - metabolism: - - !type:DefaultFood - rate: 1 diff --git a/Resources/Prototypes/Reagents/chemicals.yml b/Resources/Prototypes/Reagents/chemicals.yml index 3d6d49be64..ff882e463c 100644 --- a/Resources/Prototypes/Reagents/chemicals.yml +++ b/Resources/Prototypes/Reagents/chemicals.yml @@ -89,9 +89,6 @@ desc: All the vitamins, minerals, and carbohydrates the body needs in pure form. physicalDesc: opaque color: "#664330" - metabolism: - - !type:DefaultFood - rate: 1 plantMetabolism: - !type:AdjustNutrition amount: 1 @@ -180,7 +177,7 @@ amount: 10 - !type:AdjustHealth amount: -5 - + - type: reagent id: SulfuricAcid name: sulfuric acid @@ -218,9 +215,6 @@ color: "#c0e0ff20" boilingPoint: 100.0 meltingPoint: 0.0 - metabolism: - - !type:DefaultDrink - rate: 1 tileReactions: - !type:ExtinguishTileReaction {} - !type:SpillIfPuddlePresentTileReaction {} @@ -234,7 +228,7 @@ desc: Used by chefs to cook. physicalDesc: oily color: "#b67823" - boilingPoint: 300.0 + boilingPoint: 300.0 meltingPoint: -16.0 tileReactions: - !type:FlammableTileReaction {} diff --git a/Resources/Prototypes/Reagents/medicine.yml b/Resources/Prototypes/Reagents/medicine.yml index 16dba85352..c49cc13300 100644 --- a/Resources/Prototypes/Reagents/medicine.yml +++ b/Resources/Prototypes/Reagents/medicine.yml @@ -18,10 +18,6 @@ desc: A broad-spectrum anti-toxin, which treats toxin damage in the blood stream. Overdosing will cause vomiting, dizzyness and pain. physicalDesc: translucent color: "#3a1d8a" - metabolism: - - !type:HealthChangeMetabolism - healthChange: -1 - damageClass: Toxin plantMetabolism: - !type:AdjustToxins amount: -10 @@ -34,13 +30,6 @@ desc: A slightly unstable medication used for the most extreme any serious case of radiation poisoning. Lowers radiation level at over twice the rate Hyronalin does and will heal toxin damage at the same time. Deals very minor brute damage to the patient over time, but the patient's body will typically out-regenerate it easily. physicalDesc: cloudy color: "#bd5902" - metabolism: - - !type:HealthChangeMetabolism - healthChange: -1 - damageClass: Toxin #I think you need multiple of these components for different types of damage so I'll maybe change it to work better in the future - - !type:HealthChangeMetabolism - healthChange: 0.5 - damageClass: Brute - type: reagent id: Bicaridine @@ -48,10 +37,6 @@ desc: An analgesic which is highly effective at treating brute damage. It is useful for stabilizing people who have been severely beaten, as well as treating less life-threatening injuries. In the case of bleeding (internal or external), bicaridine will slow down the bleeding heavily. If the dosage exceeds the overdose limit, it'll stop it outright. physicalDesc: opaque color: "#ffaa00" - metabolism: - - !type:HealthChangeMetabolism - healthChange: -2 - damageClass: Brute - type: reagent id: Cryoxadone @@ -90,10 +75,6 @@ desc: An advanced chemical that is more effective at treating burn damage than Kelotane. physicalDesc: translucent color: "#215263" - metabolism: - - !type:HealthChangeMetabolism - healthChange: -3 - damageClass: Burn - type: reagent id: Dexalin @@ -101,21 +82,13 @@ desc: Used for treating oxygen deprivation. In most cases where it is likely to be needed, the strength of Dexalin Plus will probably be more useful (Results in 1 unit instead of 2). physicalDesc: opaque color: "#0041a8" - metabolism: - - !type:HealthChangeMetabolism - healthChange: -1 - damageClass: Airloss #this may be asphyxiation - + - type: reagent id: DexalinPlus name: dexalin plus desc: Used in treatment of extreme cases of oxygen deprivation. Even a single unit immediately counters all oxygen loss, which is hugely useful in many circumstances. Any dose beyond this will continue to counter oxygen loss until it is metabolized, essentially removing the need to breathe. physicalDesc: cloudy color: "#4da0bd" - metabolism: - - !type:HealthChangeMetabolism - healthChange: -3 - damageClass: Airloss - type: reagent id: Ethylredoxrazine @@ -165,10 +138,6 @@ desc: Treats burn damage and prevents infection. physicalDesc: strong-smelling color: "#bf3d19" - metabolism: - - !type:HealthChangeMetabolism - healthChange: -1 - damageClass: Burn - type: reagent id: Leporazine @@ -201,7 +170,7 @@ - type: reagent id: Paroxetine name: paroxetine - desc: Prevents hallucination, but has a 10% chance of causing intense hallucinations. + desc: Prevents hallucination, but has a 10% chance of causing intense hallucinations. physicalDesc: acrid color: "#fffbad" @@ -225,11 +194,6 @@ desc: Toxic, but treats hallucinations, drowsiness & halves the duration of paralysis, stuns and knockdowns. It is metabolized very slowly. One unit is enough to treat hallucinations; two units is deadly. physicalDesc: pungent color: "#d49a2f" - metabolism: - - !type:HealthChangeMetabolism - healthChange: 0.67 - damageClass: Toxin - rate: 0.2 - type: reagent id: Tramadol @@ -289,10 +253,6 @@ plantMetabolism: - !type:AdjustToxins amount: 10 - metabolism: - - !type:HealthChangeMetabolism - healthChange: 1 - damageClass: Airloss - type: reagent id: Impedrezene @@ -307,10 +267,6 @@ desc: Temporarily stops respiration and causes tissue damage. Large doses are fatal, and will cause people to pass out very quickly. Dexalin and Dexalin Plus will both remove it, however. physicalDesc: pungent color: "#6b0007" - metabolism: - - !type:HealthChangeMetabolism - healthChange: 7 - damageClass: Airloss - type: reagent id: Lipozine @@ -356,24 +312,10 @@ desc: Pure THC oil, extracted from the leaves of the cannabis plant. Much stronger than in it's natural form and can be used to numb chronic pain in patients. physicalDesc: skunky color: "#DAA520" - + - type: reagent id: Omnizine name: Omnizine desc: A soothing milky liquid with an iridescent gleam. A well known conspiracy theory says that it's origins remain a mystery because knowing the secrets of its production would render most commercial pharmaceuticals obsolete. physicalDesc: soothing color: "#fcf7f9" - metabolism: - - !type:HealthChangeMetabolism - healthChange: -2 - damageClass: Burn - - !type:HealthChangeMetabolism - healthChange: -2 - damageClass: Toxin - - !type:HealthChangeMetabolism - healthChange: -2 - damageClass: Airloss - - !type:HealthChangeMetabolism - healthChange: -2 - damageClass: Brute -