using Content.Shared.Atmos; namespace Content.Server.Atmos; /// /// Atmospherics class that stores data on tiles for Monstermos calculations and operations. /// public struct MonstermosInfo { /// /// 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. /// [ViewVariables] public int LastCycle; /// /// 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. /// /// 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) /// [ViewVariables] public long LastQueueCycle; /// /// Similar to . 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. /// [ViewVariables] public long LastSlowQueueCycle; /// /// 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. /// [ViewVariables] public float MoleDelta; /// /// Number of moles that are going to be transferred in this direction during final equalization. /// [ViewVariables] public float TransferDirectionEast; /// /// Number of moles that are going to be transferred in this direction during final equalization. /// [ViewVariables] public float TransferDirectionWest; /// /// Number of moles that are going to be transferred in this direction during final equalization. /// [ViewVariables] public float TransferDirectionNorth; /// /// Number of moles that are going to be transferred in this direction during final equalization. /// [ViewVariables] public float TransferDirectionSouth; /// /// 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. /// /// 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 , or /// /// determines how many moles to move in each direction using , /// setting the TransferDirection fields accordingly based on the ratio obtained /// from . /// [ViewVariables] public float CurrentTransferAmount; /// /// A pointer from the current tile to the direction in which air is being transferred the most. /// [ViewVariables] public AtmosDirection CurrentTransferDirection; /// /// Marks this tile as being equalized using the O(n log n) algorithm. /// [ViewVariables] public bool FastDone; /// /// Gets or sets the TransferDirection in the given direction. /// /// /// Thrown when an invalid direction is given /// (a non-cardinal direction) 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 { 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)); } } } /// /// Gets or sets the TransferDirection by index. /// /// The index of the direction public float this[int index] { get => this[(AtmosDirection) (1 << index)]; set => this[(AtmosDirection) (1 << index)] = value; } }