mirror of
https://github.com/wega-team/ss14-wega.git
synced 2026-02-14 19:30:01 +01:00
Cleanup and document AirtightData/MonstermosInfo (#41258)
cleanup and document airtightdata/monstermosinfo
This commit is contained in:
@@ -61,7 +61,22 @@ public partial class AtmosphereSystem
|
||||
return Atmospherics.CellVolume * mapGrid.TileSize * tiles;
|
||||
}
|
||||
|
||||
public readonly record struct AirtightData(AtmosDirection BlockedDirections, bool NoAirWhenBlocked,
|
||||
/// <summary>
|
||||
/// Data on the airtightness of a <see cref="TileAtmosphere"/>.
|
||||
/// Cached on the <see cref="TileAtmosphere"/> and updated during
|
||||
/// <see cref="AtmosphereSystem.ProcessRevalidate"/> if it was invalidated.
|
||||
/// </summary>
|
||||
/// <param name="BlockedDirections">The current directions blocked on this tile.
|
||||
/// This is where air cannot flow to.</param>
|
||||
/// <param name="NoAirWhenBlocked">Whether the tile can have air when blocking directions.
|
||||
/// Common for entities like thin windows which only block one face but can still have air in the residing tile.</param>
|
||||
/// <param name="FixVacuum">If true, Atmospherics will generate air (yes, creating matter from nothing)
|
||||
/// using the adjacent tiles as a seed if the airtightness is removed and the tile has no air.
|
||||
/// This allows stuff like airlocks that void air when becoming airtight to keep opening/closing without
|
||||
/// draining a room by continuously voiding air.</param>
|
||||
public readonly record struct AirtightData(
|
||||
AtmosDirection BlockedDirections,
|
||||
bool NoAirWhenBlocked,
|
||||
bool FixVacuum);
|
||||
|
||||
private void UpdateAirtightData(EntityUid uid, GridAtmosphereComponent atmos, MapGridComponent grid, TileAtmosphere tile)
|
||||
|
||||
@@ -1,80 +1,148 @@
|
||||
using Content.Shared.Atmos;
|
||||
|
||||
namespace Content.Server.Atmos
|
||||
namespace Content.Server.Atmos;
|
||||
|
||||
/// <summary>
|
||||
/// Atmospherics class that stores data on tiles for Monstermos calculations and operations.
|
||||
/// </summary>
|
||||
public struct MonstermosInfo
|
||||
{
|
||||
public struct MonstermosInfo
|
||||
/// <summary>
|
||||
/// The last cycle this tile was processed for monstermos calculations.
|
||||
/// Used to determine if Monstermos has already processed this tile in the
|
||||
/// current tick's processing run.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public int LastCycle;
|
||||
|
||||
/// <summary>
|
||||
/// <para>The last global cycle (on the GridAtmosphereComponent) this tile was processed for
|
||||
/// monstermos calculations.
|
||||
/// Monstermos can process multiple groups, and these groups may intersect with each other.
|
||||
/// This allows Monstermos to check if a tile belongs to another group that has already been processed,
|
||||
/// and skip processing it again.</para>
|
||||
///
|
||||
/// <para>Used for exploring the current area for determining tiles that should be equalized
|
||||
/// using a BFS fill (see https://en.wikipedia.org/wiki/Breadth-first_search)</para>
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public long LastQueueCycle;
|
||||
|
||||
/// <summary>
|
||||
/// Similar to <see cref="LastQueueCycle"/>. Monstermos performs a second slow pass after the main
|
||||
/// BFS fill in order to build a gradient map to determine transfer directions and amounts.
|
||||
/// This field also tracks if we've already processed this tile in that slow pass so we don't re-queue it.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public long LastSlowQueueCycle;
|
||||
|
||||
/// <summary>
|
||||
/// Difference in the amount of moles in this tile compared to the tile's neighbors.
|
||||
/// Used to determine "how strongly" air wants to flow in/out of this tile from/to its neighbors.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public float MoleDelta;
|
||||
|
||||
/// <summary>
|
||||
/// Number of moles that are going to be transferred in this direction during final equalization.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public float TransferDirectionEast;
|
||||
|
||||
/// <summary>
|
||||
/// Number of moles that are going to be transferred in this direction during final equalization.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public float TransferDirectionWest;
|
||||
|
||||
/// <summary>
|
||||
/// Number of moles that are going to be transferred in this direction during final equalization.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public float TransferDirectionNorth;
|
||||
|
||||
/// <summary>
|
||||
/// Number of moles that are going to be transferred in this direction during final equalization.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public float TransferDirectionSouth;
|
||||
|
||||
/// <summary>
|
||||
/// <para>Number of moles that are going to be transferred to this tile during final equalization.
|
||||
/// You can think of this as molar flow rate, or the amount of air currently flowing through this tile.
|
||||
/// Used for space wind and airflow sounds during explosive decompression or big movements.</para>
|
||||
///
|
||||
/// <para>During equalization calculations, Monstermos determines how much air is going to be transferred
|
||||
/// between tiles, and sums that up into this field. It then either
|
||||
///
|
||||
/// determines how many moles to transfer in the direction of <see cref="CurrentTransferDirection"/>, or
|
||||
///
|
||||
/// determines how many moles to move in each direction using <see cref="MoleDelta"/>,
|
||||
/// setting the TransferDirection fields accordingly based on the ratio obtained
|
||||
/// from <see cref="MoleDelta"/>.</para>
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public float CurrentTransferAmount;
|
||||
|
||||
/// <summary>
|
||||
/// A pointer from the current tile to the direction in which air is being transferred the most.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public AtmosDirection CurrentTransferDirection;
|
||||
|
||||
/// <summary>
|
||||
/// Marks this tile as being equalized using the O(n log n) algorithm.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public bool FastDone;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the TransferDirection in the given direction.
|
||||
/// </summary>
|
||||
/// <param name="direction"></param>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when an invalid direction is given
|
||||
/// (a non-cardinal direction)</exception>
|
||||
public float this[AtmosDirection direction]
|
||||
{
|
||||
[ViewVariables]
|
||||
public int LastCycle;
|
||||
|
||||
[ViewVariables]
|
||||
public long LastQueueCycle;
|
||||
|
||||
[ViewVariables]
|
||||
public long LastSlowQueueCycle;
|
||||
|
||||
[ViewVariables]
|
||||
public float MoleDelta;
|
||||
|
||||
[ViewVariables]
|
||||
public float TransferDirectionEast;
|
||||
|
||||
[ViewVariables]
|
||||
public float TransferDirectionWest;
|
||||
|
||||
[ViewVariables]
|
||||
public float TransferDirectionNorth;
|
||||
|
||||
[ViewVariables]
|
||||
public float TransferDirectionSouth;
|
||||
|
||||
[ViewVariables]
|
||||
public float CurrentTransferAmount;
|
||||
|
||||
[ViewVariables]
|
||||
public AtmosDirection CurrentTransferDirection;
|
||||
|
||||
[ViewVariables]
|
||||
public bool FastDone;
|
||||
|
||||
public float this[AtmosDirection direction]
|
||||
{
|
||||
get =>
|
||||
direction switch
|
||||
{
|
||||
AtmosDirection.East => TransferDirectionEast,
|
||||
AtmosDirection.West => TransferDirectionWest,
|
||||
AtmosDirection.North => TransferDirectionNorth,
|
||||
AtmosDirection.South => TransferDirectionSouth,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(direction))
|
||||
};
|
||||
|
||||
set
|
||||
get =>
|
||||
direction switch
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case AtmosDirection.East:
|
||||
TransferDirectionEast = value;
|
||||
break;
|
||||
case AtmosDirection.West:
|
||||
TransferDirectionWest = value;
|
||||
break;
|
||||
case AtmosDirection.North:
|
||||
TransferDirectionNorth = value;
|
||||
break;
|
||||
case AtmosDirection.South:
|
||||
TransferDirectionSouth = value;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(direction));
|
||||
}
|
||||
AtmosDirection.East => TransferDirectionEast,
|
||||
AtmosDirection.West => TransferDirectionWest,
|
||||
AtmosDirection.North => TransferDirectionNorth,
|
||||
AtmosDirection.South => TransferDirectionSouth,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(direction))
|
||||
};
|
||||
|
||||
set
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case AtmosDirection.East:
|
||||
TransferDirectionEast = value;
|
||||
break;
|
||||
case AtmosDirection.West:
|
||||
TransferDirectionWest = value;
|
||||
break;
|
||||
case AtmosDirection.North:
|
||||
TransferDirectionNorth = value;
|
||||
break;
|
||||
case AtmosDirection.South:
|
||||
TransferDirectionSouth = value;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(direction));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float this[int index]
|
||||
{
|
||||
get => this[(AtmosDirection) (1 << index)];
|
||||
set => this[(AtmosDirection) (1 << index)] = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the TransferDirection by index.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the direction</param>
|
||||
public float this[int index]
|
||||
{
|
||||
get => this[(AtmosDirection) (1 << index)];
|
||||
set => this[(AtmosDirection) (1 << index)] = value;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user