Canister fixes and rework (#4266)
* Kills PipeNode ConnectToContainedEntities and EnvironmentalAir with fire. * Reaction IGasMixtureHolder is nullable. * Reworks canisters * Adds PortablePipeNode and PortPipeNode, which connect to each other.
This commit is contained in:
committed by
GitHub
parent
077f158dda
commit
d8e353742c
@@ -263,7 +263,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
Merge(destination, buffer);
|
||||
}
|
||||
|
||||
public ReactionResult React(GasMixture mixture, IGasMixtureHolder holder)
|
||||
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder)
|
||||
{
|
||||
var reaction = ReactionResult.NoReaction;
|
||||
var temperature = mixture.Temperature;
|
||||
|
||||
@@ -23,12 +23,11 @@ namespace Content.Server.Atmos.Piping.Unary.Components
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("gasMixture")]
|
||||
public GasMixture InitialMixture { get; } = new();
|
||||
public GasMixture Air { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Stores the last pressure the tank had, for appearance-updating purposes.
|
||||
/// Last recorded pressure, for appearance-updating purposes.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public float LastPressure { get; set; } = 0f;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.CodeDom;
|
||||
using Content.Server.Atmos.Components;
|
||||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.Atmos.Piping.Binary.Components;
|
||||
@@ -6,6 +7,7 @@ using Content.Server.Atmos.Piping.Components;
|
||||
using Content.Server.Atmos.Piping.Unary.Components;
|
||||
using Content.Server.Hands.Components;
|
||||
using Content.Server.NodeContainer;
|
||||
using Content.Server.NodeContainer.NodeGroups;
|
||||
using Content.Server.NodeContainer.Nodes;
|
||||
using Content.Server.UserInterface;
|
||||
using Content.Shared.ActionBlocker;
|
||||
@@ -54,18 +56,6 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
|
||||
{
|
||||
containerManager.MakeContainer<ContainerSlot>(canister.ContainerName);
|
||||
}
|
||||
|
||||
if (!ComponentManager.TryGetComponent(uid, out NodeContainerComponent? nodeContainer))
|
||||
return;
|
||||
|
||||
if (!nodeContainer.TryGetNode(canister.PortName, out PipeNode? portNode))
|
||||
return;
|
||||
|
||||
// Create a pipenet if we don't have one already.
|
||||
portNode.CreateSingleNetImmediate();
|
||||
Get<AtmosphereSystem>().Merge(portNode.Air, canister.InitialMixture);
|
||||
portNode.Air.Temperature = canister.InitialMixture.Temperature;
|
||||
portNode.Volume = canister.InitialMixture.Volume;
|
||||
}
|
||||
|
||||
private void DirtyUI(EntityUid uid)
|
||||
@@ -81,7 +71,9 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
|
||||
string? tankLabel = null;
|
||||
var tankPressure = 0f;
|
||||
|
||||
if (ComponentManager.TryGetComponent(uid, out ContainerManagerComponent? containerManager) && containerManager.TryGetContainer(canister.ContainerName, out var tankContainer) && tankContainer.ContainedEntities.Count > 0)
|
||||
if (ComponentManager.TryGetComponent(uid, out ContainerManagerComponent? containerManager)
|
||||
&& containerManager.TryGetContainer(canister.ContainerName, out var tankContainer)
|
||||
&& tankContainer.ContainedEntities.Count > 0)
|
||||
{
|
||||
var tank = tankContainer.ContainedEntities[0];
|
||||
var tankComponent = tank.GetComponent<GasTankComponent>();
|
||||
@@ -89,8 +81,8 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
|
||||
tankPressure = tankComponent.Air.Pressure;
|
||||
}
|
||||
|
||||
ui.SetState(new GasCanisterBoundUserInterfaceState(metadata.EntityName, portNode.Air.Pressure,
|
||||
portNode.NodeGroup!.Nodes.Count > 1, tankLabel, tankPressure,
|
||||
ui.SetState(new GasCanisterBoundUserInterfaceState(metadata.EntityName, canister.Air.Pressure,
|
||||
portNode.NodeGroup?.Nodes.Count > 1, tankLabel, tankPressure,
|
||||
canister.ReleasePressure, canister.ReleaseValve,
|
||||
canister.MinReleasePressure, canister.MaxReleasePressure));
|
||||
}
|
||||
@@ -136,9 +128,29 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
|
||||
|| !ComponentManager.TryGetComponent(uid, out AppearanceComponent? appearance))
|
||||
return;
|
||||
|
||||
if (!nodeContainer.TryGetNode(canister.PortName, out PipeNode? portNode))
|
||||
if (!nodeContainer.TryGetNode(canister.PortName, out PortablePipeNode? portNode))
|
||||
return;
|
||||
|
||||
var atmosphereSystem = Get<AtmosphereSystem>();
|
||||
|
||||
atmosphereSystem.React(canister.Air, portNode);
|
||||
|
||||
if (portNode.NodeGroup is PipeNet {NodeCount: > 1} net)
|
||||
{
|
||||
var buffer = new GasMixture(net.Air.Volume + canister.Air.Volume);
|
||||
|
||||
atmosphereSystem.Merge(buffer, net.Air);
|
||||
atmosphereSystem.Merge(buffer, canister.Air);
|
||||
|
||||
net.Air.Clear();
|
||||
atmosphereSystem.Merge(net.Air, buffer);
|
||||
net.Air.Multiply(net.Air.Volume / buffer.Volume);
|
||||
|
||||
canister.Air.Clear();
|
||||
atmosphereSystem.Merge(canister.Air, buffer);
|
||||
canister.Air.Multiply(canister.Air.Volume / buffer.Volume);
|
||||
}
|
||||
|
||||
// Release valve is open, release gas.
|
||||
if (canister.ReleaseValve)
|
||||
{
|
||||
@@ -146,38 +158,36 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
|
||||
|| !containerManager.TryGetContainer(canister.ContainerName, out var container))
|
||||
return;
|
||||
|
||||
var atmosphereSystem = Get<AtmosphereSystem>();
|
||||
|
||||
if (container.ContainedEntities.Count > 0)
|
||||
{
|
||||
var gasTank = container.ContainedEntities[0].GetComponent<GasTankComponent>();
|
||||
atmosphereSystem.ReleaseGasTo(portNode.Air, gasTank.Air, canister.ReleasePressure);
|
||||
atmosphereSystem.ReleaseGasTo(canister.Air, gasTank.Air, canister.ReleasePressure);
|
||||
}
|
||||
else
|
||||
{
|
||||
var tileAtmosphere = canister.Owner.Transform.Coordinates.GetTileAtmosphere();
|
||||
atmosphereSystem.ReleaseGasTo(portNode.Air, tileAtmosphere?.Air, canister.ReleasePressure);
|
||||
atmosphereSystem.ReleaseGasTo(canister.Air, tileAtmosphere?.Air, canister.ReleasePressure);
|
||||
tileAtmosphere?.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
DirtyUI(uid);
|
||||
|
||||
// Nothing to do here.
|
||||
if (MathHelper.CloseTo(portNode.Air.Pressure, canister.LastPressure))
|
||||
// If last pressure is very close to the current pressure, do nothing.
|
||||
if (MathHelper.CloseTo(canister.Air.Pressure, canister.LastPressure))
|
||||
return;
|
||||
|
||||
canister.LastPressure = portNode.Air.Pressure;
|
||||
canister.LastPressure = canister.Air.Pressure;
|
||||
|
||||
if (portNode.Air.Pressure < 10)
|
||||
if (canister.Air.Pressure < 10)
|
||||
{
|
||||
appearance.SetData(GasCanisterVisuals.PressureState, 0);
|
||||
}
|
||||
else if (portNode.Air.Pressure < Atmospherics.OneAtmosphere)
|
||||
else if (canister.Air.Pressure < Atmospherics.OneAtmosphere)
|
||||
{
|
||||
appearance.SetData(GasCanisterVisuals.PressureState, 1);
|
||||
}
|
||||
else if (portNode.Air.Pressure < (15 * Atmospherics.OneAtmosphere))
|
||||
else if (canister.Air.Pressure < (15 * Atmospherics.OneAtmosphere))
|
||||
{
|
||||
appearance.SetData(GasCanisterVisuals.PressureState, 2);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace Content.Server.Atmos.Reactions
|
||||
/// </summary>
|
||||
[DataField("effects")] private List<IGasReactionEffect> _effects = new();
|
||||
|
||||
public ReactionResult React(GasMixture mixture, IGasMixtureHolder holder, AtmosphereSystem atmosphereSystem)
|
||||
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem)
|
||||
{
|
||||
var result = ReactionResult.NoReaction;
|
||||
|
||||
|
||||
@@ -34,10 +34,6 @@ namespace Content.Server.NodeContainer.Nodes
|
||||
[DataField("pipeDirection")]
|
||||
public PipeDirection PipeDirection { get; private set; }
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("connectToContainedEntities")]
|
||||
public bool ConnectToContainedEntities { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// The directions in which this node is connected to other nodes.
|
||||
/// Used by <see cref="PipeVisualState"/>.
|
||||
@@ -81,20 +77,13 @@ namespace Content.Server.NodeContainer.Nodes
|
||||
[ViewVariables]
|
||||
private IPipeNet? PipeNet => (IPipeNet?) NodeGroup;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to ignore the pipenet and return the environment's air.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("environmentalAir")]
|
||||
public bool EnvironmentalAir { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// The gases in this pipe.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public GasMixture Air
|
||||
{
|
||||
get => (!EnvironmentalAir ? PipeNet?.Air : Owner.Transform.Coordinates.GetTileAir()) ?? GasMixture.SpaceGas;
|
||||
get => PipeNet?.Air ?? GasMixture.SpaceGas;
|
||||
set
|
||||
{
|
||||
DebugTools.Assert(PipeNet != null);
|
||||
@@ -104,14 +93,8 @@ namespace Content.Server.NodeContainer.Nodes
|
||||
|
||||
public void AssumeAir(GasMixture giver)
|
||||
{
|
||||
if (EnvironmentalAir)
|
||||
{
|
||||
var tileAtmosphere = Owner.Transform.Coordinates.GetTileAtmosphere();
|
||||
tileAtmosphere?.AssumeAir(giver);
|
||||
return;
|
||||
}
|
||||
|
||||
EntitySystem.Get<AtmosphereSystem>().Merge(PipeNet!.Air, giver);
|
||||
if(PipeNet != null)
|
||||
EntitySystem.Get<AtmosphereSystem>().Merge(PipeNet.Air, giver);
|
||||
}
|
||||
|
||||
[ViewVariables]
|
||||
@@ -163,24 +146,6 @@ namespace Content.Server.NodeContainer.Nodes
|
||||
yield return pipe;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ConnectionsEnabled || !ConnectToContainedEntities || !Owner.TryGetComponent(out ContainerManagerComponent? containerManager))
|
||||
yield break;
|
||||
|
||||
// TODO ATMOS Kill it with fire.
|
||||
foreach (var container in containerManager.GetAllContainers())
|
||||
{
|
||||
foreach (var entity in container.ContainedEntities)
|
||||
{
|
||||
if (!entity.TryGetComponent(out NodeContainerComponent? nodeContainer))
|
||||
continue;
|
||||
|
||||
foreach (var node in nodeContainer.Nodes.Values)
|
||||
{
|
||||
yield return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -191,17 +156,6 @@ namespace Content.Server.NodeContainer.Nodes
|
||||
if (!Anchored)
|
||||
yield break;
|
||||
|
||||
if (pipeDir is PipeDirection.Port or PipeDirection.Connector)
|
||||
{
|
||||
foreach (var pipe in PipesInTile())
|
||||
{
|
||||
if (pipe.Anchored && pipe.ConnectionsEnabled && pipe.PipeDirection.HasDirection(pipeDir.GetOpposite()))
|
||||
yield return pipe;
|
||||
}
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (var pipe in PipesInDirection(pipeDir))
|
||||
{
|
||||
if (pipe.ConnectionsEnabled && pipe.PipeDirection.HasDirection(pipeDir.GetOpposite()))
|
||||
@@ -212,7 +166,7 @@ namespace Content.Server.NodeContainer.Nodes
|
||||
/// <summary>
|
||||
/// Gets the pipes from entities on the tile adjacent in a direction.
|
||||
/// </summary>
|
||||
private IEnumerable<PipeNode> PipesInDirection(PipeDirection pipeDir)
|
||||
protected IEnumerable<PipeNode> PipesInDirection(PipeDirection pipeDir)
|
||||
{
|
||||
if (!Owner.Transform.Anchored)
|
||||
yield break;
|
||||
@@ -233,9 +187,9 @@ namespace Content.Server.NodeContainer.Nodes
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pipes from entities on the tile adjacent in a direction.
|
||||
/// Gets the pipes from entities on the same tile.
|
||||
/// </summary>
|
||||
private IEnumerable<PipeNode> PipesInTile()
|
||||
protected IEnumerable<PipeNode> PipesInTile()
|
||||
{
|
||||
if (!Owner.Transform.Anchored)
|
||||
yield break;
|
||||
|
||||
23
Content.Server/NodeContainer/Nodes/PortPipeNode.cs
Normal file
23
Content.Server/NodeContainer/Nodes/PortPipeNode.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Content.Server.NodeContainer.Nodes
|
||||
{
|
||||
[DataDefinition]
|
||||
public class PortPipeNode : PipeNode
|
||||
{
|
||||
public override IEnumerable<Node> GetReachableNodes()
|
||||
{
|
||||
foreach (var node in PipesInTile())
|
||||
{
|
||||
if (node is PortablePipeNode)
|
||||
yield return node;
|
||||
}
|
||||
|
||||
foreach (var node in base.GetReachableNodes())
|
||||
{
|
||||
yield return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Content.Server/NodeContainer/Nodes/PortablePipeNode.cs
Normal file
23
Content.Server/NodeContainer/Nodes/PortablePipeNode.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Content.Server.NodeContainer.Nodes
|
||||
{
|
||||
[DataDefinition]
|
||||
public class PortablePipeNode : PipeNode
|
||||
{
|
||||
public override IEnumerable<Node> GetReachableNodes()
|
||||
{
|
||||
foreach (var node in PipesInTile())
|
||||
{
|
||||
if (node is PortPipeNode)
|
||||
yield return node;
|
||||
}
|
||||
|
||||
foreach (var node in base.GetReachableNodes())
|
||||
{
|
||||
yield return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,8 +36,6 @@ namespace Content.Shared.Atmos
|
||||
South = 1 << 1,
|
||||
West = 1 << 2,
|
||||
East = 1 << 3,
|
||||
Port = 1 << 4,
|
||||
Connector = 1 << 5,
|
||||
|
||||
//Straight pipes
|
||||
Longitudinal = North | South,
|
||||
@@ -49,12 +47,6 @@ namespace Content.Shared.Atmos
|
||||
SWBend = South | West,
|
||||
SEBend = South | East,
|
||||
|
||||
//Vertical Bends (Port only)
|
||||
NPBend = North | Port,
|
||||
SPBend = South | Port,
|
||||
WPBend = West | Port,
|
||||
EPBend = East | Port,
|
||||
|
||||
//T-Junctions
|
||||
TNorth = North | Lateral,
|
||||
TSouth = South | Lateral,
|
||||
@@ -72,7 +64,6 @@ namespace Content.Shared.Atmos
|
||||
Half,
|
||||
Straight,
|
||||
Bend,
|
||||
VerticalBend,
|
||||
TJunction,
|
||||
Fourway
|
||||
}
|
||||
@@ -89,7 +80,6 @@ namespace Content.Shared.Atmos
|
||||
PipeShape.Half => PipeDirection.South,
|
||||
PipeShape.Straight => PipeDirection.Longitudinal,
|
||||
PipeShape.Bend => PipeDirection.SWBend,
|
||||
PipeShape.VerticalBend => PipeDirection.SPBend,
|
||||
PipeShape.TJunction => PipeDirection.TSouth,
|
||||
PipeShape.Fourway => PipeDirection.Fourway,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(shape), $"{shape} does not have an associated {nameof(PipeDirection)}."),
|
||||
@@ -148,8 +138,6 @@ namespace Content.Shared.Atmos
|
||||
PipeDirection.South => PipeDirection.North,
|
||||
PipeDirection.East => PipeDirection.West,
|
||||
PipeDirection.West => PipeDirection.East,
|
||||
PipeDirection.Port => PipeDirection.Connector,
|
||||
PipeDirection.Connector => PipeDirection.Port,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(pipeDirection)),
|
||||
};
|
||||
}
|
||||
@@ -171,11 +159,6 @@ namespace Content.Shared.Atmos
|
||||
PipeDirection.SEBend => PipeShape.Bend,
|
||||
PipeDirection.SWBend => PipeShape.Bend,
|
||||
|
||||
PipeDirection.NPBend => PipeShape.VerticalBend,
|
||||
PipeDirection.SPBend => PipeShape.VerticalBend,
|
||||
PipeDirection.WPBend => PipeShape.VerticalBend,
|
||||
PipeDirection.EPBend => PipeShape.VerticalBend,
|
||||
|
||||
PipeDirection.TNorth => PipeShape.TJunction,
|
||||
PipeDirection.TSouth => PipeShape.TJunction,
|
||||
PipeDirection.TEast => PipeShape.TJunction,
|
||||
|
||||
@@ -122,6 +122,6 @@
|
||||
- type: NodeContainer
|
||||
nodes:
|
||||
connected:
|
||||
!type:PipeNode
|
||||
!type:PortPipeNode
|
||||
nodeGroupID: Pipe
|
||||
pipeDirection: SPBend
|
||||
pipeDirection: South
|
||||
|
||||
@@ -64,13 +64,10 @@
|
||||
- type: NodeContainer
|
||||
nodes:
|
||||
port:
|
||||
!type:PipeNode
|
||||
!type:PortablePipeNode
|
||||
nodeGroupID: Pipe
|
||||
pipeDirection: Connector
|
||||
connectionsEnabled: false
|
||||
needAnchored: false
|
||||
rotationsEnabled: false
|
||||
volume: 1000
|
||||
volume: 1
|
||||
- type: GasPortable
|
||||
- type: GasCanister
|
||||
|
||||
|
||||
Reference in New Issue
Block a user