De-hardcode chemical metabolism of StomachComponent (#437)

* Move chemical reaction effects into Chemistry/ReactionEffects/ subfolder

* Replace hardcoded StomachComponent metabolism with IMetabolizable

The benefits of this approach are that reagent metabolism effects are not hardcoded into StomachComponent, and metabolism effects can be more easily chained together in yaml prototypes, and reagents can have different metabolism rates. One problem with this approach is that getting metabolism rates slower than 1u / second is impossible. Implementing #377 should resolve that problem.

* Fix DefaultFood and DefaultDrink so they remove reagent regardless of Hunger/ThirstComponent presence

Previously if neither of those were present the reagents wouldn't be removed from the stomach. This fixes that.

* Additional comment on function

* Make metabolizer interface implementations explicit

Also removed some unused using statements

* Make StomachComponent._reagentDeltas readonly

* Fix misleading variable names and docs for metabolizables

Changes one of the arguments for `IMetabolizable.Metabolize()` to be called `tickTime` instead of `frameTime` to more accurately reflect it's purpose. It's not really the frametime, but the time since the last metabolism tick. Also updated and expanded the docs to reflect this and to be more clear.
This commit is contained in:
moneyl
2019-11-21 17:24:19 -05:00
committed by Pieter-Jan Briers
parent 1f177a044d
commit 3ab8036363
11 changed files with 213 additions and 85 deletions

View File

@@ -0,0 +1,41 @@
using System;
using Content.Server.GameObjects.Components.Nutrition;
using Content.Shared.Interfaces.Chemistry;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Serialization;
using Robust.Shared.Serialization;
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.
/// </summary>
class DefaultDrink : IMetabolizable
{
//Rate of metabolism in units / second
private int _metabolismRate;
public int MetabolismRate => _metabolismRate;
//How much thirst is satiated when 1u of the reagent is metabolized
private float _hydrationFactor;
public float HydrationFactor => _hydrationFactor;
void IExposeData.ExposeData(ObjectSerializer serializer)
{
serializer.DataField(ref _metabolismRate, "rate", 1);
serializer.DataField(ref _hydrationFactor, "nutrimentFactor", 30.0f);
}
//Remove reagent at set rate, satiate thirst if a ThirstComponent can be found
int IMetabolizable.Metabolize(IEntity solutionEntity, string reagentId, float tickTime)
{
int metabolismAmount = (int)Math.Round(MetabolismRate * tickTime);
if (solutionEntity.TryGetComponent(out ThirstComponent thirst))
thirst.UpdateThirst(metabolismAmount * HydrationFactor);
//Return amount of reagent to be removed, remove reagent regardless of ThirstComponent presence
return metabolismAmount;
}
}
}

View File

@@ -0,0 +1,41 @@
using System;
using Content.Server.GameObjects.Components.Nutrition;
using Content.Shared.Interfaces.Chemistry;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Serialization;
using Robust.Shared.Serialization;
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.
/// </summary>
class DefaultFood : IMetabolizable
{
//Rate of metabolism in units / second
private int _metabolismRate;
public int MetabolismRate => _metabolismRate;
//How much hunger is satiated when 1u of the reagent is metabolized
private float _nutritionFactor;
public float NutritionFactor => _nutritionFactor;
void IExposeData.ExposeData(ObjectSerializer serializer)
{
serializer.DataField(ref _metabolismRate, "rate", 1);
serializer.DataField(ref _nutritionFactor, "nutrimentFactor", 30.0f);
}
//Remove reagent at set rate, satiate hunger if a HungerComponent can be found
int IMetabolizable.Metabolize(IEntity solutionEntity, string reagentId, float tickTime)
{
int metabolismAmount = (int)Math.Round(MetabolismRate * tickTime);
if (solutionEntity.TryGetComponent(out HungerComponent hunger))
hunger.UpdateFood(metabolismAmount * NutritionFactor);
//Return amount of reagent to be removed, remove reagent regardless of HungerComponent presence
return metabolismAmount;
}
}
}

View File

@@ -5,7 +5,7 @@ using Content.Shared.Interfaces;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Serialization;
namespace Content.Server.Chemistry
namespace Content.Server.Chemistry.ReactionEffects
{
class ExplosionReactionEffect : IReactionEffect
{