2020-09-13 14:23:52 +02:00
using System.Linq ;
using Content.Server.Atmos ;
2020-08-27 09:45:27 -06:00
using Content.Server.GameObjects.Components.NodeContainer ;
using Content.Server.GameObjects.Components.NodeContainer.Nodes ;
2020-09-13 14:23:52 +02:00
using Content.Shared.GameObjects.Components.Atmos ;
2020-08-31 04:33:05 -06:00
using Robust.Server.GameObjects ;
2020-10-12 05:02:57 -06:00
using Robust.Shared.GameObjects ;
using Robust.Shared.GameObjects.Components.Transform ;
2020-08-27 09:45:27 -06:00
using Robust.Shared.Log ;
using Robust.Shared.Serialization ;
using Robust.Shared.ViewVariables ;
2020-09-13 14:23:52 +02:00
namespace Content.Server.GameObjects.Components.Atmos.Piping.Pumps
2020-08-27 09:45:27 -06:00
{
/// <summary>
/// Transfer gas from one <see cref="PipeNode"/> to another.
/// </summary>
public abstract class BasePumpComponent : PipeNetDeviceComponent
{
2020-08-31 16:29:53 -06:00
/// <summary>
/// If the pump is currently pumping.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public bool PumpEnabled
{
get = > _pumpEnabled ;
set
{
_pumpEnabled = value ;
UpdateAppearance ( ) ;
}
}
2020-10-12 05:02:57 -06:00
private bool _pumpEnabled ;
2020-08-31 16:29:53 -06:00
2020-08-27 09:45:27 -06:00
/// <summary>
/// Needs to be same <see cref="PipeDirection"/> as that of a <see cref="Pipe"/> on this entity.
/// </summary>
[ViewVariables]
private PipeDirection _inletDirection ;
/// <summary>
/// Needs to be same <see cref="PipeDirection"/> as that of a <see cref="Pipe"/> on this entity.
/// </summary>
[ViewVariables]
private PipeDirection _outletDirection ;
[ViewVariables]
private PipeNode _inletPipe ;
[ViewVariables]
private PipeNode _outletPipe ;
2020-08-31 04:33:05 -06:00
private AppearanceComponent _appearance ;
2020-08-27 09:45:27 -06:00
public override void ExposeData ( ObjectSerializer serializer )
{
base . ExposeData ( serializer ) ;
serializer . DataField ( ref _inletDirection , "inletDirection" , PipeDirection . None ) ;
serializer . DataField ( ref _outletDirection , "outletDirection" , PipeDirection . None ) ;
2020-10-12 05:02:57 -06:00
serializer . DataField ( ref _pumpEnabled , "pumpEnabled" , false ) ;
2020-08-27 09:45:27 -06:00
}
public override void Initialize ( )
{
base . Initialize ( ) ;
2020-10-12 05:02:57 -06:00
UpdatePipes ( ) ;
Owner . EntityManager . EventBus . SubscribeEvent < RotateEvent > ( EventSource . Local , this , RotateEvent ) ;
2020-08-31 04:33:05 -06:00
Owner . TryGetComponent ( out _appearance ) ;
UpdateAppearance ( ) ;
2020-08-27 09:45:27 -06:00
}
public override void Update ( )
{
2020-08-31 16:29:53 -06:00
if ( ! PumpEnabled )
return ;
2020-08-27 09:45:27 -06:00
PumpGas ( _inletPipe . Air , _outletPipe . Air ) ;
}
protected abstract void PumpGas ( GasMixture inletGas , GasMixture outletGas ) ;
2020-08-31 04:33:05 -06:00
2020-10-12 05:02:57 -06:00
private void RotateEvent ( RotateEvent ev )
{
if ( ev . Sender ! = Owner | | ev . NewRotation = = ev . OldRotation )
return ;
var diff = ev . NewRotation - ev . OldRotation ;
_inletDirection = _inletDirection . RotatePipeDirection ( diff ) ;
_outletDirection = _outletDirection . RotatePipeDirection ( diff ) ;
UpdatePipes ( ) ;
}
2020-08-31 04:33:05 -06:00
private void UpdateAppearance ( )
{
2020-10-12 05:02:57 -06:00
if ( _inletPipe = = null | | _outletPipe = = null ) return ;
2020-08-31 16:29:53 -06:00
_appearance ? . SetData ( PumpVisuals . VisualState , new PumpVisualState ( _inletDirection , _outletDirection , _inletPipe . ConduitLayer , _outletPipe . ConduitLayer , PumpEnabled ) ) ;
2020-08-31 04:33:05 -06:00
}
2020-10-12 05:02:57 -06:00
private void UpdatePipes ( )
{
_inletPipe = null ;
_outletPipe = null ;
if ( ! Owner . TryGetComponent < NodeContainerComponent > ( out var container ) )
{
JoinedGridAtmos ? . RemovePipeNetDevice ( this ) ;
Logger . Error ( $"{typeof(BasePumpComponent)} on entity {Owner.Uid} did not have a {nameof(NodeContainerComponent)}." ) ;
return ;
}
var pipeNodes = container . Nodes . OfType < PipeNode > ( ) ;
_inletPipe = pipeNodes . Where ( pipe = > pipe . PipeDirection = = _inletDirection ) . FirstOrDefault ( ) ;
_outletPipe = pipeNodes . Where ( pipe = > pipe . PipeDirection = = _outletDirection ) . FirstOrDefault ( ) ;
if ( _inletPipe = = null | _outletPipe = = null )
{
JoinedGridAtmos ? . RemovePipeNetDevice ( this ) ;
Logger . Error ( $"{typeof(BasePumpComponent)} on entity {Owner.Uid} could not find compatible {nameof(PipeNode)}s on its {nameof(NodeContainerComponent)}." ) ;
return ;
}
}
2020-08-27 09:45:27 -06:00
}
}