diff --git a/Content.Server/Atmos/Components/AirtightComponent.cs b/Content.Server/Atmos/Components/AirtightComponent.cs index ca107eafbe8..69488a71307 100644 --- a/Content.Server/Atmos/Components/AirtightComponent.cs +++ b/Content.Server/Atmos/Components/AirtightComponent.cs @@ -9,27 +9,53 @@ public sealed partial class AirtightComponent : Component { public (EntityUid Grid, Vector2i Tile) LastPosition { get; set; } + /// + /// The directions in which this entity should block airflow, relative to its own reference frame. + /// [DataField("airBlockedDirection", customTypeSerializer: typeof(FlagSerializer))] public int InitialAirBlockedDirection { get; set; } = (int) AtmosDirection.All; + /// + /// The directions in which the entity is currently blocking airflow, relative to the grid that the entity is on. + /// I.e., this is a variant of that takes into account the entity's + /// current rotation. + /// [ViewVariables] public int CurrentAirBlockedDirection; - [DataField("airBlocked")] + /// + /// Whether the airtight entity is currently blocking airflow. + /// + [DataField] public bool AirBlocked { get; set; } = true; - [DataField("fixVacuum")] + /// + /// If true, entities on this tile will attempt to draw air from surrounding tiles when they become unblocked + /// and currently have no air. This is generally only required when is + /// true, or if the entity is likely to occupy the same tile as another no-air airtight entity. + /// + [DataField] public bool FixVacuum { get; set; } = true; + // I think fixvacuum exists to ensure that repeatedly closing/opening air-blocking doors doesn't end up + // depressurizing a room. However it can also effectively be used as a means of generating gasses for free + // TODO ATMOS Mass conservation. Make it actually push/pull air from adjacent tiles instead of destroying & creating, + + // TODO ATMOS Do we need these two fields? [DataField("rotateAirBlocked")] public bool RotateAirBlocked { get; set; } = true; + // TODO ATMOS remove this? What is this even for?? [DataField("fixAirBlockedDirectionInitialize")] public bool FixAirBlockedDirectionInitialize { get; set; } = true; - [DataField("noAirWhenFullyAirBlocked")] + /// + /// If true, then the tile that this entity is on will have no air at all if all directions are blocked. + /// + [DataField] public bool NoAirWhenFullyAirBlocked { get; set; } = true; + /// [Access(Other = AccessPermissions.ReadWriteExecute)] public AtmosDirection AirBlockedDirection => (AtmosDirection)CurrentAirBlockedDirection; } diff --git a/Content.Server/Atmos/EntitySystems/AirtightSystem.cs b/Content.Server/Atmos/EntitySystems/AirtightSystem.cs index 548d6a36926..152fba8fc4d 100644 --- a/Content.Server/Atmos/EntitySystems/AirtightSystem.cs +++ b/Content.Server/Atmos/EntitySystems/AirtightSystem.cs @@ -85,8 +85,6 @@ private void OnAirtightMoved(Entity airtight, ref MoveEvent e private bool AirtightMove(Entity 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; diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.GridAtmosphere.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.GridAtmosphere.cs index d43cc81b0f8..beddef4be7e 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.GridAtmosphere.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.GridAtmosphere.cs @@ -399,10 +399,7 @@ private void GridIsHotspotActive(EntityUid uid, GridAtmosphereComponent componen args.Handled = true; } - private void GridFixTileVacuum( - Entity ent, - TileAtmosphere tile, - float volume) + private void GridFixTileVacuum(TileAtmosphere tile) { DebugTools.AssertNotNull(tile.Air); DebugTools.Assert(tile.Air?.Immutable == false ); @@ -416,6 +413,9 @@ private void GridFixTileVacuum( count++; } + if (count == 0) + return; + var ratio = 1f / count; var totalTemperature = 0f; diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Processing.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Processing.cs index 1f3ca2145b9..eba398c1821 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Processing.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Processing.cs @@ -272,7 +272,7 @@ private void UpdateTileAir( tile.Air = new GasMixture(volume){Temperature = Atmospherics.T20C}; if (data.FixVacuum) - GridFixTileVacuum(ent, tile, volume); + GridFixTileVacuum(tile); } private void QueueRunTiles( diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Utils.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Utils.cs index 9b0d0d9670d..67c6d5998dd 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Utils.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Utils.cs @@ -78,12 +78,13 @@ private AirtightData GetAirtightData(EntityUid uid, MapGridComponent grid, Vecto if (!_airtightQuery.TryGetComponent(ent, out var airtight)) continue; + fixVacuum |= airtight.FixVacuum; + if(!airtight.AirBlocked) continue; blockedDirs |= airtight.AirBlockedDirection; noAirWhenBlocked |= airtight.NoAirWhenFullyAirBlocked; - fixVacuum |= airtight.FixVacuum; if (blockedDirs == AtmosDirection.All && noAirWhenBlocked && fixVacuum) break; diff --git a/Content.Server/Atmos/GasMixture.cs b/Content.Server/Atmos/GasMixture.cs index 77fd7018333..3d73a4d0b16 100644 --- a/Content.Server/Atmos/GasMixture.cs +++ b/Content.Server/Atmos/GasMixture.cs @@ -62,9 +62,9 @@ public float Temperature get => _temperature; set { - DebugTools.Assert(!float.IsNaN(_temperature)); - if (Immutable) return; - _temperature = MathF.Min(MathF.Max(value, Atmospherics.TCMB), Atmospherics.Tmax); + DebugTools.Assert(!float.IsNaN(value)); + if (!Immutable) + _temperature = MathF.Min(MathF.Max(value, Atmospherics.TCMB), Atmospherics.Tmax); } } @@ -91,6 +91,7 @@ public GasMixture(float[] moles, float temp, float volume = Atmospherics.CellVol if (volume < 0) volume = 0; + DebugTools.Assert(!float.IsNaN(temp)); _temperature = temp; Moles = moles; Volume = volume; diff --git a/Content.Server/Atmos/TileAtmosphere.cs b/Content.Server/Atmos/TileAtmosphere.cs index 0dd35a29e76..0026dbbf4f0 100644 --- a/Content.Server/Atmos/TileAtmosphere.cs +++ b/Content.Server/Atmos/TileAtmosphere.cs @@ -28,6 +28,9 @@ public sealed class TileAtmosphere : IGasMixtureHolder [ViewVariables] public TileAtmosphere? PressureSpecificTarget { get; set; } + /// + /// This is either the pressure difference, or the quantity of moles transferred if monstermos is enabled. + /// [ViewVariables] public float PressureDifference { get; set; } diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml index 4bc43b5559e..476e715175e 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml @@ -104,7 +104,6 @@ - key: enum.WiresUiKey.Key type: WiresBoundUserInterface - type: Airtight - fixVacuum: true noAirWhenFullyAirBlocked: false - type: RadiationBlocker resistance: 3 diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml index d799558df75..a26226c9578 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml @@ -1,105 +1,104 @@ -- type: entity - id: HighSecDoor - parent: BaseStructure - name: high security door - description: Keeps the bad out and keeps the good in. - placement: - mode: SnapgridCenter - components: - - type: InteractionOutline - - type: Sprite - sprite: Structures/Doors/Airlocks/highsec/highsec.rsi - layers: - - state: closed - map: ["enum.DoorVisualLayers.Base"] - - state: closed_unlit - shader: unshaded - map: ["enum.DoorVisualLayers.BaseUnlit"] - - state: welded - map: ["enum.WeldableLayers.BaseWelded"] - - state: bolted_unlit - shader: unshaded - map: ["enum.DoorVisualLayers.BaseBolted"] - - state: emergency_unlit - map: ["enum.DoorVisualLayers.BaseEmergencyAccess"] - shader: unshaded - - state: panel_open - map: ["enum.WiresVisualLayers.MaintenancePanel"] - - type: AnimationPlayer - - type: Physics - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeAabb - bounds: "-0.49,-0.49,0.49,0.49" # don't want this colliding with walls or they won't close - density: 100 - mask: - - FullTileMask - layer: - - WallLayer - - type: ContainerFill - containers: - board: [ DoorElectronics ] - - type: ContainerContainer - containers: - board: !type:Container - - type: Door - crushDamage: - types: - Blunt: 50 - openSound: - path: /Audio/Machines/airlock_open.ogg - closeSound: - path: /Audio/Machines/airlock_close.ogg - denySound: - path: /Audio/Machines/airlock_deny.ogg - - type: Weldable - time: 10 - - type: Airlock - - type: NavMapDoor - - type: DoorBolt - - type: AccessReader - - type: Appearance - - type: WiresVisuals - - type: ApcPowerReceiver - powerLoad: 20 - - type: ExtensionCableReceiver - - type: Electrified - enabled: false - usesApcPower: true - - type: WiresPanel - - type: WiresPanelSecurity - securityLevel: maxSecurity - - type: Wires - boardName: wires-board-name-highsec - layoutId: HighSec - alwaysRandomize: true - - type: UserInterface - interfaces: - - key: enum.WiresUiKey.Key - type: WiresBoundUserInterface - - type: Airtight - fixVacuum: true - - type: Occluder - - type: Damageable - damageContainer: StructuralInorganic - damageModifierSet: StrongMetallic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 1500 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - type: IconSmooth - key: walls - mode: NoSprite - - type: Construction - graph: Airlock - node: highSecDoor - - type: Tag - tags: - - HighSecDoor - # This tag is used to nagivate the Airlock construction graph. It's needed because this construction graph is shared between Airlock, AirlockGlass, and HighSecDoor +- type: entity + id: HighSecDoor + parent: BaseStructure + name: high security door + description: Keeps the bad out and keeps the good in. + placement: + mode: SnapgridCenter + components: + - type: InteractionOutline + - type: Sprite + sprite: Structures/Doors/Airlocks/highsec/highsec.rsi + layers: + - state: closed + map: ["enum.DoorVisualLayers.Base"] + - state: closed_unlit + shader: unshaded + map: ["enum.DoorVisualLayers.BaseUnlit"] + - state: welded + map: ["enum.WeldableLayers.BaseWelded"] + - state: bolted_unlit + shader: unshaded + map: ["enum.DoorVisualLayers.BaseBolted"] + - state: emergency_unlit + map: ["enum.DoorVisualLayers.BaseEmergencyAccess"] + shader: unshaded + - state: panel_open + map: ["enum.WiresVisualLayers.MaintenancePanel"] + - type: AnimationPlayer + - type: Physics + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.49,-0.49,0.49,0.49" # don't want this colliding with walls or they won't close + density: 100 + mask: + - FullTileMask + layer: + - WallLayer + - type: ContainerFill + containers: + board: [ DoorElectronics ] + - type: ContainerContainer + containers: + board: !type:Container + - type: Door + crushDamage: + types: + Blunt: 50 + openSound: + path: /Audio/Machines/airlock_open.ogg + closeSound: + path: /Audio/Machines/airlock_close.ogg + denySound: + path: /Audio/Machines/airlock_deny.ogg + - type: Weldable + time: 10 + - type: Airlock + - type: NavMapDoor + - type: DoorBolt + - type: AccessReader + - type: Appearance + - type: WiresVisuals + - type: ApcPowerReceiver + powerLoad: 20 + - type: ExtensionCableReceiver + - type: Electrified + enabled: false + usesApcPower: true + - type: WiresPanel + - type: WiresPanelSecurity + securityLevel: maxSecurity + - type: Wires + boardName: wires-board-name-highsec + layoutId: HighSec + alwaysRandomize: true + - type: UserInterface + interfaces: + - key: enum.WiresUiKey.Key + type: WiresBoundUserInterface + - type: Airtight + - type: Occluder + - type: Damageable + damageContainer: StructuralInorganic + damageModifierSet: StrongMetallic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 1500 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - type: IconSmooth + key: walls + mode: NoSprite + - type: Construction + graph: Airlock + node: highSecDoor + - type: Tag + tags: + - HighSecDoor + # This tag is used to nagivate the Airlock construction graph. It's needed because this construction graph is shared between Airlock, AirlockGlass, and HighSecDoor diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/shuttle.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/shuttle.yml index 21d485be0c8..9771f633888 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/shuttle.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/shuttle.yml @@ -57,7 +57,6 @@ denySound: path: /Audio/Machines/airlock_deny.ogg - type: Airtight - fixVacuum: true noAirWhenFullyAirBlocked: false - type: Tag tags: diff --git a/Resources/Prototypes/Entities/Structures/Doors/Firelocks/firelock.yml b/Resources/Prototypes/Entities/Structures/Doors/Firelocks/firelock.yml index dccc76e96c1..e677ef185be 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Firelocks/firelock.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Firelocks/firelock.yml @@ -93,7 +93,6 @@ - type: Physics canCollide: false - type: Airtight - fixVacuum: true airBlocked: false noAirWhenFullyAirBlocked: true - type: RadiationBlocker @@ -158,7 +157,6 @@ sprite: Structures/Doors/edge_door_hazard.rsi snapCardinals: false - type: Airtight - fixVacuum: true airBlocked: false noAirWhenFullyAirBlocked: false airBlockedDirection: diff --git a/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml b/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml index 644976eb9c4..3709b739a3e 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml @@ -40,7 +40,6 @@ path: /Audio/Effects/stonedoor_openclose.ogg - type: Appearance - type: Airtight - fixVacuum: true - type: Damageable damageContainer: Inorganic damageModifierSet: Metallic diff --git a/Resources/Prototypes/Entities/Structures/Doors/SecretDoor/secret_door.yml b/Resources/Prototypes/Entities/Structures/Doors/SecretDoor/secret_door.yml index 2c54d3cd418..d6c087af0a5 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/SecretDoor/secret_door.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/SecretDoor/secret_door.yml @@ -38,7 +38,6 @@ - type: Weldable time: 2 - type: Airtight - fixVacuum: true - type: Damageable damageContainer: Inorganic damageModifierSet: Metallic diff --git a/Resources/Prototypes/Entities/Structures/Doors/Shutter/shutters.yml b/Resources/Prototypes/Entities/Structures/Doors/Shutter/shutters.yml index 7d3af93a64d..55010eea512 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Shutter/shutters.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Shutter/shutters.yml @@ -59,7 +59,6 @@ - key: enum.WiresUiKey.Key type: WiresBoundUserInterface - type: Airtight - fixVacuum: true - type: RadiationBlocker resistance: 2 - type: Damageable diff --git a/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml b/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml index 56167c178e2..d03765d4fc9 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml @@ -130,7 +130,6 @@ - type: Appearance - type: WiresVisuals - type: Airtight - fixVacuum: true noAirWhenFullyAirBlocked: false airBlockedDirection: - South diff --git a/Resources/Prototypes/Entities/Structures/plastic_flaps.yml b/Resources/Prototypes/Entities/Structures/plastic_flaps.yml index 8c53daf3b60..bf49eb1be35 100644 --- a/Resources/Prototypes/Entities/Structures/plastic_flaps.yml +++ b/Resources/Prototypes/Entities/Structures/plastic_flaps.yml @@ -83,7 +83,6 @@ - !type:DoActsBehavior acts: ["Destruction"] - type: Airtight - fixVacuum: true - type: entity id: PlasticFlapsAirtightOpaque @@ -101,4 +100,3 @@ - !type:DoActsBehavior acts: ["Destruction"] - type: Airtight - fixVacuum: true