Skip to content

Commit

Permalink
Mirror 26441: Fix atmos NaN error (#449)
Browse files Browse the repository at this point in the history
## Mirror of PR #26441: [Fix atmos NaN
error](space-wizards/space-station-14#26441)
from <img src="https://avatars.githubusercontent.com/u/10567778?v=4"
alt="space-wizards" width="22"/>
[space-wizards](https://github.com/space-wizards)/[space-station-14](https://github.com/space-wizards/space-station-14)

###### `fdb4a61487db9fc67714c913832427063abdea42`

PR opened by <img
src="https://avatars.githubusercontent.com/u/60421075?v=4"
width="16"/><a href="https://github.com/ElectroJr"> ElectroJr</a> at
2024-03-26 04:27:08 UTC - merged at 2024-03-26 04:44:56 UTC

---

PR changed 16 files with 43 additions and 25 deletions.

The PR had the following labels:
- Status: Needs Review


---

<details open="true"><summary><h1>Original Body</h1></summary>

> - Fixes a bug I introduced in #22521 that caused the temperature to be
set to `NaN`. I don't know for sure, but I assume this is causing the
current atmos issues
> - Fixes `FixVacuum` not working after #22521
> - Removes some redundant yaml that was setting FixVacuum to its
default value
> 
> 🆑
> - fix: Fixed an atmos bug, which was (probably) causing atmospherics
on the station to behave incorrectly.


</details>

Co-authored-by: SimpleStation14 <Unknown>
  • Loading branch information
SimpleStation14 committed Jun 13, 2024
1 parent 32394b0 commit 2138b8a
Show file tree
Hide file tree
Showing 16 changed files with 147 additions and 129 deletions.
32 changes: 29 additions & 3 deletions Content.Server/Atmos/Components/AirtightComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,53 @@ public sealed partial class AirtightComponent : Component
{
public (EntityUid Grid, Vector2i Tile) LastPosition { get; set; }

/// <summary>
/// The directions in which this entity should block airflow, relative to its own reference frame.
/// </summary>
[DataField("airBlockedDirection", customTypeSerializer: typeof(FlagSerializer<AtmosDirectionFlags>))]
public int InitialAirBlockedDirection { get; set; } = (int) AtmosDirection.All;

/// <summary>
/// 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 <see cref="InitialAirBlockedDirection"/> that takes into account the entity's
/// current rotation.
/// </summary>
[ViewVariables]
public int CurrentAirBlockedDirection;

[DataField("airBlocked")]
/// <summary>
/// Whether the airtight entity is currently blocking airflow.
/// </summary>
[DataField]
public bool AirBlocked { get; set; } = true;

[DataField("fixVacuum")]
/// <summary>
/// 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 <see cref="NoAirWhenFullyAirBlocked"/> is
/// true, or if the entity is likely to occupy the same tile as another no-air airtight entity.
/// </summary>
[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")]
/// <summary>
/// If true, then the tile that this entity is on will have no air at all if all directions are blocked.
/// </summary>
[DataField]
public bool NoAirWhenFullyAirBlocked { get; set; } = true;

/// <inheritdoc cref="CurrentAirBlockedDirection"/>
[Access(Other = AccessPermissions.ReadWriteExecute)]
public AtmosDirection AirBlockedDirection => (AtmosDirection)CurrentAirBlockedDirection;
}
Expand Down
2 changes: 0 additions & 2 deletions Content.Server/Atmos/EntitySystems/AirtightSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,6 @@ private void OnAirtightMoved(Entity<AirtightComponent> airtight, ref MoveEvent e
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,10 +399,7 @@ private void GridIsHotspotActive(EntityUid uid, GridAtmosphereComponent componen
args.Handled = true;
}

private void GridFixTileVacuum(
Entity<GridAtmosphereComponent, GasTileOverlayComponent, MapGridComponent, TransformComponent> ent,
TileAtmosphere tile,
float volume)
private void GridFixTileVacuum(TileAtmosphere tile)
{
DebugTools.AssertNotNull(tile.Air);
DebugTools.Assert(tile.Air?.Immutable == false );
Expand All @@ -416,6 +413,9 @@ private void GridFixTileVacuum(
count++;
}

if (count == 0)
return;

var ratio = 1f / count;
var totalTemperature = 0f;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
3 changes: 2 additions & 1 deletion Content.Server/Atmos/EntitySystems/AtmosphereSystem.Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
7 changes: 4 additions & 3 deletions Content.Server/Atmos/GasMixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand All @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions Content.Server/Atmos/TileAtmosphere.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ public sealed class TileAtmosphere : IGasMixtureHolder
[ViewVariables]
public TileAtmosphere? PressureSpecificTarget { get; set; }

/// <summary>
/// This is either the pressure difference, or the quantity of moles transferred if monstermos is enabled.
/// </summary>
[ViewVariables]
public float PressureDifference { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@
- key: enum.WiresUiKey.Key
type: WiresBoundUserInterface
- type: Airtight
fixVacuum: true
noAirWhenFullyAirBlocked: false
- type: RadiationBlocker
resistance: 3
Expand Down
209 changes: 104 additions & 105 deletions Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
denySound:
path: /Audio/Machines/airlock_deny.ogg
- type: Airtight
fixVacuum: true
noAirWhenFullyAirBlocked: false
- type: Tag
tags:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@
- type: Physics
canCollide: false
- type: Airtight
fixVacuum: true
airBlocked: false
noAirWhenFullyAirBlocked: true
- type: RadiationBlocker
Expand Down Expand Up @@ -158,7 +157,6 @@
sprite: Structures/Doors/edge_door_hazard.rsi
snapCardinals: false
- type: Airtight
fixVacuum: true
airBlocked: false
noAirWhenFullyAirBlocked: false
airBlockedDirection:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
path: /Audio/Effects/stonedoor_openclose.ogg
- type: Appearance
- type: Airtight
fixVacuum: true
- type: Damageable
damageContainer: Inorganic
damageModifierSet: Metallic
Expand Down
Loading

0 comments on commit 2138b8a

Please sign in to comment.