diff --git a/Content.Server/Atmos/Piping/Binary/Components/GasDualPortVentPumpComponent.cs b/Content.Server/Atmos/Piping/Binary/Components/GasDualPortVentPumpComponent.cs deleted file mode 100644 index d26970fb04..0000000000 --- a/Content.Server/Atmos/Piping/Binary/Components/GasDualPortVentPumpComponent.cs +++ /dev/null @@ -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, - } -} diff --git a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasDualPortVentPumpSystem.cs b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasDualPortVentPumpSystem.cs deleted file mode 100644 index 0ffeca3973..0000000000 --- a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasDualPortVentPumpSystem.cs +++ /dev/null @@ -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(OnGasDualPortVentPumpUpdated); - SubscribeLocalEvent(OnGasDualPortVentPumpDisabled); - } - - private void OnGasDualPortVentPumpUpdated(EntityUid uid, GasDualPortVentPumpComponent vent, AtmosDeviceUpdateEvent args) - { - var appearance = EntityManager.GetComponentOrNull(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(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); - } - } - } -} diff --git a/Content.Server/Atmos/Piping/Unary/Components/GasVentPumpComponent.cs b/Content.Server/Atmos/Piping/Unary/Components/GasVentPumpComponent.cs index 5b19eb3168..9289f6c804 100644 --- a/Content.Server/Atmos/Piping/Unary/Components/GasVentPumpComponent.cs +++ b/Content.Server/Atmos/Piping/Unary/Components/GasVentPumpComponent.cs @@ -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 + /// + /// Whether or not machine linking is enabled for this component. + /// + [DataField("canLink")] + public readonly bool CanLink = false; + + [DataField("pressurizePort", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string PressurizePort = "Pressurize"; + + [DataField("depressurizePort", customTypeSerializer: typeof(PrototypeIdSerializer))] + 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 diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs index 36fa196eb9..5351e6e2a9 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs @@ -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(OnAtmosAlarm); SubscribeLocalEvent(OnPowerChanged); SubscribeLocalEvent(OnPacketRecv); + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(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)) diff --git a/Resources/Locale/en-US/machine-linking/receiver_ports.ftl b/Resources/Locale/en-US/machine-linking/receiver_ports.ftl index 1aa3505f43..1879039550 100644 --- a/Resources/Locale/en-US/machine-linking/receiver_ports.ftl +++ b/Resources/Locale/en-US/machine-linking/receiver_ports.ftl @@ -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. diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml index 4e6d190112..6f9c17991a 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml @@ -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 diff --git a/Resources/Prototypes/MachineLinking/receiver_ports.yml b/Resources/Prototypes/MachineLinking/receiver_ports.yml index 7a4385e70c..cf3596fe10 100644 --- a/Resources/Prototypes/MachineLinking/receiver_ports.yml +++ b/Resources/Prototypes/MachineLinking/receiver_ports.yml @@ -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