diff --git a/Content.Client/Atmos/Visualizers/GasValveVisualizer.cs b/Content.Client/Atmos/Visualizers/GasValveVisualizer.cs new file mode 100644 index 0000000000..6cd963b4a4 --- /dev/null +++ b/Content.Client/Atmos/Visualizers/GasValveVisualizer.cs @@ -0,0 +1,18 @@ +using System; +using Content.Shared.Atmos.Piping; +using JetBrains.Annotations; + +namespace Content.Client.Atmos.Visualizers +{ + [UsedImplicitly] + public class GasValveVisualizer : EnabledAtmosDeviceVisualizer + { + protected override object LayerMap => Layers.Enabled; + protected override Enum DataKey => FilterVisuals.Enabled; + + enum Layers : byte + { + Enabled, + } + } +} diff --git a/Content.Server/Atmos/Piping/Binary/Components/GasValveComponent.cs b/Content.Server/Atmos/Piping/Binary/Components/GasValveComponent.cs index 9076207be2..e912685333 100644 --- a/Content.Server/Atmos/Piping/Binary/Components/GasValveComponent.cs +++ b/Content.Server/Atmos/Piping/Binary/Components/GasValveComponent.cs @@ -1,4 +1,3 @@ -using Content.Shared.Interaction; using Content.Shared.Sound; using Robust.Shared.GameObjects; using Robust.Shared.Serialization.Manager.Attributes; @@ -15,11 +14,13 @@ namespace Content.Server.Atmos.Piping.Binary.Components [DataField("open")] public bool Open { get; set; } = true; - [DataField("pipe")] - [ViewVariables(VVAccess.ReadWrite)] - public string PipeName { get; } = "pipe"; + [DataField("inlet")] + public string InletName { get; set; } = "inlet"; + + [DataField("outlet")] + public string OutletName { get; set; } = "outlet"; [DataField("valveSound")] - public SoundSpecifier _valveSound { get; } = new SoundCollectionSpecifier("valveSqueak"); + public SoundSpecifier ValveSound { get; } = new SoundCollectionSpecifier("valveSqueak"); } } diff --git a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasValveSystem.cs b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasValveSystem.cs index 5d04f55d01..dd31411b1f 100644 --- a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasValveSystem.cs +++ b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasValveSystem.cs @@ -20,6 +20,8 @@ namespace Content.Server.Atmos.Piping.Binary.EntitySystems [UsedImplicitly] public class GasValveSystem : EntitySystem { + [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!; + public override void Initialize() { base.Initialize(); @@ -31,7 +33,7 @@ namespace Content.Server.Atmos.Piping.Binary.EntitySystems private void OnExamined(EntityUid uid, GasValveComponent valve, ExaminedEvent args) { - if (!EntityManager.GetComponent(valve.Owner).Anchored || !args.IsInDetailsRange) // Not anchored? Out of range? No status. + if (!Comp(valve.Owner).Anchored || !args.IsInDetailsRange) // Not anchored? Out of range? No status. return; if (Loc.TryGetString("gas-valve-system-examined", out var str, @@ -49,21 +51,34 @@ namespace Content.Server.Atmos.Piping.Binary.EntitySystems private void OnActivate(EntityUid uid, GasValveComponent component, ActivateInWorldEvent args) { - if (args.User.InRangeUnobstructed(args.Target) && Get().CanInteract(args.User)) + if (args.User.InRangeUnobstructed(args.Target) && _actionBlockerSystem.CanInteract(args.User)) { Toggle(uid, component); - SoundSystem.Play(Filter.Pvs(component.Owner), component._valveSound.GetSound(), component.Owner, AudioHelpers.WithVariation(0.25f)); + SoundSystem.Play(Filter.Pvs(component.Owner), component.ValveSound.GetSound(), component.Owner, AudioHelpers.WithVariation(0.25f)); } } public void Set(EntityUid uid, GasValveComponent component, bool value) { component.Open = value; - - if (EntityManager.TryGetComponent(uid, out NodeContainerComponent? nodeContainer) - && nodeContainer.TryGetNode(component.PipeName, out PipeNode? pipe)) + if (TryComp(uid, out NodeContainerComponent? nodeContainer) + && nodeContainer.TryGetNode(component.InletName, out PipeNode? inlet) + && nodeContainer.TryGetNode(component.OutletName, out PipeNode? outlet)) { - pipe.ConnectionsEnabled = component.Open; + if (TryComp(component.Owner,out var appearance)) + { + appearance.SetData(FilterVisuals.Enabled, component.Open); + } + if (component.Open) + { + inlet.AddAlwaysReachable(outlet); + outlet.AddAlwaysReachable(inlet); + } + else + { + inlet.RemoveAlwaysReachable(outlet); + outlet.RemoveAlwaysReachable(inlet); + } } } diff --git a/Content.Server/NodeContainer/Nodes/PipeNode.cs b/Content.Server/NodeContainer/Nodes/PipeNode.cs index 15b30c247c..8fba7ce342 100644 --- a/Content.Server/NodeContainer/Nodes/PipeNode.cs +++ b/Content.Server/NodeContainer/Nodes/PipeNode.cs @@ -35,6 +35,26 @@ namespace Content.Server.NodeContainer.Nodes /// public PipeDirection CurrentPipeDirection { get; private set; } + private HashSet? _alwaysReachable; + + public void AddAlwaysReachable(PipeNode pipeNode) + { + if (NodeGroup == null) return; + if (pipeNode.NodeGroupID != NodeGroupID) return; + _alwaysReachable ??= new(); + _alwaysReachable.Add(pipeNode); + EntitySystem.Get().QueueRemakeGroup((BaseNodeGroup) NodeGroup); + } + + public void RemoveAlwaysReachable(PipeNode pipeNode) + { + if (_alwaysReachable == null) return; + if (NodeGroup == null) return; + if (pipeNode.NodeGroupID != NodeGroupID) return; + _alwaysReachable.Remove(pipeNode); + EntitySystem.Get().QueueRemakeGroup((BaseNodeGroup) NodeGroup); + } + /// /// The directions in which this node is connected to other nodes. /// Used by . @@ -144,6 +164,24 @@ namespace Content.Server.NodeContainer.Nodes yield return pipe; } } + + if(_alwaysReachable != null) + { + var remQ = new RemQueue(); + foreach(var pipe in _alwaysReachable) + { + if (pipe.Deleting) + { + remQ.Add(pipe); + } + yield return pipe; + } + + foreach(var pipe in remQ) + { + _alwaysReachable.Remove(pipe); + } + } } /// diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml index fd665d0146..fe32f84efb 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml @@ -116,20 +116,29 @@ - sprite: Structures/Piping/Atmospherics/pipe.rsi state: pipeStraight map: [ "enum.PipeColorVisualizer+Layers.Pipe" ] - - state: pumpPassiveGate - map: [ "enum.SubFloorShowLayerVisualizer+Layers.FirstLayer" ] + - state: pumpManualValve + map: [ "enum.SubFloorShowLayerVisualizer+Layers.FirstLayer", "enum.GasValveVisualizer+Layers.Enabled" ] - type: Appearance visuals: - type: SubFloorShowLayerVisualizer - type: PipeConnectorVisualizer - type: PipeColorVisualizer + - type: GasValveVisualizer + disabledState: pumpManualValve + enabledState: pumpManualValveOn - type: GasValve - type: NodeContainer nodes: - pipe: + inlet: !type:PipeNode nodeGroupID: Pipe - pipeDirection: Longitudinal + pipeDirection: North + volume: 100 + outlet: + !type:PipeNode + nodeGroupID: Pipe + pipeDirection: South + volume: 100 - type: entity parent: GasBinaryBase diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/pump.rsi/meta.json index 8f00e4796d..2d84c00953 100644 --- a/Resources/Textures/Structures/Piping/Atmospherics/pump.rsi/meta.json +++ b/Resources/Textures/Structures/Piping/Atmospherics/pump.rsi/meta.json @@ -15,6 +15,10 @@ "name":"pumpManualValve", "directions":4 }, + { + "name":"pumpManualValveOn", + "directions":4 + }, { "name":"pumpPassiveGate", "directions":4 @@ -42,4 +46,4 @@ "delays":[ [ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 ], [ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 ], [ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 ], [ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 ] ] } ] -} \ No newline at end of file +} diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump.rsi/pumpManualValveOn.png b/Resources/Textures/Structures/Piping/Atmospherics/pump.rsi/pumpManualValveOn.png new file mode 100644 index 0000000000..845e867de2 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump.rsi/pumpManualValveOn.png differ