Files
tbd-station-14/Content.Server/GameObjects/Components/Body/Respiratory/LungComponent.cs
DrSmugleaf 34b2902641 Fix errors with creating gas mixtures on class instantiation (#1916)
* Fix errors when gas mixtures are created on class instantiation

* Fix mistake
2020-08-25 16:53:59 +02:00

130 lines
3.6 KiB
C#

using System;
using Content.Server.Atmos;
using Content.Server.GameObjects.Components.Body.Circulatory;
using Content.Server.Interfaces;
using Content.Shared.Atmos;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
namespace Content.Server.GameObjects.Components.Body.Respiratory
{
[RegisterComponent]
public class LungComponent : Component, IGasMixtureHolder
{
public override string Name => "Lung";
private float _accumulatedFrameTime;
/// <summary>
/// The pressure that this lung exerts on the air around it
/// </summary>
[ViewVariables(VVAccess.ReadWrite)] private float Pressure { get; set; }
[ViewVariables] public GasMixture Air { get; set; }
[ViewVariables] public LungStatus Status { get; set; }
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
Air = new GasMixture();
serializer.DataReadWriteFunction(
"volume",
6,
vol => Air.Volume = vol,
() => Air.Volume);
serializer.DataField(this, l => l.Pressure, "pressure", 100);
}
public void Update(float frameTime)
{
if (Status == LungStatus.None)
{
Status = LungStatus.Inhaling;
}
_accumulatedFrameTime += Status switch
{
LungStatus.Inhaling => frameTime,
LungStatus.Exhaling => -frameTime,
_ => throw new ArgumentOutOfRangeException()
};
var absoluteTime = Math.Abs(_accumulatedFrameTime);
if (absoluteTime < 2)
{
return;
}
switch (Status)
{
case LungStatus.Inhaling:
Inhale(absoluteTime);
Status = LungStatus.Exhaling;
break;
case LungStatus.Exhaling:
Exhale(absoluteTime);
Status = LungStatus.Inhaling;
break;
default:
throw new ArgumentOutOfRangeException();
}
_accumulatedFrameTime = absoluteTime - 2;
}
public void Inhale(float frameTime)
{
if (!Owner.TryGetComponent(out BloodstreamComponent bloodstream))
{
return;
}
if (!Owner.Transform.GridPosition.TryGetTileAir(out var tileAir))
{
return;
}
var amount = Atmospherics.BreathPercentage * frameTime;
var volumeRatio = amount / tileAir.Volume;
var temp = tileAir.RemoveRatio(volumeRatio);
temp.PumpGasTo(Air, Pressure);
Air.PumpGasTo(bloodstream.Air, Pressure);
tileAir.Merge(temp);
}
public void Exhale(float frameTime)
{
if (!Owner.TryGetComponent(out BloodstreamComponent bloodstream))
{
return;
}
if (!Owner.Transform.GridPosition.TryGetTileAir(out var tileAir))
{
return;
}
bloodstream.PumpToxins(Air, Pressure);
var amount = Atmospherics.BreathPercentage * frameTime;
var volumeRatio = amount / tileAir.Volume;
var temp = tileAir.RemoveRatio(volumeRatio);
temp.PumpGasTo(tileAir, Pressure);
Air.Merge(temp);
}
}
public enum LungStatus
{
None = 0,
Inhaling,
Exhaling
}
}