2021-11-04 19:41:56 -05:00
using System ;
2021-12-10 12:23:18 -06:00
using Content.Server.Administration.Logs ;
2021-07-19 12:07:37 +02:00
using Content.Server.Atmos.EntitySystems ;
2021-06-19 13:25:05 +02:00
using Content.Server.Atmos.Piping.Binary.Components ;
using Content.Server.Atmos.Piping.Components ;
using Content.Server.NodeContainer ;
2021-07-04 18:11:52 +02:00
using Content.Server.NodeContainer.Nodes ;
2021-11-04 19:41:56 -05:00
using Content.Shared.Atmos ;
using Content.Shared.Atmos.Piping.Binary.Components ;
2021-12-10 12:23:18 -06:00
using Content.Shared.Database ;
2021-10-19 21:46:31 +00:00
using Content.Shared.Examine ;
2021-11-04 19:41:56 -05:00
using Content.Shared.Interaction ;
2021-11-11 16:10:21 -06:00
using Content.Shared.Popups ;
2021-06-19 13:25:05 +02:00
using JetBrains.Annotations ;
2021-11-04 19:41:56 -05:00
using Robust.Server.GameObjects ;
2021-06-19 13:25:05 +02:00
using Robust.Shared.GameObjects ;
using Robust.Shared.IoC ;
2021-10-19 21:46:31 +00:00
using Robust.Shared.Localization ;
2021-06-19 13:25:05 +02:00
using Robust.Shared.Timing ;
namespace Content.Server.Atmos.Piping.Binary.EntitySystems
{
[UsedImplicitly]
public class GasVolumePumpSystem : EntitySystem
{
2021-07-26 12:58:17 +02:00
[Dependency] private readonly IGameTiming _gameTiming = default ! ;
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default ! ;
2021-11-04 19:41:56 -05:00
[Dependency] private UserInterfaceSystem _userInterfaceSystem = default ! ;
2021-12-10 12:23:18 -06:00
[Dependency] private AdminLogSystem _adminLogSystem = default ! ;
2021-06-19 13:25:05 +02:00
public override void Initialize ( )
{
base . Initialize ( ) ;
SubscribeLocalEvent < GasVolumePumpComponent , AtmosDeviceUpdateEvent > ( OnVolumePumpUpdated ) ;
2021-10-19 21:46:31 +00:00
SubscribeLocalEvent < GasVolumePumpComponent , ExaminedEvent > ( OnExamined ) ;
2021-11-04 19:41:56 -05:00
SubscribeLocalEvent < GasVolumePumpComponent , InteractHandEvent > ( OnPumpInteractHand ) ;
// Bound UI subscriptions
SubscribeLocalEvent < GasVolumePumpComponent , GasVolumePumpChangeTransferRateMessage > ( OnTransferRateChangeMessage ) ;
SubscribeLocalEvent < GasVolumePumpComponent , GasVolumePumpToggleStatusMessage > ( OnToggleStatusMessage ) ;
2021-10-19 21:46:31 +00:00
}
private void OnExamined ( EntityUid uid , GasVolumePumpComponent pump , ExaminedEvent args )
{
2021-12-08 13:00:43 +01:00
if ( ! EntityManager . GetComponent < TransformComponent > ( pump . Owner ) . Anchored | | ! args . IsInDetailsRange ) // Not anchored? Out of range? No status.
2021-10-19 21:46:31 +00:00
return ;
if ( Loc . TryGetString ( "gas-volume-pump-system-examined" , out var str ,
( "statusColor" , "lightblue" ) , // TODO: change with volume?
( "rate" , pump . TransferRate )
) )
args . PushMarkup ( str ) ;
2021-06-19 13:25:05 +02:00
}
private void OnVolumePumpUpdated ( EntityUid uid , GasVolumePumpComponent pump , AtmosDeviceUpdateEvent args )
{
if ( ! pump . Enabled )
return ;
2021-09-28 13:35:29 +02:00
if ( ! EntityManager . TryGetComponent ( uid , out NodeContainerComponent ? nodeContainer ) )
2021-06-19 13:25:05 +02:00
return ;
2021-09-28 13:35:29 +02:00
if ( ! EntityManager . TryGetComponent ( uid , out AtmosDeviceComponent ? device ) )
2021-06-19 13:25:05 +02:00
return ;
if ( ! nodeContainer . TryGetNode ( pump . InletName , out PipeNode ? inlet )
| | ! nodeContainer . TryGetNode ( pump . OutletName , out PipeNode ? outlet ) )
return ;
var inputStartingPressure = inlet . Air . Pressure ;
var outputStartingPressure = outlet . Air . Pressure ;
// Pump mechanism won't do anything if the pressure is too high/too low unless you overclock it.
if ( ( inputStartingPressure < pump . LowerThreshold ) | | ( outputStartingPressure > pump . HigherThreshold ) & & ! pump . Overclocked )
return ;
// Overclocked pumps can only force gas a certain amount.
if ( ( outputStartingPressure - inputStartingPressure > pump . OverclockThreshold ) & & pump . Overclocked )
return ;
// We multiply the transfer rate in L/s by the seconds passed since the last process to get the liters.
var transferRatio = ( float ) ( pump . TransferRate * ( _gameTiming . CurTime - device . LastProcess ) . TotalSeconds ) / inlet . Air . Volume ;
var removed = inlet . Air . RemoveRatio ( transferRatio ) ;
// Some of the gas from the mixture leaks when overclocked.
if ( pump . Overclocked )
{
2021-12-08 13:00:43 +01:00
var tile = _atmosphereSystem . GetTileMixture ( EntityManager . GetComponent < TransformComponent > ( pump . Owner ) . Coordinates , true ) ;
2021-06-19 13:25:05 +02:00
if ( tile ! = null )
{
var leaked = removed . RemoveRatio ( pump . LeakRatio ) ;
2021-07-26 12:58:17 +02:00
_atmosphereSystem . Merge ( tile , leaked ) ;
2021-06-19 13:25:05 +02:00
}
}
outlet . AssumeAir ( removed ) ;
}
2021-11-04 19:41:56 -05:00
private void OnPumpInteractHand ( EntityUid uid , GasVolumePumpComponent component , InteractHandEvent args )
{
2021-12-08 13:00:43 +01:00
if ( ! EntityManager . TryGetComponent ( args . User , out ActorComponent ? actor ) )
2021-11-04 19:41:56 -05:00
return ;
2021-12-08 13:00:43 +01:00
if ( EntityManager . GetComponent < TransformComponent > ( component . Owner ) . Anchored )
2021-11-11 16:10:21 -06:00
{
_userInterfaceSystem . TryOpen ( uid , GasVolumePumpUiKey . Key , actor . PlayerSession ) ;
DirtyUI ( uid , component ) ;
}
else
{
args . User . PopupMessageCursor ( Loc . GetString ( "comp-gas-pump-ui-needs-anchor" ) ) ;
}
2021-11-04 19:41:56 -05:00
args . Handled = true ;
}
private void OnToggleStatusMessage ( EntityUid uid , GasVolumePumpComponent pump , GasVolumePumpToggleStatusMessage args )
{
pump . Enabled = args . Enabled ;
2021-12-10 12:23:18 -06:00
_adminLogSystem . Add ( LogType . AtmosPowerChanged , LogImpact . Medium ,
$"{EntityManager.ToPrettyString(args.Session.AttachedEntity!.Value):player} set the power on {EntityManager.ToPrettyString(uid):device} to {args.Enabled}" ) ;
2021-11-04 19:41:56 -05:00
DirtyUI ( uid , pump ) ;
}
private void OnTransferRateChangeMessage ( EntityUid uid , GasVolumePumpComponent pump , GasVolumePumpChangeTransferRateMessage args )
{
pump . TransferRate = Math . Clamp ( args . TransferRate , 0f , Atmospherics . MaxTransferRate ) ;
2021-12-10 12:23:18 -06:00
_adminLogSystem . Add ( LogType . AtmosVolumeChanged , LogImpact . Medium ,
$"{EntityManager.ToPrettyString(args.Session.AttachedEntity!.Value):player} set the transfer rate on {EntityManager.ToPrettyString(uid):device} to {args.TransferRate}" ) ;
2021-11-04 19:41:56 -05:00
DirtyUI ( uid , pump ) ;
}
private void DirtyUI ( EntityUid uid , GasVolumePumpComponent ? pump )
{
if ( ! Resolve ( uid , ref pump ) )
return ;
_userInterfaceSystem . TrySetUiState ( uid , GasVolumePumpUiKey . Key ,
2021-12-08 13:00:43 +01:00
new GasVolumePumpBoundUserInterfaceState ( EntityManager . GetComponent < MetaDataComponent > ( pump . Owner ) . EntityName , pump . TransferRate , pump . Enabled ) ) ;
2021-11-04 19:41:56 -05:00
}
2021-06-19 13:25:05 +02:00
}
}