private void OnDeviceUpdated(EntityUid uid, PortableScrubberComponent component, AtmosDeviceUpdateEvent args)
        {
            if (!TryComp(uid, out AtmosDeviceComponent? device))
            {
                return;
            }

            var timeDelta = (float)(_gameTiming.CurTime - device.LastProcess).TotalSeconds;

            if (!component.Enabled)
            {
                return;
            }

            /// If we are on top of a connector port, empty into it.
            if (TryComp <NodeContainerComponent>(uid, out var nodeContainer) &&
                nodeContainer.TryGetNode(component.PortName, out PortablePipeNode? portableNode) &&
                portableNode.ConnectionsEnabled)
            {
                _atmosphereSystem.React(component.Air, portableNode);
                if (portableNode.NodeGroup is PipeNet {
                    NodeCount : > 1
                } net)
                {
                    _canisterSystem.MixContainerWithPipeNet(component.Air, net.Air);
                }
            }

            if (component.Full)
            {
                UpdateAppearance(uid, true, false);
                return;
            }

            var xform = Transform(uid);

            if (xform.GridUid == null)
            {
                return;
            }

            var position = _transformSystem.GetGridOrMapTilePosition(uid, xform);

            var environment = _atmosphereSystem.GetTileMixture(xform.GridUid, xform.MapUid, position, true);

            var running = Scrub(timeDelta, component, environment);

            UpdateAppearance(uid, false, running);
            /// We scrub once to see if we can and set the animation
            if (!running)
            {
                return;
            }
            /// widenet
            foreach (var adjacent in _atmosphereSystem.GetAdjacentTileMixtures(xform.GridUid.Value, position, false, true))
            {
                Scrub(timeDelta, component, environment);
            }
        }
        private void OnCanisterUpdated(EntityUid uid, GasCanisterComponent canister, AtmosDeviceUpdateEvent args)
        {
            _atmosphereSystem.React(canister.Air, canister);

            if (!EntityManager.TryGetComponent(uid, out NodeContainerComponent? nodeContainer) ||
                !EntityManager.TryGetComponent(uid, out AppearanceComponent? appearance))
            {
                return;
            }

            if (!nodeContainer.TryGetNode(canister.PortName, out PortablePipeNode? portNode))
            {
                return;
            }

            if (portNode.NodeGroup is PipeNet {
                NodeCount: > 1
            } net)
            {
                MixContainerWithPipeNet(canister.Air, net.Air);
            }

            ContainerManagerComponent?containerManager = null;

            // Release valve is open, release gas.
            if (canister.ReleaseValve)
            {
                if (!EntityManager.TryGetComponent(uid, out containerManager) ||
                    !containerManager.TryGetContainer(canister.ContainerName, out var container))
                {
                    return;
                }

                if (container.ContainedEntities.Count > 0)
                {
                    var gasTank = EntityManager.GetComponent <GasTankComponent>(container.ContainedEntities[0]);
                    _atmosphereSystem.ReleaseGasTo(canister.Air, gasTank.Air, canister.ReleasePressure);
                }
                else
                {
                    var environment = _atmosphereSystem.GetContainingMixture(uid, false, true);
                    _atmosphereSystem.ReleaseGasTo(canister.Air, environment, canister.ReleasePressure);
                }
            }

            // If last pressure is very close to the current pressure, do nothing.
            if (MathHelper.CloseToPercent(canister.Air.Pressure, canister.LastPressure))
            {
                return;
            }

            DirtyUI(uid, canister, nodeContainer, containerManager);

            canister.LastPressure = canister.Air.Pressure;

            if (canister.Air.Pressure < 10)
            {
                appearance.SetData(GasCanisterVisuals.PressureState, 0);
            }
            else if (canister.Air.Pressure < Atmospherics.OneAtmosphere)
            {
                appearance.SetData(GasCanisterVisuals.PressureState, 1);
            }
            else if (canister.Air.Pressure < (15 * Atmospherics.OneAtmosphere))
            {
                appearance.SetData(GasCanisterVisuals.PressureState, 2);
            }
            else
            {
                appearance.SetData(GasCanisterVisuals.PressureState, 3);
            }
        }
        private void OnCanisterUpdated(EntityUid uid, GasCanisterComponent canister, AtmosDeviceUpdateEvent args)
        {
            if (!ComponentManager.TryGetComponent(uid, out NodeContainerComponent? nodeContainer) ||
                !ComponentManager.TryGetComponent(uid, out AppearanceComponent? appearance))
            {
                return;
            }

            if (!nodeContainer.TryGetNode(canister.PortName, out PortablePipeNode? portNode))
            {
                return;
            }

            _atmosphereSystem.React(canister.Air, portNode);

            if (portNode.NodeGroup is PipeNet {
                NodeCount: > 1
            } net)
            {
                var buffer = new GasMixture(net.Air.Volume + canister.Air.Volume);

                _atmosphereSystem.Merge(buffer, net.Air);
                _atmosphereSystem.Merge(buffer, canister.Air);

                net.Air.Clear();
                _atmosphereSystem.Merge(net.Air, buffer);
                net.Air.Multiply(net.Air.Volume / buffer.Volume);

                canister.Air.Clear();
                _atmosphereSystem.Merge(canister.Air, buffer);
                canister.Air.Multiply(canister.Air.Volume / buffer.Volume);
            }

            // Release valve is open, release gas.
            if (canister.ReleaseValve)
            {
                if (!ComponentManager.TryGetComponent(uid, out ContainerManagerComponent? containerManager) ||
                    !containerManager.TryGetContainer(canister.ContainerName, out var container))
                {
                    return;
                }

                if (container.ContainedEntities.Count > 0)
                {
                    var gasTank = container.ContainedEntities[0].GetComponent <GasTankComponent>();
                    _atmosphereSystem.ReleaseGasTo(canister.Air, gasTank.Air, canister.ReleasePressure);
                }
                else
                {
                    var environment = _atmosphereSystem.GetTileMixture(canister.Owner.Transform.Coordinates, true);
                    _atmosphereSystem.ReleaseGasTo(canister.Air, environment, canister.ReleasePressure);
                }
            }

            DirtyUI(uid);

            // If last pressure is very close to the current pressure, do nothing.
            if (MathHelper.CloseTo(canister.Air.Pressure, canister.LastPressure))
            {
                return;
            }

            canister.LastPressure = canister.Air.Pressure;

            if (canister.Air.Pressure < 10)
            {
                appearance.SetData(GasCanisterVisuals.PressureState, 0);
            }
            else if (canister.Air.Pressure < Atmospherics.OneAtmosphere)
            {
                appearance.SetData(GasCanisterVisuals.PressureState, 1);
            }
            else if (canister.Air.Pressure < (15 * Atmospherics.OneAtmosphere))
            {
                appearance.SetData(GasCanisterVisuals.PressureState, 2);
            }
            else
            {
                appearance.SetData(GasCanisterVisuals.PressureState, 3);
            }
        }