GasFilterComponent (#2935)

* GasFilterComponent

* Client ignore component

* Diff fixes

* diff fix 2

Co-authored-by: py01 <pyronetics01@gmail.com>
This commit is contained in:
py01
2021-01-13 16:15:53 -06:00
committed by GitHub
parent 02f0620b48
commit 1f18dd568a
5 changed files with 251 additions and 2 deletions

View File

@@ -0,0 +1,179 @@
#nullable enable
using Content.Server.Atmos;
using Content.Server.GameObjects.Components.NodeContainer;
using Content.Server.GameObjects.Components.NodeContainer.Nodes;
using Content.Shared.Atmos;
using Content.Shared.GameObjects.Components.Atmos;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.ComponentDependencies;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Log;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
using System;
using System.Linq;
namespace Content.Server.GameObjects.Components.Atmos.Piping.Filters
{
[RegisterComponent]
public class GasFilterComponent : Component
{
public override string Name => "GasFilter";
/// <summary>
/// If the filter is currently filtering.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public bool FilterEnabled
{
get => _filterEnabled;
set
{
_filterEnabled = value;
UpdateAppearance();
}
}
private bool _filterEnabled;
[ViewVariables(VVAccess.ReadWrite)]
public Gas GasToFilter
{
get => _gasToFilter;
set
{
_gasToFilter = value;
UpdateAppearance();
}
}
private Gas _gasToFilter;
[ViewVariables(VVAccess.ReadWrite)]
public int VolumeFilterRate
{
get => _volumeFilterRate;
set => _volumeFilterRate = Math.Clamp(value, 0, MaxVolumeFilterRate);
}
private int _volumeFilterRate;
[ViewVariables(VVAccess.ReadWrite)]
public int MaxVolumeFilterRate
{
get => _maxVolumeFilterRate;
set => Math.Max(value, 0);
}
private int _maxVolumeFilterRate;
[ViewVariables]
private PipeDirection _initialInletDirection;
/// <summary>
/// The direction the filtered-out gas goes.
/// </summary>
[ViewVariables]
private PipeDirection _initialFilterOutletDirection;
/// <summary>
/// The direction the rest of the gas goes.
/// </summary>
[ViewVariables]
private PipeDirection _initialOutletDirection;
[ViewVariables]
private PipeNode? _inletPipe;
[ViewVariables]
private PipeNode? _filterOutletPipe;
[ViewVariables]
private PipeNode? _outletPipe;
[ComponentDependency]
private readonly AppearanceComponent? _appearance = default;
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _volumeFilterRate, "startingVolumePumpRate", 0);
serializer.DataField(ref _maxVolumeFilterRate, "maxVolumePumpRate", 100);
serializer.DataField(ref _gasToFilter, "gasToFilter", Gas.Phoron);
serializer.DataField(ref _initialInletDirection, "inletDirection", PipeDirection.None);
serializer.DataField(ref _initialFilterOutletDirection, "filterOutletDirection", PipeDirection.None);
serializer.DataField(ref _initialOutletDirection, "outletDirection", PipeDirection.None);
}
public override void Initialize()
{
base.Initialize();
Owner.EnsureComponent<PipeNetDeviceComponent>();
SetPipes();
UpdateAppearance();
}
public override void HandleMessage(ComponentMessage message, IComponent? component)
{
base.HandleMessage(message, component);
switch (message)
{
case PipeNetUpdateMessage:
Update();
break;
}
}
public void Update()
{
if (!FilterEnabled)
return;
if (_inletPipe == null || _inletPipe.Air == null ||
_filterOutletPipe == null || _filterOutletPipe.Air == null ||
_outletPipe == null || _outletPipe.Air == null)
return;
FilterGas(_inletPipe.Air, _filterOutletPipe.Air, _outletPipe.Air);
}
private void FilterGas(GasMixture inletGas, GasMixture filterOutletGas, GasMixture outletGas)
{
var volumeRatio = Math.Clamp(VolumeFilterRate / inletGas.Volume, 0, 1);
var gas = inletGas.RemoveRatio(volumeRatio);
var molesToSeperate = gas.GetMoles(GasToFilter);
gas.SetMoles(GasToFilter, 0);
filterOutletGas.AdjustMoles(GasToFilter, molesToSeperate);
outletGas.Merge(gas);
}
private void UpdateAppearance()
{
_appearance?.SetData(FilterVisuals.VisualState, new FilterVisualState());
}
private void SetPipes()
{
_inletPipe = null;
_filterOutletPipe = null;
_outletPipe = null;
if (!Owner.TryGetComponent<NodeContainerComponent>(out var container))
{
Logger.Error($"{typeof(GasFilterComponent)} on {Owner?.Prototype?.ID}, Uid {Owner?.Uid} did not have a {nameof(NodeContainerComponent)}.");
return;
}
var pipeNodes = container.Nodes.OfType<PipeNode>();
_inletPipe = pipeNodes.Where(pipe => pipe.PipeDirection == _initialInletDirection).FirstOrDefault();
_filterOutletPipe = pipeNodes.Where(pipe => pipe.PipeDirection == _initialFilterOutletDirection).FirstOrDefault();
_outletPipe = pipeNodes.Where(pipe => pipe.PipeDirection == _initialOutletDirection).FirstOrDefault();
if (_inletPipe == null || _filterOutletPipe == null || _outletPipe == null)
{
Logger.Error($"{typeof(GasFilterComponent)} on {Owner?.Prototype?.ID}, Uid {Owner?.Uid} could not find compatible {nameof(PipeNode)}s on its {nameof(NodeContainerComponent)}.");
return;
}
}
}
}