Files
tbd-station-14/Content.Server/Atmos/EntitySystems/AtmosPipeLayersSystem.cs
Perry Fraser e09b7debe2 Fix some popup issues with pipe layer changes (#38244)
* fix: only show pipe layer popups to the user changing them

* fix: don't show pipe layer subfloor popup when not using a screwdriver

* fix: properly pass down user and used for serverside pipe layer changes

Technically this doesn't matter as the Shared codepath for this method
doesn't actually use these on the server: only the user is used for a
clientside popup. Still, will be good to have these for future changes
that might need them.
2025-06-11 22:31:48 -07:00

78 lines
2.8 KiB
C#

using Content.Server.Atmos.Components;
using Content.Server.NodeContainer.EntitySystems;
using Content.Server.NodeContainer.NodeGroups;
using Content.Server.NodeContainer.Nodes;
using Content.Shared.Atmos.Components;
using Content.Shared.Atmos.EntitySystems;
using Content.Shared.Construction.Components;
using Content.Shared.NodeContainer;
using Content.Shared.Popups;
namespace Content.Server.Atmos.EntitySystems;
/// <summary>
/// The system responsible for checking and adjusting the connection layering of gas pipes
/// </summary>
public sealed partial class AtmosPipeLayersSystem : SharedAtmosPipeLayersSystem
{
[Dependency] private readonly NodeGroupSystem _nodeGroup = default!;
[Dependency] private readonly PipeRestrictOverlapSystem _pipeRestrictOverlap = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly SharedTransformSystem _xform = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<AtmosPipeLayersComponent, ComponentInit>(OnInit);
}
private void OnInit(Entity<AtmosPipeLayersComponent> ent, ref ComponentInit args)
{
SetPipeLayer(ent, ent.Comp.CurrentPipeLayer);
}
/// <inheritdoc/>
public override void SetPipeLayer(Entity<AtmosPipeLayersComponent> ent, AtmosPipeLayer layer, EntityUid? user = null, EntityUid? used = null)
{
if (ent.Comp.PipeLayersLocked)
return;
base.SetPipeLayer(ent, layer, user, used);
if (!TryComp<NodeContainerComponent>(ent, out var nodeContainer))
return;
// Update the layer values of all pipe nodes associated with the entity
foreach (var (id, node) in nodeContainer.Nodes)
{
if (node is not PipeNode { } pipeNode)
continue;
if (pipeNode.CurrentPipeLayer == ent.Comp.CurrentPipeLayer)
continue;
pipeNode.CurrentPipeLayer = ent.Comp.CurrentPipeLayer;
if (pipeNode.NodeGroup != null)
_nodeGroup.QueueRemakeGroup((BaseNodeGroup)pipeNode.NodeGroup);
}
// If a user wasn't responsible for unanchoring the pipe, leave it be
if (user == null || used == null)
return;
// Unanchor the pipe if its new layer overlaps with another pipe
var xform = Transform(ent);
if (!HasComp<PipeRestrictOverlapComponent>(ent) || !_pipeRestrictOverlap.CheckOverlap((ent, nodeContainer, xform)))
return;
RaiseLocalEvent(ent, new BeforeUnanchoredEvent(user.Value, used.Value));
_xform.Unanchor(ent, xform);
RaiseLocalEvent(ent, new UserUnanchoredEvent(user.Value, used.Value));
_popup.PopupEntity(Loc.GetString("pipe-restrict-overlap-popup-blocked", ("pipe", ent)), ent, user.Value);
}
}