Files
tbd-station-14/Content.Server/GameObjects/Components/Body/Behavior/LiverBehavior.cs
ike709 7b3e25b3ef Basic liver mechanism (#3424)
* Basic liver mechanism

* makes the stupid thing work
2021-02-28 02:58:08 +01:00

117 lines
4.2 KiB
C#

#nullable enable
using System.Linq;
using Content.Server.GameObjects.Components.Body.Circulatory;
using Content.Shared.Chemistry;
using Content.Shared.GameObjects.Components.Body.Networks;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
namespace Content.Server.GameObjects.Components.Body.Behavior
{
/// <summary>
/// Metabolizes reagents in <see cref="SharedBloodstreamComponent"/> after they are digested.
/// </summary>
public class LiverBehavior : MechanismBehavior
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
private float _accumulatedFrameTime;
/// <summary>
/// Whether the liver is functional.
/// </summary>
[ViewVariables] private bool _liverFailing = false;
/// <summary>
/// Modifier for alcohol damage.
/// </summary>
[ViewVariables] private float _alcoholLethality = 0.005f;
/// <summary>
/// Modifier for alcohol damage.
/// </summary>
[ViewVariables] private float _alcoholExponent = 1.6f;
/// <summary>
/// Toxin volume that can be purged without damage.
/// </summary>
[ViewVariables] private float _toxinTolerance = 3f;
/// <summary>
/// Toxin damage modifier.
/// </summary>
[ViewVariables] private float _toxinLethality = 0.01f;
/// <summary>
/// Loops through each reagent in _internalSolution,
/// and calls <see cref="IMetabolizable.Metabolize"/> for each of them.
/// Also handles toxins and alcohol.
/// </summary>
/// <param name="frameTime">
/// The time since the last update in seconds.
/// </param>
public override void Update(float frameTime)
{
if (Body == null)
{
return;
}
_accumulatedFrameTime += frameTime;
// Update at most once per second
if (_accumulatedFrameTime < 1)
{
return;
}
_accumulatedFrameTime -= 1;
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;
}
//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, frameTime);
bloodstream.Solution.TryRemoveReagent(reagent.ReagentId, reagentDelta);
}
}
}
public override void ExposeData(ObjectSerializer serializer)
{
//Uses typical human values for defaults.
base.ExposeData(serializer);
serializer.DataField(ref _alcoholLethality, "alcoholLethality", 0.005f);
serializer.DataField(ref _alcoholExponent, "alcoholExponent", 1.6f);
serializer.DataField(ref _toxinTolerance, "toxinTolerance", 3f);
serializer.DataField(ref _toxinLethality, "toxinLethality", 0.01f);
}
}
}