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;
|
||||||
using Content.Shared.Atmos.Piping.Unary.Components;
|
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
|
namespace Content.Server.Atmos.Piping.Unary.Components
|
||||||
{
|
{
|
||||||
@@ -17,7 +19,11 @@ namespace Content.Server.Atmos.Piping.Unary.Components
|
|||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
[DataField("inlet")]
|
[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)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
[DataField("pumpDirection")]
|
[DataField("pumpDirection")]
|
||||||
@@ -72,6 +78,28 @@ namespace Content.Server.Atmos.Piping.Unary.Components
|
|||||||
[DataField("targetPressureChange")]
|
[DataField("targetPressureChange")]
|
||||||
public float TargetPressureChange = Atmospherics.OneAtmosphere;
|
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()
|
public GasVentPumpData ToAirAlarmData()
|
||||||
{
|
{
|
||||||
return new GasVentPumpData
|
return new GasVentPumpData
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ using Content.Server.Atmos.Piping.Unary.Components;
|
|||||||
using Content.Server.DeviceNetwork;
|
using Content.Server.DeviceNetwork;
|
||||||
using Content.Server.DeviceNetwork.Components;
|
using Content.Server.DeviceNetwork.Components;
|
||||||
using Content.Server.DeviceNetwork.Systems;
|
using Content.Server.DeviceNetwork.Systems;
|
||||||
|
using Content.Server.MachineLinking.Events;
|
||||||
|
using Content.Server.MachineLinking.System;
|
||||||
using Content.Server.NodeContainer;
|
using Content.Server.NodeContainer;
|
||||||
using Content.Server.NodeContainer.Nodes;
|
using Content.Server.NodeContainer.Nodes;
|
||||||
using Content.Server.Power.Components;
|
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 AtmosphereSystem _atmosphereSystem = default!;
|
||||||
[Dependency] private readonly DeviceNetworkSystem _deviceNetSystem = default!;
|
[Dependency] private readonly DeviceNetworkSystem _deviceNetSystem = default!;
|
||||||
|
[Dependency] private readonly SignalLinkerSystem _signalSystem = default!;
|
||||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
[Dependency] private readonly SharedAmbientSoundSystem _ambientSoundSystem = default!;
|
[Dependency] private readonly SharedAmbientSoundSystem _ambientSoundSystem = default!;
|
||||||
|
|
||||||
@@ -37,6 +40,8 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
|
|||||||
SubscribeLocalEvent<GasVentPumpComponent, AtmosMonitorAlarmEvent>(OnAtmosAlarm);
|
SubscribeLocalEvent<GasVentPumpComponent, AtmosMonitorAlarmEvent>(OnAtmosAlarm);
|
||||||
SubscribeLocalEvent<GasVentPumpComponent, PowerChangedEvent>(OnPowerChanged);
|
SubscribeLocalEvent<GasVentPumpComponent, PowerChangedEvent>(OnPowerChanged);
|
||||||
SubscribeLocalEvent<GasVentPumpComponent, DeviceNetworkPacketEvent>(OnPacketRecv);
|
SubscribeLocalEvent<GasVentPumpComponent, DeviceNetworkPacketEvent>(OnPacketRecv);
|
||||||
|
SubscribeLocalEvent<GasVentPumpComponent, ComponentInit>(OnInit);
|
||||||
|
SubscribeLocalEvent<GasVentPumpComponent, SignalReceivedEvent>(OnSignalReceived);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGasVentPumpUpdated(EntityUid uid, GasVentPumpComponent vent, AtmosDeviceUpdateEvent args)
|
private void OnGasVentPumpUpdated(EntityUid uid, GasVentPumpComponent vent, AtmosDeviceUpdateEvent args)
|
||||||
@@ -47,10 +52,17 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var nodeName = vent.PumpDirection switch
|
||||||
|
{
|
||||||
|
VentPumpDirection.Releasing => vent.Inlet,
|
||||||
|
VentPumpDirection.Siphoning => vent.Outlet,
|
||||||
|
_ => throw new ArgumentOutOfRangeException()
|
||||||
|
};
|
||||||
|
|
||||||
if (!vent.Enabled
|
if (!vent.Enabled
|
||||||
|| !TryComp(uid, out AtmosDeviceComponent? device)
|
|| !TryComp(uid, out AtmosDeviceComponent? device)
|
||||||
|| !TryComp(uid, out NodeContainerComponent? nodeContainer)
|
|| !TryComp(uid, out NodeContainerComponent? nodeContainer)
|
||||||
|| !nodeContainer.TryGetNode(vent.InletName, out PipeNode? pipe))
|
|| !nodeContainer.TryGetNode(nodeName, out PipeNode? pipe))
|
||||||
{
|
{
|
||||||
return;
|
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)
|
private void UpdateState(EntityUid uid, GasVentPumpComponent vent, AppearanceComponent? appearance = null)
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref appearance, false))
|
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-name-order-receiver = Order receiver
|
||||||
signal-port-description-order-receiver = Cargo console 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
|
node: port
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: GasUnaryBase
|
parent: GasVentPump
|
||||||
id: GasDualPortVentPump
|
id: GasDualPortVentPump
|
||||||
name: dual-port air vent
|
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:
|
placement:
|
||||||
mode: SnapgridCenter
|
mode: SnapgridCenter
|
||||||
components:
|
components:
|
||||||
@@ -228,6 +228,19 @@
|
|||||||
- type: PipeColorVisualizer
|
- type: PipeColorVisualizer
|
||||||
- type: VentPumpVisualizer
|
- type: VentPumpVisualizer
|
||||||
- type: GasVentPump
|
- type: GasVentPump
|
||||||
|
inlet: inlet
|
||||||
|
outlet: outlet
|
||||||
|
canLink: true
|
||||||
- type: Construction
|
- type: Construction
|
||||||
graph: GasBinary
|
graph: GasBinary
|
||||||
node: dualportventpump
|
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
|
id: OrderReceiver
|
||||||
name: signal-port-name-order-receiver
|
name: signal-port-name-order-receiver
|
||||||
description: signal-port-description-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