Delta-v/Content.Server/_DV/NodeCrawl/NodeCrawlSystem.cs

102 lines
3.0 KiB
C#

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<CrawlableNodeComponent, NodeGroupsRebuilt>(OnNodeGroupsRebuilt);
SubscribeLocalEvent<NodeCrawlerComponent, InhaleLocationEvent>(OnInhaleLocation);
SubscribeLocalEvent<NodeCrawlerComponent, ExhaleLocationEvent>(OnExhaleLocation);
SubscribeLocalEvent<NodeCrawlerComponent, AtmosExposedGetAirEvent>(OnGetAir);
}
private Entity<NodeContainerComponent>? GetNodeContainer(Entity<NodeCrawlerComponent> crawler)
{
if (!TryComp<NodeCrawlerMovementComponent>(crawler.Comp.Mover, out var mover) || mover.Node is not { } node)
return null;
if (!TryComp<NodeContainerComponent>(node, out var nodeContainer))
return null;
return (node, nodeContainer);
}
private GasMixture? GetAir(Entity<NodeCrawlerComponent> 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<NodeCrawlerComponent> ent, ref InhaleLocationEvent args)
{
if (GetAir(ent) is not { } air)
return;
args.Gas = air;
}
private void OnExhaleLocation(Entity<NodeCrawlerComponent> ent, ref ExhaleLocationEvent args)
{
if (GetAir(ent) is not { } air)
return;
args.Gas = air;
}
private void OnGetAir(Entity<NodeCrawlerComponent> ent, ref AtmosExposedGetAirEvent args)
{
if (args.Handled || GetAir(ent) is not { } air)
return;
args.Gas = air;
args.Handled = true;
}
private void OnNodeGroupsRebuilt(Entity<CrawlableNodeComponent> ent, ref NodeGroupsRebuilt args)
{
if (!TryComp<NodeContainerComponent>(ent, out var nodeContainer))
return;
ent.Comp.DeadEnd = false;
var set = new HashSet<EntityUid>();
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);
}
}