Metabolism refactor (#4395)
* metabolism -> respirator, add reageanteffect and reagenteffectcondition, start on metabolizercomp/system * move LiverBehavior metabolism logic to Metabolizer * minor tweaks and update all YAML * how about actually taking conditions into account * off by one * removals * reviews
This commit is contained in:
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
[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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
[DataDefinition]
|
||||
public class DefaultFood : DefaultMetabolizable
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// How much hunger is satiated when 1u of the reagent is metabolized
|
||||
/// </summary>
|
||||
[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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
[DataDefinition]
|
||||
public class HealthChangeMetabolism : DefaultMetabolizable
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// How much damage is changed when 1u of the reagent is metabolized.
|
||||
/// </summary>
|
||||
[DataField("healthChange")]
|
||||
public float HealthChange { get; set; } = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Class of damage changed, Brute, Burn, Toxin, Airloss.
|
||||
/// </summary>
|
||||
[DataField("damageClass")]
|
||||
public DamageClass DamageType { get; set; } = DamageClass.Brute;
|
||||
|
||||
private float _accumulatedHealth;
|
||||
|
||||
/// <summary>
|
||||
/// Remove reagent at set rate, changes damage if a DamageableComponent can be found.
|
||||
/// </summary>
|
||||
/// <param name="solutionEntity"></param>
|
||||
/// <param name="reagentId"></param>
|
||||
/// <param name="tickTime"></param>
|
||||
/// <param name="availableReagent">Reagent available to be metabolized.</param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Used for implementing reagent effects that require a certain amount of reagent before it should be applied.
|
||||
/// For instance, overdoses.
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
56
Content.Server/Chemistry/ReagentEffects/HealthChange.cs
Normal file
56
Content.Server/Chemistry/ReagentEffects/HealthChange.cs
Normal file
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Default metabolism for medicine reagents. Attempts to find a DamageableComponent on the target,
|
||||
/// and to update its damage values.
|
||||
/// </summary>
|
||||
public class HealthChange : ReagentEffect
|
||||
{
|
||||
/// <summary>
|
||||
/// How much damage is changed when 1u of the reagent is metabolized.
|
||||
/// </summary>
|
||||
[DataField("healthChange")]
|
||||
public float AmountToChange { get; set; } = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Class of damage changed, Brute, Burn, Toxin, Airloss.
|
||||
/// </summary>
|
||||
[DataField("damageClass")]
|
||||
public DamageClass DamageType { get; set; } = DamageClass.Brute;
|
||||
|
||||
private float _accumulatedHealth;
|
||||
|
||||
/// <summary>
|
||||
/// Changes damage if a DamageableComponent can be found.
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
28
Content.Server/Chemistry/ReagentEffects/SatiateHunger.cs
Normal file
28
Content.Server/Chemistry/ReagentEffects/SatiateHunger.cs
Normal file
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Attempts to find a HungerComponent on the target,
|
||||
/// and to update it's hunger values.
|
||||
/// </summary>
|
||||
public class SatiateHunger : ReagentEffect
|
||||
{
|
||||
/// <summary>
|
||||
/// How much hunger is satiated when 1u of the reagent is metabolized
|
||||
/// </summary>
|
||||
[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);
|
||||
}
|
||||
}
|
||||
}
|
||||
28
Content.Server/Chemistry/ReagentEffects/SatiateThirst.cs
Normal file
28
Content.Server/Chemistry/ReagentEffects/SatiateThirst.cs
Normal file
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Default metabolism for drink reagents. Attempts to find a ThirstComponent on the target,
|
||||
/// and to update it's thirst values.
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user