diff --git a/Content.Server/Atmos/Monitor/Components/AtmosMonitorComponent.cs b/Content.Server/Atmos/Monitor/Components/AtmosMonitorComponent.cs index cb6d4d1630162b..830479561dea0a 100644 --- a/Content.Server/Atmos/Monitor/Components/AtmosMonitorComponent.cs +++ b/Content.Server/Atmos/Monitor/Components/AtmosMonitorComponent.cs @@ -48,7 +48,9 @@ public sealed partial class AtmosMonitorComponent : Component [DataField("gasThresholds")] public Dictionary? GasThresholds; - // Stores a reference to the gas on the tile this is on. + /// + /// Stores a reference to the gas on the tile this entity is on (or the pipe network it monitors; see ). + /// [ViewVariables] public GasMixture? TileGas; @@ -65,4 +67,19 @@ public sealed partial class AtmosMonitorComponent : Component /// [DataField("registeredDevices")] public HashSet RegisteredDevices = new(); + + /// + /// Specifies whether this device monitors its own internal pipe network rather than the surrounding atmosphere. + /// + /// + /// If 'true', the entity will require a NodeContainerComponent with one or more PipeNodes to function. + /// + [DataField] + public bool MonitorsPipeNet = false; + + /// + /// Specifies the name of the pipe node that this device is monitoring. + /// + [DataField] + public string NodeNameMonitoredPipe = "monitored"; } diff --git a/Content.Server/Atmos/Monitor/Systems/AtmosMonitoringSystem.cs b/Content.Server/Atmos/Monitor/Systems/AtmosMonitoringSystem.cs index fbe74cbab7f902..17a24b1b0cb6b1 100644 --- a/Content.Server/Atmos/Monitor/Systems/AtmosMonitoringSystem.cs +++ b/Content.Server/Atmos/Monitor/Systems/AtmosMonitoringSystem.cs @@ -4,6 +4,9 @@ using Content.Server.Atmos.Piping.EntitySystems; using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork.Systems; +using Content.Server.NodeContainer; +using Content.Server.NodeContainer.EntitySystems; +using Content.Server.NodeContainer.Nodes; using Content.Server.Power.Components; using Content.Server.Power.EntitySystems; using Content.Shared.Atmos; @@ -25,6 +28,7 @@ public sealed class AtmosMonitorSystem : EntitySystem [Dependency] private readonly AtmosDeviceSystem _atmosDeviceSystem = default!; [Dependency] private readonly DeviceNetworkSystem _deviceNetSystem = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly NodeContainerSystem _nodeContainerSystem = default!; // Commands public const string AtmosMonitorSetThresholdCmd = "atmos_monitor_set_threshold"; @@ -56,8 +60,15 @@ private void OnAtmosDeviceLeaveAtmosphere(EntityUid uid, AtmosMonitorComponent a private void OnAtmosDeviceEnterAtmosphere(EntityUid uid, AtmosMonitorComponent atmosMonitor, ref AtmosDeviceEnabledEvent args) { + if (atmosMonitor.MonitorsPipeNet && _nodeContainerSystem.TryGetNode(uid, atmosMonitor.NodeNameMonitoredPipe, out var pipeNode)) + { + atmosMonitor.TileGas = pipeNode.Air; + return; + } + atmosMonitor.TileGas = _atmosphereSystem.GetContainingMixture(uid, true); } + private void OnMapInit(EntityUid uid, AtmosMonitorComponent component, MapInitEvent args) { if (component.TemperatureThresholdId != null) @@ -206,7 +217,7 @@ private void OnAtmosUpdate(EntityUid uid, AtmosMonitorComponent component, ref A if (!this.IsPowered(uid, EntityManager)) return; - if (args.Grid == null) + if (args.Grid == null) return; // if we're not monitoring atmos, don't bother @@ -215,6 +226,10 @@ private void OnAtmosUpdate(EntityUid uid, AtmosMonitorComponent component, ref A && component.GasThresholds == null) return; + // If monitoring a pipe network, get its most recent gas mixture + if (component.MonitorsPipeNet && _nodeContainerSystem.TryGetNode(uid, component.NodeNameMonitoredPipe, out var pipeNode)) + component.TileGas = pipeNode.Air; + UpdateState(uid, component.TileGas, component); } diff --git a/Resources/Locale/en-US/atmos/gas-pipe-sensor.ftl b/Resources/Locale/en-US/atmos/gas-pipe-sensor.ftl new file mode 100644 index 00000000000000..8c3b8962e32780 --- /dev/null +++ b/Resources/Locale/en-US/atmos/gas-pipe-sensor.ftl @@ -0,0 +1,5 @@ +gas-pipe-sensor-distribution-loop = Distribution loop +gas-pipe-sensor-waste-loop = Waste loop +gas-pipe-sensor-mixed-air = Mixed air +gas-pipe-sensor-teg-hot-loop = TEG hot loop +gas-pipe-sensor-teg-cold-loop = TEG cold loop diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/gas_pipe_sensor.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/gas_pipe_sensor.yml new file mode 100644 index 00000000000000..08015abe7d6595 --- /dev/null +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/gas_pipe_sensor.yml @@ -0,0 +1,84 @@ +- type: entity + parent: [AirSensorBase, GasPipeBase] + id: GasPipeSensor + name: gas pipe sensor + description: Reports on the status of the gas in the attached pipe network. + placement: + mode: SnapgridCenter + components: + - type: Sprite + sprite: Structures/Piping/Atmospherics/gas_pipe_sensor.rsi + drawdepth: BelowFloor + layers: + - sprite: Structures/Piping/Atmospherics/pipe.rsi + map: [ "enum.PipeVisualLayers.Pipe" ] + state: pipeStraight + - map: ["base"] + state: base + - map: [ "enum.PowerDeviceVisualLayers.Powered" ] + state: lights + shader: unshaded + - type: Appearance + - type: GenericVisualizer + visuals: + enum.PowerDeviceVisuals.Powered: + enum.PowerDeviceVisualLayers.Powered: + False: { state: blank } + True: { state: lights } + - type: AtmosMonitor + monitorsPipeNet: true + - type: ApcPowerReceiver + - type: ExtensionCableReceiver + - type: Construction + graph: GasPipeSensor + node: sensor + - type: NodeContainer + nodes: + monitored: + !type:PipeNode + nodeGroupID: Pipe + pipeDirection: Longitudinal + - type: Tag + tags: + - AirSensor + - Unstackable + +- type: entity + parent: GasPipeSensor + id: GasPipeSensorDistribution + suffix: Distribution + components: + - type: Label + currentLabel: gas-pipe-sensor-distribution-loop + +- type: entity + parent: GasPipeSensor + id: GasPipeSensorWaste + suffix: Waste + components: + - type: Label + currentLabel: gas-pipe-sensor-waste-loop + +- type: entity + parent: GasPipeSensor + id: GasPipeSensorMixedAir + suffix: Mixed air + components: + - type: Label + currentLabel: gas-pipe-sensor-mixed-air + +- type: entity + parent: GasPipeSensor + id: GasPipeSensorTEGHot + suffix: TEG hot + components: + - type: Label + currentLabel: gas-pipe-sensor-teg-hot-loop + +- type: entity + parent: GasPipeSensor + id: GasPipeSensorTEGCold + suffix: TEG cold + components: + - type: Label + currentLabel: gas-pipe-sensor-teg-cold-loop \ No newline at end of file diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/utilities/gas_pipe_sensor.yml b/Resources/Prototypes/Recipes/Construction/Graphs/utilities/gas_pipe_sensor.yml new file mode 100644 index 00000000000000..bda6d036e9b9e7 --- /dev/null +++ b/Resources/Prototypes/Recipes/Construction/Graphs/utilities/gas_pipe_sensor.yml @@ -0,0 +1,29 @@ +- type: constructionGraph + id: GasPipeSensor + start: start + graph: + - node: start + edges: + - to: sensor + steps: + - material: Steel + amount: 2 + doAfter: 1 + + - node: sensor + entity: GasPipeSensor + actions: + - !type:SetAnchor + edges: + - to: start + completed: + - !type:SpawnPrototype + prototype: SheetSteel1 + amount: 2 + - !type:DeleteEntity + conditions: + - !type:EntityAnchored + anchored: false + steps: + - tool: Welding + doAfter: 1 \ No newline at end of file diff --git a/Resources/Prototypes/Recipes/Construction/utilities.yml b/Resources/Prototypes/Recipes/Construction/utilities.yml index 5dc0168fd36ca3..2dec0e4a7d5ab7 100644 --- a/Resources/Prototypes/Recipes/Construction/utilities.yml +++ b/Resources/Prototypes/Recipes/Construction/utilities.yml @@ -366,6 +366,21 @@ objectType: Structure canRotate: true +- type: construction + name: gas pipe sensor + id: GasPipeSensor + graph: GasPipeSensor + startNode: start + targetNode: sensor + category: construction-category-structures + description: Reports on the status of the gas within the attached pipe network. + icon: + sprite: Structures/Piping/Atmospherics/gas_pipe_sensor.rsi + state: icon + placementMode: SnapgridCenter + objectType: Structure + canRotate: true + # ATMOS PIPES - type: construction name: gas pipe half diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/base.png b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/base.png new file mode 100644 index 00000000000000..4a9a8f6f206949 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/base.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/blank.png b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/blank.png new file mode 100644 index 00000000000000..7bee0a002b75fb Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/blank.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/icon.png b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/icon.png new file mode 100644 index 00000000000000..4ac9e76480361a Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/icon.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/lights.png b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/lights.png new file mode 100644 index 00000000000000..6108d2b9949213 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/lights.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/meta.json new file mode 100644 index 00000000000000..878c7817a2b387 --- /dev/null +++ b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/meta.json @@ -0,0 +1,29 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Created by chromiumboy (github) for SS14, based on the digital valve from /tg/, taken from https://github.com/tgstation/tgstation at commit 57cd1d59ca019dd0e7811ac451f295f818e573da.", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "base" + }, + { + "name": "blank" + }, + { + "name": "lights", + "delays": [ + [ + 1.0, + 0.25 + ] + ] + } + ] +}