using System.Numerics; using Content.Server.Atmos.Monitor.Components; using Content.Shared.Atmos; using Robust.Shared.Console; using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Prototypes; using Robust.Shared.Utility; namespace Content.IntegrationTests.Tests.Atmos; /// /// Test for determining that an AtmosMonitoringComponent/System correctly references /// the GasMixture of the tile it is on if the tile's GasMixture ever changes. /// [TestOf(typeof(Atmospherics))] public sealed class AtmosMonitoringTest : AtmosTest { // We can just reuse the dP test, I just want a grid. protected override ResPath? TestMapPath => new("Maps/Test/Atmospherics/DeltaPressure/deltapressuretest.yml"); private readonly EntProtoId _airSensorProto = new("AirSensor"); private readonly EntProtoId _wallProto = new("WallSolid"); /// /// Tests if the monitor properly nulls out its reference to the tile mixture /// when a wall is placed on top of it, and restores the reference when the wall is removed. /// [Test] public async Task NullOutTileAtmosphereGasMixture() { // run an atmos update to initialize everything For Real surely SAtmos.RunProcessingFull(ProcessEnt, MapData.Grid.Owner, SAtmos.AtmosTickRate); var gridNetEnt = SEntMan.GetNetEntity(RelevantAtmos.Owner); TargetCoords = new NetCoordinates(gridNetEnt, Vector2.Zero); var netEnt = await Spawn(_airSensorProto); var airSensorUid = SEntMan.GetEntity(netEnt); Transform.TryGetGridTilePosition(airSensorUid, out var vec); // run another one to ensure that the ref to the GasMixture was picked up SAtmos.RunProcessingFull(ProcessEnt, MapData.Grid.Owner, SAtmos.AtmosTickRate); // should be in the middle Assert.That(vec, Is.EqualTo(Vector2i.Zero), "Air sensor not in expected position on grid (0, 0)"); var atmosMonitor = SEntMan.GetComponent(airSensorUid); var tileMixture = SAtmos.GetTileMixture(airSensorUid); Assert.That(tileMixture, Is.SameAs(atmosMonitor.TileGas), "Atmos monitor's TileGas does not match actual tile mixture after spawn."); // ok now spawn a wall or something on top of it var wall = await Spawn(_wallProto); var wallUid = SEntMan.GetEntity(wall); // ensure that atmospherics registers the change - the gas mixture should no longer exist SAtmos.RunProcessingFull(ProcessEnt, MapData.Grid.Owner, SAtmos.AtmosTickRate); // the monitor's ref to the gas should be null now Assert.That(atmosMonitor.TileGas, Is.Null, "Atmos monitor's TileGas is not null after wall placed on top. Possible dead reference."); // the actual mixture on the tile should be null now too var nullTileMixture = SAtmos.GetTileMixture(airSensorUid); Assert.That(nullTileMixture, Is.Null, "Tile mixture is not null after wall placed on top."); // ok now delete the wall await Delete(wallUid); // ensure that atmospherics registers the change - the gas mixture should be back SAtmos.RunProcessingFull(ProcessEnt, MapData.Grid.Owner, SAtmos.AtmosTickRate); // gas mixture should now exist again var newTileMixture = SAtmos.GetTileMixture(airSensorUid); Assert.That(newTileMixture, Is.Not.Null, "Tile mixture is null after wall removed."); // monitor's ref to the gas should be back too Assert.That(atmosMonitor.TileGas, Is.SameAs(newTileMixture), "Atmos monitor's TileGas does not match actual tile mixture after wall removed."); } /// /// Tests if the monitor properly updates its reference to the tile mixture /// when the FixGridAtmos command is called. /// [Test] public async Task FixGridAtmosReplaceMixtureOnTileChange() { // run an atmos update to initialize everything For Real surely SAtmos.RunProcessingFull(ProcessEnt, MapData.Grid.Owner, SAtmos.AtmosTickRate); var gridNetEnt = SEntMan.GetNetEntity(RelevantAtmos.Owner); TargetCoords = new NetCoordinates(gridNetEnt, Vector2.Zero); var netEnt = await Spawn(_airSensorProto); var airSensorUid = SEntMan.GetEntity(netEnt); Transform.TryGetGridTilePosition(airSensorUid, out var vec); // run another one to ensure that the ref to the GasMixture was picked up SAtmos.RunProcessingFull(ProcessEnt, MapData.Grid.Owner, SAtmos.AtmosTickRate); // should be in the middle Assert.That(vec, Is.EqualTo(Vector2i.Zero), "Air sensor not in expected position on grid (0, 0)"); var atmosMonitor = SEntMan.GetComponent(airSensorUid); var tileMixture = SAtmos.GetTileMixture(airSensorUid); Assert.That(tileMixture, Is.SameAs(atmosMonitor.TileGas), "Atmos monitor's TileGas does not match actual tile mixture after spawn."); SAtmos.RebuildGridAtmosphere((ProcessEnt.Owner, ProcessEnt.Comp1, ProcessEnt.Comp3)); // EXTREMELY IMPORTANT: The reference to the tile mixture on the tile should be completely different. var newTileMixture = SAtmos.GetTileMixture(airSensorUid); Assert.That(newTileMixture, Is.Not.SameAs(tileMixture), "Tile mixture is the same instance after fixgridatmos was ran. It should be a new instance."); // The monitor's ref to the tile mixture should have updated too. Assert.That(atmosMonitor.TileGas, Is.SameAs(newTileMixture), "Atmos monitor's TileGas does not match actual tile mixture after fixgridatmos was ran."); } }