ECS Atmos Part 3: Removes AtmosHelpers, add many methods to AtmosphereSystem. (#4285)

* ECS Atmos Part 3: Removes AtmosHelpers, add many methods to AtmosphereSystem

* Adds API for adding/removing active tiles.

* Adds API for FixVacuum.

* Adds API for UpdateAdjacent.

* Adds API for IsTileAirBlocked.

* Re-organize hotspot code

* Adds API for IsTileSpace.

* RemoveGasCommand uses AtmosphereSystem

* AddGasCommand uses AtmosphereSystem.

* SetTemperatureCommand uses AtmosphereSystem.

* Adds API for IsSimulatedGrid.

* GasLeak uses AtmosphereSystem.

* Makes Spark method in GasLeak ALSO use AtmosphereSystem.

* GasPassiveVentSystem uses AtmosphereSystem.

* GasMinerSystem uses AtmosphereSystem.

* GasOutletInjectorSystem uses AtmosphereSystem.

* GasVentPumpSystem uses AtmosphereSystem.

* GasDualPortVentPumpSystem uses AtmosphereSystem.

* GasVolumePumpSystem uses AtmosphereSystem.

* GasAnalyzerComponent uses AtmosphereSystem.

* Add API for GetAdjacentTileMixtures.

* GasVentScrubberSystem uses AtmosphereSystem.

* AirtightComponent uses AtmosphereSystem.

* GasLeaks's TryFindRandomTile uses AtmosphereSystem.

* Adds API for GetAdjacentTiles.

* FirelockComponent's IsHoldingFire uses AtmosphereSystem.

* Adds API for GetAllTileMixtures.

* DeleteGasCommand uses AtmosphereSystem.

* FixGridAtmos uses AtmosphereSystem.

* FillGasCommand uses AtmosphereSystem.

* SetAtmosTemperatureCommand uses AtmosphereSystem.
This commit is contained in:
Vera Aguilera Puerto
2021-07-19 12:07:37 +02:00
committed by GitHub
parent 10ced26b0d
commit c8ba345cdc
34 changed files with 1214 additions and 483 deletions

View File

@@ -1,61 +0,0 @@
using System.Diagnostics.CodeAnalysis;
using Content.Server.Atmos.EntitySystems;
using Content.Shared.Atmos;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
namespace Content.Server.Atmos
{
public static class AtmosHelpers
{
public static TileAtmosphere? GetTileAtmosphere(this EntityCoordinates coordinates)
{
return EntitySystem.Get<AtmosphereSystem>().GetGridAtmosphere(coordinates).GetTile(coordinates);
}
public static GasMixture? GetTileAir(this EntityCoordinates coordinates, IEntityManager? entityManager = null)
{
return coordinates.GetTileAtmosphere()?.Air;
}
public static bool TryGetTileAtmosphere(this EntityCoordinates coordinates, [NotNullWhen(true)] out TileAtmosphere? atmosphere)
{
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
return !Equals(atmosphere = coordinates.GetTileAtmosphere(), default);
}
public static bool TryGetTileAir(this EntityCoordinates coordinates, [NotNullWhen(true)] out GasMixture? air, IEntityManager? entityManager = null)
{
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
return !Equals(air = coordinates.GetTileAir(entityManager), default);
}
public static bool IsTileAirProbablySafe(this EntityCoordinates coordinates)
{
// Note that oxygen mix isn't checked, but survival boxes make that not necessary.
var air = coordinates.GetTileAir();
if (air == null)
return false;
if (air.Pressure <= Atmospherics.WarningLowPressure)
return false;
if (air.Pressure >= Atmospherics.WarningHighPressure)
return false;
if (air.Temperature <= 260)
return false;
if (air.Temperature >= 360)
return false;
return true;
}
public static bool InvalidateTileAir(this EntityCoordinates coordinates)
{
if (!coordinates.TryGetTileAtmosphere(out var tileAtmos))
{
return false;
}
tileAtmos.Invalidate();
return true;
}
}
}

View File

@@ -16,7 +16,6 @@ namespace Content.Server.Atmos.Components
[Dependency] private readonly IMapManager _mapManager = default!;
private (GridId, Vector2i) _lastPosition;
private AtmosphereSystem _atmosphereSystem = default!;
public override string Name => "Airtight";
@@ -76,8 +75,6 @@ namespace Content.Server.Atmos.Components
{
base.Initialize();
_atmosphereSystem = EntitySystem.Get<AtmosphereSystem>();
if (_fixAirBlockedDirectionInitialize)
RotateEvent(new RotateEvent(Owner, Angle.Zero, Owner.Transform.WorldRotation));
@@ -132,7 +129,7 @@ namespace Content.Server.Atmos.Components
if (_fixVacuum)
{
_atmosphereSystem.GetGridAtmosphere(_lastPosition.Item1)?.FixVacuum(_lastPosition.Item2);
EntitySystem.Get<AtmosphereSystem>().FixVacuum(_lastPosition.Item1, _lastPosition.Item2);
}
}
@@ -164,10 +161,9 @@ namespace Content.Server.Atmos.Components
if (!gridId.IsValid())
return;
var gridAtmos = _atmosphereSystem.GetGridAtmosphere(gridId);
gridAtmos?.UpdateAdjacentBits(pos);
gridAtmos?.Invalidate(pos);
var atmosphereSystem = EntitySystem.Get<AtmosphereSystem>();
atmosphereSystem.UpdateAdjacent(gridId, pos);
atmosphereSystem.InvalidateTile(gridId, pos);
}
}
}

