using System.Numerics; using Content.Server.Atmos.EntitySystems; using Content.Server.Body.Systems; using Content.Server.NodeContainer.EntitySystems; using Content.Server.NodeContainer.Nodes; using Content.Shared._DV.NodeCrawl; using Content.Shared.Atmos; using Content.Shared.NodeContainer; namespace Content.Server._DV.NodeCrawl; public sealed class NodeCrawlSystem : SharedNodeCrawlSystem { public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnNodeGroupsRebuilt); SubscribeLocalEvent(OnInhaleLocation); SubscribeLocalEvent(OnExhaleLocation); SubscribeLocalEvent(OnGetAir); } private Entity? GetNodeContainer(Entity crawler) { if (!TryComp(crawler.Comp.Mover, out var mover) || mover.Node is not { } node) return null; if (!TryComp(node, out var nodeContainer)) return null; return (node, nodeContainer); } private GasMixture? GetAir(Entity crawler) { if (GetNodeContainer(crawler) is not { } nodeContainer) return null; foreach (var containedNode in nodeContainer.Comp.Nodes.Values) { if (containedNode is not PipeNode pipe) continue; return pipe.Air; } return null; } private void OnInhaleLocation(Entity ent, ref InhaleLocationEvent args) { if (GetAir(ent) is not { } air) return; args.Gas = air; } private void OnExhaleLocation(Entity ent, ref ExhaleLocationEvent args) { if (GetAir(ent) is not { } air) return; args.Gas = air; } private void OnGetAir(Entity ent, ref AtmosExposedGetAirEvent args) { if (args.Handled || GetAir(ent) is not { } air) return; args.Gas = air; args.Handled = true; } private void OnNodeGroupsRebuilt(Entity ent, ref NodeGroupsRebuilt args) { if (!TryComp(ent, out var nodeContainer)) return; ent.Comp.DeadEnd = false; var set = new HashSet(); foreach (var node in nodeContainer.Nodes.Values) { foreach (var reachable in node.ReachableNodes) { set.Add(reachable.Owner); } if (node is PipeNode pipeNode && node.ReachableNodes.Count != BitOperations.PopCount((uint)pipeNode.CurrentPipeDirection)) { ent.Comp.DeadEnd = true; } } ent.Comp.ReachableNodes = set; Dirty(ent); } }