Merge remote-tracking branch 'upstream/master' into upstream
# Conflicts: # Content.Server/Body/Components/BloodstreamComponent.cs # Content.Server/Chemistry/EntitySystems/ChemistrySystem.cs # Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml # Resources/Prototypes/Entities/Structures/Machines/lathe.yml # Resources/Textures/Clothing/OuterClothing/Coats/labcoat.rsi/open-inhand-left.png # Resources/Textures/Clothing/OuterClothing/Coats/labcoat.rsi/open-inhand-right.png # Resources/Textures/Clothing/OuterClothing/Coats/labcoat_chem.rsi/open-inhand-left.png # Resources/Textures/Clothing/OuterClothing/Coats/labcoat_chem.rsi/open-inhand-right.png # Resources/Textures/Clothing/OuterClothing/Coats/labcoat_gene.rsi/open-inhand-left.png # Resources/Textures/Clothing/OuterClothing/Coats/labcoat_gene.rsi/open-inhand-right.png # Resources/Textures/Clothing/OuterClothing/Coats/labcoat_robo.rsi/open-inhand-left.png # Resources/Textures/Clothing/OuterClothing/Coats/labcoat_robo.rsi/open-inhand-right.png # Resources/Textures/Clothing/OuterClothing/Coats/labcoat_viro.rsi/open-inhand-left.png # Resources/Textures/Clothing/OuterClothing/Coats/labcoat_viro.rsi/open-inhand-right.png # Resources/Textures/Clothing/OuterClothing/Coats/rndcoat.rsi/open-inhand-left.png # Resources/Textures/Clothing/OuterClothing/Coats/rndcoat.rsi/open-inhand-right.png # Resources/Textures/Clothing/OuterClothing/Hardsuits/evaprisoner.rsi/open-inhand-left.png # Resources/Textures/Clothing/OuterClothing/Hardsuits/evaprisoner.rsi/open-inhand-right.png
This commit is contained in:
@@ -13,6 +13,7 @@ public sealed class AirFilterSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly AtmosphereSystem _atmosphere = default!;
|
||||
[Dependency] private readonly IMapManager _map = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -31,7 +32,7 @@ public sealed class AirFilterSystem : EntitySystem
|
||||
if (air.Pressure >= intake.Pressure)
|
||||
return;
|
||||
|
||||
var environment = _atmosphere.GetContainingMixture(uid, true, true);
|
||||
var environment = _atmosphere.GetContainingMixture(uid, args.Grid, args.Map, true, true);
|
||||
// nothing to intake from
|
||||
if (environment == null)
|
||||
return;
|
||||
@@ -63,12 +64,11 @@ public sealed class AirFilterSystem : EntitySystem
|
||||
var oxygen = air.GetMoles(filter.Oxygen) / air.TotalMoles;
|
||||
var gases = oxygen >= filter.TargetOxygen ? filter.Gases : filter.OverflowGases;
|
||||
|
||||
var coordinates = Transform(uid).MapPosition;
|
||||
GasMixture? destination = null;
|
||||
if (_map.TryFindGridAt(coordinates, out _, out var grid))
|
||||
if (args.Grid is {} grid)
|
||||
{
|
||||
var tile = grid.GetTileRef(coordinates);
|
||||
destination = _atmosphere.GetTileMixture(tile.GridUid, null, tile.GridIndices, true);
|
||||
var position = _transform.GetGridTilePositionOrDefault(uid);
|
||||
destination = _atmosphere.GetTileMixture(grid, args.Map, position, true);
|
||||
}
|
||||
|
||||
if (destination != null)
|
||||
|
||||
@@ -24,6 +24,8 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
/// <summary>
|
||||
/// Event that tries to query the mixture a certain entity is exposed to.
|
||||
/// This is mainly intended for use with entities inside of containers.
|
||||
/// This event is not raised for entities that are directly parented to the grid.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public struct AtmosExposedGetAirEvent
|
||||
@@ -31,7 +33,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
/// <summary>
|
||||
/// The entity we want to query this for.
|
||||
/// </summary>
|
||||
public readonly EntityUid Entity;
|
||||
public readonly Entity<TransformComponent> Entity;
|
||||
|
||||
/// <summary>
|
||||
/// The mixture that the entity is exposed to. Output parameter.
|
||||
@@ -39,9 +41,9 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
public GasMixture? Gas = null;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to invalidate the mixture, if possible.
|
||||
/// Whether to excite the mixture, if possible.
|
||||
/// </summary>
|
||||
public bool Invalidate = false;
|
||||
public readonly bool Excite = false;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this event has been handled or not.
|
||||
@@ -49,10 +51,10 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
/// </summary>
|
||||
public bool Handled = false;
|
||||
|
||||
public AtmosExposedGetAirEvent(EntityUid entity, bool invalidate = false)
|
||||
public AtmosExposedGetAirEvent(Entity<TransformComponent> entity, bool excite = false)
|
||||
{
|
||||
Entity = entity;
|
||||
Invalidate = invalidate;
|
||||
Excite = excite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using Content.Server.Atmos.Piping.Components;
|
||||
using Content.Server.Atmos.Reactions;
|
||||
using Content.Server.NodeContainer.NodeGroups;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Components;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -11,41 +12,39 @@ namespace Content.Server.Atmos.EntitySystems;
|
||||
|
||||
public partial class AtmosphereSystem
|
||||
{
|
||||
public GasMixture? GetContainingMixture(EntityUid uid, bool ignoreExposed = false, bool excite = false, TransformComponent? transform = null)
|
||||
public GasMixture? GetContainingMixture(Entity<TransformComponent?> ent, bool ignoreExposed = false, bool excite = false)
|
||||
{
|
||||
if (!ignoreExposed)
|
||||
if (!Resolve(ent, ref ent.Comp))
|
||||
return null;
|
||||
|
||||
return GetContainingMixture(ent, ent.Comp.GridUid, ent.Comp.MapUid, ignoreExposed, excite);
|
||||
}
|
||||
|
||||
public GasMixture? GetContainingMixture(
|
||||
Entity<TransformComponent?> ent,
|
||||
Entity<GridAtmosphereComponent?, GasTileOverlayComponent?>? grid,
|
||||
Entity<MapAtmosphereComponent?>? map,
|
||||
bool ignoreExposed = false,
|
||||
bool excite = false)
|
||||
{
|
||||
if (!Resolve(ent, ref ent.Comp))
|
||||
return null;
|
||||
|
||||
if (!ignoreExposed && !ent.Comp.Anchored)
|
||||
{
|
||||
// Used for things like disposals/cryo to change which air people are exposed to.
|
||||
var ev = new AtmosExposedGetAirEvent(uid, excite);
|
||||
|
||||
// Give the entity itself a chance to handle this.
|
||||
RaiseLocalEvent(uid, ref ev, false);
|
||||
|
||||
var ev = new AtmosExposedGetAirEvent((ent, ent.Comp), excite);
|
||||
RaiseLocalEvent(ent, ref ev);
|
||||
if (ev.Handled)
|
||||
return ev.Gas;
|
||||
|
||||
// We need to get the parent now, so we need the transform... If the parent is invalid, we can't do much else.
|
||||
if(!Resolve(uid, ref transform) || !transform.ParentUid.IsValid() || transform.MapUid == null)
|
||||
return GetTileMixture(null, null, Vector2i.Zero, excite);
|
||||
|
||||
// Give the parent entity a chance to handle the event...
|
||||
RaiseLocalEvent(transform.ParentUid, ref ev, false);
|
||||
|
||||
if (ev.Handled)
|
||||
return ev.Gas;
|
||||
}
|
||||
// Oops, we did a little bit of code duplication...
|
||||
else if(!Resolve(uid, ref transform))
|
||||
{
|
||||
return GetTileMixture(null, null, Vector2i.Zero, excite);
|
||||
// TODO ATMOS: recursively iterate up through parents
|
||||
// This really needs recursive InContainer metadata flag for performance
|
||||
// And ideally some fast way to get the innermost airtight container.
|
||||
}
|
||||
|
||||
|
||||
var gridUid = transform.GridUid;
|
||||
var mapUid = transform.MapUid;
|
||||
var position = _transformSystem.GetGridOrMapTilePosition(uid, transform);
|
||||
|
||||
return GetTileMixture(gridUid, mapUid, position, excite);
|
||||
var position = _transformSystem.GetGridTilePositionOrDefault((ent, ent.Comp));
|
||||
return GetTileMixture(grid, map, position, excite);
|
||||
}
|
||||
|
||||
public bool HasAtmosphere(EntityUid gridUid) => _atmosQuery.HasComponent(gridUid);
|
||||
@@ -84,21 +83,28 @@ public partial class AtmosphereSystem
|
||||
entity.Comp.InvalidatedCoords.Add(tile);
|
||||
}
|
||||
|
||||
public GasMixture?[]? GetTileMixtures(Entity<GridAtmosphereComponent?>? grid, Entity<MapAtmosphereComponent?>? map, List<Vector2i> tiles, bool excite = false)
|
||||
public GasMixture?[]? GetTileMixtures(
|
||||
Entity<GridAtmosphereComponent?, GasTileOverlayComponent?>? grid,
|
||||
Entity<MapAtmosphereComponent?>? map,
|
||||
List<Vector2i> tiles,
|
||||
bool excite = false)
|
||||
{
|
||||
GasMixture?[]? mixtures = null;
|
||||
var handled = false;
|
||||
|
||||
// If we've been passed a grid, try to let it handle it.
|
||||
if (grid is {} gridEnt && Resolve(gridEnt, ref gridEnt.Comp))
|
||||
if (grid is {} gridEnt && Resolve(gridEnt, ref gridEnt.Comp1))
|
||||
{
|
||||
if (excite)
|
||||
Resolve(gridEnt, ref gridEnt.Comp2);
|
||||
|
||||
handled = true;
|
||||
mixtures = new GasMixture?[tiles.Count];
|
||||
|
||||
for (var i = 0; i < tiles.Count; i++)
|
||||
{
|
||||
var tile = tiles[i];
|
||||
if (!gridEnt.Comp.Tiles.TryGetValue(tile, out var atmosTile))
|
||||
if (!gridEnt.Comp1.Tiles.TryGetValue(tile, out var atmosTile))
|
||||
{
|
||||
// need to get map atmosphere
|
||||
handled = false;
|
||||
@@ -108,7 +114,10 @@ public partial class AtmosphereSystem
|
||||
mixtures[i] = atmosTile.Air;
|
||||
|
||||
if (excite)
|
||||
gridEnt.Comp.InvalidatedCoords.Add(tile);
|
||||
{
|
||||
AddActiveTile(gridEnt.Comp1, atmosTile);
|
||||
InvalidateVisuals((gridEnt.Owner, gridEnt.Comp2), tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,15 +155,22 @@ public partial class AtmosphereSystem
|
||||
return GetTileMixture(entity.Comp.GridUid, entity.Comp.MapUid, indices, excite);
|
||||
}
|
||||
|
||||
public GasMixture? GetTileMixture(Entity<GridAtmosphereComponent?>? grid, Entity<MapAtmosphereComponent?>? map, Vector2i gridTile, bool excite = false)
|
||||
public GasMixture? GetTileMixture(
|
||||
Entity<GridAtmosphereComponent?, GasTileOverlayComponent?>? grid,
|
||||
Entity<MapAtmosphereComponent?>? map,
|
||||
Vector2i gridTile,
|
||||
bool excite = false)
|
||||
{
|
||||
// If we've been passed a grid, try to let it handle it.
|
||||
if (grid is {} gridEnt
|
||||
&& Resolve(gridEnt, ref gridEnt.Comp, false)
|
||||
&& gridEnt.Comp.Tiles.TryGetValue(gridTile, out var tile))
|
||||
&& Resolve(gridEnt, ref gridEnt.Comp1, false)
|
||||
&& gridEnt.Comp1.Tiles.TryGetValue(gridTile, out var tile))
|
||||
{
|
||||
if (excite)
|
||||
gridEnt.Comp.InvalidatedCoords.Add(gridTile);
|
||||
{
|
||||
AddActiveTile(gridEnt.Comp1, tile);
|
||||
InvalidateVisuals((grid.Value.Owner, grid.Value.Comp2), gridTile);
|
||||
}
|
||||
|
||||
return tile.Air;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using Content.Server.Atmos.Components;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Components;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.Atmos.EntitySystems
|
||||
@@ -64,10 +66,12 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
excitedGroup.DismantleCooldown = 0;
|
||||
}
|
||||
|
||||
private void ExcitedGroupSelfBreakdown(GridAtmosphereComponent gridAtmosphere, ExcitedGroup excitedGroup)
|
||||
private void ExcitedGroupSelfBreakdown(
|
||||
Entity<GridAtmosphereComponent, GasTileOverlayComponent, MapGridComponent, TransformComponent> ent,
|
||||
ExcitedGroup excitedGroup)
|
||||
{
|
||||
DebugTools.Assert(!excitedGroup.Disposed, "Excited group is disposed!");
|
||||
DebugTools.Assert(gridAtmosphere.ExcitedGroups.Contains(excitedGroup), "Grid Atmosphere does not contain Excited Group!");
|
||||
DebugTools.Assert(ent.Comp1.ExcitedGroups.Contains(excitedGroup), "Grid Atmosphere does not contain Excited Group!");
|
||||
var combined = new GasMixture(Atmospherics.CellVolume);
|
||||
|
||||
var tileSize = excitedGroup.Tiles.Count;
|
||||
@@ -77,7 +81,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
if (tileSize == 0)
|
||||
{
|
||||
ExcitedGroupDispose(gridAtmosphere, excitedGroup);
|
||||
ExcitedGroupDispose(ent.Comp1, excitedGroup);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -103,7 +107,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
continue;
|
||||
|
||||
tile.Air.CopyFromMutable(combined);
|
||||
InvalidateVisuals(tile.GridIndex, tile.GridIndices);
|
||||
InvalidateVisuals(ent, tile);
|
||||
}
|
||||
|
||||
excitedGroup.BreakdownCooldown = 0;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Atmos.Components;
|
||||
using Content.Server.Atmos.Reactions;
|
||||
using Content.Shared.Atmos;
|
||||
@@ -160,7 +159,7 @@ public sealed partial class AtmosphereSystem
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update array of adjacent tiles and the adjacency flags. Optionally activates all tiles with modified adjacencies.
|
||||
/// Update array of adjacent tiles and the adjacency flags.
|
||||
/// </summary>
|
||||
private void UpdateAdjacentTiles(
|
||||
Entity<GridAtmosphereComponent, GasTileOverlayComponent, MapGridComponent, TransformComponent> ent,
|
||||
@@ -195,14 +194,16 @@ public sealed partial class AtmosphereSystem
|
||||
if (activate)
|
||||
AddActiveTile(atmos, adjacent);
|
||||
|
||||
var oppositeDirection = direction.GetOpposite();
|
||||
var oppositeIndex = i.ToOppositeIndex();
|
||||
var oppositeDirection = (AtmosDirection) (1 << oppositeIndex);
|
||||
|
||||
if (adjBlockDirs.IsFlagSet(oppositeDirection) || blockedDirs.IsFlagSet(direction))
|
||||
{
|
||||
// Adjacency is blocked by some airtight entity.
|
||||
tile.AdjacentBits &= ~direction;
|
||||
adjacent.AdjacentBits &= ~oppositeDirection;
|
||||
tile.AdjacentTiles[i] = null;
|
||||
adjacent.AdjacentTiles[oppositeDirection.ToIndex()] = null;
|
||||
adjacent.AdjacentTiles[oppositeIndex] = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -210,7 +211,7 @@ public sealed partial class AtmosphereSystem
|
||||
tile.AdjacentBits |= direction;
|
||||
adjacent.AdjacentBits |= oppositeDirection;
|
||||
tile.AdjacentTiles[i] = adjacent;
|
||||
adjacent.AdjacentTiles[oppositeDirection.ToIndex()] = tile;
|
||||
adjacent.AdjacentTiles[oppositeIndex] = tile;
|
||||
}
|
||||
|
||||
DebugTools.Assert(!(tile.AdjacentBits.IsFlagSet(direction) ^
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using Content.Server.Atmos.Components;
|
||||
using Content.Server.Atmos.Reactions;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Components;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.Database;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Server.Atmos.EntitySystems
|
||||
@@ -18,18 +20,18 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public string? HotspotSound { get; private set; } = "/Audio/Effects/fire.ogg";
|
||||
|
||||
private void ProcessHotspot(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile)
|
||||
private void ProcessHotspot(
|
||||
Entity<GridAtmosphereComponent, GasTileOverlayComponent, MapGridComponent, TransformComponent> ent,
|
||||
TileAtmosphere tile)
|
||||
{
|
||||
var gridAtmosphere = ent.Comp1;
|
||||
if (!tile.Hotspot.Valid)
|
||||
{
|
||||
gridAtmosphere.HotspotTiles.Remove(tile);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tile.Excited)
|
||||
{
|
||||
AddActiveTile(gridAtmosphere, tile);
|
||||
}
|
||||
AddActiveTile(gridAtmosphere, tile);
|
||||
|
||||
if (!tile.Hotspot.SkippedFirstProcess)
|
||||
{
|
||||
@@ -44,7 +46,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|| 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.GetMoles(Gas.Hydrogen) < 0.5f && tile.Air.GetMoles(Gas.HyperNoblium) > 5f))
|
||||
{
|
||||
tile.Hotspot = new Hotspot();
|
||||
InvalidateVisuals(tile.GridIndex, tile.GridIndices);
|
||||
InvalidateVisuals(ent, tile);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
using Content.Server.Atmos.Components;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Components;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.Atmos.EntitySystems
|
||||
{
|
||||
public sealed partial class AtmosphereSystem
|
||||
{
|
||||
private void ProcessCell(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile, int fireCount, GasTileOverlayComponent visuals)
|
||||
private void ProcessCell(
|
||||
Entity<GridAtmosphereComponent, GasTileOverlayComponent, MapGridComponent, TransformComponent> ent,
|
||||
TileAtmosphere tile, int fireCount)
|
||||
{
|
||||
var gridAtmosphere = ent.Comp1;
|
||||
// Can't process a tile without air
|
||||
if (tile.Air == null)
|
||||
{
|
||||
@@ -52,11 +56,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
shouldShareAir = true;
|
||||
} else if (CompareExchange(tile.Air, enemyTile.Air) != GasCompareResult.NoExchange)
|
||||
{
|
||||
if (!enemyTile.Excited)
|
||||
{
|
||||
AddActiveTile(gridAtmosphere, enemyTile);
|
||||
}
|
||||
|
||||
AddActiveTile(gridAtmosphere, enemyTile);
|
||||
if (ExcitedGroups)
|
||||
{
|
||||
var excitedGroup = tile.ExcitedGroup;
|
||||
@@ -91,7 +91,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsiderPressureDifference(gridAtmosphere, enemyTile, direction.GetOpposite(), -difference);
|
||||
ConsiderPressureDifference(gridAtmosphere, enemyTile, i.ToOppositeDir(), -difference);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
if(tile.Air != null)
|
||||
React(tile.Air, tile);
|
||||
|
||||
InvalidateVisuals(tile.GridIndex, tile.GridIndices, visuals);
|
||||
InvalidateVisuals(ent, tile);
|
||||
|
||||
var remove = true;
|
||||
|
||||
@@ -146,7 +146,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
/// <param name="tile">Tile Atmosphere to be activated.</param>
|
||||
private void AddActiveTile(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile)
|
||||
{
|
||||
if (tile.Air == null)
|
||||
if (tile.Air == null || tile.Excited)
|
||||
return;
|
||||
|
||||
tile.Excited = true;
|
||||
|
||||
@@ -230,7 +230,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
if (otherTile2.MonstermosInfo.LastSlowQueueCycle == queueCycleSlow) continue;
|
||||
_equalizeQueue[queueLength++] = otherTile2;
|
||||
otherTile2.MonstermosInfo.LastSlowQueueCycle = queueCycleSlow;
|
||||
otherTile2.MonstermosInfo.CurrentTransferDirection = direction.GetOpposite();
|
||||
otherTile2.MonstermosInfo.CurrentTransferDirection = k.ToOppositeDir();
|
||||
otherTile2.MonstermosInfo.CurrentTransferAmount = 0;
|
||||
if (otherTile2.MonstermosInfo.MoleDelta < 0)
|
||||
{
|
||||
@@ -296,7 +296,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
if (otherTile2.MonstermosInfo.LastSlowQueueCycle == queueCycleSlow) continue;
|
||||
_equalizeQueue[queueLength++] = otherTile2;
|
||||
otherTile2.MonstermosInfo.LastSlowQueueCycle = queueCycleSlow;
|
||||
otherTile2.MonstermosInfo.CurrentTransferDirection = direction.GetOpposite();
|
||||
otherTile2.MonstermosInfo.CurrentTransferDirection = k.ToOppositeDir();
|
||||
otherTile2.MonstermosInfo.CurrentTransferAmount = 0;
|
||||
|
||||
if (otherTile2.MonstermosInfo.MoleDelta > 0)
|
||||
@@ -338,7 +338,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
for (var i = 0; i < tileCount; i++)
|
||||
{
|
||||
var otherTile = _equalizeTiles[i]!;
|
||||
FinalizeEq(gridAtmosphere, otherTile, ent);
|
||||
FinalizeEq(ent, otherTile);
|
||||
}
|
||||
|
||||
for (var i = 0; i < tileCount; i++)
|
||||
@@ -473,7 +473,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
if(tile2.Space)
|
||||
continue;
|
||||
|
||||
tile2.MonstermosInfo.CurrentTransferDirection = direction.GetOpposite();
|
||||
tile2.MonstermosInfo.CurrentTransferDirection = j.ToOppositeDir();
|
||||
tile2.MonstermosInfo.CurrentTransferAmount = 0.0f;
|
||||
tile2.PressureSpecificTarget = otherTile.PressureSpecificTarget;
|
||||
tile2.MonstermosInfo.LastSlowQueueCycle = queueCycleSlow;
|
||||
@@ -549,7 +549,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
otherTile.Air.Temperature = Atmospherics.TCMB;
|
||||
}
|
||||
|
||||
InvalidateVisuals(otherTile.GridIndex, otherTile.GridIndices, visuals);
|
||||
InvalidateVisuals(ent, otherTile);
|
||||
HandleDecompressionFloorRip(mapGrid, otherTile, otherTile.MonstermosInfo.CurrentTransferAmount);
|
||||
}
|
||||
|
||||
@@ -598,11 +598,13 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
UpdateAdjacentTiles(ent, tile);
|
||||
UpdateAdjacentTiles(ent, other);
|
||||
InvalidateVisuals(tile.GridIndex, tile.GridIndices, ent);
|
||||
InvalidateVisuals(other.GridIndex, other.GridIndices, ent);
|
||||
InvalidateVisuals(ent, tile);
|
||||
InvalidateVisuals(ent, other);
|
||||
}
|
||||
|
||||
private void FinalizeEq(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile, GasTileOverlayComponent? visuals)
|
||||
private void FinalizeEq(
|
||||
Entity<GridAtmosphereComponent, GasTileOverlayComponent, MapGridComponent, TransformComponent> ent,
|
||||
TileAtmosphere tile)
|
||||
{
|
||||
Span<float> transferDirections = stackalloc float[Atmospherics.Directions];
|
||||
var hasTransferDirs = false;
|
||||
@@ -629,17 +631,19 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
// Everything that calls this method already ensures that Air will not be null.
|
||||
if (tile.Air!.TotalMoles < amount)
|
||||
FinalizeEqNeighbors(gridAtmosphere, tile, transferDirections, visuals);
|
||||
FinalizeEqNeighbors(ent, tile, transferDirections);
|
||||
|
||||
otherTile.MonstermosInfo[direction.GetOpposite()] = 0;
|
||||
otherTile.MonstermosInfo[i.ToOppositeDir()] = 0;
|
||||
Merge(otherTile.Air, tile.Air.Remove(amount));
|
||||
InvalidateVisuals(tile.GridIndex, tile.GridIndices, visuals);
|
||||
InvalidateVisuals(otherTile.GridIndex, otherTile.GridIndices, visuals);
|
||||
ConsiderPressureDifference(gridAtmosphere, tile, direction, amount);
|
||||
InvalidateVisuals(ent, tile);
|
||||
InvalidateVisuals(ent, otherTile);
|
||||
ConsiderPressureDifference(ent, tile, direction, amount);
|
||||
}
|
||||
}
|
||||
|
||||
private void FinalizeEqNeighbors(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile, ReadOnlySpan<float> transferDirs, GasTileOverlayComponent? visuals)
|
||||
private void FinalizeEqNeighbors(
|
||||
Entity<GridAtmosphereComponent, GasTileOverlayComponent, MapGridComponent, TransformComponent> ent,
|
||||
TileAtmosphere tile, ReadOnlySpan<float> transferDirs)
|
||||
{
|
||||
for (var i = 0; i < Atmospherics.Directions; i++)
|
||||
{
|
||||
@@ -647,7 +651,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
var amount = transferDirs[i];
|
||||
// Since AdjacentBits is set, AdjacentTiles[i] wouldn't be null, and neither would its air.
|
||||
if(amount < 0 && tile.AdjacentBits.IsFlagSet(direction))
|
||||
FinalizeEq(gridAtmosphere, tile.AdjacentTiles[i]!, visuals); // A bit of recursion if needed.
|
||||
FinalizeEq(ent, tile.AdjacentTiles[i]!); // A bit of recursion if needed.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -664,7 +668,9 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
Log.Error($"Encountered null-tile in {nameof(AdjustEqMovement)}. Trace: {Environment.StackTrace}");
|
||||
return;
|
||||
}
|
||||
var adj = tile.AdjacentTiles[direction.ToIndex()];
|
||||
|
||||
var idx = direction.ToIndex();
|
||||
var adj = tile.AdjacentTiles[idx];
|
||||
if (adj == null)
|
||||
{
|
||||
var nonNull = tile.AdjacentTiles.Where(x => x != null).Count();
|
||||
@@ -673,7 +679,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
}
|
||||
|
||||
tile.MonstermosInfo[direction] += amount;
|
||||
adj.MonstermosInfo[direction.GetOpposite()] -= amount;
|
||||
adj.MonstermosInfo[idx.ToOppositeDir()] -= amount;
|
||||
}
|
||||
|
||||
private void HandleDecompressionFloorRip(MapGridComponent mapGrid, TileAtmosphere tile, float sum)
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
DebugTools.Assert(atmosphere.Tiles.GetValueOrDefault(tile.GridIndices) == tile);
|
||||
UpdateAdjacentTiles(ent, tile, activate: true);
|
||||
UpdateTileAir(ent, tile, volume);
|
||||
InvalidateVisuals(uid, tile.GridIndices, visuals);
|
||||
InvalidateVisuals(ent, tile);
|
||||
|
||||
if (number++ < InvalidCoordinatesLagCheckIterations)
|
||||
continue;
|
||||
@@ -313,15 +313,17 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ProcessActiveTiles(GridAtmosphereComponent atmosphere, GasTileOverlayComponent visuals)
|
||||
private bool ProcessActiveTiles(
|
||||
Entity<GridAtmosphereComponent, GasTileOverlayComponent, MapGridComponent, TransformComponent> ent)
|
||||
{
|
||||
var atmosphere = ent.Comp1;
|
||||
if(!atmosphere.ProcessingPaused)
|
||||
QueueRunTiles(atmosphere.CurrentRunTiles, atmosphere.ActiveTiles);
|
||||
|
||||
var number = 0;
|
||||
while (atmosphere.CurrentRunTiles.TryDequeue(out var tile))
|
||||
{
|
||||
ProcessCell(atmosphere, tile, atmosphere.UpdateCounter, visuals);
|
||||
ProcessCell(ent, tile, atmosphere.UpdateCounter);
|
||||
|
||||
if (number++ < LagCheckIterations)
|
||||
continue;
|
||||
@@ -337,8 +339,10 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ProcessExcitedGroups(GridAtmosphereComponent gridAtmosphere)
|
||||
private bool ProcessExcitedGroups(
|
||||
Entity<GridAtmosphereComponent, GasTileOverlayComponent, MapGridComponent, TransformComponent> ent)
|
||||
{
|
||||
var gridAtmosphere = ent.Comp1;
|
||||
if (!gridAtmosphere.ProcessingPaused)
|
||||
{
|
||||
gridAtmosphere.CurrentRunExcitedGroups.Clear();
|
||||
@@ -356,7 +360,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
excitedGroup.DismantleCooldown++;
|
||||
|
||||
if (excitedGroup.BreakdownCooldown > Atmospherics.ExcitedGroupBreakdownCycles)
|
||||
ExcitedGroupSelfBreakdown(gridAtmosphere, excitedGroup);
|
||||
ExcitedGroupSelfBreakdown(ent, excitedGroup);
|
||||
else if (excitedGroup.DismantleCooldown > Atmospherics.ExcitedGroupsDismantleCycles)
|
||||
DeactivateGroupTiles(gridAtmosphere, excitedGroup);
|
||||
// TODO ATMOS. What is the point of this? why is this only de-exciting the group? Shouldn't it also dismantle it?
|
||||
@@ -411,15 +415,17 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ProcessHotspots(GridAtmosphereComponent atmosphere)
|
||||
private bool ProcessHotspots(
|
||||
Entity<GridAtmosphereComponent, GasTileOverlayComponent, MapGridComponent, TransformComponent> ent)
|
||||
{
|
||||
var atmosphere = ent.Comp1;
|
||||
if(!atmosphere.ProcessingPaused)
|
||||
QueueRunTiles(atmosphere.CurrentRunTiles, atmosphere.HotspotTiles);
|
||||
|
||||
var number = 0;
|
||||
while (atmosphere.CurrentRunTiles.TryDequeue(out var hotspot))
|
||||
{
|
||||
ProcessHotspot(atmosphere, hotspot);
|
||||
ProcessHotspot(ent, hotspot);
|
||||
|
||||
if (number++ < LagCheckIterations)
|
||||
continue;
|
||||
@@ -507,8 +513,11 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
return num * AtmosTime;
|
||||
}
|
||||
|
||||
private bool ProcessAtmosDevices(GridAtmosphereComponent atmosphere)
|
||||
private bool ProcessAtmosDevices(
|
||||
Entity<GridAtmosphereComponent, GasTileOverlayComponent, MapGridComponent, TransformComponent> ent,
|
||||
Entity<MapAtmosphereComponent?> map)
|
||||
{
|
||||
var atmosphere = ent.Comp1;
|
||||
if (!atmosphere.ProcessingPaused)
|
||||
{
|
||||
atmosphere.CurrentRunAtmosDevices.Clear();
|
||||
@@ -521,7 +530,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
var time = _gameTiming.CurTime;
|
||||
var number = 0;
|
||||
var ev = new AtmosDeviceUpdateEvent(RealAtmosTime());
|
||||
var ev = new AtmosDeviceUpdateEvent(RealAtmosTime(), (ent, ent.Comp1, ent.Comp2), map);
|
||||
while (atmosphere.CurrentRunAtmosDevices.TryDequeue(out var device))
|
||||
{
|
||||
RaiseLocalEvent(device, ref ev);
|
||||
@@ -565,12 +574,11 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
var ent = _currentRunAtmosphere[_currentRunAtmosphereIndex];
|
||||
var (owner, atmosphere, visuals, grid, xform) = ent;
|
||||
|
||||
if (!TryComp(owner, out TransformComponent? x)
|
||||
|| x.MapUid == null
|
||||
|| TerminatingOrDeleted(x.MapUid.Value)
|
||||
|| x.MapID == MapId.Nullspace)
|
||||
if (xform.MapUid == null
|
||||
|| TerminatingOrDeleted(xform.MapUid.Value)
|
||||
|| xform.MapID == MapId.Nullspace)
|
||||
{
|
||||
Log.Error($"Attempted to process atmos without a map? Entity: {ToPrettyString(owner)}. Map: {ToPrettyString(x?.MapUid)}. MapId: {x?.MapID}");
|
||||
Log.Error($"Attempted to process atmos without a map? Entity: {ToPrettyString(owner)}. Map: {ToPrettyString(xform?.MapUid)}. MapId: {xform?.MapID}");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -585,6 +593,8 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
// We subtract it so it takes lost time into account.
|
||||
atmosphere.Timer -= AtmosTime;
|
||||
|
||||
var map = new Entity<MapAtmosphereComponent?>(xform.MapUid.Value, _mapAtmosQuery.CompOrNull(xform.MapUid.Value));
|
||||
|
||||
switch (atmosphere.State)
|
||||
{
|
||||
case AtmosphereProcessingState.Revalidate:
|
||||
@@ -614,7 +624,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
atmosphere.State = AtmosphereProcessingState.ActiveTiles;
|
||||
continue;
|
||||
case AtmosphereProcessingState.ActiveTiles:
|
||||
if (!ProcessActiveTiles(ent, ent))
|
||||
if (!ProcessActiveTiles(ent))
|
||||
{
|
||||
atmosphere.ProcessingPaused = true;
|
||||
return;
|
||||
@@ -625,7 +635,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
atmosphere.State = ExcitedGroups ? AtmosphereProcessingState.ExcitedGroups : AtmosphereProcessingState.HighPressureDelta;
|
||||
continue;
|
||||
case AtmosphereProcessingState.ExcitedGroups:
|
||||
if (!ProcessExcitedGroups(atmosphere))
|
||||
if (!ProcessExcitedGroups(ent))
|
||||
{
|
||||
atmosphere.ProcessingPaused = true;
|
||||
return;
|
||||
@@ -645,7 +655,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
atmosphere.State = AtmosphereProcessingState.Hotspots;
|
||||
continue;
|
||||
case AtmosphereProcessingState.Hotspots:
|
||||
if (!ProcessHotspots(atmosphere))
|
||||
if (!ProcessHotspots(ent))
|
||||
{
|
||||
atmosphere.ProcessingPaused = true;
|
||||
return;
|
||||
@@ -680,7 +690,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
atmosphere.State = AtmosphereProcessingState.AtmosDevices;
|
||||
continue;
|
||||
case AtmosphereProcessingState.AtmosDevices:
|
||||
if (!ProcessAtmosDevices(atmosphere))
|
||||
if (!ProcessAtmosDevices(ent, map))
|
||||
{
|
||||
atmosphere.ProcessingPaused = true;
|
||||
return;
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
if (!directions.IsFlagSet(direction))
|
||||
continue;
|
||||
|
||||
var adjacent = tile.AdjacentTiles[direction.ToIndex()];
|
||||
var adjacent = tile.AdjacentTiles[i];
|
||||
|
||||
// TODO ATMOS handle adjacent being null.
|
||||
if (adjacent == null || adjacent.ThermalConductivity == 0f)
|
||||
|
||||
@@ -36,9 +36,17 @@ public partial class AtmosphereSystem
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void InvalidateVisuals(EntityUid gridUid, Vector2i tile, GasTileOverlayComponent? comp = null)
|
||||
public void InvalidateVisuals(Entity<GasTileOverlayComponent?> grid, Vector2i tile)
|
||||
{
|
||||
_gasTileOverlaySystem.Invalidate(gridUid, tile, comp);
|
||||
_gasTileOverlaySystem.Invalidate(grid, tile);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void InvalidateVisuals(
|
||||
Entity<GridAtmosphereComponent, GasTileOverlayComponent, MapGridComponent, TransformComponent> ent,
|
||||
TileAtmosphere tile)
|
||||
{
|
||||
_gasTileOverlaySystem.Invalidate((ent.Owner, ent.Comp2), tile.GridIndices);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -96,7 +96,7 @@ public sealed partial class AtmosphereSystem : SharedAtmosphereSystem
|
||||
var query = EntityQueryEnumerator<AtmosExposedComponent, TransformComponent>();
|
||||
while (query.MoveNext(out var uid, out _, out var transform))
|
||||
{
|
||||
var air = GetContainingMixture(uid, transform:transform);
|
||||
var air = GetContainingMixture((uid, transform));
|
||||
|
||||
if (air == null)
|
||||
continue;
|
||||
|
||||
@@ -168,7 +168,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
private void ReleaseGas(Entity<GasTankComponent> gasTank)
|
||||
{
|
||||
var removed = RemoveAirVolume(gasTank, gasTank.Comp.ValveOutputRate * TimerDelay);
|
||||
var environment = _atmosphereSystem.GetContainingMixture(gasTank, false, true);
|
||||
var environment = _atmosphereSystem.GetContainingMixture(gasTank.Owner, false, true);
|
||||
if (environment != null)
|
||||
{
|
||||
_atmosphereSystem.Merge(environment, removed);
|
||||
|
||||
@@ -52,12 +52,15 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
new DefaultObjectPool<Dictionary<NetEntity, HashSet<Vector2i>>>(
|
||||
new DefaultPooledObjectPolicy<Dictionary<NetEntity, HashSet<Vector2i>>>(), 64);
|
||||
|
||||
private bool _doSessionUpdate;
|
||||
|
||||
/// <summary>
|
||||
/// Overlay update interval, in seconds.
|
||||
/// </summary>
|
||||
private float _updateInterval;
|
||||
|
||||
private int _thresholds;
|
||||
private EntityQuery<GasTileOverlayComponent> _query;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -82,6 +85,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
SubscribeLocalEvent<RoundRestartCleanupEvent>(Reset);
|
||||
SubscribeLocalEvent<GasTileOverlayComponent, ComponentStartup>(OnStartup);
|
||||
_query = GetEntityQuery<GasTileOverlayComponent>();
|
||||
}
|
||||
|
||||
private void OnStartup(EntityUid uid, GasTileOverlayComponent component, ComponentStartup args)
|
||||
@@ -130,10 +134,10 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
private void UpdateThresholds(int value) => _thresholds = value;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Invalidate(EntityUid grid, Vector2i index, GasTileOverlayComponent? comp = null)
|
||||
public void Invalidate(Entity<GasTileOverlayComponent?> grid, Vector2i index)
|
||||
{
|
||||
if (Resolve(grid, ref comp))
|
||||
comp.InvalidTiles.Add(index);
|
||||
if (_query.Resolve(grid.Owner, ref grid.Comp))
|
||||
grid.Comp.InvalidTiles.Add(index);
|
||||
}
|
||||
|
||||
private void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs e)
|
||||
@@ -192,7 +196,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
/// <summary>
|
||||
/// Updates the visuals for a tile on some grid chunk. Returns true if the visuals have changed.
|
||||
/// </summary>
|
||||
private bool UpdateChunkTile(GridAtmosphereComponent gridAtmosphere, GasOverlayChunk chunk, Vector2i index, GameTick curTick)
|
||||
private bool UpdateChunkTile(GridAtmosphereComponent gridAtmosphere, GasOverlayChunk chunk, Vector2i index)
|
||||
{
|
||||
ref var oldData = ref chunk.TileData[chunk.GetDataIndex(index)];
|
||||
if (!gridAtmosphere.Tiles.TryGetValue(index, out var tile))
|
||||
@@ -200,7 +204,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
if (oldData.Equals(default))
|
||||
return false;
|
||||
|
||||
chunk.LastUpdate = curTick;
|
||||
chunk.LastUpdate = _gameTiming.CurTick;
|
||||
oldData = default;
|
||||
return true;
|
||||
}
|
||||
@@ -258,11 +262,11 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
if (!changed)
|
||||
return false;
|
||||
|
||||
chunk.LastUpdate = curTick;
|
||||
chunk.LastUpdate = _gameTiming.CurTick;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void UpdateOverlayData(GameTick curTick)
|
||||
private void UpdateOverlayData()
|
||||
{
|
||||
// TODO parallelize?
|
||||
var query = EntityQueryEnumerator<GasTileOverlayComponent, GridAtmosphereComponent, MetaDataComponent>();
|
||||
@@ -276,7 +280,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
if (!overlay.Chunks.TryGetValue(chunkIndex, out var chunk))
|
||||
overlay.Chunks[chunkIndex] = chunk = new GasOverlayChunk(chunkIndex);
|
||||
|
||||
changed |= UpdateChunkTile(gam, chunk, index, curTick);
|
||||
changed |= UpdateChunkTile(gam, chunk, index);
|
||||
}
|
||||
|
||||
if (changed)
|
||||
@@ -291,13 +295,28 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
base.Update(frameTime);
|
||||
AccumulatedFrameTime += frameTime;
|
||||
|
||||
if (AccumulatedFrameTime < _updateInterval) return;
|
||||
if (_doSessionUpdate)
|
||||
{
|
||||
UpdateSessions();
|
||||
return;
|
||||
}
|
||||
|
||||
if (AccumulatedFrameTime < _updateInterval)
|
||||
return;
|
||||
|
||||
AccumulatedFrameTime -= _updateInterval;
|
||||
|
||||
var curTick = _gameTiming.CurTick;
|
||||
|
||||
// First, update per-chunk visual data for any invalidated tiles.
|
||||
UpdateOverlayData(curTick);
|
||||
UpdateOverlayData();
|
||||
|
||||
// Then, next tick we send the data to players.
|
||||
// This is to avoid doing all the work in the same tick.
|
||||
_doSessionUpdate = true;
|
||||
}
|
||||
|
||||
public void UpdateSessions()
|
||||
{
|
||||
_doSessionUpdate = false;
|
||||
|
||||
if (!PvsEnabled)
|
||||
return;
|
||||
@@ -315,11 +334,11 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
_sessions.Add(player);
|
||||
}
|
||||
|
||||
if (_sessions.Count > 0)
|
||||
{
|
||||
_updateJob.CurrentTick = curTick;
|
||||
_parMan.ProcessNow(_updateJob, _sessions.Count);
|
||||
}
|
||||
if (_sessions.Count == 0)
|
||||
return;
|
||||
|
||||
_parMan.ProcessNow(_updateJob, _sessions.Count);
|
||||
_updateJob.LastSessionUpdate = _gameTiming.CurTick;
|
||||
}
|
||||
|
||||
public void Reset(RoundRestartCleanupEvent ev)
|
||||
@@ -352,7 +371,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
public ObjectPool<HashSet<Vector2i>> ChunkIndexPool;
|
||||
public ObjectPool<Dictionary<NetEntity, HashSet<Vector2i>>> ChunkViewerPool;
|
||||
|
||||
public GameTick CurrentTick;
|
||||
public GameTick LastSessionUpdate;
|
||||
public Dictionary<ICommonSession, Dictionary<NetEntity, HashSet<Vector2i>>> LastSentChunks;
|
||||
public List<ICommonSession> Sessions;
|
||||
|
||||
@@ -415,7 +434,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
if (previousChunks != null &&
|
||||
previousChunks.Contains(gIndex) &&
|
||||
value.LastUpdate != CurrentTick)
|
||||
value.LastUpdate > LastSessionUpdate)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -40,24 +40,16 @@ public sealed class HeatExchangerSystem : EntitySystem
|
||||
|
||||
private void OnAtmosUpdate(EntityUid uid, HeatExchangerComponent comp, ref AtmosDeviceUpdateEvent args)
|
||||
{
|
||||
if (!TryComp(uid, out NodeContainerComponent? nodeContainer)
|
||||
|| !TryComp(uid, out AtmosDeviceComponent? device)
|
||||
|| !_nodeContainer.TryGetNode(nodeContainer, comp.InletName, out PipeNode? inlet)
|
||||
|| !_nodeContainer.TryGetNode(nodeContainer, comp.OutletName, out PipeNode? outlet))
|
||||
// make sure that the tile the device is on isn't blocked by a wall or something similar.
|
||||
if (args.Grid is {} grid
|
||||
&& _transform.TryGetGridTilePosition(uid, out var tile)
|
||||
&& _atmosphereSystem.IsTileAirBlocked(grid, tile))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure that the tile the device is on isn't blocked by a wall or something similar.
|
||||
var xform = Transform(uid);
|
||||
if (_transform.TryGetGridTilePosition(uid, out var tile))
|
||||
{
|
||||
// TryGetGridTilePosition() already returns false if GridUid is null, but the null checker isn't smart enough yet
|
||||
if (xform.GridUid != null && _atmosphereSystem.IsTileAirBlocked(xform.GridUid.Value, tile))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!_nodeContainer.TryGetNodes(uid, comp.InletName, comp.OutletName, out PipeNode? inlet, out PipeNode? outlet))
|
||||
return;
|
||||
|
||||
var dt = args.dt;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user