View File

@@ -74,15 +74,12 @@ namespace Content.Server.Atmos.Components
{
var atmosphereSystem = EntitySystem.Get<AtmosphereSystem>();
var gridAtmosphere = atmosphereSystem.GetGridAtmosphere(Owner.Transform.Coordinates);
var minMoles = float.MaxValue;
var maxMoles = 0f;
foreach (var (_, adjacent) in gridAtmosphere.GetAdjacentTiles(Owner.Transform.Coordinates))
foreach (var adjacent in atmosphereSystem.GetAdjacentTileMixtures(Owner.Transform.Coordinates))
{
// includeAirBlocked remains false, and therefore Air must be present
var moles = adjacent.Air!.TotalMoles;
var moles = adjacent.TotalMoles;
if (moles < minMoles)
minMoles = moles;
if (moles > maxMoles)
@@ -96,17 +93,18 @@ namespace Content.Server.Atmos.Components
{
var atmosphereSystem = EntitySystem.Get<AtmosphereSystem>();
if (!Owner.Transform.Coordinates.TryGetTileAtmosphere(out var tileAtmos))
if (!atmosphereSystem.TryGetGridAndTile(Owner.Transform.Coordinates, out var tuple))
return false;
if (tileAtmos.Hotspot.Valid)
if (atmosphereSystem.GetTileMixture(tuple.Value.Grid, tuple.Value.Tile) == null)
return false;
if (atmosphereSystem.IsHotspotActive(tuple.Value.Grid, tuple.Value.Tile))
return true;
var gridAtmosphere = atmosphereSystem.GetGridAtmosphere(Owner.Transform.Coordinates);
foreach (var (_, adjacent) in gridAtmosphere.GetAdjacentTiles(tileAtmos.GridIndices))
foreach (var adjacent in atmosphereSystem.GetAdjacentTiles(Owner.Transform.Coordinates))
{
if (adjacent.Hotspot.Valid)
if (atmosphereSystem.IsHotspotActive(tuple.Value.Grid, adjacent))
return true;
}

View File

@@ -123,8 +123,7 @@ namespace Content.Server.Atmos.Components
{
// Already get the pressure before Dirty(), because we can't get the EntitySystem in that thread or smth
var pressure = 0f;
var gam = EntitySystem.Get<AtmosphereSystem>().GetGridAtmosphere(Owner.Transform.Coordinates);
var tile = gam?.GetTile(Owner.Transform.Coordinates)?.Air;
var tile = EntitySystem.Get<AtmosphereSystem>().GetTileMixture(Owner.Transform.Coordinates);
if (tile != null)
{
pressure = tile.Pressure;
@@ -182,9 +181,8 @@ namespace Content.Server.Atmos.Components
pos = _position.Value;
}
var atmosSystem = EntitySystem.Get<AtmosphereSystem>();
var gam = atmosSystem.GetGridAtmosphere(pos);
var tile = gam.GetTile(pos)?.Air;
var atmosphereSystem = EntitySystem.Get<AtmosphereSystem>();
var tile = atmosphereSystem.GetTileMixture(pos);
if (tile == null)
{
error = "No Atmosphere!";
@@ -201,7 +199,7 @@ namespace Content.Server.Atmos.Components
for (var i = 0; i < Atmospherics.TotalNumberOfGases; i++)
{
var gas = atmosSystem.GetGas(i);
var gas = atmosphereSystem.GetGas(i);
if (tile.Moles[i] <= Atmospherics.GasMinMoles) continue;

View File

@@ -278,8 +278,9 @@ namespace Content.Server.Atmos.Components
{
if (_integrity <= 0)
{
var tileAtmos = Owner.Transform.Coordinates.GetTileAtmosphere();
tileAtmos?.AssumeAir(Air);
var environment = atmosphereSystem.GetTileMixture(Owner.Transform.Coordinates, true);
if(environment != null)
atmosphereSystem.Merge(environment, Air);
SoundSystem.Play(Filter.Pvs(Owner), "Audio/Effects/spray.ogg", Owner.Transform.Coordinates,
AudioHelpers.WithVariation(0.125f));
@@ -296,12 +297,12 @@ namespace Content.Server.Atmos.Components
{
if (_integrity <= 0)
{
var tileAtmos = Owner.Transform.Coordinates.GetTileAtmosphere();
if (tileAtmos == null)
var environment = atmosphereSystem.GetTileMixture(Owner.Transform.Coordinates, true);
if (environment == null)
return;
var leakedGas = Air.RemoveRatio(0.25f);
tileAtmos.AssumeAir(leakedGas);
atmosphereSystem.Merge(environment, leakedGas);
}
else
{

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,12 @@
using System;
using System.Diagnostics.CodeAnalysis;
using Content.Server.Atmos.Components;
using Content.Server.NodeContainer.EntitySystems;
using Content.Shared.Atmos.EntitySystems;
using Content.Shared.Maps;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Server.Atmos.EntitySystems
{
@@ -20,16 +15,11 @@ namespace Content.Server.Atmos.EntitySystems
{
[Dependency] private readonly IPrototypeManager _protoMan = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IPauseManager _pauseManager = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
private GridTileLookupSystem? _gridTileLookup = null;
private const float ExposedUpdateDelay = 1f;
private float _exposedTimer = 0f;
public GridTileLookupSystem GridTileLookupSystem => _gridTileLookup ??= Get<GridTileLookupSystem>();
public override void Initialize()
{
base.Initialize();
@@ -81,73 +71,6 @@ namespace Content.Server.Atmos.EntitySystems
map.AddComponent<SpaceGridAtmosphereComponent>();
}
#region Helper Methods
public IGridAtmosphereComponent? GetGridAtmosphere(GridId gridId)
{
if (!gridId.IsValid())
return null;
if (!_mapManager.TryGetGrid(gridId, out var grid))
return null;
return ComponentManager.TryGetComponent(grid.GridEntityId, out IGridAtmosphereComponent? gridAtmosphere)
? gridAtmosphere : null;
}
public IGridAtmosphereComponent GetGridAtmosphere(EntityCoordinates coordinates)
{
return GetGridAtmosphere(coordinates.ToMap(EntityManager));
}
public IGridAtmosphereComponent GetGridAtmosphere(MapCoordinates coordinates)
{
if (coordinates.MapId == MapId.Nullspace)
{
throw new ArgumentException($"Coordinates cannot be in nullspace!", nameof(coordinates));
}
if (_mapManager.TryFindGridAt(coordinates, out var grid))
{
if (ComponentManager.TryGetComponent(grid.GridEntityId, out IGridAtmosphereComponent? atmos))
{
return atmos;
}
}
return _mapManager.GetMapEntity(coordinates.MapId).GetComponent<IGridAtmosphereComponent>();
}
/// <summary>
/// Unlike <see cref="GetGridAtmosphere"/>, this doesn't return space grid when not found.
/// </summary>
public bool TryGetSimulatedGridAtmosphere(MapCoordinates coordinates, [NotNullWhen(true)] out IGridAtmosphereComponent? atmosphere)
{
if (coordinates.MapId == MapId.Nullspace)
{
atmosphere = null;
return false;
}
if (_mapManager.TryFindGridAt(coordinates, out var mapGrid)
&& ComponentManager.TryGetComponent(mapGrid.GridEntityId, out IGridAtmosphereComponent? atmosGrid)
&& atmosGrid.Simulated)
{
atmosphere = atmosGrid;
return true;
}
if (_mapManager.GetMapEntity(coordinates.MapId).TryGetComponent(out IGridAtmosphereComponent? atmosMap)
&& atmosMap.Simulated)
{
atmosphere = atmosMap;
return true;
}
atmosphere = null;
return false;
}
#endregion
public override void Update(float frameTime)
{
base.Update(frameTime);
@@ -158,9 +81,11 @@ namespace Content.Server.Atmos.EntitySystems
if (_exposedTimer >= ExposedUpdateDelay)
{
foreach (var exposed in EntityManager.ComponentManager.EntityQuery<AtmosExposedComponent>(true))
foreach (var exposed in EntityManager.ComponentManager.EntityQuery<AtmosExposedComponent>())
{
var tile = exposed.Owner.Transform.Coordinates.GetTileAtmosphere();
// TODO ATMOS: Kill this with fire.
var atmos = GetGridAtmosphere(exposed.Owner.Transform.Coordinates);
var tile = atmos.GetTile(exposed.Owner.Transform.Coordinates);
if (tile == null) continue;
exposed.Update(tile, _exposedTimer, this);
}

View File

@@ -46,10 +46,11 @@ namespace Content.Server.Atmos.Piping.Binary.EntitySystems
|| !nodeContainer.TryGetNode(vent.OutletName, out PipeNode? outlet))
return;
var environment = args.Atmosphere.GetTile(vent.Owner.Transform.Coordinates)!;
var atmosphereSystem = Get<AtmosphereSystem>();
var environment = atmosphereSystem.GetTileMixture(vent.Owner.Transform.Coordinates, true);
// We're in an air-blocked tile... Do nothing.
if (environment.Air == null)
if (environment == null)
return;
if (vent.PumpDirection == VentPumpDirection.Releasing)
@@ -58,38 +59,37 @@ namespace Content.Server.Atmos.Piping.Binary.EntitySystems
var pressureDelta = 10000f;
if ((vent.PressureChecks & DualPortVentPressureBound.ExternalBound) != 0)
pressureDelta = MathF.Min(pressureDelta, (vent.ExternalPressureBound - environment.Air.Pressure));
pressureDelta = MathF.Min(pressureDelta, (vent.ExternalPressureBound - environment.Pressure));
if ((vent.PressureChecks & DualPortVentPressureBound.InputMinimum) != 0)
pressureDelta = MathF.Min(pressureDelta, (inlet.Air.Pressure - vent.InputPressureMin));
if (pressureDelta > 0 && inlet.Air.Temperature > 0)
{
var transferMoles = pressureDelta * environment.Air.Volume / inlet.Air.Temperature * Atmospherics.R;
var transferMoles = pressureDelta * environment.Volume / inlet.Air.Temperature * Atmospherics.R;
var removed = inlet.Air.Remove(transferMoles);
environment.AssumeAir(removed);
atmosphereSystem.Merge(environment, removed);
}
}
else if (vent.PumpDirection == VentPumpDirection.Siphoning && environment.Air.Pressure > 0f)
else if (vent.PumpDirection == VentPumpDirection.Siphoning && environment.Pressure > 0f)
{
appearance?.SetData(VentPumpVisuals.State, VentPumpState.In);
var ourMultiplier = outlet.Air.Volume / environment.Air.Temperature * Atmospherics.R;
var ourMultiplier = outlet.Air.Volume / environment.Temperature * Atmospherics.R;
var molesDelta = 10000 * ourMultiplier;
if ((vent.PressureChecks & DualPortVentPressureBound.ExternalBound) != 0)
molesDelta =
MathF.Min(molesDelta,
(environment.Air.Pressure - vent.OutputPressureMax) * environment.Air.Volume / (environment.Air.Temperature * Atmospherics.R));
(environment.Pressure - vent.OutputPressureMax) * environment.Volume / (environment.Temperature * Atmospherics.R));
if ((vent.PressureChecks &DualPortVentPressureBound.InputMinimum) != 0)
molesDelta = MathF.Min(molesDelta, (vent.InputPressureMin - outlet.Air.Pressure) * ourMultiplier);
if (molesDelta > 0)
{
var removed = environment.Air.Remove(molesDelta);
var removed = environment.Remove(molesDelta);
Get<AtmosphereSystem>().Merge(outlet.Air, removed);
environment.Invalidate();
}
}
}

View File

@@ -1,3 +1,4 @@
using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Piping.Binary.Components;
using Content.Server.Atmos.Piping.Components;
using Content.Server.NodeContainer;
@@ -55,12 +56,13 @@ namespace Content.Server.Atmos.Piping.Binary.EntitySystems
// Some of the gas from the mixture leaks when overclocked.
if (pump.Overclocked)
{
var tile = args.Atmosphere.GetTile(pump.Owner.Transform.Coordinates);
var atmosphereSystem = Get<AtmosphereSystem>();
var tile = atmosphereSystem.GetTileMixture(pump.Owner.Transform.Coordinates, true);
if (tile != null)
{
var leaked = removed.RemoveRatio(pump.LeakRatio);
tile.AssumeAir(leaked);
atmosphereSystem.Merge(tile, leaked);
}
}

View File

@@ -1,3 +1,4 @@
using System.Buffers;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Piping.Components;
using Content.Server.Construction.Components;
@@ -25,7 +26,7 @@ namespace Content.Server.Atmos.Piping.EntitySystems
if (!component.Enabled || !ComponentManager.TryGetComponent(uid, out NodeContainerComponent? nodes))
return;
if (!component.Owner.Transform.Coordinates.TryGetTileAir(out var environment, EntityManager))
if (Get<AtmosphereSystem>().GetTileMixture(component.Owner.Transform.Coordinates) is not {} environment)
return;
foreach (var node in nodes.Nodes.Values)
@@ -46,12 +47,10 @@ namespace Content.Server.Atmos.Piping.EntitySystems
if (!component.Enabled || !ComponentManager.TryGetComponent(uid, out NodeContainerComponent? nodes))
return;
if (!component.Owner.Transform.Coordinates.TryGetTileAtmosphere(out var environment))
environment = null;
var atmosphereSystem = Get<AtmosphereSystem>();
var environmentPressure = environment?.Air?.Pressure ?? 0f;
var environmentVolume = environment?.Air?.Volume ?? Atmospherics.CellVolume;
var environmentTemperature = environment?.Air?.Volume ?? Atmospherics.TCMB;
if (atmosphereSystem.GetTileMixture(component.Owner.Transform.Coordinates, true) is not {} environment)
environment = GasMixture.SpaceGas;
var lost = 0f;
var timesLost = 0;
@@ -60,16 +59,14 @@ namespace Content.Server.Atmos.Piping.EntitySystems
{
if (node is not PipeNode pipe) continue;
var difference = pipe.Air.Pressure - environmentPressure;
lost += difference * environmentVolume / (environmentTemperature * Atmospherics.R);
var difference = pipe.Air.Pressure - environment.Pressure;
lost += difference * environment.Volume / (environment.Temperature * Atmospherics.R);
timesLost++;
}
var sharedLoss = lost / timesLost;
var buffer = new GasMixture();
var atmosphereSystem = Get<AtmosphereSystem>();
foreach (var node in nodes.Nodes.Values)
{
if (node is not PipeNode pipe) continue;
@@ -77,7 +74,7 @@ namespace Content.Server.Atmos.Piping.EntitySystems
atmosphereSystem.Merge(buffer, pipe.Air.Remove(sharedLoss));
}
environment?.AssumeAir(buffer);
atmosphereSystem.Merge(environment, buffer);
}
}
}

View File

@@ -1,5 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Piping.Components;
using Content.Server.Atmos.Piping.Other.Components;
using Content.Shared.Atmos;
@@ -20,7 +21,9 @@ namespace Content.Server.Atmos.Piping.Other.EntitySystems
private void OnMinerUpdated(EntityUid uid, GasMinerComponent miner, AtmosDeviceUpdateEvent args)
{
if (!CheckMinerOperation(args.Atmosphere, miner, out var tile) || !miner.Enabled || !miner.SpawnGas.HasValue || miner.SpawnAmount <= 0f)
var atmosphereSystem = Get<AtmosphereSystem>();
if (!CheckMinerOperation(atmosphereSystem, miner, out var environment) || !miner.Enabled || !miner.SpawnGas.HasValue || miner.SpawnAmount <= 0f)
return;
// Time to mine some gas.
@@ -28,22 +31,22 @@ namespace Content.Server.Atmos.Piping.Other.EntitySystems
var merger = new GasMixture(1) { Temperature = miner.SpawnTemperature };
merger.SetMoles(miner.SpawnGas.Value, miner.SpawnAmount);
tile.AssumeAir(merger);
atmosphereSystem.Merge(environment, merger);
}
private bool CheckMinerOperation(IGridAtmosphereComponent atmosphere, GasMinerComponent miner, [NotNullWhen(true)] out TileAtmosphere? tile)
private bool CheckMinerOperation(AtmosphereSystem atmosphereSystem, GasMinerComponent miner, [NotNullWhen(true)] out GasMixture? environment)
{
tile = atmosphere.GetTile(miner.Owner.Transform.Coordinates)!;
environment = atmosphereSystem.GetTileMixture(miner.Owner.Transform.Coordinates, true);
// Space.
if (atmosphere.IsSpace(tile.GridIndices))
if (atmosphereSystem.IsTileSpace(miner.Owner.Transform.Coordinates))
{
miner.Broken = true;
return false;
}
// Airblocked location.
if (tile.Air == null)
// Air-blocked location.
if (environment == null)
{
miner.Broken = true;
return false;
@@ -51,14 +54,14 @@ namespace Content.Server.Atmos.Piping.Other.EntitySystems
// External pressure above threshold.
if (!float.IsInfinity(miner.MaxExternalPressure) &&
tile.Air.Pressure > miner.MaxExternalPressure - miner.SpawnAmount * miner.SpawnTemperature * Atmospherics.R / tile.Air.Volume)
environment.Pressure > miner.MaxExternalPressure - miner.SpawnAmount * miner.SpawnTemperature * Atmospherics.R / environment.Volume)
{
miner.Broken = true;
return false;
}
// External gas amount above threshold.
if (!float.IsInfinity(miner.MaxExternalAmount) && tile.Air.TotalMoles > miner.MaxExternalAmount)
if (!float.IsInfinity(miner.MaxExternalAmount) && environment.TotalMoles > miner.MaxExternalAmount)
{
miner.Broken = true;
return false;

View File

@@ -165,9 +165,8 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
}
else
{
var tileAtmosphere = canister.Owner.Transform.Coordinates.GetTileAtmosphere();
atmosphereSystem.ReleaseGasTo(canister.Air, tileAtmosphere?.Air, canister.ReleasePressure);
tileAtmosphere?.Invalidate();
var environment = atmosphereSystem.GetTileMixture(canister.Owner.Transform.Coordinates, true);
atmosphereSystem.ReleaseGasTo(canister.Air, environment, canister.ReleasePressure);
}
}

View File

@@ -1,3 +1,4 @@
using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Piping.Components;
using Content.Server.Atmos.Piping.Unary.Components;
using Content.Server.NodeContainer;
@@ -31,9 +32,10 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
if (!nodeContainer.TryGetNode(injector.InletName, out PipeNode? inlet))
return;
var environment = args.Atmosphere.GetTile(injector.Owner.Transform.Coordinates)!;
var atmosphereSystem = Get<AtmosphereSystem>();
var environment = atmosphereSystem.GetTileMixture(injector.Owner.Transform.Coordinates, true);
if (environment.Air == null)
if (environment == null)
return;
if (inlet.Air.Temperature > 0)
@@ -42,8 +44,7 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
var removed = inlet.Air.Remove(transferMoles);
environment.AssumeAir(removed);
environment.Invalidate();
atmosphereSystem.Merge(environment, removed);
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Piping.Components;
using Content.Server.Atmos.Piping.Unary.Components;
using Content.Server.NodeContainer;
@@ -21,9 +22,10 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
private void OnPassiveVentUpdated(EntityUid uid, GasPassiveVentComponent vent, AtmosDeviceUpdateEvent args)
{
var environment = args.Atmosphere.GetTile(vent.Owner.Transform.Coordinates)!;
var atmosphereSystem = Get<AtmosphereSystem>();
var environment = atmosphereSystem.GetTileMixture(vent.Owner.Transform.Coordinates, true);
if (environment.Air == null)
if (environment == null)
return;
if (!ComponentManager.TryGetComponent(uid, out NodeContainerComponent? nodeContainer))
@@ -32,27 +34,26 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
if (!nodeContainer.TryGetNode(vent.InletName, out PipeNode? inlet))
return;
var environmentPressure = environment.Air.Pressure;
var environmentPressure = environment.Pressure;
var pressureDelta = MathF.Abs(environmentPressure - inlet.Air.Pressure);
if ((environment.Air.Temperature > 0 || inlet.Air.Temperature > 0) && pressureDelta > 0.5f)
if ((environment.Temperature > 0 || inlet.Air.Temperature > 0) && pressureDelta > 0.5f)
{
if (environmentPressure < inlet.Air.Pressure)
{
var airTemperature = environment.Temperature > 0 ? environment.Temperature : inlet.Air.Temperature;
var transferMoles = pressureDelta * environment.Air.Volume / (airTemperature * Atmospherics.R);
var transferMoles = pressureDelta * environment.Volume / (airTemperature * Atmospherics.R);
var removed = inlet.Air.Remove(transferMoles);
environment.AssumeAir(removed);
atmosphereSystem.Merge(environment, removed);
}
else
{
var airTemperature = inlet.Air.Temperature > 0 ? inlet.Air.Temperature : environment.Temperature;
var outputVolume = inlet.Air.Volume;
var transferMoles = (pressureDelta * outputVolume) / (airTemperature * Atmospherics.R);
transferMoles = MathF.Min(transferMoles, environment.Air.TotalMoles * inlet.Air.Volume / environment.Air.Volume);
var removed = environment.Air.Remove(transferMoles);
transferMoles = MathF.Min(transferMoles, environment.TotalMoles * inlet.Air.Volume / environment.Volume);
var removed = environment.Remove(transferMoles);
inlet.AssumeAir(removed);
environment.Invalidate();
}
}

View File

@@ -1,4 +1,5 @@
using System;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Piping.Components;
using Content.Server.Atmos.Piping.Unary.Components;
using Content.Server.NodeContainer;
@@ -43,10 +44,11 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
if (!nodeContainer.TryGetNode(vent.InletName, out PipeNode? pipe))
return;
var environment = args.Atmosphere.GetTile(vent.Owner.Transform.Coordinates)!;
var atmosphereSystem = Get<AtmosphereSystem>();
var environment = atmosphereSystem.GetTileMixture(vent.Owner.Transform.Coordinates, true);
// We're in an air-blocked tile... Do nothing.
if (environment.Air == null)
if (environment == null)
return;
if (vent.PumpDirection == VentPumpDirection.Releasing)
@@ -55,37 +57,36 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
var pressureDelta = 10000f;
if ((vent.PressureChecks & VentPressureBound.ExternalBound) != 0)
pressureDelta = MathF.Min(pressureDelta, vent.ExternalPressureBound - environment.Air.Pressure);
pressureDelta = MathF.Min(pressureDelta, vent.ExternalPressureBound - environment.Pressure);
if ((vent.PressureChecks & VentPressureBound.InternalBound) != 0)
pressureDelta = MathF.Min(pressureDelta, pipe.Air.Pressure - vent.InternalPressureBound);
if (pressureDelta > 0 && pipe.Air.Temperature > 0)
{
var transferMoles = pressureDelta * environment.Air.Volume / (pipe.Air.Temperature * Atmospherics.R);
var transferMoles = pressureDelta * environment.Volume / (pipe.Air.Temperature * Atmospherics.R);
environment.AssumeAir(pipe.Air.Remove(transferMoles));
atmosphereSystem.Merge(environment, pipe.Air.Remove(transferMoles));
}
}
else if (vent.PumpDirection == VentPumpDirection.Siphoning && environment.Air.Pressure > 0)
else if (vent.PumpDirection == VentPumpDirection.Siphoning && environment.Pressure > 0)
{
appearance?.SetData(VentPumpVisuals.State, VentPumpState.In);
var ourMultiplier = pipe.Air.Volume / (environment.Air.Temperature * Atmospherics.R);
var ourMultiplier = pipe.Air.Volume / (environment.Temperature * Atmospherics.R);
var molesDelta = 10000f * ourMultiplier;
if ((vent.PressureChecks & VentPressureBound.ExternalBound) != 0)
molesDelta = MathF.Min(molesDelta,
(environment.Air.Pressure - vent.ExternalPressureBound) * environment.Air.Volume /
(environment.Air.Temperature * Atmospherics.R));
(environment.Pressure - vent.ExternalPressureBound) * environment.Volume /
(environment.Temperature * Atmospherics.R));
if ((vent.PressureChecks & VentPressureBound.InternalBound) != 0)
molesDelta = MathF.Min(molesDelta, (vent.InternalPressureBound - pipe.Air.Pressure) * ourMultiplier);
if (molesDelta > 0)
{
var removed = environment.Air.Remove(molesDelta);
var removed = environment.Remove(molesDelta);
pipe.AssumeAir(removed);
environment.Invalidate();
}
}
}

View File

@@ -45,17 +45,17 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
if (!nodeContainer.TryGetNode(scrubber.OutletName, out PipeNode? outlet))
return;
var environment = args.Atmosphere.GetTile(scrubber.Owner.Transform.Coordinates)!;
var atmosphereSystem = Get<AtmosphereSystem>();
var environment = atmosphereSystem.GetTileMixture(scrubber.Owner.Transform.Coordinates, true);
Scrub(scrubber, appearance, environment, outlet);
Scrub(atmosphereSystem, scrubber, appearance, environment, outlet);
if (!scrubber.WideNet) return;
// Scrub adjacent tiles too.
foreach (var adjacent in environment.AdjacentTiles)
foreach (var adjacent in atmosphereSystem.GetAdjacentTileMixtures(scrubber.Owner.Transform.Coordinates, false, true))
{
// Pass null appearance, we don't need to set it there.
Scrub(scrubber, null, adjacent, outlet);
Scrub(atmosphereSystem, scrubber, null, adjacent, outlet);
}
}
@@ -67,10 +67,10 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
}
}
private void Scrub(GasVentScrubberComponent scrubber, AppearanceComponent? appearance, TileAtmosphere? tile, PipeNode outlet)
private void Scrub(AtmosphereSystem atmosphereSystem, GasVentScrubberComponent scrubber, AppearanceComponent? appearance, GasMixture? tile, PipeNode outlet)
{
// Cannot scrub if tile is null or air-blocked.
if (tile?.Air == null)
if (tile == null)
return;
// Cannot scrub if pressure too high.
@@ -80,30 +80,28 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
if (scrubber.PumpDirection == ScrubberPumpDirection.Scrubbing)
{
appearance?.SetData(ScrubberVisuals.State, scrubber.WideNet ? ScrubberState.WideScrub : ScrubberState.Scrub);
var transferMoles = MathF.Min(1f, (scrubber.VolumeRate / tile.Air.Volume) * tile.Air.TotalMoles);
var transferMoles = MathF.Min(1f, (scrubber.VolumeRate / tile.Volume) * tile.TotalMoles);
// Take a gas sample.
var removed = tile.Air.Remove(transferMoles);
var removed = tile.Remove(transferMoles);
// Nothing left to remove from the tile.
if (MathHelper.CloseTo(removed.TotalMoles, 0f))
return;
// TODO: Entity system dependency
Get<AtmosphereSystem>().ScrubInto(removed, outlet.Air, scrubber.FilterGases);
atmosphereSystem.ScrubInto(removed, outlet.Air, scrubber.FilterGases);
// Remix the gases.
tile.AssumeAir(removed);
atmosphereSystem.Merge(tile, removed);
}
else if (scrubber.PumpDirection == ScrubberPumpDirection.Siphoning)
{
appearance?.SetData(ScrubberVisuals.State, ScrubberState.Siphon);
var transferMoles = tile.Air.TotalMoles * (scrubber.VolumeRate / tile.Air.Volume);
var transferMoles = tile.TotalMoles * (scrubber.VolumeRate / tile.Volume);
var removed = tile.Air.Remove(transferMoles);
var removed = tile.Remove(transferMoles);
outlet.AssumeAir(removed);
tile.Invalidate();
}
}
}