Remove 700 usages of Component.Owner (#21100)
This commit is contained in:
@@ -4,7 +4,6 @@ using Content.Shared.Atmos;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Content.Shared.Destructible;
|
||||
|
||||
namespace Content.Server.Atmos.EntitySystems
|
||||
{
|
||||
@@ -24,31 +23,32 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
SubscribeLocalEvent<AirtightComponent, MoveEvent>(OnAirtightMoved);
|
||||
}
|
||||
|
||||
private void OnAirtightInit(EntityUid uid, AirtightComponent airtight, ComponentInit args)
|
||||
private void OnAirtightInit(Entity<AirtightComponent> airtight, ref ComponentInit args)
|
||||
{
|
||||
var xform = EntityManager.GetComponent<TransformComponent>(uid);
|
||||
var xform = EntityManager.GetComponent<TransformComponent>(airtight);
|
||||
|
||||
if (airtight.FixAirBlockedDirectionInitialize)
|
||||
if (airtight.Comp.FixAirBlockedDirectionInitialize)
|
||||
{
|
||||
var moveEvent = new MoveEvent(uid, default, default, Angle.Zero, xform.LocalRotation, xform, false);
|
||||
if (AirtightMove(uid, airtight, ref moveEvent))
|
||||
var moveEvent = new MoveEvent(airtight, default, default, Angle.Zero, xform.LocalRotation, xform, false);
|
||||
if (AirtightMove(airtight, ref moveEvent))
|
||||
return;
|
||||
}
|
||||
|
||||
UpdatePosition(airtight);
|
||||
}
|
||||
|
||||
private void OnAirtightShutdown(EntityUid uid, AirtightComponent airtight, ComponentShutdown args)
|
||||
private void OnAirtightShutdown(Entity<AirtightComponent> airtight, ref ComponentShutdown args)
|
||||
{
|
||||
var xform = Transform(uid);
|
||||
var xform = Transform(airtight);
|
||||
|
||||
// If the grid is deleting no point updating atmos.
|
||||
if (_mapManager.TryGetGrid(xform.GridUid, out var grid))
|
||||
if (HasComp<MapGridComponent>(xform.GridUid) &&
|
||||
MetaData(xform.GridUid.Value).EntityLifeStage > EntityLifeStage.MapInitialized)
|
||||
{
|
||||
if (MetaData(grid.Owner).EntityLifeStage > EntityLifeStage.MapInitialized) return;
|
||||
return;
|
||||
}
|
||||
|
||||
SetAirblocked(uid, airtight, false, xform);
|
||||
SetAirblocked(airtight, false, xform);
|
||||
}
|
||||
|
||||
private void OnAirtightPositionChanged(EntityUid uid, AirtightComponent airtight, ref AnchorStateChangedEvent args)
|
||||
@@ -78,44 +78,47 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
}
|
||||
}
|
||||
|
||||
private void OnAirtightMoved(EntityUid uid, AirtightComponent airtight, ref MoveEvent ev)
|
||||
private void OnAirtightMoved(Entity<AirtightComponent> airtight, ref MoveEvent ev)
|
||||
{
|
||||
AirtightMove(uid, airtight, ref ev);
|
||||
AirtightMove(airtight, ref ev);
|
||||
}
|
||||
|
||||
private bool AirtightMove(EntityUid uid, AirtightComponent airtight, ref MoveEvent ev)
|
||||
private bool AirtightMove(Entity<AirtightComponent> ent, ref MoveEvent ev)
|
||||
{
|
||||
var (owner, airtight) = ent;
|
||||
if (!airtight.RotateAirBlocked || airtight.InitialAirBlockedDirection == (int)AtmosDirection.Invalid)
|
||||
return false;
|
||||
|
||||
airtight.CurrentAirBlockedDirection = (int) Rotate((AtmosDirection)airtight.InitialAirBlockedDirection, ev.NewRotation);
|
||||
var pos = airtight.LastPosition;
|
||||
UpdatePosition(airtight, ev.Component);
|
||||
var airtightEv = new AirtightChanged(uid, airtight, pos);
|
||||
RaiseLocalEvent(uid, ref airtightEv, true);
|
||||
UpdatePosition(ent, ev.Component);
|
||||
var airtightEv = new AirtightChanged(owner, airtight, pos);
|
||||
RaiseLocalEvent(owner, ref airtightEv, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetAirblocked(EntityUid uid, AirtightComponent airtight, bool airblocked, TransformComponent? xform = null)
|
||||
public void SetAirblocked(Entity<AirtightComponent> airtight, bool airblocked, TransformComponent? xform = null)
|
||||
{
|
||||
if (airtight.AirBlocked == airblocked)
|
||||
if (airtight.Comp.AirBlocked == airblocked)
|
||||
return;
|
||||
|
||||
if (!Resolve(uid, ref xform))
|
||||
if (!Resolve(airtight, ref xform))
|
||||
return;
|
||||
|
||||
var pos = airtight.LastPosition;
|
||||
airtight.AirBlocked = airblocked;
|
||||
var pos = airtight.Comp.LastPosition;
|
||||
airtight.Comp.AirBlocked = airblocked;
|
||||
UpdatePosition(airtight, xform);
|
||||
var airtightEv = new AirtightChanged(uid, airtight, pos);
|
||||
RaiseLocalEvent(uid, ref airtightEv, true);
|
||||
var airtightEv = new AirtightChanged(airtight, airtight, pos);
|
||||
RaiseLocalEvent(airtight, ref airtightEv, true);
|
||||
}
|
||||
|
||||
public void UpdatePosition(AirtightComponent airtight, TransformComponent? xform = null)
|
||||
public void UpdatePosition(Entity<AirtightComponent> ent, TransformComponent? xform = null)
|
||||
{
|
||||
if (!Resolve(airtight.Owner, ref xform)) return;
|
||||
var (owner, airtight) = ent;
|
||||
if (!Resolve(owner, ref xform))
|
||||
return;
|
||||
|
||||
if (!xform.Anchored || !_mapManager.TryGetGrid(xform.GridUid, out var grid))
|
||||
if (!xform.Anchored || !TryComp(xform.GridUid, out MapGridComponent? grid))
|
||||
return;
|
||||
|
||||
airtight.LastPosition = (xform.GridUid.Value, grid.TileIndicesFor(xform.Coordinates));
|
||||
@@ -124,15 +127,13 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
public void InvalidatePosition(EntityUid gridId, Vector2i pos, bool fixVacuum = false)
|
||||
{
|
||||
if (!_mapManager.TryGetGrid(gridId, out var grid))
|
||||
if (!TryComp(gridId, out MapGridComponent? grid))
|
||||
return;
|
||||
|
||||
var gridUid = grid.Owner;
|
||||
|
||||
var query = EntityManager.GetEntityQuery<AirtightComponent>();
|
||||
_explosionSystem.UpdateAirtightMap(gridId, pos, grid, query);
|
||||
// TODO make atmos system use query
|
||||
_atmosphereSystem.InvalidateTile(gridUid, pos);
|
||||
_atmosphereSystem.InvalidateTile(gridId, pos);
|
||||
}
|
||||
|
||||
private AtmosDirection Rotate(AtmosDirection myDirection, Angle myAngle)
|
||||
@@ -146,7 +147,8 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
for (var i = 0; i < Atmospherics.Directions; i++)
|
||||
{
|
||||
var direction = (AtmosDirection) (1 << i);
|
||||
if (!myDirection.IsFlagSet(direction)) continue;
|
||||
if (!myDirection.IsFlagSet(direction))
|
||||
continue;
|
||||
var angle = direction.ToAngle();
|
||||
angle += myAngle;
|
||||
newAirBlockedDirs |= angle.ToAtmosDirectionCardinal();
|
||||
|
||||
@@ -4,10 +4,12 @@ using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.EntitySystems;
|
||||
using Content.Shared.CCVar;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
|
||||
namespace Content.Server.Atmos.EntitySystems
|
||||
{
|
||||
@@ -18,6 +20,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IConfigurationManager _configManager = default!;
|
||||
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
|
||||
[Dependency] private readonly MapSystem _mapSystem = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Players allowed to see the atmos debug overlay.
|
||||
@@ -31,6 +34,8 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
/// </summary>
|
||||
private float _updateCooldown;
|
||||
|
||||
private List<Entity<MapGridComponent>> _grids = new();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
@@ -137,7 +142,10 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
var worldBounds = Box2.CenteredAround(transform.WorldPosition,
|
||||
new Vector2(LocalViewRange, LocalViewRange));
|
||||
|
||||
foreach (var grid in _mapManager.FindGridsIntersecting(transform.MapID, worldBounds))
|
||||
_grids.Clear();
|
||||
_mapManager.FindGridsIntersecting(transform.MapID, worldBounds, ref _grids);
|
||||
|
||||
foreach (var grid in _grids)
|
||||
{
|
||||
var uid = grid.Owner;
|
||||
|
||||
@@ -147,7 +155,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
if (!TryComp(uid, out GridAtmosphereComponent? gridAtmos))
|
||||
continue;
|
||||
|
||||
var entityTile = grid.GetTileRef(transform.Coordinates).GridIndices;
|
||||
var entityTile = _mapSystem.GetTileRef(grid, grid, transform.Coordinates).GridIndices;
|
||||
var baseTile = new Vector2i(entityTile.X - (LocalViewRange / 2), entityTile.Y - (LocalViewRange / 2));
|
||||
var debugOverlayContent = new AtmosDebugOverlayData[LocalViewRange * LocalViewRange];
|
||||
|
||||
@@ -161,7 +169,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
}
|
||||
}
|
||||
|
||||
RaiseNetworkEvent(new AtmosDebugOverlayMessage(GetNetEntity(grid.Owner), baseTile, debugOverlayContent), session.ConnectedClient);
|
||||
RaiseNetworkEvent(new AtmosDebugOverlayMessage(GetNetEntity(grid), baseTile, debugOverlayContent), session.ConnectedClient);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public sealed partial class AtmosphereSystem
|
||||
|
||||
if (TryComp<InternalsComponent>(old, out var internalsComponent))
|
||||
{
|
||||
_internals.DisconnectBreathTool(internalsComponent);
|
||||
_internals.DisconnectBreathTool((old.Value, internalsComponent));
|
||||
}
|
||||
|
||||
component.IsFunctional = false;
|
||||
|
||||
@@ -3,7 +3,6 @@ using Content.Server.Administration;
|
||||
using Content.Server.Atmos.Components;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Maps;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
@@ -128,12 +127,13 @@ public sealed partial class AtmosphereSystem
|
||||
if (playerMap == null)
|
||||
return CompletionResult.FromOptions(options);
|
||||
|
||||
foreach (var grid in _mapManager.GetAllMapGrids(playerMap.Value).OrderBy(o => o.Owner))
|
||||
foreach (var grid in _mapManager.GetAllGrids(playerMap.Value).OrderBy(o => o.Owner))
|
||||
{
|
||||
if (!TryComp<TransformComponent>(grid.Owner, out var gridXform))
|
||||
var uid = grid.Owner;
|
||||
if (!TryComp<TransformComponent>(uid, out var gridXform))
|
||||
continue;
|
||||
|
||||
options.Add(new CompletionOption(grid.Owner.ToString(), $"{MetaData(grid.Owner).EntityName} - Map {gridXform.MapID}"));
|
||||
options.Add(new CompletionOption(uid.ToString(), $"{MetaData(uid).EntityName} - Map {gridXform.MapID}"));
|
||||
}
|
||||
|
||||
return CompletionResult.FromOptions(options);
|
||||
|
||||
@@ -3,7 +3,6 @@ using Content.Server.Atmos.Components;
|
||||
using Content.Server.Atmos.Reactions;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Components;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -57,7 +56,7 @@ public sealed partial class AtmosphereSystem
|
||||
tile.GridIndex = uid;
|
||||
}
|
||||
|
||||
GridRepopulateTiles(mapGrid, gridAtmosphere);
|
||||
GridRepopulateTiles((uid, mapGrid, gridAtmosphere));
|
||||
}
|
||||
|
||||
private void OnGridSplit(EntityUid uid, GridAtmosphereComponent originalGridAtmos, ref GridSplitEvent args)
|
||||
@@ -65,14 +64,12 @@ public sealed partial class AtmosphereSystem
|
||||
foreach (var newGrid in args.NewGrids)
|
||||
{
|
||||
// Make extra sure this is a valid grid.
|
||||
if (!_mapManager.TryGetGrid(newGrid, out var mapGrid))
|
||||
if (!TryComp(newGrid, out MapGridComponent? mapGrid))
|
||||
continue;
|
||||
|
||||
var entity = mapGrid.Owner;
|
||||
|
||||
// If the new split grid has an atmosphere already somehow, use that. Otherwise, add a new one.
|
||||
if (!TryComp(entity, out GridAtmosphereComponent? newGridAtmos))
|
||||
newGridAtmos = AddComp<GridAtmosphereComponent>(entity);
|
||||
if (!TryComp(newGrid, out GridAtmosphereComponent? newGridAtmos))
|
||||
newGridAtmos = AddComp<GridAtmosphereComponent>(newGrid);
|
||||
|
||||
// We assume the tiles on the new grid have the same coordinates as they did on the old grid...
|
||||
var enumerator = mapGrid.GetAllTilesEnumerator();
|
||||
@@ -505,16 +502,15 @@ public sealed partial class AtmosphereSystem
|
||||
args.Handled = component.PipeNets.Remove(args.PipeNet);
|
||||
}
|
||||
|
||||
private void GridAddAtmosDevice(EntityUid uid, GridAtmosphereComponent component,
|
||||
ref AddAtmosDeviceMethodEvent args)
|
||||
private void GridAddAtmosDevice(Entity<GridAtmosphereComponent> grid, ref AddAtmosDeviceMethodEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (!component.AtmosDevices.Add(args.Device))
|
||||
if (!grid.Comp.AtmosDevices.Add((args.Device.Owner, args.Device)))
|
||||
return;
|
||||
|
||||
args.Device.JoinedGrid = uid;
|
||||
args.Device.JoinedGrid = grid;
|
||||
args.Handled = true;
|
||||
args.Result = true;
|
||||
}
|
||||
@@ -525,7 +521,7 @@ public sealed partial class AtmosphereSystem
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (!component.AtmosDevices.Remove(args.Device))
|
||||
if (!component.AtmosDevices.Remove((args.Device.Owner, args.Device)))
|
||||
return;
|
||||
|
||||
args.Device.JoinedGrid = null;
|
||||
@@ -538,8 +534,9 @@ public sealed partial class AtmosphereSystem
|
||||
/// </summary>
|
||||
/// <param name="mapGrid">The grid where to get all valid tiles from.</param>
|
||||
/// <param name="gridAtmosphere">The grid atmosphere where the tiles will be repopulated.</param>
|
||||
private void GridRepopulateTiles(MapGridComponent mapGrid, GridAtmosphereComponent gridAtmosphere)
|
||||
private void GridRepopulateTiles(Entity<MapGridComponent, GridAtmosphereComponent> grid)
|
||||
{
|
||||
var (uid, mapGrid, gridAtmosphere) = grid;
|
||||
var volume = GetVolumeForTiles(mapGrid, 1);
|
||||
|
||||
foreach (var tile in mapGrid.GetAllTiles())
|
||||
@@ -551,16 +548,14 @@ public sealed partial class AtmosphereSystem
|
||||
gridAtmosphere.InvalidatedCoords.Add(tile.GridIndices);
|
||||
}
|
||||
|
||||
var uid = gridAtmosphere.Owner;
|
||||
|
||||
TryComp(gridAtmosphere.Owner, out GasTileOverlayComponent? overlay);
|
||||
TryComp(uid, out GasTileOverlayComponent? overlay);
|
||||
|
||||
// Gotta do this afterwards so we can properly update adjacent tiles.
|
||||
foreach (var (position, _) in gridAtmosphere.Tiles.ToArray())
|
||||
{
|
||||
var ev = new UpdateAdjacentMethodEvent(uid, position);
|
||||
GridUpdateAdjacent(uid, gridAtmosphere, ref ev);
|
||||
InvalidateVisuals(mapGrid.Owner, position, overlay);
|
||||
InvalidateVisuals(uid, position, overlay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,32 +22,34 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public string? SpaceWindSound { get; private set; } = "/Audio/Effects/space_wind.ogg";
|
||||
|
||||
private HashSet<MovedByPressureComponent> _activePressures = new(8);
|
||||
private readonly HashSet<Entity<MovedByPressureComponent>> _activePressures = new(8);
|
||||
|
||||
private void UpdateHighPressure(float frameTime)
|
||||
{
|
||||
var toRemove = new RemQueue<MovedByPressureComponent>();
|
||||
var toRemove = new RemQueue<Entity<MovedByPressureComponent>>();
|
||||
|
||||
foreach (var comp in _activePressures)
|
||||
foreach (var ent in _activePressures)
|
||||
{
|
||||
var uid = comp.Owner;
|
||||
var (uid, comp) = ent;
|
||||
MetaDataComponent? metadata = null;
|
||||
|
||||
if (Deleted(uid, metadata))
|
||||
{
|
||||
toRemove.Add(comp);
|
||||
toRemove.Add((uid, comp));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Paused(uid, metadata)) continue;
|
||||
if (Paused(uid, metadata))
|
||||
continue;
|
||||
|
||||
comp.Accumulator += frameTime;
|
||||
|
||||
if (comp.Accumulator < 2f) continue;
|
||||
if (comp.Accumulator < 2f)
|
||||
continue;
|
||||
|
||||
// Reset it just for VV reasons even though it doesn't matter
|
||||
comp.Accumulator = 0f;
|
||||
toRemove.Add(comp);
|
||||
toRemove.Add(ent);
|
||||
|
||||
if (HasComp<MobStateComponent>(uid) &&
|
||||
TryComp<PhysicsComponent>(uid, out var body))
|
||||
@@ -86,10 +88,10 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
// idk it's hard.
|
||||
|
||||
component.Accumulator = 0f;
|
||||
_activePressures.Add(component);
|
||||
_activePressures.Add((uid, component));
|
||||
}
|
||||
|
||||
private void HighPressureMovements(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile, EntityQuery<PhysicsComponent> bodies, EntityQuery<TransformComponent> xforms, EntityQuery<MovedByPressureComponent> pressureQuery, EntityQuery<MetaDataComponent> metas)
|
||||
private void HighPressureMovements(Entity<GridAtmosphereComponent> gridAtmosphere, TileAtmosphere tile, EntityQuery<PhysicsComponent> bodies, EntityQuery<TransformComponent> xforms, EntityQuery<MovedByPressureComponent> pressureQuery, EntityQuery<MetaDataComponent> metas)
|
||||
{
|
||||
// TODO ATMOS finish this
|
||||
|
||||
@@ -118,7 +120,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
return;
|
||||
|
||||
// Used by ExperiencePressureDifference to correct push/throw directions from tile-relative to physics world.
|
||||
var gridWorldRotation = xforms.GetComponent(gridAtmosphere.Owner).WorldRotation;
|
||||
var gridWorldRotation = xforms.GetComponent(gridAtmosphere).WorldRotation;
|
||||
|
||||
// If we're using monstermos, smooth out the yeet direction to follow the flow
|
||||
if (MonstermosEqualization)
|
||||
@@ -151,12 +153,12 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
if (_containers.IsEntityInContainer(entity, metas.GetComponent(entity))) continue;
|
||||
|
||||
var pressureMovements = EnsureComp<MovedByPressureComponent>(entity);
|
||||
if (pressure.LastHighPressureMovementAirCycle < gridAtmosphere.UpdateCounter)
|
||||
if (pressure.LastHighPressureMovementAirCycle < gridAtmosphere.Comp.UpdateCounter)
|
||||
{
|
||||
// tl;dr YEET
|
||||
ExperiencePressureDifference(
|
||||
pressureMovements,
|
||||
gridAtmosphere.UpdateCounter,
|
||||
(entity, pressureMovements),
|
||||
gridAtmosphere.Comp.UpdateCounter,
|
||||
tile.PressureDifference,
|
||||
tile.PressureDirection, 0,
|
||||
tile.PressureSpecificTarget?.GridIndices.ToEntityCoordinates(tile.GridIndex, _mapManager) ?? EntityCoordinates.Invalid,
|
||||
@@ -180,7 +182,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
}
|
||||
|
||||
public void ExperiencePressureDifference(
|
||||
MovedByPressureComponent component,
|
||||
Entity<MovedByPressureComponent> ent,
|
||||
int cycle,
|
||||
float pressureDifference,
|
||||
AtmosDirection direction,
|
||||
@@ -190,12 +192,12 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
TransformComponent? xform = null,
|
||||
PhysicsComponent? physics = null)
|
||||
{
|
||||
var uid = component.Owner;
|
||||
|
||||
var (uid, component) = ent;
|
||||
if (!Resolve(uid, ref physics, false))
|
||||
return;
|
||||
|
||||
if (!Resolve(uid, ref xform)) return;
|
||||
if (!Resolve(uid, ref xform))
|
||||
return;
|
||||
|
||||
// TODO ATMOS stuns?
|
||||
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Server.Atmos.Components;
|
||||
using Content.Server.Doors.Systems;
|
||||
using Content.Shared.Doors.Components;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Components;
|
||||
using Content.Shared.Database;
|
||||
using Robust.Shared.Map;
|
||||
using Content.Shared.Doors.Components;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Content.Server.Atmos.EntitySystems
|
||||
{
|
||||
@@ -28,7 +27,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
private readonly TileAtmosphere[] _depressurizeSpaceTiles = new TileAtmosphere[Atmospherics.MonstermosHardTileLimit];
|
||||
private readonly TileAtmosphere[] _depressurizeProgressionOrder = new TileAtmosphere[Atmospherics.MonstermosHardTileLimit * 2];
|
||||
|
||||
private void EqualizePressureInZone(MapGridComponent mapGrid, GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile, int cycleNum, GasTileOverlayComponent? visuals)
|
||||
private void EqualizePressureInZone(Entity<MapGridComponent, GridAtmosphereComponent> ent, TileAtmosphere tile, int cycleNum, GasTileOverlayComponent? visuals)
|
||||
{
|
||||
if (tile.Air == null || (tile.MonstermosInfo.LastCycle >= cycleNum))
|
||||
return; // Already done.
|
||||
@@ -57,6 +56,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
return;
|
||||
}
|
||||
|
||||
var (_, mapGrid, gridAtmosphere) = ent;
|
||||
var queueCycle = ++gridAtmosphere.EqualizationQueueCycleControl;
|
||||
var totalMoles = 0f;
|
||||
_equalizeTiles[0] = tile;
|
||||
@@ -91,7 +91,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
{
|
||||
// Looks like someone opened an airlock to space!
|
||||
|
||||
ExplosivelyDepressurize(mapGrid, gridAtmosphere, tile, cycleNum, visuals);
|
||||
ExplosivelyDepressurize(ent, tile, cycleNum, visuals);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -359,7 +359,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
Array.Clear(_equalizeQueue, 0, Atmospherics.MonstermosTileLimit);
|
||||
}
|
||||
|
||||
private void ExplosivelyDepressurize(MapGridComponent mapGrid, GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile, int cycleNum, GasTileOverlayComponent? visuals)
|
||||
private void ExplosivelyDepressurize(Entity<MapGridComponent, GridAtmosphereComponent> ent, TileAtmosphere tile, int cycleNum, GasTileOverlayComponent? visuals)
|
||||
{
|
||||
// Check if explosive depressurization is enabled and if the tile is valid.
|
||||
if (!MonstermosDepressurization || tile.Air == null)
|
||||
@@ -368,6 +368,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
const int limit = Atmospherics.MonstermosHardTileLimit;
|
||||
|
||||
var totalMolesRemoved = 0f;
|
||||
var (owner, mapGrid, gridAtmosphere) = ent;
|
||||
var queueCycle = ++gridAtmosphere.EqualizationQueueCycleControl;
|
||||
|
||||
var tileCount = 0;
|
||||
@@ -394,7 +395,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
DebugTools.Assert(otherTile2.AdjacentBits.IsFlagSet(direction.GetOpposite()));
|
||||
if (otherTile2.MonstermosInfo.LastQueueCycle == queueCycle) continue;
|
||||
|
||||
ConsiderFirelocks(gridAtmosphere, otherTile, otherTile2, visuals, mapGrid);
|
||||
ConsiderFirelocks((owner, gridAtmosphere), otherTile, otherTile2, visuals, mapGrid);
|
||||
|
||||
// The firelocks might have closed on us.
|
||||
if (!otherTile.AdjacentBits.IsFlagSet(direction)) continue;
|
||||
@@ -527,11 +528,11 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
{
|
||||
var direction = ((Vector2)_depressurizeTiles[tileCount - 1].GridIndices - tile.GridIndices).Normalized();
|
||||
|
||||
var gridPhysics = Comp<PhysicsComponent>(mapGrid.Owner);
|
||||
var gridPhysics = Comp<PhysicsComponent>(owner);
|
||||
|
||||
// TODO ATMOS: Come up with better values for these.
|
||||
_physics.ApplyLinearImpulse(mapGrid.Owner, direction * totalMolesRemoved * gridPhysics.Mass, body: gridPhysics);
|
||||
_physics.ApplyAngularImpulse(mapGrid.Owner, Vector2Helpers.Cross(tile.GridIndices - gridPhysics.LocalCenter, direction) * totalMolesRemoved, body: gridPhysics);
|
||||
_physics.ApplyLinearImpulse(owner, direction * totalMolesRemoved * gridPhysics.Mass, body: gridPhysics);
|
||||
_physics.ApplyAngularImpulse(owner, Vector2Helpers.Cross(tile.GridIndices - gridPhysics.LocalCenter, direction) * totalMolesRemoved, body: gridPhysics);
|
||||
}
|
||||
|
||||
if(tileCount > 10 && (totalMolesRemoved / tileCount) > 10)
|
||||
@@ -543,7 +544,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
Array.Clear(_depressurizeProgressionOrder, 0, Atmospherics.MonstermosHardTileLimit * 2);
|
||||
}
|
||||
|
||||
private void ConsiderFirelocks(GridAtmosphereComponent gridAtmosphere, TileAtmosphere tile, TileAtmosphere other, GasTileOverlayComponent? visuals, MapGridComponent mapGrid)
|
||||
private void ConsiderFirelocks(Entity<GridAtmosphereComponent> ent, TileAtmosphere tile, TileAtmosphere other, GasTileOverlayComponent? visuals, MapGridComponent mapGrid)
|
||||
{
|
||||
var reconsiderAdjacent = false;
|
||||
|
||||
@@ -566,10 +567,11 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
if (!reconsiderAdjacent)
|
||||
return;
|
||||
|
||||
var tileEv = new UpdateAdjacentMethodEvent(mapGrid.Owner, tile.GridIndices);
|
||||
var otherEv = new UpdateAdjacentMethodEvent(mapGrid.Owner, other.GridIndices);
|
||||
GridUpdateAdjacent(mapGrid.Owner, gridAtmosphere, ref tileEv);
|
||||
GridUpdateAdjacent(mapGrid.Owner, gridAtmosphere, ref otherEv);
|
||||
var (owner, gridAtmosphere) = ent;
|
||||
var tileEv = new UpdateAdjacentMethodEvent(owner, tile.GridIndices);
|
||||
var otherEv = new UpdateAdjacentMethodEvent(owner, other.GridIndices);
|
||||
GridUpdateAdjacent(owner, gridAtmosphere, ref tileEv);
|
||||
GridUpdateAdjacent(owner, gridAtmosphere, ref otherEv);
|
||||
InvalidateVisuals(tile.GridIndex, tile.GridIndices, visuals);
|
||||
InvalidateVisuals(other.GridIndex, other.GridIndices, visuals);
|
||||
}
|
||||
|
||||
@@ -26,50 +26,49 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
/// </summary>
|
||||
private const int InvalidCoordinatesLagCheckIterations = 50;
|
||||
|
||||
private int _currentRunAtmosphereIndex = 0;
|
||||
private bool _simulationPaused = false;
|
||||
private int _currentRunAtmosphereIndex;
|
||||
private bool _simulationPaused;
|
||||
|
||||
private readonly List<GridAtmosphereComponent> _currentRunAtmosphere = new();
|
||||
private readonly List<Entity<GridAtmosphereComponent>> _currentRunAtmosphere = new();
|
||||
|
||||
/// <summary>
|
||||
/// Revalidates all invalid coordinates in a grid atmosphere.
|
||||
/// </summary>
|
||||
/// <param name="atmosphere">The grid atmosphere in question.</param>
|
||||
/// <param name="ent">The grid atmosphere in question.</param>
|
||||
/// <returns>Whether the process succeeded or got paused due to time constrains.</returns>
|
||||
private bool ProcessRevalidate(GridAtmosphereComponent atmosphere, GasTileOverlayComponent? visuals)
|
||||
private bool ProcessRevalidate(Entity<GridAtmosphereComponent> ent, GasTileOverlayComponent? visuals)
|
||||
{
|
||||
var (owner, atmosphere) = ent;
|
||||
if (!atmosphere.ProcessingPaused)
|
||||
{
|
||||
atmosphere.CurrentRunInvalidatedCoordinates = new Queue<Vector2i>(atmosphere.InvalidatedCoords);
|
||||
atmosphere.InvalidatedCoords.Clear();
|
||||
}
|
||||
|
||||
var uid = atmosphere.Owner;
|
||||
|
||||
if (!TryComp(uid, out MapGridComponent? mapGridComp))
|
||||
if (!TryComp(owner, out MapGridComponent? mapGridComp))
|
||||
return true;
|
||||
|
||||
var mapUid = _mapManager.GetMapEntityIdOrThrow(Transform(mapGridComp.Owner).MapID);
|
||||
var mapUid = _mapManager.GetMapEntityIdOrThrow(Transform(owner).MapID);
|
||||
|
||||
var volume = GetVolumeForTiles(mapGridComp, 1);
|
||||
var volume = GetVolumeForTiles(mapGridComp);
|
||||
|
||||
var number = 0;
|
||||
while (atmosphere.CurrentRunInvalidatedCoordinates.TryDequeue(out var indices))
|
||||
{
|
||||
if (!atmosphere.Tiles.TryGetValue(indices, out var tile))
|
||||
{
|
||||
tile = new TileAtmosphere(mapGridComp.Owner, indices,
|
||||
tile = new TileAtmosphere(owner, indices,
|
||||
new GasMixture(volume) { Temperature = Atmospherics.T20C });
|
||||
atmosphere.Tiles[indices] = tile;
|
||||
}
|
||||
|
||||
var airBlockedEv = new IsTileAirBlockedMethodEvent(uid, indices, MapGridComponent:mapGridComp);
|
||||
GridIsTileAirBlocked(uid, atmosphere, ref airBlockedEv);
|
||||
var airBlockedEv = new IsTileAirBlockedMethodEvent(owner, indices, MapGridComponent:mapGridComp);
|
||||
GridIsTileAirBlocked(owner, atmosphere, ref airBlockedEv);
|
||||
var isAirBlocked = airBlockedEv.Result;
|
||||
|
||||
var oldBlocked = tile.BlockedAirflow;
|
||||
var updateAdjacentEv = new UpdateAdjacentMethodEvent(uid, indices, mapGridComp);
|
||||
GridUpdateAdjacent(uid, atmosphere, ref updateAdjacentEv);
|
||||
var updateAdjacentEv = new UpdateAdjacentMethodEvent(owner, indices, mapGridComp);
|
||||
GridUpdateAdjacent(owner, atmosphere, ref updateAdjacentEv);
|
||||
|
||||
// Blocked airflow changed, rebuild excited groups!
|
||||
if (tile.Excited && tile.BlockedAirflow != oldBlocked)
|
||||
@@ -99,8 +98,8 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
{
|
||||
if (tile.Air == null && NeedsVacuumFixing(mapGridComp, indices))
|
||||
{
|
||||
var vacuumEv = new FixTileVacuumMethodEvent(uid, indices);
|
||||
GridFixTileVacuum(uid, atmosphere, ref vacuumEv);
|
||||
var vacuumEv = new FixTileVacuumMethodEvent(owner, indices);
|
||||
GridFixTileVacuum(owner, atmosphere, ref vacuumEv);
|
||||
}
|
||||
|
||||
// Tile used to be space, but isn't anymore.
|
||||
@@ -122,11 +121,12 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
// TODO ATMOS: Query all the contents of this tile (like walls) and calculate the correct thermal conductivity and heat capacity
|
||||
var tileDef = mapGridComp.TryGetTileRef(indices, out var tileRef)
|
||||
? tileRef.GetContentTileDefinition(_tileDefinitionManager) : null;
|
||||
? tileRef.GetContentTileDefinition(_tileDefinitionManager)
|
||||
: null;
|
||||
|
||||
tile.ThermalConductivity = tileDef?.ThermalConductivity ?? 0.5f;
|
||||
tile.HeatCapacity = tileDef?.HeatCapacity ?? float.PositiveInfinity;
|
||||
InvalidateVisuals(mapGridComp.Owner, indices, visuals);
|
||||
InvalidateVisuals(owner, indices, visuals);
|
||||
|
||||
for (var i = 0; i < Atmospherics.Directions; i++)
|
||||
{
|
||||
@@ -137,7 +137,9 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
AddActiveTile(atmosphere, otherTile);
|
||||
}
|
||||
|
||||
if (number++ < InvalidCoordinatesLagCheckIterations) continue;
|
||||
if (number++ < InvalidCoordinatesLagCheckIterations)
|
||||
continue;
|
||||
|
||||
number = 0;
|
||||
// Process the rest next time.
|
||||
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
|
||||
@@ -149,22 +151,23 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ProcessTileEqualize(GridAtmosphereComponent atmosphere, GasTileOverlayComponent? visuals)
|
||||
private bool ProcessTileEqualize(Entity<GridAtmosphereComponent> ent, GasTileOverlayComponent? visuals)
|
||||
{
|
||||
if(!atmosphere.ProcessingPaused)
|
||||
var (uid, atmosphere) = ent;
|
||||
if (!atmosphere.ProcessingPaused)
|
||||
atmosphere.CurrentRunTiles = new Queue<TileAtmosphere>(atmosphere.ActiveTiles);
|
||||
|
||||
var uid = atmosphere.Owner;
|
||||
|
||||
if (!TryComp(uid, out MapGridComponent? mapGridComp))
|
||||
throw new Exception("Tried to process a grid atmosphere on an entity that isn't a grid!");
|
||||
|
||||
var number = 0;
|
||||
while (atmosphere.CurrentRunTiles.TryDequeue(out var tile))
|
||||
{
|
||||
EqualizePressureInZone(mapGridComp, atmosphere, tile, atmosphere.UpdateCounter, visuals);
|
||||
EqualizePressureInZone((uid, mapGridComp, atmosphere), tile, atmosphere.UpdateCounter, visuals);
|
||||
|
||||
if (number++ < LagCheckIterations)
|
||||
continue;
|
||||
|
||||
if (number++ < LagCheckIterations) continue;
|
||||
number = 0;
|
||||
// Process the rest next time.
|
||||
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
|
||||
@@ -186,7 +189,9 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
{
|
||||
ProcessCell(atmosphere, tile, atmosphere.UpdateCounter, visuals);
|
||||
|
||||
if (number++ < LagCheckIterations) continue;
|
||||
if (number++ < LagCheckIterations)
|
||||
continue;
|
||||
|
||||
number = 0;
|
||||
// Process the rest next time.
|
||||
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
|
||||
@@ -215,7 +220,9 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
else if(excitedGroup.DismantleCooldown > Atmospherics.ExcitedGroupsDismantleCycles)
|
||||
ExcitedGroupDismantle(gridAtmosphere, excitedGroup);
|
||||
|
||||
if (number++ < LagCheckIterations) continue;
|
||||
if (number++ < LagCheckIterations)
|
||||
continue;
|
||||
|
||||
number = 0;
|
||||
// Process the rest next time.
|
||||
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
|
||||
@@ -227,9 +234,10 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ProcessHighPressureDelta(GridAtmosphereComponent atmosphere)
|
||||
private bool ProcessHighPressureDelta(Entity<GridAtmosphereComponent> ent)
|
||||
{
|
||||
if(!atmosphere.ProcessingPaused)
|
||||
var atmosphere = ent.Comp;
|
||||
if (!atmosphere.ProcessingPaused)
|
||||
atmosphere.CurrentRunTiles = new Queue<TileAtmosphere>(atmosphere.HighPressureDelta);
|
||||
|
||||
// Note: This is still processed even if space wind is turned off since this handles playing the sounds.
|
||||
@@ -242,14 +250,15 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
while (atmosphere.CurrentRunTiles.TryDequeue(out var tile))
|
||||
{
|
||||
HighPressureMovements(atmosphere, tile, bodies, xforms, pressureQuery, metas);
|
||||
HighPressureMovements(ent, tile, bodies, xforms, pressureQuery, metas);
|
||||
tile.PressureDifference = 0f;
|
||||
tile.LastPressureDirection = tile.PressureDirection;
|
||||
tile.PressureDirection = AtmosDirection.Invalid;
|
||||
tile.PressureSpecificTarget = null;
|
||||
atmosphere.HighPressureDelta.Remove(tile);
|
||||
|
||||
if (number++ < LagCheckIterations) continue;
|
||||
if (number++ < LagCheckIterations)
|
||||
continue;
|
||||
number = 0;
|
||||
// Process the rest next time.
|
||||
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
|
||||
@@ -271,7 +280,9 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
{
|
||||
ProcessHotspot(atmosphere, hotspot);
|
||||
|
||||
if (number++ < LagCheckIterations) continue;
|
||||
if (number++ < LagCheckIterations)
|
||||
continue;
|
||||
|
||||
number = 0;
|
||||
// Process the rest next time.
|
||||
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
|
||||
@@ -293,7 +304,9 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
{
|
||||
Superconduct(atmosphere, superconductivity);
|
||||
|
||||
if (number++ < LagCheckIterations) continue;
|
||||
if (number++ < LagCheckIterations)
|
||||
continue;
|
||||
|
||||
number = 0;
|
||||
// Process the rest next time.
|
||||
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
|
||||
@@ -315,7 +328,9 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
{
|
||||
pipenet.Update();
|
||||
|
||||
if (number++ < LagCheckIterations) continue;
|
||||
if (number++ < LagCheckIterations)
|
||||
continue;
|
||||
|
||||
number = 0;
|
||||
// Process the rest next time.
|
||||
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
|
||||
@@ -346,17 +361,19 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
private bool ProcessAtmosDevices(GridAtmosphereComponent atmosphere)
|
||||
{
|
||||
if(!atmosphere.ProcessingPaused)
|
||||
atmosphere.CurrentRunAtmosDevices = new Queue<AtmosDeviceComponent>(atmosphere.AtmosDevices);
|
||||
if (!atmosphere.ProcessingPaused)
|
||||
atmosphere.CurrentRunAtmosDevices = new Queue<Entity<AtmosDeviceComponent>>(atmosphere.AtmosDevices);
|
||||
|
||||
var time = _gameTiming.CurTime;
|
||||
var number = 0;
|
||||
while (atmosphere.CurrentRunAtmosDevices.TryDequeue(out var device))
|
||||
{
|
||||
RaiseLocalEvent(device.Owner, new AtmosDeviceUpdateEvent(RealAtmosTime()), false);
|
||||
device.LastProcess = time;
|
||||
RaiseLocalEvent(device, new AtmosDeviceUpdateEvent(RealAtmosTime()));
|
||||
device.Comp.LastProcess = time;
|
||||
|
||||
if (number++ < LagCheckIterations)
|
||||
continue;
|
||||
|
||||
if (number++ < LagCheckIterations) continue;
|
||||
number = 0;
|
||||
// Process the rest next time.
|
||||
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
|
||||
@@ -376,7 +393,12 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
{
|
||||
_currentRunAtmosphereIndex = 0;
|
||||
_currentRunAtmosphere.Clear();
|
||||
_currentRunAtmosphere.AddRange(EntityManager.EntityQuery<GridAtmosphereComponent>());
|
||||
|
||||
var query = EntityQueryEnumerator<GridAtmosphereComponent>();
|
||||
while (query.MoveNext(out var uid, out var grid))
|
||||
{
|
||||
_currentRunAtmosphere.Add((uid, grid));
|
||||
}
|
||||
}
|
||||
|
||||
// We set this to true just in case we have to stop processing due to time constraints.
|
||||
@@ -384,10 +406,11 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
for (; _currentRunAtmosphereIndex < _currentRunAtmosphere.Count; _currentRunAtmosphereIndex++)
|
||||
{
|
||||
var atmosphere = _currentRunAtmosphere[_currentRunAtmosphereIndex];
|
||||
TryComp(atmosphere.Owner, out GasTileOverlayComponent? visuals);
|
||||
var ent = _currentRunAtmosphere[_currentRunAtmosphereIndex];
|
||||
var (owner, atmosphere) = ent;
|
||||
TryComp(owner, out GasTileOverlayComponent? visuals);
|
||||
|
||||
if (atmosphere.LifeStage >= ComponentLifeStage.Stopping || Paused(atmosphere.Owner) || !atmosphere.Simulated)
|
||||
if (atmosphere.LifeStage >= ComponentLifeStage.Stopping || Paused(owner) || !atmosphere.Simulated)
|
||||
continue;
|
||||
|
||||
atmosphere.Timer += frameTime;
|
||||
@@ -401,7 +424,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
switch (atmosphere.State)
|
||||
{
|
||||
case AtmosphereProcessingState.Revalidate:
|
||||
if (!ProcessRevalidate(atmosphere, visuals))
|
||||
if (!ProcessRevalidate(ent, visuals))
|
||||
{
|
||||
atmosphere.ProcessingPaused = true;
|
||||
return;
|
||||
@@ -416,7 +439,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
: AtmosphereProcessingState.ActiveTiles;
|
||||
continue;
|
||||
case AtmosphereProcessingState.TileEqualize:
|
||||
if (!ProcessTileEqualize(atmosphere, visuals))
|
||||
if (!ProcessTileEqualize(ent, visuals))
|
||||
{
|
||||
atmosphere.ProcessingPaused = true;
|
||||
return;
|
||||
@@ -447,7 +470,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
atmosphere.State = AtmosphereProcessingState.HighPressureDelta;
|
||||
continue;
|
||||
case AtmosphereProcessingState.HighPressureDelta:
|
||||
if (!ProcessHighPressureDelta(atmosphere))
|
||||
if (!ProcessHighPressureDelta(ent))
|
||||
{
|
||||
atmosphere.ProcessingPaused = true;
|
||||
return;
|
||||
|
||||
@@ -4,7 +4,6 @@ using Content.Server.Body.Systems;
|
||||
using Content.Server.Maps;
|
||||
using Content.Server.NodeContainer.EntitySystems;
|
||||
using Content.Shared.Atmos.EntitySystems;
|
||||
using Content.Shared.Maps;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Containers;
|
||||
@@ -76,15 +75,16 @@ public sealed partial class AtmosphereSystem : SharedAtmosphereSystem
|
||||
if (_exposedTimer < ExposedUpdateDelay)
|
||||
return;
|
||||
|
||||
foreach (var (exposed, transform) in EntityManager.EntityQuery<AtmosExposedComponent, TransformComponent>())
|
||||
var query = EntityQueryEnumerator<AtmosExposedComponent, TransformComponent>();
|
||||
while (query.MoveNext(out var uid, out var exposed, out var transform))
|
||||
{
|
||||
var air = GetContainingMixture(exposed.Owner, transform:transform);
|
||||
var air = GetContainingMixture(uid, transform:transform);
|
||||
|
||||
if (air == null)
|
||||
continue;
|
||||
|
||||
var updateEvent = new AtmosExposedUpdateEvent(transform.Coordinates, air, transform);
|
||||
RaiseLocalEvent(exposed.Owner, ref updateEvent);
|
||||
RaiseLocalEvent(uid, ref updateEvent);
|
||||
}
|
||||
|
||||
_exposedTimer -= ExposedUpdateDelay;
|
||||
|
||||
@@ -16,9 +16,7 @@ using Content.Shared.Temperature;
|
||||
using Content.Shared.Throwing;
|
||||
using Content.Shared.Weapons.Melee.Events;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Physics.Dynamics;
|
||||
using Robust.Shared.Physics.Events;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
|
||||
@@ -48,7 +46,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
private float _timer;
|
||||
|
||||
private Dictionary<FlammableComponent, float> _fireEvents = new();
|
||||
private readonly Dictionary<Entity<FlammableComponent>, float> _fireEvents = new();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -188,14 +186,14 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
args.IsHot = flammable.OnFire;
|
||||
}
|
||||
|
||||
private void OnTileFire(EntityUid uid, FlammableComponent flammable, ref TileFireEvent args)
|
||||
private void OnTileFire(Entity<FlammableComponent> ent, ref TileFireEvent args)
|
||||
{
|
||||
var tempDelta = args.Temperature - MinIgnitionTemperature;
|
||||
|
||||
_fireEvents.TryGetValue(flammable, out var maxTemp);
|
||||
_fireEvents.TryGetValue(ent, out var maxTemp);
|
||||
|
||||
if (tempDelta > maxTemp)
|
||||
_fireEvents[flammable] = tempDelta;
|
||||
_fireEvents[ent] = tempDelta;
|
||||
}
|
||||
|
||||
private void OnRejuvenate(EntityUid uid, FlammableComponent component, RejuvenateEvent args)
|
||||
@@ -295,7 +293,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
{
|
||||
// 100 -> 1, 200 -> 2, 400 -> 3...
|
||||
var fireStackMod = Math.Max(MathF.Log2(deltaTemp / 100) + 1, 0);
|
||||
var fireStackDelta = fireStackMod - flammable.FireStacks;
|
||||
var fireStackDelta = fireStackMod - flammable.Comp.FireStacks;
|
||||
var flammableEntity = flammable.Owner;
|
||||
if (fireStackDelta > 0)
|
||||
{
|
||||
@@ -313,10 +311,9 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
_timer -= UpdateTime;
|
||||
|
||||
// TODO: This needs cleanup to take off the crust from TemperatureComponent and shit.
|
||||
foreach (var (flammable, transform) in EntityManager.EntityQuery<FlammableComponent, TransformComponent>())
|
||||
var query = EntityQueryEnumerator<FlammableComponent, TransformComponent>();
|
||||
while (query.MoveNext(out var uid, out var flammable, out var transform))
|
||||
{
|
||||
var uid = flammable.Owner;
|
||||
|
||||
// Slowly dry ourselves off if wet.
|
||||
if (flammable.FireStacks < 0)
|
||||
{
|
||||
|
||||
@@ -53,31 +53,35 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
SubscribeLocalEvent<GasTankComponent, GetVerbsEvent<AlternativeVerb>>(OnGetAlternativeVerb);
|
||||
}
|
||||
|
||||
private void OnGasShutdown(EntityUid uid, GasTankComponent component, ComponentShutdown args)
|
||||
private void OnGasShutdown(Entity<GasTankComponent> gasTank, ref ComponentShutdown args)
|
||||
{
|
||||
DisconnectFromInternals(component);
|
||||
DisconnectFromInternals(gasTank);
|
||||
}
|
||||
|
||||
private void OnGasTankToggleInternals(EntityUid uid, GasTankComponent component, GasTankToggleInternalsMessage args)
|
||||
private void OnGasTankToggleInternals(Entity<GasTankComponent> ent, ref GasTankToggleInternalsMessage args)
|
||||
{
|
||||
if (args.Session is not IPlayerSession playerSession ||
|
||||
playerSession.AttachedEntity is not {} player) return;
|
||||
playerSession.AttachedEntity == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ToggleInternals(component);
|
||||
ToggleInternals(ent);
|
||||
}
|
||||
|
||||
private void OnGasTankSetPressure(EntityUid uid, GasTankComponent component, GasTankSetPressureMessage args)
|
||||
private void OnGasTankSetPressure(Entity<GasTankComponent> ent, ref GasTankSetPressureMessage args)
|
||||
{
|
||||
var pressure = Math.Min(args.Pressure, component.MaxOutputPressure);
|
||||
var pressure = Math.Min(args.Pressure, ent.Comp.MaxOutputPressure);
|
||||
|
||||
component.OutputPressure = pressure;
|
||||
ent.Comp.OutputPressure = pressure;
|
||||
|
||||
UpdateUserInterface(component, true);
|
||||
UpdateUserInterface(ent, true);
|
||||
}
|
||||
|
||||
public void UpdateUserInterface(GasTankComponent component, bool initialUpdate = false)
|
||||
public void UpdateUserInterface(Entity<GasTankComponent> ent, bool initialUpdate = false)
|
||||
{
|
||||
_ui.TrySetUiState(component.Owner, SharedGasTankUiKey.Key,
|
||||
var (owner, component) = ent;
|
||||
_ui.TrySetUiState(owner, SharedGasTankUiKey.Key,
|
||||
new GasTankBoundUserInterfaceState
|
||||
{
|
||||
TankPressure = component.Air?.Pressure ?? 0,
|
||||
@@ -87,10 +91,10 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
});
|
||||
}
|
||||
|
||||
private void BeforeUiOpen(EntityUid uid, GasTankComponent component, BeforeActivatableUIOpenEvent args)
|
||||
private void BeforeUiOpen(Entity<GasTankComponent> ent, ref BeforeActivatableUIOpenEvent args)
|
||||
{
|
||||
// Only initial update includes output pressure information, to avoid overwriting client-input as the updates come in.
|
||||
UpdateUserInterface(component, true);
|
||||
UpdateUserInterface(ent, true);
|
||||
}
|
||||
|
||||
private void OnParentChange(EntityUid uid, GasTankComponent component, ref EntParentChangedMessage args)
|
||||
@@ -115,12 +119,12 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
args.PushMarkup(Loc.GetString(component.IsValveOpen ? "comp-gas-tank-examine-open-valve" : "comp-gas-tank-examine-closed-valve"));
|
||||
}
|
||||
|
||||
private void OnActionToggle(EntityUid uid, GasTankComponent component, ToggleActionEvent args)
|
||||
private void OnActionToggle(Entity<GasTankComponent> gasTank, ref ToggleActionEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
ToggleInternals(component);
|
||||
ToggleInternals(gasTank);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
@@ -130,30 +134,33 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
_timer += frameTime;
|
||||
|
||||
if (_timer < TimerDelay) return;
|
||||
if (_timer < TimerDelay)
|
||||
return;
|
||||
|
||||
_timer -= TimerDelay;
|
||||
|
||||
var query = EntityQueryEnumerator<GasTankComponent>();
|
||||
while (query.MoveNext(out var uid, out var gasTank))
|
||||
while (query.MoveNext(out var uid, out var comp))
|
||||
{
|
||||
if (gasTank.IsValveOpen && !gasTank.IsLowPressure)
|
||||
var gasTank = (uid, comp);
|
||||
if (comp.IsValveOpen && !comp.IsLowPressure)
|
||||
{
|
||||
ReleaseGas(uid, gasTank);
|
||||
ReleaseGas(gasTank);
|
||||
}
|
||||
|
||||
if (gasTank.CheckUser)
|
||||
if (comp.CheckUser)
|
||||
{
|
||||
gasTank.CheckUser = false;
|
||||
if (Transform(uid).ParentUid != gasTank.User)
|
||||
comp.CheckUser = false;
|
||||
if (Transform(uid).ParentUid != comp.User)
|
||||
{
|
||||
DisconnectFromInternals(gasTank);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (gasTank.Air != null)
|
||||
if (comp.Air != null)
|
||||
{
|
||||
_atmosphereSystem.React(gasTank.Air, gasTank);
|
||||
_atmosphereSystem.React(comp.Air, comp);
|
||||
}
|
||||
CheckStatus(gasTank);
|
||||
if (_ui.IsUiOpen(uid, SharedGasTankUiKey.Key))
|
||||
@@ -163,47 +170,48 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
}
|
||||
}
|
||||
|
||||
private void ReleaseGas(EntityUid uid, GasTankComponent component)
|
||||
private void ReleaseGas(Entity<GasTankComponent> gasTank)
|
||||
{
|
||||
var removed = RemoveAirVolume(component, component.ValveOutputRate * TimerDelay);
|
||||
var environment = _atmosphereSystem.GetContainingMixture(uid, false, true);
|
||||
var removed = RemoveAirVolume(gasTank, gasTank.Comp.ValveOutputRate * TimerDelay);
|
||||
var environment = _atmosphereSystem.GetContainingMixture(gasTank, false, true);
|
||||
if (environment != null)
|
||||
{
|
||||
_atmosphereSystem.Merge(environment, removed);
|
||||
}
|
||||
var impulse = removed.TotalMoles * removed.Temperature;
|
||||
_physics.ApplyLinearImpulse(uid, _random.NextAngle().ToWorldVec() * impulse);
|
||||
_physics.ApplyAngularImpulse(uid, _random.NextFloat(-3f, 3f));
|
||||
_audioSys.PlayPvs(component.RuptureSound, uid);
|
||||
_physics.ApplyLinearImpulse(gasTank, _random.NextAngle().ToWorldVec() * impulse);
|
||||
_physics.ApplyAngularImpulse(gasTank, _random.NextFloat(-3f, 3f));
|
||||
_audioSys.PlayPvs(gasTank.Comp.RuptureSound, gasTank);
|
||||
}
|
||||
|
||||
private void ToggleInternals(GasTankComponent component)
|
||||
private void ToggleInternals(Entity<GasTankComponent> ent)
|
||||
{
|
||||
if (component.IsConnected)
|
||||
if (ent.Comp.IsConnected)
|
||||
{
|
||||
DisconnectFromInternals(component);
|
||||
DisconnectFromInternals(ent);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConnectToInternals(component);
|
||||
ConnectToInternals(ent);
|
||||
}
|
||||
}
|
||||
|
||||
public GasMixture? RemoveAir(GasTankComponent component, float amount)
|
||||
public GasMixture? RemoveAir(Entity<GasTankComponent> gasTank, float amount)
|
||||
{
|
||||
var gas = component.Air?.Remove(amount);
|
||||
CheckStatus(component);
|
||||
var gas = gasTank.Comp.Air?.Remove(amount);
|
||||
CheckStatus(gasTank);
|
||||
return gas;
|
||||
}
|
||||
|
||||
public GasMixture RemoveAirVolume(GasTankComponent component, float volume)
|
||||
public GasMixture RemoveAirVolume(Entity<GasTankComponent> gasTank, float volume)
|
||||
{
|
||||
var component = gasTank.Comp;
|
||||
if (component.Air == null)
|
||||
return new GasMixture(volume);
|
||||
|
||||
var molesNeeded = component.OutputPressure * volume / (Atmospherics.R * component.Air.Temperature);
|
||||
|
||||
var air = RemoveAir(component, molesNeeded);
|
||||
var air = RemoveAir(gasTank, molesNeeded);
|
||||
|
||||
if (air != null)
|
||||
air.Volume = volume;
|
||||
@@ -215,12 +223,13 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
public bool CanConnectToInternals(GasTankComponent component)
|
||||
{
|
||||
var internals = GetInternalsComponent(component);
|
||||
var internals = GetInternalsComponent(component, component.User);
|
||||
return internals != null && internals.BreathToolEntity != null && !component.IsValveOpen;
|
||||
}
|
||||
|
||||
public void ConnectToInternals(GasTankComponent component)
|
||||
public void ConnectToInternals(Entity<GasTankComponent> ent)
|
||||
{
|
||||
var (owner, component) = ent;
|
||||
if (component.IsConnected || !CanConnectToInternals(component))
|
||||
return;
|
||||
|
||||
@@ -228,7 +237,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
if (internals == null)
|
||||
return;
|
||||
|
||||
if (_internals.TryConnectTank(internals, component.Owner))
|
||||
if (_internals.TryConnectTank((internals.Owner, internals), owner))
|
||||
component.User = internals.Owner;
|
||||
|
||||
_actions.SetToggled(component.ToggleActionEntity, component.IsConnected);
|
||||
@@ -240,13 +249,14 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
component.ConnectStream?.Stop();
|
||||
|
||||
if (component.ConnectSound != null)
|
||||
component.ConnectStream = _audioSys.PlayPvs(component.ConnectSound, component.Owner);
|
||||
component.ConnectStream = _audioSys.PlayPvs(component.ConnectSound, owner);
|
||||
|
||||
UpdateUserInterface(component);
|
||||
UpdateUserInterface(ent);
|
||||
}
|
||||
|
||||
public void DisconnectFromInternals(GasTankComponent component)
|
||||
public void DisconnectFromInternals(Entity<GasTankComponent> ent)
|
||||
{
|
||||
var (owner, component) = ent;
|
||||
if (component.User == null)
|
||||
return;
|
||||
|
||||
@@ -259,29 +269,30 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
component.DisconnectStream?.Stop();
|
||||
|
||||
if (component.DisconnectSound != null)
|
||||
component.DisconnectStream = _audioSys.PlayPvs(component.DisconnectSound, component.Owner);
|
||||
component.DisconnectStream = _audioSys.PlayPvs(component.DisconnectSound, owner);
|
||||
|
||||
UpdateUserInterface(component);
|
||||
UpdateUserInterface(ent);
|
||||
}
|
||||
|
||||
private InternalsComponent? GetInternalsComponent(GasTankComponent component, EntityUid? owner = null)
|
||||
{
|
||||
owner ??= component.User;
|
||||
if (Deleted(component.Owner)) return null;
|
||||
if (Deleted(component.Owner))return null;
|
||||
if (owner != null) return CompOrNull<InternalsComponent>(owner.Value);
|
||||
return _containers.TryGetContainingContainer(component.Owner, out var container)
|
||||
? CompOrNull<InternalsComponent>(container.Owner)
|
||||
: null;
|
||||
}
|
||||
|
||||
public void AssumeAir(GasTankComponent component, GasMixture giver)
|
||||
public void AssumeAir(Entity<GasTankComponent> ent, GasMixture giver)
|
||||
{
|
||||
_atmosphereSystem.Merge(component.Air, giver);
|
||||
CheckStatus(component);
|
||||
_atmosphereSystem.Merge(ent.Comp.Air, giver);
|
||||
CheckStatus(ent);
|
||||
}
|
||||
|
||||
public void CheckStatus(GasTankComponent component)
|
||||
public void CheckStatus(Entity<GasTankComponent> ent)
|
||||
{
|
||||
var (owner, component) = ent;
|
||||
if (component.Air == null)
|
||||
return;
|
||||
|
||||
@@ -305,7 +316,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
range = GasTankComponent.MaxExplosionRange;
|
||||
}
|
||||
|
||||
_explosions.TriggerExplosive(component.Owner, radius: range);
|
||||
_explosions.TriggerExplosive(owner, radius: range);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -314,13 +325,13 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
{
|
||||
if (component.Integrity <= 0)
|
||||
{
|
||||
var environment = _atmosphereSystem.GetContainingMixture(component.Owner, false, true);
|
||||
var environment = _atmosphereSystem.GetContainingMixture(owner, false, true);
|
||||
if(environment != null)
|
||||
_atmosphereSystem.Merge(environment, component.Air);
|
||||
|
||||
_audioSys.Play(component.RuptureSound, Filter.Pvs(component.Owner), Transform(component.Owner).Coordinates, true, AudioParams.Default.WithVariation(0.125f));
|
||||
_audioSys.Play(component.RuptureSound, Filter.Pvs(owner), Transform(owner).Coordinates, true, AudioParams.Default.WithVariation(0.125f));
|
||||
|
||||
QueueDel(component.Owner);
|
||||
QueueDel(owner);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -332,7 +343,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
{
|
||||
if (component.Integrity <= 0)
|
||||
{
|
||||
var environment = _atmosphereSystem.GetContainingMixture(component.Owner, false, true);
|
||||
var environment = _atmosphereSystem.GetContainingMixture(owner, false, true);
|
||||
if (environment == null)
|
||||
return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user