Fix dual port vents 2: Electric Boogaloo (#8396)
This commit is contained in:
@@ -1,46 +0,0 @@
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Piping.Unary.Components;
|
||||
|
||||
namespace Content.Server.Atmos.Piping.Binary.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed class GasDualPortVentPumpComponent : Component
|
||||
{
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool Welded { get; set; } = false;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("inlet")]
|
||||
public string InletName { get; set; } = "inlet";
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("outlet")]
|
||||
public string OutletName { get; set; } = "outlet";
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public VentPumpDirection PumpDirection { get; set; } = VentPumpDirection.Releasing;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public DualPortVentPressureBound PressureChecks { get; set; } = DualPortVentPressureBound.ExternalBound;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float ExternalPressureBound { get; set; } = Atmospherics.OneAtmosphere;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float InputPressureMin { get; set; } = 0f;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float OutputPressureMax { get; set; } = 0f;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum DualPortVentPressureBound : sbyte
|
||||
{
|
||||
NoBound = 0,
|
||||
ExternalBound = 1,
|
||||
InputMinimum = 2,
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.Atmos.Piping.Binary.Components;
|
||||
using Content.Server.Atmos.Piping.Components;
|
||||
using Content.Server.NodeContainer;
|
||||
using Content.Server.NodeContainer.Nodes;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Piping.Unary.Components;
|
||||
using Content.Shared.Atmos.Visuals;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Content.Server.Atmos.Piping.Binary.EntitySystems
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public sealed class GasDualPortVentPumpSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<GasDualPortVentPumpComponent, AtmosDeviceUpdateEvent>(OnGasDualPortVentPumpUpdated);
|
||||
SubscribeLocalEvent<GasDualPortVentPumpComponent, AtmosDeviceDisabledEvent>(OnGasDualPortVentPumpDisabled);
|
||||
}
|
||||
|
||||
private void OnGasDualPortVentPumpUpdated(EntityUid uid, GasDualPortVentPumpComponent vent, AtmosDeviceUpdateEvent args)
|
||||
{
|
||||
var appearance = EntityManager.GetComponentOrNull<AppearanceComponent>(vent.Owner);
|
||||
|
||||
if (vent.Welded)
|
||||
{
|
||||
appearance?.SetData(VentPumpVisuals.State, VentPumpState.Welded);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!vent.Enabled
|
||||
|| !EntityManager.TryGetComponent(uid, out NodeContainerComponent? nodeContainer)
|
||||
|| !nodeContainer.TryGetNode(vent.InletName, out PipeNode? inlet)
|
||||
|| !nodeContainer.TryGetNode(vent.OutletName, out PipeNode? outlet))
|
||||
{
|
||||
appearance?.SetData(VentPumpVisuals.State, VentPumpState.Off);
|
||||
return;
|
||||
}
|
||||
|
||||
var environment = _atmosphereSystem.GetTileMixture(EntityManager.GetComponent<TransformComponent>(vent.Owner).Coordinates, true);
|
||||
|
||||
// We're in an air-blocked tile... Do nothing.
|
||||
if (environment == null)
|
||||
{
|
||||
appearance?.SetData(VentPumpVisuals.State, VentPumpState.Off);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vent.PumpDirection == VentPumpDirection.Releasing)
|
||||
{
|
||||
appearance?.SetData(VentPumpVisuals.State, VentPumpState.Out);
|
||||
var pressureDelta = 10000f;
|
||||
|
||||
if ((vent.PressureChecks & DualPortVentPressureBound.ExternalBound) != 0)
|
||||
pressureDelta = MathF.Min(pressureDelta, (vent.ExternalPressureBound - environment.Pressure));
|
||||
|
||||
if ((vent.PressureChecks & DualPortVentPressureBound.InputMinimum) != 0)
|
||||
pressureDelta = MathF.Min(pressureDelta, (inlet.Air.Pressure - vent.InputPressureMin));
|
||||
|
||||
if (pressureDelta > 0 && inlet.Air.Temperature > 0)
|
||||
{
|
||||
var transferMoles = pressureDelta * environment.Volume / inlet.Air.Temperature * Atmospherics.R;
|
||||
var removed = inlet.Air.Remove(transferMoles);
|
||||
_atmosphereSystem.Merge(environment, removed);
|
||||
}
|
||||
}
|
||||
else if (vent.PumpDirection == VentPumpDirection.Siphoning && environment.Pressure > 0f)
|
||||
{
|
||||
appearance?.SetData(VentPumpVisuals.State, VentPumpState.In);
|
||||
var ourMultiplier = outlet.Air.Volume / environment.Temperature * Atmospherics.R;
|
||||
var molesDelta = 10000 * ourMultiplier;
|
||||
|
||||
if ((vent.PressureChecks & DualPortVentPressureBound.ExternalBound) != 0)
|
||||
molesDelta =
|
||||
MathF.Min(molesDelta,
|
||||
(environment.Pressure - vent.OutputPressureMax) * environment.Volume / (environment.Temperature * Atmospherics.R));
|
||||
|
||||
if ((vent.PressureChecks &DualPortVentPressureBound.InputMinimum) != 0)
|
||||
molesDelta = MathF.Min(molesDelta, (vent.InputPressureMin - outlet.Air.Pressure) * ourMultiplier);
|
||||
|
||||
if (molesDelta > 0)
|
||||
{
|
||||
var removed = environment.Remove(molesDelta);
|
||||
|
||||
_atmosphereSystem.Merge(outlet.Air, removed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGasDualPortVentPumpDisabled(EntityUid uid, GasDualPortVentPumpComponent vent, AtmosDeviceDisabledEvent args)
|
||||
{
|
||||
if (EntityManager.TryGetComponent(uid, out AppearanceComponent? appearance))
|
||||
{
|
||||
appearance.SetData(VentPumpVisuals.State, VentPumpState.Off);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Piping.Unary.Components;
|
||||
using Content.Shared.MachineLinking;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
namespace Content.Server.Atmos.Piping.Unary.Components
|
||||
{
|
||||
@@ -17,7 +19,11 @@ namespace Content.Server.Atmos.Piping.Unary.Components
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("inlet")]
|
||||
public string InletName { get; set; } = "pipe";
|
||||
public string Inlet { get; set; } = "pipe";
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("outlet")]
|
||||
public string Outlet { get; set; } = "pipe";
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("pumpDirection")]
|
||||
@@ -72,6 +78,28 @@ namespace Content.Server.Atmos.Piping.Unary.Components
|
||||
[DataField("targetPressureChange")]
|
||||
public float TargetPressureChange = Atmospherics.OneAtmosphere;
|
||||
|
||||
#region Machine Linking
|
||||
/// <summary>
|
||||
/// Whether or not machine linking is enabled for this component.
|
||||
/// </summary>
|
||||
[DataField("canLink")]
|
||||
public readonly bool CanLink = false;
|
||||
|
||||
[DataField("pressurizePort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))]
|
||||
public string PressurizePort = "Pressurize";
|
||||
|
||||
[DataField("depressurizePort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))]
|
||||
public string DepressurizePort = "Depressurize";
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("pressurizePressure")]
|
||||
public float PressurizePressure = Atmospherics.OneAtmosphere;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("depressurizePressure")]
|
||||
public float DepressurizePressure = 0;
|
||||
#endregion
|
||||
|
||||
public GasVentPumpData ToAirAlarmData()
|
||||
{
|
||||
return new GasVentPumpData
|
||||
|
||||
@@ -6,6 +6,8 @@ using Content.Server.Atmos.Piping.Unary.Components;
|
||||
using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.MachineLinking.Events;
|
||||
using Content.Server.MachineLinking.System;
|
||||
using Content.Server.NodeContainer;
|
||||
using Content.Server.NodeContainer.Nodes;
|
||||
using Content.Server.Power.Components;
|
||||
@@ -24,6 +26,7 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
|
||||
{
|
||||
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
|
||||
[Dependency] private readonly DeviceNetworkSystem _deviceNetSystem = default!;
|
||||
[Dependency] private readonly SignalLinkerSystem _signalSystem = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly SharedAmbientSoundSystem _ambientSoundSystem = default!;
|
||||
|
||||
@@ -37,6 +40,8 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
|
||||
SubscribeLocalEvent<GasVentPumpComponent, AtmosMonitorAlarmEvent>(OnAtmosAlarm);
|
||||
SubscribeLocalEvent<GasVentPumpComponent, PowerChangedEvent>(OnPowerChanged);
|
||||
SubscribeLocalEvent<GasVentPumpComponent, DeviceNetworkPacketEvent>(OnPacketRecv);
|
||||
SubscribeLocalEvent<GasVentPumpComponent, ComponentInit>(OnInit);
|
||||
SubscribeLocalEvent<GasVentPumpComponent, SignalReceivedEvent>(OnSignalReceived);
|
||||
}
|
||||
|
||||
private void OnGasVentPumpUpdated(EntityUid uid, GasVentPumpComponent vent, AtmosDeviceUpdateEvent args)
|
||||
@@ -47,10 +52,17 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
|
||||
return;
|
||||
}
|
||||
|
||||
var nodeName = vent.PumpDirection switch
|
||||
{
|
||||
VentPumpDirection.Releasing => vent.Inlet,
|
||||
VentPumpDirection.Siphoning => vent.Outlet,
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
|
||||
if (!vent.Enabled
|
||||
|| !TryComp(uid, out AtmosDeviceComponent? device)
|
||||
|| !TryComp(uid, out NodeContainerComponent? nodeContainer)
|
||||
|| !nodeContainer.TryGetNode(vent.InletName, out PipeNode? pipe))
|
||||
|| !nodeContainer.TryGetNode(nodeName, out PipeNode? pipe))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -191,6 +203,33 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
|
||||
}
|
||||
}
|
||||
|
||||
private void OnInit(EntityUid uid, GasVentPumpComponent component, ComponentInit args)
|
||||
{
|
||||
if (component.CanLink)
|
||||
_signalSystem.EnsureReceiverPorts(uid, component.PressurizePort, component.DepressurizePort);
|
||||
}
|
||||
|
||||
private void OnSignalReceived(EntityUid uid, GasVentPumpComponent component, SignalReceivedEvent args)
|
||||
{
|
||||
if (!component.CanLink)
|
||||
return;
|
||||
|
||||
if (args.Port == component.PressurizePort)
|
||||
{
|
||||
component.PumpDirection = VentPumpDirection.Releasing;
|
||||
component.ExternalPressureBound = component.PressurizePressure;
|
||||
component.PressureChecks = VentPressureBound.ExternalBound;
|
||||
UpdateState(uid, component);
|
||||
}
|
||||
else if (args.Port == component.DepressurizePort)
|
||||
{
|
||||
component.PumpDirection = VentPumpDirection.Siphoning;
|
||||
component.ExternalPressureBound = component.DepressurizePressure;
|
||||
component.PressureChecks = VentPressureBound.ExternalBound;
|
||||
UpdateState(uid, component);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateState(EntityUid uid, GasVentPumpComponent vent, AppearanceComponent? appearance = null)
|
||||
{
|
||||
if (!Resolve(uid, ref appearance, false))
|
||||
|
||||
@@ -27,3 +27,9 @@ signal-port-description-order-sender = Cargo console order sender
|
||||
|
||||
signal-port-name-order-receiver = Order receiver
|
||||
signal-port-description-order-receiver = Cargo console order receiver
|
||||
|
||||
signal-port-name-pressurize = Pressurize
|
||||
signal-port-description-pressurize = Causes the device to starts releasing air until some target pressure is reached.
|
||||
|
||||
signal-port-name-depressurize = Depressurize
|
||||
signal-port-description-depressurize = Causes the device to starts siphoning air until some target pressure is reached.
|
||||
|
||||
@@ -206,10 +206,10 @@
|
||||
node: port
|
||||
|
||||
- type: entity
|
||||
parent: GasUnaryBase
|
||||
parent: GasVentPump
|
||||
id: GasDualPortVentPump
|
||||
name: dual-port air vent
|
||||
description: Has a valve and a pump attached to it. There are two ports.
|
||||
description: Has a valve and a pump attached to it. There are two ports, one is an input for releasing air, the other is an output when siphoning.
|
||||
placement:
|
||||
mode: SnapgridCenter
|
||||
components:
|
||||
@@ -228,6 +228,19 @@
|
||||
- type: PipeColorVisualizer
|
||||
- type: VentPumpVisualizer
|
||||
- type: GasVentPump
|
||||
inlet: inlet
|
||||
outlet: outlet
|
||||
canLink: true
|
||||
- type: Construction
|
||||
graph: GasBinary
|
||||
node: dualportventpump
|
||||
- type: NodeContainer
|
||||
nodes:
|
||||
inlet:
|
||||
!type:PipeNode
|
||||
nodeGroupID: Pipe
|
||||
pipeDirection: North
|
||||
outlet:
|
||||
!type:PipeNode
|
||||
nodeGroupID: Pipe
|
||||
pipeDirection: South
|
||||
|
||||
@@ -42,3 +42,13 @@
|
||||
id: OrderReceiver
|
||||
name: signal-port-name-order-receiver
|
||||
description: signal-port-description-order-receiver
|
||||
|
||||
- type: receiverPort
|
||||
id: Pressurize
|
||||
name: signal-port-name-pressurize
|
||||
description: signal-port-description-pressurize
|
||||
|
||||
- type: receiverPort
|
||||
id: Depressurize
|
||||
name: signal-port-name-depressurize
|
||||
description: signal-port-description-depressurize
|
||||
|
||||
Reference in New Issue
Block a user