using System.Linq;
using Content.Server.Atmos;
using Content.Server.Atmos.EntitySystems;
using Content.Server.NodeContainer.Nodes;
using Content.Shared.Atmos;
using Robust.Shared.Map;
using Robust.Shared.Utility;
namespace Content.Server.NodeContainer.NodeGroups
{
public interface IPipeNet : INodeGroup, IGasMixtureHolder
{
///
/// Causes gas in the PipeNet to react.
///
void Update();
}
[NodeGroup(NodeGroupID.Pipe)]
public sealed class PipeNet : BaseNodeGroup, IPipeNet
{
[ViewVariables] public GasMixture Air { get; set; } = new() {Temperature = Atmospherics.T20C};
[ViewVariables] private AtmosphereSystem? _atmosphereSystem;
public GridId Grid => GridId;
public override void Initialize(Node sourceNode)
{
base.Initialize(sourceNode);
_atmosphereSystem = EntitySystem.Get();
_atmosphereSystem.AddPipeNet(this);
}
public void Update()
{
_atmosphereSystem?.React(Air, this);
}
public override void LoadNodes(List groupNodes)
{
base.LoadNodes(groupNodes);
foreach (var node in groupNodes)
{
var pipeNode = (PipeNode) node;
Air.Volume += pipeNode.Volume;
}
}
public override void RemoveNode(Node node)
{
base.RemoveNode(node);
// if the node is simply being removed into a separate group, we do nothing, as gas redistribution will be
// handled by AfterRemake(). But if it is being deleted, we actually want to remove the gas stored in this node.
if (!node.Deleting || node is not PipeNode pipe)
return;
Air.Multiply(1f - pipe.Volume / Air.Volume);
Air.Volume -= pipe.Volume;
}
public override void AfterRemake(IEnumerable> newGroups)
{
RemoveFromGridAtmos();
var newAir = new List(newGroups.Count());
foreach (var newGroup in newGroups)
{
if (newGroup.Key is IPipeNet newPipeNet)
newAir.Add(newPipeNet.Air);
}
_atmosphereSystem!.DivideInto(Air, newAir);
}
private void RemoveFromGridAtmos()
{
DebugTools.AssertNotNull(_atmosphereSystem);
_atmosphereSystem?.RemovePipeNet(this);
}
public override string GetDebugData()
{
return @$"Pressure: { Air.Pressure:G3}
Temperature: {Air.Temperature:G3}
Volume: {Air.Volume:G3}";
}
}
}