ECS Atmos Part 5: Moves all logic from GridAtmosphereComponent to AtmosphereSystem. (#4331)
This commit is contained in:
committed by
GitHub
parent
354ef6daf3
commit
4112847142
@@ -1,24 +1,13 @@
|
|||||||
// ReSharper disable once RedundantUsingDirective
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using Content.Server.Atmos.EntitySystems;
|
using Content.Server.Atmos.EntitySystems;
|
||||||
using Content.Server.Atmos.Piping.Components;
|
using Content.Server.Atmos.Piping.Components;
|
||||||
using Content.Server.CPUJob.JobQueues.Queues;
|
|
||||||
using Content.Server.NodeContainer.NodeGroups;
|
using Content.Server.NodeContainer.NodeGroups;
|
||||||
using Content.Shared.Atmos;
|
|
||||||
using Content.Shared.Maps;
|
|
||||||
using Robust.Server.GameObjects;
|
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Log;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.Serialization.Manager.Attributes;
|
using Robust.Shared.Serialization.Manager.Attributes;
|
||||||
using Robust.Shared.Timing;
|
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
using Dependency = Robust.Shared.IoC.DependencyAttribute;
|
using Dependency = Robust.Shared.IoC.DependencyAttribute;
|
||||||
|
|
||||||
@@ -31,33 +20,21 @@ namespace Content.Server.Atmos.Components
|
|||||||
[RegisterComponent, Serializable]
|
[RegisterComponent, Serializable]
|
||||||
public class GridAtmosphereComponent : Component, IGridAtmosphereComponent, ISerializationHooks
|
public class GridAtmosphereComponent : Component, IGridAtmosphereComponent, ISerializationHooks
|
||||||
{
|
{
|
||||||
[Dependency] private IMapManager _mapManager = default!;
|
|
||||||
[Dependency] private ITileDefinitionManager _tileDefinitionManager = default!;
|
|
||||||
[Dependency] private IServerEntityManager _serverEntityManager = default!;
|
|
||||||
[Dependency] private IGameTiming _gameTiming = default!;
|
|
||||||
|
|
||||||
internal GasTileOverlaySystem GasTileOverlaySystem { get; private set; } = default!;
|
|
||||||
public AtmosphereSystem AtmosphereSystem { get; private set; } = default!;
|
|
||||||
|
|
||||||
public override string Name => "GridAtmosphere";
|
public override string Name => "GridAtmosphere";
|
||||||
|
|
||||||
public bool ProcessingPaused { get; set; } = false;
|
|
||||||
public float Timer { get; set; }
|
|
||||||
private GridId _gridId;
|
|
||||||
|
|
||||||
[ComponentDependency] private IMapGridComponent? _mapGridComponent;
|
|
||||||
|
|
||||||
public virtual bool Simulated => true;
|
public virtual bool Simulated => true;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public bool RevalidatePaused { get; set; } = false;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public bool ProcessingPaused { get; set; } = false;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public float Timer { get; set; } = 0f;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public int UpdateCounter { get; set; } = 0;
|
public int UpdateCounter { get; set; } = 0;
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public readonly HashSet<ExcitedGroup> ExcitedGroups = new(1000);
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public int ExcitedGroupCount => ExcitedGroups.Count;
|
|
||||||
|
|
||||||
[DataField("uniqueMixes")]
|
[DataField("uniqueMixes")]
|
||||||
public List<GasMixture>? UniqueMixes;
|
public List<GasMixture>? UniqueMixes;
|
||||||
|
|
||||||
@@ -73,6 +50,12 @@ namespace Content.Server.Atmos.Components
|
|||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public int ActiveTilesCount => ActiveTiles.Count;
|
public int ActiveTilesCount => ActiveTiles.Count;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public readonly HashSet<ExcitedGroup> ExcitedGroups = new(1000);
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public int ExcitedGroupCount => ExcitedGroups.Count;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public readonly HashSet<TileAtmosphere> HotspotTiles = new(1000);
|
public readonly HashSet<TileAtmosphere> HotspotTiles = new(1000);
|
||||||
|
|
||||||
@@ -85,9 +68,6 @@ namespace Content.Server.Atmos.Components
|
|||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public int SuperconductivityTilesCount => SuperconductivityTiles.Count;
|
public int SuperconductivityTilesCount => SuperconductivityTiles.Count;
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public readonly HashSet<Vector2i> InvalidatedCoords = new(1000);
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public HashSet<TileAtmosphere> HighPressureDelta = new(1000);
|
public HashSet<TileAtmosphere> HighPressureDelta = new(1000);
|
||||||
|
|
||||||
@@ -112,22 +92,21 @@ namespace Content.Server.Atmos.Components
|
|||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public Queue<AtmosDeviceComponent> CurrentRunAtmosDevices = new();
|
public Queue<AtmosDeviceComponent> CurrentRunAtmosDevices = new();
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public readonly HashSet<Vector2i> InvalidatedCoords = new(1000);
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public Queue<Vector2i> CurrentRunInvalidatedCoordinates = new();
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public int InvalidatedCoordsCount => InvalidatedCoords.Count;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public long EqualizationQueueCycleControl { get; set; }
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public AtmosphereProcessingState State { get; set; } = AtmosphereProcessingState.TileEqualize;
|
public AtmosphereProcessingState State { get; set; } = AtmosphereProcessingState.TileEqualize;
|
||||||
|
|
||||||
public GridAtmosphereComponent()
|
|
||||||
{
|
|
||||||
ProcessingPaused = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public virtual void PryTile(Vector2i indices)
|
|
||||||
{
|
|
||||||
if (IsSpace(indices) || IsAirBlocked(indices)) return;
|
|
||||||
|
|
||||||
indices.PryTile(_gridId, _mapManager, _tileDefinitionManager, _serverEntityManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ISerializationHooks.BeforeSerialization()
|
void ISerializationHooks.BeforeSerialization()
|
||||||
{
|
{
|
||||||
var uniqueMixes = new List<GasMixture>();
|
var uniqueMixes = new List<GasMixture>();
|
||||||
@@ -156,403 +135,5 @@ namespace Content.Server.Atmos.Components
|
|||||||
UniqueMixes = uniqueMixes;
|
UniqueMixes = uniqueMixes;
|
||||||
TilesUniqueMixes = tiles;
|
TilesUniqueMixes = tiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
Tiles.Clear();
|
|
||||||
|
|
||||||
if (TilesUniqueMixes != null && Owner.TryGetComponent(out IMapGridComponent? mapGrid))
|
|
||||||
{
|
|
||||||
foreach (var (indices, mix) in TilesUniqueMixes)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Tiles.Add(indices, new TileAtmosphere(this, mapGrid.GridIndex, indices, (GasMixture) UniqueMixes![mix].Clone()));
|
|
||||||
}
|
|
||||||
catch (ArgumentOutOfRangeException)
|
|
||||||
{
|
|
||||||
Logger.Error($"Error during atmos serialization! Tile at {indices} points to an unique mix ({mix}) out of range!");
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
Invalidate(indices);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GasTileOverlaySystem = EntitySystem.Get<GasTileOverlaySystem>();
|
|
||||||
AtmosphereSystem = EntitySystem.Get<AtmosphereSystem>();
|
|
||||||
|
|
||||||
RepopulateTiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnAdd()
|
|
||||||
{
|
|
||||||
base.OnAdd();
|
|
||||||
|
|
||||||
if (Owner.TryGetComponent(out IMapGridComponent? mapGrid))
|
|
||||||
_gridId = mapGrid.GridIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void RepopulateTiles()
|
|
||||||
{
|
|
||||||
if (!Owner.TryGetComponent(out IMapGridComponent? mapGrid)) return;
|
|
||||||
|
|
||||||
foreach (var tile in mapGrid.Grid.GetAllTiles())
|
|
||||||
{
|
|
||||||
if(!Tiles.ContainsKey(tile.GridIndices))
|
|
||||||
Tiles.Add(tile.GridIndices, new TileAtmosphere(this, tile.GridIndex, tile.GridIndices, new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C}));
|
|
||||||
|
|
||||||
Invalidate(tile.GridIndices);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var (_, tile) in Tiles.ToArray())
|
|
||||||
{
|
|
||||||
tile.UpdateAdjacent();
|
|
||||||
tile.UpdateVisuals();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public virtual void Invalidate(Vector2i indices)
|
|
||||||
{
|
|
||||||
InvalidatedCoords.Add(indices);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Revalidate()
|
|
||||||
{
|
|
||||||
foreach (var indices in InvalidatedCoords)
|
|
||||||
{
|
|
||||||
var tile = GetTile(indices);
|
|
||||||
|
|
||||||
if (tile == null)
|
|
||||||
{
|
|
||||||
tile = new TileAtmosphere(this, _gridId, indices, new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C});
|
|
||||||
Tiles[indices] = tile;
|
|
||||||
}
|
|
||||||
|
|
||||||
var isAirBlocked = IsAirBlocked(indices);
|
|
||||||
|
|
||||||
if (IsSpace(indices) && !isAirBlocked)
|
|
||||||
{
|
|
||||||
tile.Air = new GasMixture(GetVolumeForCells(1));
|
|
||||||
tile.Air.MarkImmutable();
|
|
||||||
Tiles[indices] = tile;
|
|
||||||
|
|
||||||
} else if (isAirBlocked)
|
|
||||||
{
|
|
||||||
var nullAir = false;
|
|
||||||
|
|
||||||
foreach (var airtight in GetObstructingComponents(indices))
|
|
||||||
{
|
|
||||||
if (airtight.NoAirWhenFullyAirBlocked)
|
|
||||||
{
|
|
||||||
nullAir = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(nullAir)
|
|
||||||
tile.Air = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (tile.Air == null && NeedsVacuumFixing(indices))
|
|
||||||
{
|
|
||||||
FixVacuum(tile.GridIndices);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tile used to be space, but isn't anymore.
|
|
||||||
if (tile.Air?.Immutable ?? false)
|
|
||||||
{
|
|
||||||
tile.Air = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
tile.Air ??= new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C};
|
|
||||||
}
|
|
||||||
|
|
||||||
// By removing the active tile, we effectively remove its excited group, if any.
|
|
||||||
RemoveActiveTile(tile);
|
|
||||||
|
|
||||||
// Then we activate the tile again.
|
|
||||||
AddActiveTile(tile);
|
|
||||||
|
|
||||||
tile.BlockedAirflow = GetBlockedDirections(indices);
|
|
||||||
|
|
||||||
// TODO ATMOS: Query all the contents of this tile (like walls) and calculate the correct thermal conductivity
|
|
||||||
tile.ThermalConductivity = tile.Tile?.Tile.GetContentTileDefinition().ThermalConductivity ?? 0.5f;
|
|
||||||
tile.UpdateAdjacent();
|
|
||||||
GasTileOverlaySystem.Invalidate(_gridId, indices);
|
|
||||||
|
|
||||||
for (var i = 0; i < Atmospherics.Directions; i++)
|
|
||||||
{
|
|
||||||
var direction = (AtmosDirection) (1 << i);
|
|
||||||
var otherIndices = indices.Offset(direction.ToDirection());
|
|
||||||
var otherTile = GetTile(otherIndices);
|
|
||||||
if (otherTile != null) AddActiveTile(otherTile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InvalidatedCoords.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void UpdateAdjacentBits(Vector2i indices)
|
|
||||||
{
|
|
||||||
GetTile(indices)?.UpdateAdjacent();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public virtual void FixVacuum(Vector2i indices)
|
|
||||||
{
|
|
||||||
var tile = GetTile(indices);
|
|
||||||
if (tile?.GridIndex != _gridId) return;
|
|
||||||
// includeAirBlocked is false, therefore all tiles in this have Air != null.
|
|
||||||
var adjacent = GetAdjacentTiles(indices);
|
|
||||||
tile.Air = new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C};
|
|
||||||
Tiles[indices] = tile;
|
|
||||||
|
|
||||||
var ratio = 1f / adjacent.Count;
|
|
||||||
|
|
||||||
foreach (var (_, adj) in adjacent)
|
|
||||||
{
|
|
||||||
var mix = adj.Air!.RemoveRatio(ratio);
|
|
||||||
AtmosphereSystem.Merge(tile.Air, mix);
|
|
||||||
AtmosphereSystem.Merge(adj.Air, mix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public virtual void AddActiveTile(TileAtmosphere tile)
|
|
||||||
{
|
|
||||||
if (tile?.GridIndex != _gridId || tile.Air == null) return;
|
|
||||||
tile.Excited = true;
|
|
||||||
ActiveTiles.Add(tile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public virtual void RemoveActiveTile(TileAtmosphere tile, bool disposeGroup = true)
|
|
||||||
{
|
|
||||||
ActiveTiles.Remove(tile);
|
|
||||||
tile.Excited = false;
|
|
||||||
if(disposeGroup)
|
|
||||||
tile.ExcitedGroup?.Dispose();
|
|
||||||
else
|
|
||||||
tile.ExcitedGroup?.RemoveTile(tile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public virtual void AddHotspotTile(TileAtmosphere tile)
|
|
||||||
{
|
|
||||||
if (tile?.GridIndex != _gridId || tile?.Air == null) return;
|
|
||||||
HotspotTiles.Add(tile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public virtual void RemoveHotspotTile(TileAtmosphere tile)
|
|
||||||
{
|
|
||||||
HotspotTiles.Remove(tile);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void AddSuperconductivityTile(TileAtmosphere tile)
|
|
||||||
{
|
|
||||||
if (tile?.GridIndex != _gridId || !AtmosphereSystem.Superconduction) return;
|
|
||||||
SuperconductivityTiles.Add(tile);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void RemoveSuperconductivityTile(TileAtmosphere tile)
|
|
||||||
{
|
|
||||||
SuperconductivityTiles.Remove(tile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public virtual void AddHighPressureDelta(TileAtmosphere tile)
|
|
||||||
{
|
|
||||||
if (tile.GridIndex != _gridId) return;
|
|
||||||
HighPressureDelta.Add(tile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public virtual bool HasHighPressureDelta(TileAtmosphere tile)
|
|
||||||
{
|
|
||||||
return HighPressureDelta.Contains(tile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public virtual void AddExcitedGroup(ExcitedGroup excitedGroup)
|
|
||||||
{
|
|
||||||
ExcitedGroups.Add(excitedGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public virtual void RemoveExcitedGroup(ExcitedGroup excitedGroup)
|
|
||||||
{
|
|
||||||
ExcitedGroups.Remove(excitedGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void AddPipeNet(IPipeNet pipeNet)
|
|
||||||
{
|
|
||||||
PipeNets.Add(pipeNet);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void RemovePipeNet(IPipeNet pipeNet)
|
|
||||||
{
|
|
||||||
PipeNets.Remove(pipeNet);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void AddAtmosDevice(AtmosDeviceComponent atmosDevice)
|
|
||||||
{
|
|
||||||
AtmosDevices.Add(atmosDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void RemoveAtmosDevice(AtmosDeviceComponent atmosDevice)
|
|
||||||
{
|
|
||||||
AtmosDevices.Remove(atmosDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public virtual TileAtmosphere? GetTile(EntityCoordinates coordinates, bool createSpace = true)
|
|
||||||
{
|
|
||||||
return GetTile(coordinates.ToVector2i(_serverEntityManager, _mapManager), createSpace);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public virtual TileAtmosphere? GetTile(Vector2i indices, bool createSpace = true)
|
|
||||||
{
|
|
||||||
if (Tiles.TryGetValue(indices, out var tile)) return tile;
|
|
||||||
|
|
||||||
// We don't have that tile!
|
|
||||||
if (IsSpace(indices) && createSpace)
|
|
||||||
{
|
|
||||||
return new TileAtmosphere(this, _gridId, indices, new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.TCMB}, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool IsAirBlocked(Vector2i indices, AtmosDirection direction = AtmosDirection.All)
|
|
||||||
{
|
|
||||||
var directions = AtmosDirection.Invalid;
|
|
||||||
|
|
||||||
foreach (var obstructingComponent in GetObstructingComponents(indices))
|
|
||||||
{
|
|
||||||
if (!obstructingComponent.AirBlocked)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// We set the directions that are air-blocked so far,
|
|
||||||
// as you could have a full obstruction with only 4 directional air blockers.
|
|
||||||
directions |= obstructingComponent.AirBlockedDirection;
|
|
||||||
|
|
||||||
if (directions.IsFlagSet(direction))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public virtual bool IsSpace(Vector2i indices)
|
|
||||||
{
|
|
||||||
if (_mapGridComponent == null) return default;
|
|
||||||
|
|
||||||
return _mapGridComponent.Grid.GetTileRef(indices).IsSpace();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<AtmosDirection, TileAtmosphere> GetAdjacentTiles(EntityCoordinates coordinates, bool includeAirBlocked = false)
|
|
||||||
{
|
|
||||||
return GetAdjacentTiles(coordinates.ToVector2i(_serverEntityManager, _mapManager), includeAirBlocked);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<AtmosDirection, TileAtmosphere> GetAdjacentTiles(Vector2i indices, bool includeAirBlocked = false)
|
|
||||||
{
|
|
||||||
var sides = new Dictionary<AtmosDirection, TileAtmosphere>();
|
|
||||||
for (var i = 0; i < Atmospherics.Directions; i++)
|
|
||||||
{
|
|
||||||
var direction = (AtmosDirection) (1 << i);
|
|
||||||
var side = indices.Offset(direction.ToDirection());
|
|
||||||
var tile = GetTile(side);
|
|
||||||
if (tile != null && (tile.Air != null || includeAirBlocked))
|
|
||||||
sides[direction] = tile;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sides;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long EqualizationQueueCycleControl { get; set; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public float GetVolumeForCells(int cellCount)
|
|
||||||
{
|
|
||||||
if (_mapGridComponent == null) return default;
|
|
||||||
|
|
||||||
return _mapGridComponent.Grid.TileSize * cellCount * Atmospherics.CellVolume;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual IEnumerable<AirtightComponent> GetObstructingComponents(Vector2i indices)
|
|
||||||
{
|
|
||||||
var gridLookup = EntitySystem.Get<GridTileLookupSystem>();
|
|
||||||
|
|
||||||
foreach (var v in gridLookup.GetEntitiesIntersecting(_gridId, indices))
|
|
||||||
{
|
|
||||||
if (v.TryGetComponent<AirtightComponent>(out var ac))
|
|
||||||
yield return ac;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool NeedsVacuumFixing(Vector2i indices)
|
|
||||||
{
|
|
||||||
var value = false;
|
|
||||||
|
|
||||||
foreach (var airtightComponent in GetObstructingComponents(indices))
|
|
||||||
{
|
|
||||||
value |= airtightComponent.FixVacuum;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private AtmosDirection GetBlockedDirections(Vector2i indices)
|
|
||||||
{
|
|
||||||
var value = AtmosDirection.Invalid;
|
|
||||||
|
|
||||||
foreach (var airtightComponent in GetObstructingComponents(indices))
|
|
||||||
{
|
|
||||||
if(airtightComponent.AirBlocked)
|
|
||||||
value |= airtightComponent.AirBlockedDirection;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerator<TileAtmosphere> GetEnumerator()
|
|
||||||
{
|
|
||||||
return Tiles.Values.GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
|
||||||
{
|
|
||||||
return GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public virtual void BurnTile(Vector2i gridIndices)
|
|
||||||
{
|
|
||||||
// TODO ATMOS
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,181 +1,12 @@
|
|||||||
using System.Collections.Generic;
|
using Robust.Shared.GameObjects;
|
||||||
using Content.Server.Atmos.Piping.Components;
|
|
||||||
using Content.Server.NodeContainer.NodeGroups;
|
|
||||||
using Content.Shared.Atmos;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
|
|
||||||
namespace Content.Server.Atmos.Components
|
namespace Content.Server.Atmos.Components
|
||||||
{
|
{
|
||||||
public interface IGridAtmosphereComponent : IComponent, IEnumerable<TileAtmosphere>
|
public interface IGridAtmosphereComponent : IComponent
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether this atmosphere is simulated or not.
|
/// Whether this atmosphere is simulated or not.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool Simulated { get; }
|
bool Simulated { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Number of times <see cref="Update"/> has been called.
|
|
||||||
/// </summary>
|
|
||||||
int UpdateCounter { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Control variable for equalization.
|
|
||||||
/// </summary>
|
|
||||||
long EqualizationQueueCycleControl { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Attemps to pry a tile.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="indices"></param>
|
|
||||||
void PryTile(Vector2i indices);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Burns a tile.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="gridIndices"></param>
|
|
||||||
void BurnTile(Vector2i gridIndices);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Invalidates a coordinate to be revalidated again.
|
|
||||||
/// Use this after changing a tile's gas contents, or when the tile becomes space, etc.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="indices"></param>
|
|
||||||
void Invalidate(Vector2i indices);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Attempts to fix a sudden vacuum by creating gas.
|
|
||||||
/// </summary>
|
|
||||||
void FixVacuum(Vector2i indices);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Revalidates indices immediately.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="indices"></param>
|
|
||||||
void UpdateAdjacentBits(Vector2i indices);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds an active tile so it becomes processed every update until it becomes inactive.
|
|
||||||
/// Also makes the tile excited.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="tile"></param>
|
|
||||||
void AddActiveTile(TileAtmosphere tile);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes an active tile and disposes of its <seealso cref="ExcitedGroup"/>.
|
|
||||||
/// Use with caution.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="tile"></param>
|
|
||||||
void RemoveActiveTile(TileAtmosphere tile, bool disposeGroup = true);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Marks a tile as having a hotspot so it can be processed.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="tile"></param>
|
|
||||||
void AddHotspotTile(TileAtmosphere tile);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes a tile from the hotspot processing list.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="tile"></param>
|
|
||||||
void RemoveHotspotTile(TileAtmosphere tile);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Marks a tile as superconductive so it can be processed.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="tile"></param>
|
|
||||||
void AddSuperconductivityTile(TileAtmosphere tile);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes a tile from the superconductivity processing list.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="tile"></param>
|
|
||||||
void RemoveSuperconductivityTile(TileAtmosphere tile);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Marks a tile has having high pressure differences that need to be equalized.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="tile"></param>
|
|
||||||
void AddHighPressureDelta(TileAtmosphere tile);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns whether the tile in question is marked as having high pressure differences or not.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="tile"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
bool HasHighPressureDelta(TileAtmosphere tile);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a excited group to be processed.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="excitedGroup"></param>
|
|
||||||
void AddExcitedGroup(ExcitedGroup excitedGroup);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes an excited group.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="excitedGroup"></param>
|
|
||||||
void RemoveExcitedGroup(ExcitedGroup excitedGroup);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a tile.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="indices"></param>
|
|
||||||
/// <param name="createSpace"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
TileAtmosphere? GetTile(Vector2i indices, bool createSpace = true);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a tile.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="coordinates"></param>
|
|
||||||
/// <param name="createSpace"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
TileAtmosphere? GetTile(EntityCoordinates coordinates, bool createSpace = true);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns if the tile in question is air-blocked.
|
|
||||||
/// This could be due to a wall, an airlock, etc.
|
|
||||||
/// <seealso cref="AirtightComponent"/>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="indices"></param>
|
|
||||||
/// <param name="direction"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
bool IsAirBlocked(Vector2i indices, AtmosDirection direction);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns if the tile in question is space.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="indices"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
bool IsSpace(Vector2i indices);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the volume in liters for a number of cells/tiles.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="cellCount"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
float GetVolumeForCells(int cellCount);
|
|
||||||
|
|
||||||
void RepopulateTiles();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a dictionary of adjacent TileAtmospheres.
|
|
||||||
/// </summary>
|
|
||||||
Dictionary<AtmosDirection, TileAtmosphere> GetAdjacentTiles(EntityCoordinates coordinates, bool includeAirBlocked = false);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a dictionary of adjacent TileAtmospheres.
|
|
||||||
/// </summary>
|
|
||||||
Dictionary<AtmosDirection, TileAtmosphere> GetAdjacentTiles(Vector2i indices, bool includeAirBlocked = false);
|
|
||||||
|
|
||||||
void AddPipeNet(IPipeNet pipeNet);
|
|
||||||
|
|
||||||
void RemovePipeNet(IPipeNet pipeNet);
|
|
||||||
|
|
||||||
void AddAtmosDevice(AtmosDeviceComponent atmosDevice);
|
|
||||||
|
|
||||||
void RemoveAtmosDevice(AtmosDeviceComponent atmosDevice);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,22 +12,5 @@ namespace Content.Server.Atmos.Components
|
|||||||
public class SpaceGridAtmosphereComponent : UnsimulatedGridAtmosphereComponent
|
public class SpaceGridAtmosphereComponent : UnsimulatedGridAtmosphereComponent
|
||||||
{
|
{
|
||||||
public override string Name => "SpaceGridAtmosphere";
|
public override string Name => "SpaceGridAtmosphere";
|
||||||
|
|
||||||
public override void RepopulateTiles() { }
|
|
||||||
|
|
||||||
public override bool IsSpace(Vector2i indices)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override TileAtmosphere GetTile(Vector2i indices, bool createSpace = true)
|
|
||||||
{
|
|
||||||
return new(this, GridId.Invalid, indices, new GasMixture(Atmospherics.CellVolume), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override IEnumerable<AirtightComponent> GetObstructingComponents(Vector2i indices)
|
|
||||||
{
|
|
||||||
return Enumerable.Empty<AirtightComponent>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,55 +16,5 @@ namespace Content.Server.Atmos.Components
|
|||||||
public override string Name => "UnsimulatedGridAtmosphere";
|
public override string Name => "UnsimulatedGridAtmosphere";
|
||||||
|
|
||||||
public override bool Simulated => false;
|
public override bool Simulated => false;
|
||||||
|
|
||||||
public override void PryTile(Vector2i indices) { }
|
|
||||||
|
|
||||||
public override void RepopulateTiles()
|
|
||||||
{
|
|
||||||
if (!Owner.TryGetComponent(out IMapGridComponent? mapGrid)) return;
|
|
||||||
|
|
||||||
foreach (var tile in mapGrid.Grid.GetAllTiles())
|
|
||||||
{
|
|
||||||
if(!Tiles.ContainsKey(tile.GridIndices))
|
|
||||||
Tiles.Add(tile.GridIndices, new TileAtmosphere(this, tile.GridIndex, tile.GridIndices, new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Invalidate(Vector2i indices) { }
|
|
||||||
|
|
||||||
public override void Revalidate() { }
|
|
||||||
|
|
||||||
public override void FixVacuum(Vector2i indices) { }
|
|
||||||
|
|
||||||
public override void AddActiveTile(TileAtmosphere? tile) { }
|
|
||||||
|
|
||||||
public override void RemoveActiveTile(TileAtmosphere? tile, bool disposeGroup = true) { }
|
|
||||||
|
|
||||||
public override void AddHotspotTile(TileAtmosphere? tile) { }
|
|
||||||
|
|
||||||
public override void RemoveHotspotTile(TileAtmosphere? tile) { }
|
|
||||||
|
|
||||||
public override void AddSuperconductivityTile(TileAtmosphere? tile) { }
|
|
||||||
|
|
||||||
public override void RemoveSuperconductivityTile(TileAtmosphere? tile) { }
|
|
||||||
|
|
||||||
public override void AddHighPressureDelta(TileAtmosphere? tile) { }
|
|
||||||
|
|
||||||
public override bool HasHighPressureDelta(TileAtmosphere tile)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void AddExcitedGroup(ExcitedGroup excitedGroup) { }
|
|
||||||
|
|
||||||
public override void RemoveExcitedGroup(ExcitedGroup excitedGroup) { }
|
|
||||||
|
|
||||||
public override void AddPipeNet(IPipeNet pipeNet) { }
|
|
||||||
|
|
||||||
public override void RemovePipeNet(IPipeNet pipeNet) { }
|
|
||||||
|
|
||||||
public override void AddAtmosDevice(AtmosDeviceComponent atmosDevice) { }
|
|
||||||
|
|
||||||
public override void RemoveAtmosDevice(AtmosDeviceComponent atmosDevice) { }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
AccumulatedFrameTime -= _updateCooldown;
|
AccumulatedFrameTime -= _updateCooldown;
|
||||||
|
|
||||||
var currentTick = _gameTiming.CurTick;
|
var currentTick = _gameTiming.CurTick;
|
||||||
|
var atmosphereSystem = Get<AtmosphereSystem>();
|
||||||
|
|
||||||
// Now we'll go through each player, then through each chunk in range of that player checking if the player is still in range
|
// Now we'll go through each player, then through each chunk in range of that player checking if the player is still in range
|
||||||
// If they are, check if they need the new data to send (i.e. if there's an overlay for the gas).
|
// If they are, check if they need the new data to send (i.e. if there's an overlay for the gas).
|
||||||
@@ -156,7 +157,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
for (var x = 0; x < LocalViewRange; x++)
|
for (var x = 0; x < LocalViewRange; x++)
|
||||||
{
|
{
|
||||||
var Vector2i = new Vector2i(baseTile.X + x, baseTile.Y + y);
|
var Vector2i = new Vector2i(baseTile.X + x, baseTile.Y + y);
|
||||||
debugOverlayContent[index++] = ConvertTileToData(gam.GetTile(Vector2i));
|
debugOverlayContent[index++] = ConvertTileToData(atmosphereSystem.GetTileAtmosphereOrCreateSpace(grid, gam, Vector2i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
using Content.Shared.CCVar;
|
using Content.Shared.CCVar;
|
||||||
|
using Robust.Shared.Configuration;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
|
||||||
namespace Content.Server.Atmos.EntitySystems
|
namespace Content.Server.Atmos.EntitySystems
|
||||||
{
|
{
|
||||||
public partial class AtmosphereSystem
|
public partial class AtmosphereSystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||||
|
|
||||||
public bool SpaceWind { get; private set; }
|
public bool SpaceWind { get; private set; }
|
||||||
public string? SpaceWindSound { get; private set; }
|
public string? SpaceWindSound { get; private set; }
|
||||||
public bool MonstermosEqualization { get; private set; }
|
public bool MonstermosEqualization { get; private set; }
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
using Content.Server.Atmos.Components;
|
||||||
|
using Content.Shared.Atmos;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Server.Atmos.EntitySystems
|
||||||
|
{
|
||||||
|
public partial class AtmosphereSystem
|
||||||
|
{
|
||||||
|
private void ExcitedGroupAddTile(ExcitedGroup excitedGroup, TileAtmosphere tile)
|
||||||
|
{
|
||||||
|
DebugTools.Assert(!excitedGroup.Disposed, "Excited group is disposed!");
|
||||||
|
DebugTools.Assert(tile.ExcitedGroup == null, "Tried to add a tile to an excited group when it's already in another one!");
|
||||||
|
excitedGroup.Tiles.Add(tile);
|
||||||
|
tile.ExcitedGroup = excitedGroup;
|
||||||
|
ExcitedGroupResetCooldowns(excitedGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExcitedGroupRemoveTile(ExcitedGroup excitedGroup, TileAtmosphere tile)
|
||||||
|
{
|
||||||
|
DebugTools.Assert(!excitedGroup.Disposed, "Excited group is disposed!");
|
||||||
|
DebugTools.Assert(tile.ExcitedGroup == excitedGroup, "Tried to remove a tile from an excited group it's not present in!");
|
||||||
|
tile.ExcitedGroup = null;
|
||||||
|
excitedGroup.Tiles.Remove(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExcitedGroupMerge(GridAtmosphereComponent gridAtmosphere, ExcitedGroup ourGroup, ExcitedGroup otherGroup)
|
||||||
|
{
|
||||||
|
DebugTools.Assert(!ourGroup.Disposed, "Excited group is disposed!");
|
||||||
|
DebugTools.Assert(!otherGroup.Disposed, "Excited group is disposed!");
|
||||||
|
DebugTools.Assert(gridAtmosphere.ExcitedGroups.Contains(ourGroup), "Grid Atmosphere does not contain Excited Group!");
|
||||||
|
DebugTools.Assert(gridAtmosphere.ExcitedGroups.Contains(otherGroup), "Grid Atmosphere does not contain Excited Group!");
|
||||||
|
var ourSize = ourGroup.Tiles.Count;
|
||||||
|
var otherSize = otherGroup.Tiles.Count;
|
||||||
|
|
||||||
|
ExcitedGroup winner;
|
||||||
|
ExcitedGroup loser;
|
||||||
|
|
||||||
|
if (ourSize > otherSize)
|
||||||
|
{
|
||||||
|
winner = ourGroup;
|
||||||
|
loser = otherGroup;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
winner = otherGroup;
|
||||||
|
loser = ourGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var tile in loser.Tiles)
|
||||||
|
{
|
||||||
|
tile.ExcitedGroup = winner;
|
||||||
|
winner.Tiles.Add(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
loser.Tiles.Clear();
|
||||||
|
ExcitedGroupDispose(gridAtmosphere, loser);
|
||||||
|
ExcitedGroupResetCooldowns(winner);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExcitedGroupResetCooldowns(ExcitedGroup excitedGroup)
|
||||||
|
{
|
||||||
|
DebugTools.Assert(!excitedGroup.Disposed, "Excited group is disposed!");
|
||||||
|
excitedGroup.BreakdownCooldown = 0;
|
||||||
|
excitedGroup.DismantleCooldown = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExcitedGroupSelfBreakdown(GridAtmosphereComponent gridAtmosphere, ExcitedGroup excitedGroup, bool spaceIsAllConsuming = false)
|
||||||
|
{
|
||||||
|
DebugTools.Assert(!excitedGroup.Disposed, "Excited group is disposed!");
|
||||||
|
DebugTools.Assert(gridAtmosphere.ExcitedGroups.Contains(excitedGroup), "Grid Atmosphere does not contain Excited Group!");
|
||||||
|
var combined = new GasMixture(Atmospherics.CellVolume);
|
||||||
|
|
||||||
|
var tileSize = excitedGroup.Tiles.Count;
|
||||||
|
|
||||||
|
if (excitedGroup.Disposed) return;
|
||||||
|
|
||||||
|
if (tileSize == 0)
|
||||||
|
{
|
||||||
|
ExcitedGroupDispose(gridAtmosphere, excitedGroup);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var tile in excitedGroup.Tiles)
|
||||||
|
{
|
||||||
|
if (tile?.Air == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Merge(combined, tile.Air);
|
||||||
|
|
||||||
|
if (!spaceIsAllConsuming || !tile.Air.Immutable)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
combined.Clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
combined.Multiply(1 / (float)tileSize);
|
||||||
|
|
||||||
|
foreach (var tile in excitedGroup.Tiles)
|
||||||
|
{
|
||||||
|
if (tile?.Air == null) continue;
|
||||||
|
tile.Air.CopyFromMutable(combined);
|
||||||
|
InvalidateVisuals(tile.GridIndex, tile.GridIndices);
|
||||||
|
}
|
||||||
|
|
||||||
|
excitedGroup.BreakdownCooldown = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExcitedGroupDismantle(GridAtmosphereComponent gridAtmosphere, ExcitedGroup excitedGroup, bool unexcite = true)
|
||||||
|
{
|
||||||
|
foreach (var tile in excitedGroup.Tiles)
|
||||||
|
{
|
||||||
|
tile.ExcitedGroup = null;
|
||||||
|
|
||||||
|
if (!unexcite)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
RemoveActiveTile(gridAtmosphere, tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
excitedGroup.Tiles.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExcitedGroupDispose(GridAtmosphereComponent gridAtmosphere, ExcitedGroup excitedGroup)
|
||||||
|
{
|
||||||
|
if (excitedGroup.Disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DebugTools.Assert(gridAtmosphere.ExcitedGroups.Contains(excitedGroup), "Grid Atmosphere does not contain Excited Group!");
|
||||||
|
|
||||||
|
excitedGroup.Disposed = true;
|
||||||
|
|
||||||
|
gridAtmosphere.ExcitedGroups.Remove(excitedGroup);
|
||||||
|
ExcitedGroupDismantle(gridAtmosphere, excitedGroup, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,12 +4,16 @@ using System.Linq;
|
|||||||
using Content.Server.Atmos.Reactions;
|
using Content.Server.Atmos.Reactions;
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Shared.Atmos;
|
using Content.Shared.Atmos;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Server.Atmos.EntitySystems
|
namespace Content.Server.Atmos.EntitySystems
|
||||||
{
|
{
|
||||||
public partial class AtmosphereSystem
|
public partial class AtmosphereSystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IPrototypeManager _protoMan = default!;
|
||||||
|
|
||||||
private GasReactionPrototype[] _gasReactions = Array.Empty<GasReactionPrototype>();
|
private GasReactionPrototype[] _gasReactions = Array.Empty<GasReactionPrototype>();
|
||||||
private float[] _gasSpecificHeats = new float[Atmospherics.TotalNumberOfGases];
|
private float[] _gasSpecificHeats = new float[Atmospherics.TotalNumberOfGases];
|
||||||
|
|
||||||
@@ -51,16 +55,23 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
return mixture.Temperature * GetHeatCapacity(mixture);
|
return mixture.Temperature * GetHeatCapacity(mixture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float GetThermalEnergy(GasMixture mixture, float cachedHeatCapacity)
|
||||||
|
{
|
||||||
|
return mixture.Temperature * cachedHeatCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
public void Merge(GasMixture receiver, GasMixture giver)
|
public void Merge(GasMixture receiver, GasMixture giver)
|
||||||
{
|
{
|
||||||
if (receiver.Immutable) return;
|
if (receiver.Immutable) return;
|
||||||
|
|
||||||
if (MathF.Abs(receiver.Temperature - giver.Temperature) > Atmospherics.MinimumTemperatureDeltaToConsider)
|
if (MathF.Abs(receiver.Temperature - giver.Temperature) > Atmospherics.MinimumTemperatureDeltaToConsider)
|
||||||
{
|
{
|
||||||
var combinedHeatCapacity = GetHeatCapacity(receiver) + GetHeatCapacity(giver);
|
var receiverHeatCapacity = GetHeatCapacity(receiver);
|
||||||
|
var giverHeatCapacity = GetHeatCapacity(giver);
|
||||||
|
var combinedHeatCapacity = receiverHeatCapacity + giverHeatCapacity;
|
||||||
if (combinedHeatCapacity > 0f)
|
if (combinedHeatCapacity > 0f)
|
||||||
{
|
{
|
||||||
receiver.Temperature = (GetThermalEnergy(giver) + GetThermalEnergy(receiver)) / combinedHeatCapacity;
|
receiver.Temperature = (GetThermalEnergy(giver, giverHeatCapacity) + GetThermalEnergy(receiver, receiverHeatCapacity)) / combinedHeatCapacity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -58,7 +58,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
|
|
||||||
private void ConsiderPressureDifference(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile, TileAtmosphere other, float difference)
|
private void ConsiderPressureDifference(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile, TileAtmosphere other, float difference)
|
||||||
{
|
{
|
||||||
gridAtmosphere.AddHighPressureDelta(tile);
|
gridAtmosphere.HighPressureDelta.Add(tile);
|
||||||
if (difference > tile.PressureDifference)
|
if (difference > tile.PressureDifference)
|
||||||
{
|
{
|
||||||
tile.PressureDifference = difference;
|
tile.PressureDifference = difference;
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ using Content.Server.Atmos.Components;
|
|||||||
using Content.Server.Atmos.Reactions;
|
using Content.Server.Atmos.Reactions;
|
||||||
using Content.Server.Coordinates.Helpers;
|
using Content.Server.Coordinates.Helpers;
|
||||||
using Content.Shared.Atmos;
|
using Content.Shared.Atmos;
|
||||||
using Content.Shared.GameTicking;
|
|
||||||
using Content.Shared.Maps;
|
using Content.Shared.Maps;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
|
||||||
namespace Content.Server.Atmos.EntitySystems
|
namespace Content.Server.Atmos.EntitySystems
|
||||||
{
|
{
|
||||||
@@ -15,13 +15,13 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
{
|
{
|
||||||
if (!tile.Hotspot.Valid)
|
if (!tile.Hotspot.Valid)
|
||||||
{
|
{
|
||||||
gridAtmosphere.RemoveHotspotTile(tile);
|
gridAtmosphere.HotspotTiles.Remove(tile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tile.Excited)
|
if (!tile.Excited)
|
||||||
{
|
{
|
||||||
gridAtmosphere.AddActiveTile(tile);
|
AddActiveTile(gridAtmosphere, tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tile.Hotspot.SkippedFirstProcess)
|
if (!tile.Hotspot.SkippedFirstProcess)
|
||||||
@@ -30,13 +30,14 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tile.ExcitedGroup?.ResetCooldowns();
|
if(tile.ExcitedGroup != null)
|
||||||
|
ExcitedGroupResetCooldowns(tile.ExcitedGroup);
|
||||||
|
|
||||||
if ((tile.Hotspot.Temperature < Atmospherics.FireMinimumTemperatureToExist) || (tile.Hotspot.Volume <= 1f)
|
if ((tile.Hotspot.Temperature < Atmospherics.FireMinimumTemperatureToExist) || (tile.Hotspot.Volume <= 1f)
|
||||||
|| tile.Air == null || tile.Air.GetMoles(Gas.Oxygen) < 0.5f || (tile.Air.GetMoles(Gas.Plasma) < 0.5f && tile.Air.GetMoles(Gas.Tritium) < 0.5f))
|
|| tile.Air == null || tile.Air.GetMoles(Gas.Oxygen) < 0.5f || (tile.Air.GetMoles(Gas.Plasma) < 0.5f && tile.Air.GetMoles(Gas.Tritium) < 0.5f))
|
||||||
{
|
{
|
||||||
tile.Hotspot = new Hotspot();
|
tile.Hotspot = new Hotspot();
|
||||||
tile.UpdateVisuals();
|
InvalidateVisuals(tile.GridIndex, tile.GridIndices);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,13 +46,17 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
if (tile.Hotspot.Bypassing)
|
if (tile.Hotspot.Bypassing)
|
||||||
{
|
{
|
||||||
tile.Hotspot.State = 3;
|
tile.Hotspot.State = 3;
|
||||||
gridAtmosphere.BurnTile(tile.GridIndices);
|
// TODO ATMOS: Burn tile here
|
||||||
|
|
||||||
if (tile.Air.Temperature > Atmospherics.FireMinimumTemperatureToSpread)
|
if (tile.Air.Temperature > Atmospherics.FireMinimumTemperatureToSpread)
|
||||||
{
|
{
|
||||||
var radiatedTemperature = tile.Air.Temperature * Atmospherics.FireSpreadRadiosityScale;
|
var radiatedTemperature = tile.Air.Temperature * Atmospherics.FireSpreadRadiosityScale;
|
||||||
foreach (var otherTile in tile.AdjacentTiles)
|
foreach (var otherTile in tile.AdjacentTiles)
|
||||||
{
|
{
|
||||||
|
// TODO ATMOS: This is sus. Suss this out.
|
||||||
|
if (otherTile == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
if(!otherTile.Hotspot.Valid)
|
if(!otherTile.Hotspot.Valid)
|
||||||
HotspotExpose(gridAtmosphere, otherTile, radiatedTemperature, Atmospherics.CellVolume/4);
|
HotspotExpose(gridAtmosphere, otherTile, radiatedTemperature, Atmospherics.CellVolume/4);
|
||||||
}
|
}
|
||||||
@@ -108,8 +113,8 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
|
|
||||||
tile.Hotspot.Start();
|
tile.Hotspot.Start();
|
||||||
|
|
||||||
gridAtmosphere.AddActiveTile(tile);
|
AddActiveTile(gridAtmosphere, tile);
|
||||||
gridAtmosphere.AddHotspotTile(tile);
|
gridAtmosphere.HotspotTiles.Add(tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,11 +133,11 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
{
|
{
|
||||||
var affected = tile.Air.RemoveRatio(tile.Hotspot.Volume / tile.Air.Volume);
|
var affected = tile.Air.RemoveRatio(tile.Hotspot.Volume / tile.Air.Volume);
|
||||||
affected.Temperature = tile.Hotspot.Temperature;
|
affected.Temperature = tile.Hotspot.Temperature;
|
||||||
gridAtmosphere.AtmosphereSystem.React(affected, tile);
|
React(affected, tile);
|
||||||
tile.Hotspot.Temperature = affected.Temperature;
|
tile.Hotspot.Temperature = affected.Temperature;
|
||||||
tile.Hotspot.Volume = affected.ReactionResults[GasReaction.Fire] * Atmospherics.FireGrowthRate;
|
tile.Hotspot.Volume = affected.ReactionResults[GasReaction.Fire] * Atmospherics.FireGrowthRate;
|
||||||
Merge(tile.Air, affected);
|
Merge(tile.Air, affected);
|
||||||
gridAtmosphere.Invalidate(tile.GridIndices);
|
gridAtmosphere.InvalidatedCoords.Add(tile.GridIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
var tileRef = tile.GridIndices.GetTileRef(tile.GridIndex);
|
var tileRef = tile.GridIndices.GetTileRef(tile.GridIndex);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
// Can't process a tile without air
|
// Can't process a tile without air
|
||||||
if (tile.Air == null)
|
if (tile.Air == null)
|
||||||
{
|
{
|
||||||
gridAtmosphere.RemoveActiveTile(tile);
|
RemoveActiveTile(gridAtmosphere, tile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
{
|
{
|
||||||
if (tile.ExcitedGroup != enemyTile.ExcitedGroup)
|
if (tile.ExcitedGroup != enemyTile.ExcitedGroup)
|
||||||
{
|
{
|
||||||
tile.ExcitedGroup.MergeGroups(enemyTile.ExcitedGroup);
|
ExcitedGroupMerge(gridAtmosphere, tile.ExcitedGroup, enemyTile.ExcitedGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldShareAir = true;
|
shouldShareAir = true;
|
||||||
@@ -54,7 +54,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
{
|
{
|
||||||
if (!enemyTile.Excited)
|
if (!enemyTile.Excited)
|
||||||
{
|
{
|
||||||
gridAtmosphere.AddActiveTile(enemyTile);
|
AddActiveTile(gridAtmosphere, enemyTile);
|
||||||
}
|
}
|
||||||
|
|
||||||
var excitedGroup = tile.ExcitedGroup;
|
var excitedGroup = tile.ExcitedGroup;
|
||||||
@@ -63,14 +63,14 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
if (excitedGroup == null)
|
if (excitedGroup == null)
|
||||||
{
|
{
|
||||||
excitedGroup = new ExcitedGroup();
|
excitedGroup = new ExcitedGroup();
|
||||||
excitedGroup.Initialize(gridAtmosphere);
|
gridAtmosphere.ExcitedGroups.Add(excitedGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tile.ExcitedGroup == null)
|
if (tile.ExcitedGroup == null)
|
||||||
excitedGroup.AddTile(tile);
|
ExcitedGroupAddTile(excitedGroup, tile);
|
||||||
|
|
||||||
if(enemyTile.ExcitedGroup == null)
|
if(enemyTile.ExcitedGroup == null)
|
||||||
excitedGroup.AddTile(enemyTile);
|
ExcitedGroupAddTile(excitedGroup, enemyTile);
|
||||||
|
|
||||||
shouldShareAir = true;
|
shouldShareAir = true;
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,8 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
|
|
||||||
if(tile.Air != null)
|
if(tile.Air != null)
|
||||||
React(tile.Air, tile);
|
React(tile.Air, tile);
|
||||||
tile.UpdateVisuals();
|
|
||||||
|
InvalidateVisuals(tile.GridIndex, tile.GridIndices);
|
||||||
|
|
||||||
var remove = true;
|
var remove = true;
|
||||||
|
|
||||||
@@ -106,7 +107,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
remove = false;
|
remove = false;
|
||||||
|
|
||||||
if(tile.ExcitedGroup == null && remove)
|
if(tile.ExcitedGroup == null && remove)
|
||||||
gridAtmosphere.RemoveActiveTile(tile);
|
RemoveActiveTile(gridAtmosphere, tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Archive(TileAtmosphere tile, int fireCount)
|
private void Archive(TileAtmosphere tile, int fireCount)
|
||||||
@@ -124,7 +125,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
switch (tile.Air.LastShare)
|
switch (tile.Air.LastShare)
|
||||||
{
|
{
|
||||||
case > Atmospherics.MinimumAirToSuspend:
|
case > Atmospherics.MinimumAirToSuspend:
|
||||||
tile.ExcitedGroup.ResetCooldowns();
|
ExcitedGroupResetCooldowns(tile.ExcitedGroup);
|
||||||
break;
|
break;
|
||||||
case > Atmospherics.MinimumMolesDeltaToMove:
|
case > Atmospherics.MinimumMolesDeltaToMove:
|
||||||
tile.ExcitedGroup.DismantleCooldown = 0;
|
tile.ExcitedGroup.DismantleCooldown = 0;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using Content.Server.Atmos.Components;
|
|||||||
using Content.Server.Coordinates.Helpers;
|
using Content.Server.Coordinates.Helpers;
|
||||||
using Content.Shared.Atmos;
|
using Content.Shared.Atmos;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
@@ -18,7 +19,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
|
|
||||||
private readonly TileAtmosphereComparer _monstermosComparer = new();
|
private readonly TileAtmosphereComparer _monstermosComparer = new();
|
||||||
|
|
||||||
public void EqualizePressureInZone(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile, int cycleNum)
|
public void EqualizePressureInZone(IMapGrid mapGrid, GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile, int cycleNum)
|
||||||
{
|
{
|
||||||
if (tile.Air == null || (tile.MonstermosInfo.LastCycle >= cycleNum))
|
if (tile.Air == null || (tile.MonstermosInfo.LastCycle >= cycleNum))
|
||||||
return; // Already done.
|
return; // Already done.
|
||||||
@@ -80,7 +81,8 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
if (adj.Air.Immutable)
|
if (adj.Air.Immutable)
|
||||||
{
|
{
|
||||||
// Looks like someone opened an airlock to space!
|
// Looks like someone opened an airlock to space!
|
||||||
ExplosivelyDepressurize(gridAtmosphere, tile, cycleNum);
|
|
||||||
|
ExplosivelyDepressurize(mapGrid, gridAtmosphere, tile, cycleNum);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -339,7 +341,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
if (!otherTile.AdjacentBits.IsFlagSet(direction)) continue;
|
if (!otherTile.AdjacentBits.IsFlagSet(direction)) continue;
|
||||||
var otherTile2 = otherTile.AdjacentTiles[j];
|
var otherTile2 = otherTile.AdjacentTiles[j];
|
||||||
if (otherTile2?.Air?.Compare(tile.Air) == GasMixture.GasCompareResult.NoExchange) continue;
|
if (otherTile2?.Air?.Compare(tile.Air) == GasMixture.GasCompareResult.NoExchange) continue;
|
||||||
gridAtmosphere.AddActiveTile(otherTile2);
|
AddActiveTile(gridAtmosphere, otherTile2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -349,7 +351,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
ArrayPool<TileAtmosphere>.Shared.Return(takerTiles);
|
ArrayPool<TileAtmosphere>.Shared.Return(takerTiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ExplosivelyDepressurize(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile, int cycleNum)
|
public void ExplosivelyDepressurize(IMapGrid mapGrid, GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile, int cycleNum)
|
||||||
{
|
{
|
||||||
// Check if explosive depressurization is enabled and if the tile is valid.
|
// Check if explosive depressurization is enabled and if the tile is valid.
|
||||||
if (!MonstermosDepressurization || tile.Air == null)
|
if (!MonstermosDepressurization || tile.Air == null)
|
||||||
@@ -389,7 +391,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
if (otherTile2.Air == null) continue;
|
if (otherTile2.Air == null) continue;
|
||||||
if (otherTile2.MonstermosInfo.LastQueueCycle == queueCycle) continue;
|
if (otherTile2.MonstermosInfo.LastQueueCycle == queueCycle) continue;
|
||||||
|
|
||||||
ConsiderFirelocks(otherTile, otherTile2);
|
ConsiderFirelocks(gridAtmosphere, otherTile, otherTile2);
|
||||||
|
|
||||||
// The firelocks might have closed on us.
|
// The firelocks might have closed on us.
|
||||||
if (!otherTile.AdjacentBits.IsFlagSet(direction)) continue;
|
if (!otherTile.AdjacentBits.IsFlagSet(direction)) continue;
|
||||||
@@ -438,8 +440,8 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
{
|
{
|
||||||
var otherTile = progressionOrder[i];
|
var otherTile = progressionOrder[i];
|
||||||
if (otherTile.MonstermosInfo.CurrentTransferDirection == AtmosDirection.Invalid) continue;
|
if (otherTile.MonstermosInfo.CurrentTransferDirection == AtmosDirection.Invalid) continue;
|
||||||
gridAtmosphere.AddHighPressureDelta(otherTile);
|
gridAtmosphere.HighPressureDelta.Add(otherTile);
|
||||||
gridAtmosphere.AddActiveTile(otherTile);
|
AddActiveTile(gridAtmosphere, otherTile);
|
||||||
var otherTile2 = otherTile.AdjacentTiles[otherTile.MonstermosInfo.CurrentTransferDirection.ToIndex()];
|
var otherTile2 = otherTile.AdjacentTiles[otherTile.MonstermosInfo.CurrentTransferDirection.ToIndex()];
|
||||||
if (otherTile2?.Air == null) continue;
|
if (otherTile2?.Air == null) continue;
|
||||||
var sum = otherTile2.Air.TotalMoles;
|
var sum = otherTile2.Air.TotalMoles;
|
||||||
@@ -455,9 +457,9 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
otherTile2.PressureDirection = otherTile.MonstermosInfo.CurrentTransferDirection;
|
otherTile2.PressureDirection = otherTile.MonstermosInfo.CurrentTransferDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
otherTile.Air.Clear();
|
otherTile.Air?.Clear();
|
||||||
otherTile.UpdateVisuals();
|
InvalidateVisuals(otherTile.GridIndex, otherTile.GridIndices);
|
||||||
HandleDecompressionFloorRip(gridAtmosphere, otherTile, sum);
|
HandleDecompressionFloorRip(mapGrid, otherTile, sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayPool<TileAtmosphere>.Shared.Return(tiles);
|
ArrayPool<TileAtmosphere>.Shared.Return(tiles);
|
||||||
@@ -465,7 +467,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
ArrayPool<TileAtmosphere>.Shared.Return(progressionOrder);
|
ArrayPool<TileAtmosphere>.Shared.Return(progressionOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ConsiderFirelocks(TileAtmosphere tile, TileAtmosphere other)
|
private void ConsiderFirelocks(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile, TileAtmosphere other)
|
||||||
{
|
{
|
||||||
if (!_mapManager.TryGetGrid(tile.GridIndex, out var mapGrid))
|
if (!_mapManager.TryGetGrid(tile.GridIndex, out var mapGrid))
|
||||||
return;
|
return;
|
||||||
@@ -491,8 +493,10 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
if (!reconsiderAdjacent)
|
if (!reconsiderAdjacent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tile.UpdateAdjacent();
|
UpdateAdjacent(mapGrid, gridAtmosphere, tile);
|
||||||
other.UpdateAdjacent();
|
UpdateAdjacent(mapGrid, gridAtmosphere, other);
|
||||||
|
InvalidateVisuals(tile.GridIndex, tile.GridIndices);
|
||||||
|
InvalidateVisuals(other.GridIndex, other.GridIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FinalizeEq(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile)
|
public void FinalizeEq(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile)
|
||||||
@@ -524,8 +528,8 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
|
|
||||||
otherTile.MonstermosInfo[direction.GetOpposite()] = 0;
|
otherTile.MonstermosInfo[direction.GetOpposite()] = 0;
|
||||||
Merge(otherTile.Air, tile.Air.Remove(amount));
|
Merge(otherTile.Air, tile.Air.Remove(amount));
|
||||||
tile.UpdateVisuals();
|
InvalidateVisuals(tile.GridIndex, tile.GridIndices);
|
||||||
otherTile.UpdateVisuals();
|
InvalidateVisuals(otherTile.GridIndex, otherTile.GridIndices);
|
||||||
ConsiderPressureDifference(gridAtmosphere, tile, otherTile, amount);
|
ConsiderPressureDifference(gridAtmosphere, tile, otherTile, amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -548,12 +552,12 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
tile.AdjacentTiles[direction.ToIndex()].MonstermosInfo[direction.GetOpposite()] -= amount;
|
tile.AdjacentTiles[direction.ToIndex()].MonstermosInfo[direction.GetOpposite()] -= amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleDecompressionFloorRip(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile, float sum)
|
private void HandleDecompressionFloorRip(IMapGrid mapGrid, TileAtmosphere tile, float sum)
|
||||||
{
|
{
|
||||||
var chance = MathHelper.Clamp(sum / 500, 0.005f, 0.5f);
|
var chance = MathHelper.Clamp(sum / 500, 0.005f, 0.5f);
|
||||||
|
|
||||||
if (sum > 20 && _robustRandom.Prob(chance))
|
if (sum > 20 && _robustRandom.Prob(chance))
|
||||||
gridAtmosphere.PryTile(tile.GridIndices);
|
PryTile(mapGrid, tile.GridIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TileAtmosphereComparer : IComparer<TileAtmosphere>
|
private class TileAtmosphereComparer : IComparer<TileAtmosphere>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Content.Server.Atmos.Components;
|
using Content.Server.Atmos.Components;
|
||||||
using Content.Server.Atmos.Piping.Components;
|
using Content.Server.Atmos.Piping.Components;
|
||||||
@@ -20,6 +21,11 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private const int LagCheckIterations = 30;
|
private const int LagCheckIterations = 30;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check current execution time every n instances processed.
|
||||||
|
/// </summary>
|
||||||
|
private const int InvalidCoordinatesLagCheckIterations = 50;
|
||||||
|
|
||||||
private int _currentRunAtmosphereIndex = 0;
|
private int _currentRunAtmosphereIndex = 0;
|
||||||
private bool _simulationPaused = false;
|
private bool _simulationPaused = false;
|
||||||
|
|
||||||
@@ -30,10 +36,13 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
if(!atmosphere.ProcessingPaused)
|
if(!atmosphere.ProcessingPaused)
|
||||||
atmosphere.CurrentRunTiles = new Queue<TileAtmosphere>(atmosphere.ActiveTiles);
|
atmosphere.CurrentRunTiles = new Queue<TileAtmosphere>(atmosphere.ActiveTiles);
|
||||||
|
|
||||||
|
if (!TryGetMapGrid(atmosphere, out var mapGrid))
|
||||||
|
throw new Exception("Tried to process a grid atmosphere on an entity that isn't a grid!");
|
||||||
|
|
||||||
var number = 0;
|
var number = 0;
|
||||||
while (atmosphere.CurrentRunTiles.TryDequeue(out var tile))
|
while (atmosphere.CurrentRunTiles.TryDequeue(out var tile))
|
||||||
{
|
{
|
||||||
EqualizePressureInZone(atmosphere, tile, atmosphere.UpdateCounter);
|
EqualizePressureInZone(mapGrid, atmosphere, tile, atmosphere.UpdateCounter);
|
||||||
|
|
||||||
if (number++ < LagCheckIterations) continue;
|
if (number++ < LagCheckIterations) continue;
|
||||||
number = 0;
|
number = 0;
|
||||||
@@ -69,22 +78,22 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ProcessExcitedGroups(GridAtmosphereComponent atmosphere)
|
private bool ProcessExcitedGroups(GridAtmosphereComponent gridAtmosphere)
|
||||||
{
|
{
|
||||||
if(!atmosphere.ProcessingPaused)
|
if(!gridAtmosphere.ProcessingPaused)
|
||||||
atmosphere.CurrentRunExcitedGroups = new Queue<ExcitedGroup>(atmosphere.ExcitedGroups);
|
gridAtmosphere.CurrentRunExcitedGroups = new Queue<ExcitedGroup>(gridAtmosphere.ExcitedGroups);
|
||||||
|
|
||||||
var number = 0;
|
var number = 0;
|
||||||
while (atmosphere.CurrentRunExcitedGroups.TryDequeue(out var excitedGroup))
|
while (gridAtmosphere.CurrentRunExcitedGroups.TryDequeue(out var excitedGroup))
|
||||||
{
|
{
|
||||||
excitedGroup.BreakdownCooldown++;
|
excitedGroup.BreakdownCooldown++;
|
||||||
excitedGroup.DismantleCooldown++;
|
excitedGroup.DismantleCooldown++;
|
||||||
|
|
||||||
if(excitedGroup.BreakdownCooldown > Atmospherics.ExcitedGroupBreakdownCycles)
|
if(excitedGroup.BreakdownCooldown > Atmospherics.ExcitedGroupBreakdownCycles)
|
||||||
excitedGroup.SelfBreakdown(this, ExcitedGroupsSpaceIsAllConsuming);
|
ExcitedGroupSelfBreakdown(gridAtmosphere, excitedGroup, ExcitedGroupsSpaceIsAllConsuming);
|
||||||
|
|
||||||
else if(excitedGroup.DismantleCooldown > Atmospherics.ExcitedGroupsDismantleCycles)
|
else if(excitedGroup.DismantleCooldown > Atmospherics.ExcitedGroupsDismantleCycles)
|
||||||
excitedGroup.Dismantle();
|
ExcitedGroupDismantle(gridAtmosphere, excitedGroup);
|
||||||
|
|
||||||
if (number++ < LagCheckIterations) continue;
|
if (number++ < LagCheckIterations) continue;
|
||||||
number = 0;
|
number = 0;
|
||||||
@@ -195,7 +204,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
atmosphere.CurrentRunAtmosDevices = new Queue<AtmosDeviceComponent>(atmosphere.AtmosDevices);
|
atmosphere.CurrentRunAtmosDevices = new Queue<AtmosDeviceComponent>(atmosphere.AtmosDevices);
|
||||||
|
|
||||||
var time = _gameTiming.CurTime;
|
var time = _gameTiming.CurTime;
|
||||||
var updateEvent = new AtmosDeviceUpdateEvent(atmosphere);
|
var updateEvent = new AtmosDeviceUpdateEvent();
|
||||||
var number = 0;
|
var number = 0;
|
||||||
while (atmosphere.CurrentRunAtmosDevices.TryDequeue(out var device))
|
while (atmosphere.CurrentRunAtmosDevices.TryDequeue(out var device))
|
||||||
{
|
{
|
||||||
@@ -237,8 +246,14 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
|
|
||||||
atmosphere.Timer += frameTime;
|
atmosphere.Timer += frameTime;
|
||||||
|
|
||||||
if (atmosphere.InvalidatedCoords.Count != 0)
|
if ((atmosphere.InvalidatedCoords.Count != 0 || atmosphere.RevalidatePaused) && TryGetMapGrid(atmosphere, out var mapGrid))
|
||||||
atmosphere.Revalidate();
|
if (!GridRevalidate(mapGrid, atmosphere))
|
||||||
|
{
|
||||||
|
atmosphere.RevalidatePaused = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
atmosphere.RevalidatePaused = false;
|
||||||
|
|
||||||
if (atmosphere.Timer < AtmosTime)
|
if (atmosphere.Timer < AtmosTime)
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -48,21 +48,24 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
|
|
||||||
public bool ConsiderSuperconductivity(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile)
|
public bool ConsiderSuperconductivity(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile)
|
||||||
{
|
{
|
||||||
if (tile.ThermalConductivity == 0f)
|
if (tile.ThermalConductivity == 0f || !Superconduction)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
gridAtmosphere.AddSuperconductivityTile(tile);
|
gridAtmosphere.SuperconductivityTiles.Add(tile);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ConsiderSuperconductivity(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile, bool starting)
|
public bool ConsiderSuperconductivity(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile, bool starting)
|
||||||
{
|
{
|
||||||
|
if (!Superconduction)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (tile.Air == null || tile.Air.Temperature < (starting
|
if (tile.Air == null || tile.Air.Temperature < (starting
|
||||||
? Atmospherics.MinimumTemperatureStartSuperConduction
|
? Atmospherics.MinimumTemperatureStartSuperConduction
|
||||||
: Atmospherics.MinimumTemperatureForSuperconduction))
|
: Atmospherics.MinimumTemperatureForSuperconduction))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return !(gridAtmosphere.AtmosphereSystem.GetHeatCapacity(tile.Air) < Atmospherics.MCellWithRatio)
|
return !(GetHeatCapacity(tile.Air) < Atmospherics.MCellWithRatio)
|
||||||
&& ConsiderSuperconductivity(gridAtmosphere, tile);
|
&& ConsiderSuperconductivity(gridAtmosphere, tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +85,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
// Make sure it's still hot enough to continue conducting.
|
// Make sure it's still hot enough to continue conducting.
|
||||||
if (temperature < Atmospherics.MinimumTemperatureForSuperconduction)
|
if (temperature < Atmospherics.MinimumTemperatureForSuperconduction)
|
||||||
{
|
{
|
||||||
gridAtmosphere.RemoveSuperconductivityTile(tile);
|
gridAtmosphere.SuperconductivityTiles.Remove(tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,7 +115,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
TemperatureShareOpenToSolid(tile, other);
|
TemperatureShareOpenToSolid(tile, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
gridAtmosphere.AddActiveTile(tile);
|
AddActiveTile(gridAtmosphere, tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TemperatureShareOpenToSolid(TileAtmosphere tile, TileAtmosphere other)
|
private void TemperatureShareOpenToSolid(TileAtmosphere tile, TileAtmosphere other)
|
||||||
|
|||||||
@@ -3,19 +3,15 @@ using Content.Server.NodeContainer.EntitySystems;
|
|||||||
using Content.Shared.Atmos.EntitySystems;
|
using Content.Shared.Atmos.EntitySystems;
|
||||||
using Content.Shared.Maps;
|
using Content.Shared.Maps;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.Configuration;
|
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
|
|
||||||
namespace Content.Server.Atmos.EntitySystems
|
namespace Content.Server.Atmos.EntitySystems
|
||||||
{
|
{
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public partial class AtmosphereSystem : SharedAtmosphereSystem
|
public partial class AtmosphereSystem : SharedAtmosphereSystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IPrototypeManager _protoMan = default!;
|
|
||||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
|
||||||
|
|
||||||
private const float ExposedUpdateDelay = 1f;
|
private const float ExposedUpdateDelay = 1f;
|
||||||
private float _exposedTimer = 0f;
|
private float _exposedTimer = 0f;
|
||||||
@@ -28,6 +24,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
|
|
||||||
InitializeGases();
|
InitializeGases();
|
||||||
InitializeCVars();
|
InitializeCVars();
|
||||||
|
InitializeGrid();
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
@@ -57,7 +54,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetGridAtmosphere(eventArgs.NewTile.GridIndex)?.Invalidate(eventArgs.NewTile.GridIndices);
|
InvalidateTile(eventArgs.NewTile.GridIndex, eventArgs.NewTile.GridIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMapCreated(object? sender, MapEventArgs e)
|
private void OnMapCreated(object? sender, MapEventArgs e)
|
||||||
@@ -84,8 +81,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
foreach (var exposed in EntityManager.ComponentManager.EntityQuery<AtmosExposedComponent>())
|
foreach (var exposed in EntityManager.ComponentManager.EntityQuery<AtmosExposedComponent>())
|
||||||
{
|
{
|
||||||
// TODO ATMOS: Kill this with fire.
|
// TODO ATMOS: Kill this with fire.
|
||||||
var atmos = GetGridAtmosphere(exposed.Owner.Transform.Coordinates);
|
var tile = GetTileAtmosphereOrCreateSpace(exposed.Owner.Transform.Coordinates);
|
||||||
var tile = atmos.GetTile(exposed.Owner.Transform.Coordinates);
|
|
||||||
if (tile == null) continue;
|
if (tile == null) continue;
|
||||||
exposed.Update(tile, _exposedTimer, this);
|
exposed.Update(tile, _exposedTimer, this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,14 +144,14 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks whether the overlay-relevant data for a gas tile has been updated.
|
/// Checks whether the overlay-relevant data for a gas tile has been updated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="gam"></param>
|
/// <param name="grid"></param>
|
||||||
/// <param name="oldTile"></param>
|
/// <param name="oldTile"></param>
|
||||||
/// <param name="indices"></param>
|
/// <param name="indices"></param>
|
||||||
/// <param name="overlayData"></param>
|
/// <param name="overlayData"></param>
|
||||||
/// <returns>true if updated</returns>
|
/// <returns>true if updated</returns>
|
||||||
private bool TryRefreshTile(GridAtmosphereComponent gam, GasOverlayData oldTile, Vector2i indices, out GasOverlayData overlayData)
|
private bool TryRefreshTile(GridId grid, GasOverlayData oldTile, Vector2i indices, out GasOverlayData overlayData)
|
||||||
{
|
{
|
||||||
var tile = gam.GetTile(indices);
|
var tile = _atmosphereSystem.GetTileAtmosphereOrCreateSpace(grid, indices);
|
||||||
|
|
||||||
if (tile == null)
|
if (tile == null)
|
||||||
{
|
{
|
||||||
@@ -287,7 +287,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
{
|
{
|
||||||
var chunk = GetOrCreateChunk(gridId, invalid);
|
var chunk = GetOrCreateChunk(gridId, invalid);
|
||||||
|
|
||||||
if (!TryRefreshTile(gam, chunk.GetData(invalid), invalid, out var data)) continue;
|
if (!TryRefreshTile(grid.Index, chunk.GetData(invalid), invalid, out var data)) continue;
|
||||||
|
|
||||||
if (!updatedTiles.TryGetValue(chunk, out var tiles))
|
if (!updatedTiles.TryGetValue(chunk, out var tiles))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,146 +1,16 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Content.Server.Atmos.Components;
|
|
||||||
using Content.Server.Atmos.EntitySystems;
|
|
||||||
using Content.Shared.Atmos;
|
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Server.Atmos
|
namespace Content.Server.Atmos
|
||||||
{
|
{
|
||||||
public class ExcitedGroup : IDisposable
|
public class ExcitedGroup
|
||||||
{
|
{
|
||||||
[ViewVariables]
|
[ViewVariables] public bool Disposed = false;
|
||||||
private bool _disposed = false;
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables] public readonly List<TileAtmosphere> Tiles = new(100);
|
||||||
private readonly HashSet<TileAtmosphere> _tiles = new();
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables] public int DismantleCooldown { get; set; } = 0;
|
||||||
private GridAtmosphereComponent _gridAtmosphereComponent = default!;
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables] public int BreakdownCooldown { get; set; } = 0;
|
||||||
public int DismantleCooldown { get; set; }
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public int BreakdownCooldown { get; set; }
|
|
||||||
|
|
||||||
public void AddTile(TileAtmosphere tile)
|
|
||||||
{
|
|
||||||
_tiles.Add(tile);
|
|
||||||
tile.ExcitedGroup = this;
|
|
||||||
ResetCooldowns();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool RemoveTile(TileAtmosphere tile)
|
|
||||||
{
|
|
||||||
tile.ExcitedGroup = null;
|
|
||||||
return _tiles.Remove(tile);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void MergeGroups(ExcitedGroup other)
|
|
||||||
{
|
|
||||||
var ourSize = _tiles.Count;
|
|
||||||
var otherSize = other._tiles.Count;
|
|
||||||
|
|
||||||
if (ourSize > otherSize)
|
|
||||||
{
|
|
||||||
foreach (var tile in other._tiles)
|
|
||||||
{
|
|
||||||
tile.ExcitedGroup = this;
|
|
||||||
_tiles.Add(tile);
|
|
||||||
}
|
|
||||||
other._tiles.Clear();
|
|
||||||
other.Dispose();
|
|
||||||
ResetCooldowns();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (var tile in _tiles)
|
|
||||||
{
|
|
||||||
tile.ExcitedGroup = other;
|
|
||||||
other._tiles.Add(tile);
|
|
||||||
}
|
|
||||||
_tiles.Clear();
|
|
||||||
Dispose();
|
|
||||||
other.ResetCooldowns();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~ExcitedGroup()
|
|
||||||
{
|
|
||||||
Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialize(GridAtmosphereComponent gridAtmosphereComponent)
|
|
||||||
{
|
|
||||||
_gridAtmosphereComponent = gridAtmosphereComponent;
|
|
||||||
_gridAtmosphereComponent.AddExcitedGroup(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ResetCooldowns()
|
|
||||||
{
|
|
||||||
BreakdownCooldown = 0;
|
|
||||||
DismantleCooldown = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SelfBreakdown(AtmosphereSystem atmosphereSystem, bool spaceIsAllConsuming = false)
|
|
||||||
{
|
|
||||||
var combined = new GasMixture(Atmospherics.CellVolume);
|
|
||||||
|
|
||||||
var tileSize = _tiles.Count;
|
|
||||||
|
|
||||||
if (_disposed) return;
|
|
||||||
|
|
||||||
if (tileSize == 0)
|
|
||||||
{
|
|
||||||
Dispose();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var tile in _tiles)
|
|
||||||
{
|
|
||||||
if (tile?.Air == null) continue;
|
|
||||||
atmosphereSystem.Merge(combined, tile.Air);
|
|
||||||
if (!spaceIsAllConsuming || !tile.Air.Immutable) continue;
|
|
||||||
combined.Clear();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
combined.Multiply(1 / (float)tileSize);
|
|
||||||
|
|
||||||
foreach (var tile in _tiles)
|
|
||||||
{
|
|
||||||
if (tile?.Air == null) continue;
|
|
||||||
tile.Air.CopyFromMutable(combined);
|
|
||||||
tile.UpdateVisuals();
|
|
||||||
}
|
|
||||||
|
|
||||||
BreakdownCooldown = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dismantle(bool unexcite = true)
|
|
||||||
{
|
|
||||||
foreach (var tile in _tiles)
|
|
||||||
{
|
|
||||||
if (tile == null) continue;
|
|
||||||
tile.ExcitedGroup = null;
|
|
||||||
if (!unexcite) continue;
|
|
||||||
tile.Excited = false;
|
|
||||||
_gridAtmosphereComponent.RemoveActiveTile(tile);
|
|
||||||
}
|
|
||||||
|
|
||||||
_tiles.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if (_disposed) return;
|
|
||||||
_disposed = true;
|
|
||||||
_gridAtmosphereComponent.RemoveExcitedGroup(this);
|
|
||||||
|
|
||||||
Dismantle(false);
|
|
||||||
|
|
||||||
_gridAtmosphereComponent = null!;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using Content.Server.Atmos.Components;
|
using Content.Server.Atmos.Components;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Serialization.Manager.Attributes;
|
using Robust.Shared.Serialization.Manager.Attributes;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
@@ -21,40 +22,18 @@ namespace Content.Server.Atmos.Piping.Components
|
|||||||
[DataField("requireAnchored")]
|
[DataField("requireAnchored")]
|
||||||
public bool RequireAnchored { get; private set; } = true;
|
public bool RequireAnchored { get; private set; } = true;
|
||||||
|
|
||||||
public IGridAtmosphereComponent? Atmosphere { get; set; }
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public TimeSpan LastProcess { get; set; } = TimeSpan.Zero;
|
public TimeSpan LastProcess { get; set; } = TimeSpan.Zero;
|
||||||
|
|
||||||
|
public GridId? JoinedGrid { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class BaseAtmosDeviceEvent : EntityEventArgs
|
public sealed class AtmosDeviceUpdateEvent : EntityEventArgs
|
||||||
{
|
{}
|
||||||
public IGridAtmosphereComponent Atmosphere { get; }
|
|
||||||
|
|
||||||
public BaseAtmosDeviceEvent(IGridAtmosphereComponent atmosphere)
|
public sealed class AtmosDeviceEnabledEvent : EntityEventArgs
|
||||||
{
|
{}
|
||||||
Atmosphere = atmosphere;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class AtmosDeviceUpdateEvent : BaseAtmosDeviceEvent
|
public sealed class AtmosDeviceDisabledEvent : EntityEventArgs
|
||||||
{
|
{}
|
||||||
public AtmosDeviceUpdateEvent(IGridAtmosphereComponent atmosphere) : base(atmosphere)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class AtmosDeviceEnabledEvent : BaseAtmosDeviceEvent
|
|
||||||
{
|
|
||||||
public AtmosDeviceEnabledEvent(IGridAtmosphereComponent atmosphere) : base(atmosphere)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class AtmosDeviceDisabledEvent : BaseAtmosDeviceEvent
|
|
||||||
{
|
|
||||||
public AtmosDeviceDisabledEvent(IGridAtmosphereComponent atmosphere) : base(atmosphere)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ namespace Content.Server.Atmos.Piping.EntitySystems
|
|||||||
|
|
||||||
SubscribeLocalEvent<AtmosDeviceComponent, ComponentInit>(OnDeviceInitialize);
|
SubscribeLocalEvent<AtmosDeviceComponent, ComponentInit>(OnDeviceInitialize);
|
||||||
SubscribeLocalEvent<AtmosDeviceComponent, ComponentShutdown>(OnDeviceShutdown);
|
SubscribeLocalEvent<AtmosDeviceComponent, ComponentShutdown>(OnDeviceShutdown);
|
||||||
SubscribeLocalEvent<AtmosDeviceComponent, PhysicsBodyTypeChangedEvent>(OnDeviceBodyTypeChanged);
|
|
||||||
SubscribeLocalEvent<AtmosDeviceComponent, EntParentChangedMessage>(OnDeviceParentChanged);
|
SubscribeLocalEvent<AtmosDeviceComponent, EntParentChangedMessage>(OnDeviceParentChanged);
|
||||||
|
SubscribeLocalEvent<AtmosDeviceComponent, AnchorStateChangedEvent>(OnDeviceAnchorChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CanJoinAtmosphere(AtmosDeviceComponent component)
|
private bool CanJoinAtmosphere(AtmosDeviceComponent component)
|
||||||
{
|
{
|
||||||
return !component.RequireAnchored || !component.Owner.TryGetComponent(out PhysicsComponent? physics) || physics.BodyType == BodyType.Static;
|
return !component.RequireAnchored || !component.Owner.Transform.Anchored;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void JoinAtmosphere(AtmosDeviceComponent component)
|
public void JoinAtmosphere(AtmosDeviceComponent component)
|
||||||
@@ -34,26 +34,22 @@ namespace Content.Server.Atmos.Piping.EntitySystems
|
|||||||
if (!CanJoinAtmosphere(component))
|
if (!CanJoinAtmosphere(component))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// We try to get a valid, simulated atmosphere.
|
// We try to add the device to a valid atmosphere.
|
||||||
if (!Get<AtmosphereSystem>().TryGetSimulatedGridAtmosphere(component.Owner.Transform.MapPosition, out var atmosphere))
|
if (!Get<AtmosphereSystem>().AddAtmosDevice(component))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
component.LastProcess = _gameTiming.CurTime;
|
component.LastProcess = _gameTiming.CurTime;
|
||||||
component.Atmosphere = atmosphere;
|
|
||||||
atmosphere.AddAtmosDevice(component);
|
|
||||||
|
|
||||||
RaiseLocalEvent(component.Owner.Uid, new AtmosDeviceEnabledEvent(atmosphere), false);
|
RaiseLocalEvent(component.Owner.Uid, new AtmosDeviceEnabledEvent(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LeaveAtmosphere(AtmosDeviceComponent component)
|
public void LeaveAtmosphere(AtmosDeviceComponent component)
|
||||||
{
|
{
|
||||||
var atmosphere = component.Atmosphere;
|
if (!Get<AtmosphereSystem>().RemoveAtmosDevice(component))
|
||||||
atmosphere?.RemoveAtmosDevice(component);
|
return;
|
||||||
component.Atmosphere = null;
|
|
||||||
component.LastProcess = TimeSpan.Zero;
|
|
||||||
|
|
||||||
if(atmosphere != null)
|
component.LastProcess = TimeSpan.Zero;
|
||||||
RaiseLocalEvent(component.Owner.Uid, new AtmosDeviceDisabledEvent(atmosphere), false);
|
RaiseLocalEvent(component.Owner.Uid, new AtmosDeviceDisabledEvent(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RejoinAtmosphere(AtmosDeviceComponent component)
|
public void RejoinAtmosphere(AtmosDeviceComponent component)
|
||||||
@@ -72,13 +68,13 @@ namespace Content.Server.Atmos.Piping.EntitySystems
|
|||||||
LeaveAtmosphere(component);
|
LeaveAtmosphere(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDeviceBodyTypeChanged(EntityUid uid, AtmosDeviceComponent component, PhysicsBodyTypeChangedEvent args)
|
private void OnDeviceAnchorChanged(EntityUid uid, AtmosDeviceComponent component, AnchorStateChangedEvent args)
|
||||||
{
|
{
|
||||||
// Do nothing if the component doesn't require being anchored to function.
|
// Do nothing if the component doesn't require being anchored to function.
|
||||||
if (!component.RequireAnchored)
|
if (!component.RequireAnchored)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (args.New == BodyType.Static)
|
if(component.Owner.Transform.Anchored)
|
||||||
JoinAtmosphere(component);
|
JoinAtmosphere(component);
|
||||||
else
|
else
|
||||||
LeaveAtmosphere(component);
|
LeaveAtmosphere(component);
|
||||||
|
|||||||
@@ -21,9 +21,8 @@ namespace Content.Server.Atmos.Reactions
|
|||||||
var location = holder as TileAtmosphere;
|
var location = holder as TileAtmosphere;
|
||||||
mixture.ReactionResults[GasReaction.Fire] = 0;
|
mixture.ReactionResults[GasReaction.Fire] = 0;
|
||||||
|
|
||||||
// More plasma released at higher temperatures
|
// More plasma released at higher temperatures.
|
||||||
var temperatureScale = 0f;
|
var temperatureScale = 0f;
|
||||||
var superSaturation = false;
|
|
||||||
|
|
||||||
if (temperature > Atmospherics.PlasmaUpperTemperature)
|
if (temperature > Atmospherics.PlasmaUpperTemperature)
|
||||||
temperatureScale = 1f;
|
temperatureScale = 1f;
|
||||||
@@ -31,33 +30,31 @@ namespace Content.Server.Atmos.Reactions
|
|||||||
temperatureScale = (temperature - Atmospherics.PlasmaMinimumBurnTemperature) /
|
temperatureScale = (temperature - Atmospherics.PlasmaMinimumBurnTemperature) /
|
||||||
(Atmospherics.PlasmaUpperTemperature - Atmospherics.PlasmaMinimumBurnTemperature);
|
(Atmospherics.PlasmaUpperTemperature - Atmospherics.PlasmaMinimumBurnTemperature);
|
||||||
|
|
||||||
if (temperatureScale > 0f)
|
if (temperatureScale > 0)
|
||||||
{
|
{
|
||||||
var plasmaBurnRate = 0f;
|
|
||||||
var oxygenBurnRate = Atmospherics.OxygenBurnRateBase - temperatureScale;
|
var oxygenBurnRate = Atmospherics.OxygenBurnRateBase - temperatureScale;
|
||||||
|
var plasmaBurnRate = 0f;
|
||||||
|
|
||||||
if (mixture.GetMoles(Gas.Oxygen) / mixture.GetMoles(Gas.Plasma) >
|
var initialOxygenMoles = mixture.GetMoles(Gas.Oxygen);
|
||||||
Atmospherics.SuperSaturationThreshold)
|
var initialPlasmaMoles = mixture.GetMoles(Gas.Plasma);
|
||||||
superSaturation = true;
|
|
||||||
|
|
||||||
if (mixture.GetMoles(Gas.Oxygen) >
|
// Supersaturation makes tritium.
|
||||||
mixture.GetMoles(Gas.Plasma) * Atmospherics.PlasmaOxygenFullburn)
|
var supersaturation = initialOxygenMoles / initialPlasmaMoles > Atmospherics.SuperSaturationThreshold;
|
||||||
plasmaBurnRate = (mixture.GetMoles(Gas.Plasma) * temperatureScale) /
|
|
||||||
Atmospherics.PlasmaBurnRateDelta;
|
if (initialOxygenMoles > initialPlasmaMoles * Atmospherics.PlasmaOxygenFullburn)
|
||||||
|
plasmaBurnRate = initialPlasmaMoles * temperatureScale / Atmospherics.PlasmaBurnRateDelta;
|
||||||
else
|
else
|
||||||
plasmaBurnRate = (temperatureScale * (mixture.GetMoles(Gas.Oxygen) / Atmospherics.PlasmaOxygenFullburn)) / Atmospherics.PlasmaBurnRateDelta;
|
plasmaBurnRate = temperatureScale * (initialOxygenMoles / Atmospherics.PlasmaOxygenFullburn) / Atmospherics.PlasmaBurnRateDelta;
|
||||||
|
|
||||||
if (plasmaBurnRate > Atmospherics.MinimumHeatCapacity)
|
if (plasmaBurnRate > Atmospherics.MinimumHeatCapacity)
|
||||||
{
|
{
|
||||||
plasmaBurnRate = MathF.Min(MathF.Min(plasmaBurnRate, mixture.GetMoles(Gas.Plasma)), mixture.GetMoles(Gas.Oxygen)/oxygenBurnRate);
|
plasmaBurnRate = MathF.Min(plasmaBurnRate, MathF.Min(initialPlasmaMoles, initialOxygenMoles / oxygenBurnRate));
|
||||||
mixture.SetMoles(Gas.Plasma, mixture.GetMoles(Gas.Plasma) - plasmaBurnRate);
|
mixture.SetMoles(Gas.Plasma, initialPlasmaMoles - plasmaBurnRate);
|
||||||
mixture.SetMoles(Gas.Oxygen, mixture.GetMoles(Gas.Oxygen) - (plasmaBurnRate * oxygenBurnRate));
|
mixture.SetMoles(Gas.Oxygen, initialOxygenMoles - plasmaBurnRate * oxygenBurnRate);
|
||||||
|
mixture.AdjustMoles(supersaturation ? Gas.Tritium : Gas.CarbonDioxide, plasmaBurnRate);
|
||||||
|
|
||||||
mixture.AdjustMoles(superSaturation ? Gas.Tritium : Gas.CarbonDioxide, plasmaBurnRate);
|
energyReleased += Atmospherics.FirePlasmaEnergyReleased * plasmaBurnRate;
|
||||||
|
mixture.ReactionResults[GasReaction.Fire] += plasmaBurnRate * (1 + oxygenBurnRate);
|
||||||
energyReleased += Atmospherics.FirePlasmaEnergyReleased * (plasmaBurnRate);
|
|
||||||
|
|
||||||
mixture.ReactionResults[GasReaction.Fire] += (plasmaBurnRate) * (1 + oxygenBurnRate);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,25 +62,25 @@ namespace Content.Server.Atmos.Reactions
|
|||||||
{
|
{
|
||||||
var newHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture);
|
var newHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture);
|
||||||
if (newHeatCapacity > Atmospherics.MinimumHeatCapacity)
|
if (newHeatCapacity > Atmospherics.MinimumHeatCapacity)
|
||||||
mixture.Temperature = ((temperature * oldHeatCapacity + energyReleased) / newHeatCapacity);
|
mixture.Temperature = (temperature * oldHeatCapacity + energyReleased) / newHeatCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (location != null)
|
if (location != null)
|
||||||
{
|
{
|
||||||
temperature = mixture.Temperature;
|
var mixTemperature = mixture.Temperature;
|
||||||
if (temperature > Atmospherics.FireMinimumTemperatureToExist)
|
if (mixTemperature > Atmospherics.FireMinimumTemperatureToExist)
|
||||||
{
|
{
|
||||||
atmosphereSystem.HotspotExpose(location.GridIndex, location.GridIndices, temperature, mixture.Volume);
|
atmosphereSystem.HotspotExpose(location.GridIndex, location.GridIndices, mixTemperature, mixture.Volume);
|
||||||
|
|
||||||
foreach (var entity in location.GridIndices.GetEntitiesInTileFast(location.GridIndex))
|
foreach (var entity in location.GridIndices.GetEntitiesInTileFast(location.GridIndex))
|
||||||
{
|
{
|
||||||
foreach (var temperatureExpose in entity.GetAllComponents<ITemperatureExpose>())
|
foreach (var temperatureExpose in entity.GetAllComponents<ITemperatureExpose>())
|
||||||
{
|
{
|
||||||
temperatureExpose.TemperatureExpose(mixture, temperature, mixture.Volume);
|
temperatureExpose.TemperatureExpose(mixture, mixTemperature, mixture.Volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO ATMOS: location.TemperatureExpose(mixture, temperature, mixture.Volume);
|
// TODO ATMOS: location.TemperatureExpose(mixture, mixTemperature, mixture.Volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
#nullable disable warnings
|
#nullable disable warnings
|
||||||
#nullable enable annotations
|
#nullable enable annotations
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using Content.Server.Atmos.Components;
|
|
||||||
using Content.Server.Interfaces;
|
using Content.Server.Interfaces;
|
||||||
using Content.Shared.Atmos;
|
using Content.Shared.Atmos;
|
||||||
using Content.Shared.Maps;
|
using Content.Shared.Maps;
|
||||||
@@ -11,6 +9,9 @@ using Robust.Shared.ViewVariables;
|
|||||||
|
|
||||||
namespace Content.Server.Atmos
|
namespace Content.Server.Atmos
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Internal Atmos class that stores data about the atmosphere in a grid.
|
||||||
|
/// </summary>
|
||||||
public class TileAtmosphere : IGasMixtureHolder
|
public class TileAtmosphere : IGasMixtureHolder
|
||||||
{
|
{
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
@@ -40,9 +41,6 @@ namespace Content.Server.Atmos
|
|||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public bool Excited { get; set; }
|
public bool Excited { get; set; }
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private readonly GridAtmosphereComponent _gridAtmosphereComponent;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adjacent tiles in the same order as <see cref="AtmosDirection"/>. (NSEW)
|
/// Adjacent tiles in the same order as <see cref="AtmosDirection"/>. (NSEW)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -86,9 +84,8 @@ namespace Content.Server.Atmos
|
|||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public AtmosDirection BlockedAirflow { get; set; } = AtmosDirection.Invalid;
|
public AtmosDirection BlockedAirflow { get; set; } = AtmosDirection.Invalid;
|
||||||
|
|
||||||
public TileAtmosphere(GridAtmosphereComponent atmosphereComponent, GridId gridIndex, Vector2i gridIndices, GasMixture? mixture = null, bool immutable = false)
|
public TileAtmosphere(GridId gridIndex, Vector2i gridIndices, GasMixture? mixture = null, bool immutable = false)
|
||||||
{
|
{
|
||||||
_gridAtmosphereComponent = atmosphereComponent;
|
|
||||||
GridIndex = gridIndex;
|
GridIndex = gridIndex;
|
||||||
GridIndices = gridIndices;
|
GridIndices = gridIndices;
|
||||||
Air = mixture;
|
Air = mixture;
|
||||||
@@ -96,47 +93,5 @@ namespace Content.Server.Atmos
|
|||||||
if(immutable)
|
if(immutable)
|
||||||
Air?.MarkImmutable();
|
Air?.MarkImmutable();
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void UpdateVisuals()
|
|
||||||
{
|
|
||||||
if (Air == null) return;
|
|
||||||
|
|
||||||
_gridAtmosphereComponent.GasTileOverlaySystem.Invalidate(GridIndex, GridIndices);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateAdjacent()
|
|
||||||
{
|
|
||||||
for (var i = 0; i < Atmospherics.Directions; i++)
|
|
||||||
{
|
|
||||||
var direction = (AtmosDirection) (1 << i);
|
|
||||||
|
|
||||||
var otherIndices = GridIndices.Offset(direction.ToDirection());
|
|
||||||
|
|
||||||
var isSpace = _gridAtmosphereComponent.IsSpace(GridIndices);
|
|
||||||
var adjacent = _gridAtmosphereComponent.GetTile(otherIndices, !isSpace);
|
|
||||||
AdjacentTiles[direction.ToIndex()] = adjacent;
|
|
||||||
adjacent?.UpdateAdjacent(direction.GetOpposite());
|
|
||||||
|
|
||||||
if (adjacent != null && !BlockedAirflow.IsFlagSet(direction) && !_gridAtmosphereComponent.IsAirBlocked(adjacent.GridIndices, direction.GetOpposite()))
|
|
||||||
{
|
|
||||||
AdjacentBits |= direction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateAdjacent(AtmosDirection direction)
|
|
||||||
{
|
|
||||||
AdjacentTiles[direction.ToIndex()] = _gridAtmosphereComponent.GetTile(GridIndices.Offset(direction.ToDirection()));
|
|
||||||
|
|
||||||
if (!BlockedAirflow.IsFlagSet(direction) && !_gridAtmosphereComponent.IsAirBlocked(GridIndices.Offset(direction.ToDirection()), direction.GetOpposite()))
|
|
||||||
{
|
|
||||||
AdjacentBits |= direction;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AdjacentBits &= ~direction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ using Content.Server.Interfaces;
|
|||||||
using Content.Server.NodeContainer.Nodes;
|
using Content.Server.NodeContainer.Nodes;
|
||||||
using Content.Shared.Atmos;
|
using Content.Shared.Atmos;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Server.NodeContainer.NodeGroups
|
namespace Content.Server.NodeContainer.NodeGroups
|
||||||
@@ -30,16 +32,14 @@ namespace Content.Server.NodeContainer.NodeGroups
|
|||||||
|
|
||||||
[ViewVariables] private AtmosphereSystem? _atmosphereSystem;
|
[ViewVariables] private AtmosphereSystem? _atmosphereSystem;
|
||||||
|
|
||||||
[ViewVariables]
|
public GridId Grid => GridId;
|
||||||
private IGridAtmosphereComponent? GridAtmos =>
|
|
||||||
_atmosphereSystem?.GetGridAtmosphere(GridId);
|
|
||||||
|
|
||||||
public override void Initialize(Node sourceNode)
|
public override void Initialize(Node sourceNode)
|
||||||
{
|
{
|
||||||
base.Initialize(sourceNode);
|
base.Initialize(sourceNode);
|
||||||
|
|
||||||
_atmosphereSystem = EntitySystem.Get<AtmosphereSystem>();
|
_atmosphereSystem = EntitySystem.Get<AtmosphereSystem>();
|
||||||
GridAtmos?.AddPipeNet(this);
|
_atmosphereSystem.AddPipeNet(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
@@ -94,7 +94,8 @@ namespace Content.Server.NodeContainer.NodeGroups
|
|||||||
|
|
||||||
private void RemoveFromGridAtmos()
|
private void RemoveFromGridAtmos()
|
||||||
{
|
{
|
||||||
GridAtmos?.RemovePipeNet(this);
|
DebugTools.AssertNotNull(_atmosphereSystem);
|
||||||
|
_atmosphereSystem?.RemovePipeNet(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user