SubscribeLocalEvent<AirFilterComponent, AtmosDeviceUpdateEvent>(OnFilterUpdate);
}
- private void OnIntakeUpdate(EntityUid uid, AirIntakeComponent intake, AtmosDeviceUpdateEvent args)
+ private void OnIntakeUpdate(EntityUid uid, AirIntakeComponent intake, ref AtmosDeviceUpdateEvent args)
{
if (!GetAir(uid, out var air))
return;
_atmosphere.Merge(air, environment.Remove(transferMoles));
}
- private void OnFilterUpdate(EntityUid uid, AirFilterComponent filter, AtmosDeviceUpdateEvent args)
+ private void OnFilterUpdate(EntityUid uid, AirFilterComponent filter, ref AtmosDeviceUpdateEvent args)
{
if (!GetAir(uid, out var air))
return;
var time = _gameTiming.CurTime;
var number = 0;
+ var ev = new AtmosDeviceUpdateEvent(RealAtmosTime());
while (atmosphere.CurrentRunAtmosDevices.TryDequeue(out var device))
{
- RaiseLocalEvent(device, new AtmosDeviceUpdateEvent(RealAtmosTime()));
+ RaiseLocalEvent(device, ref ev);
device.Comp.LastProcess = time;
if (number++ < LagCheckIterations)
tileLoss = val;
}
- private void OnAtmosUpdate(EntityUid uid, HeatExchangerComponent comp, AtmosDeviceUpdateEvent args)
+ private void OnAtmosUpdate(EntityUid uid, HeatExchangerComponent comp, ref AtmosDeviceUpdateEvent args)
{
if (!TryComp(uid, out NodeContainerComponent? nodeContainer)
|| !TryComp(uid, out AtmosDeviceComponent? device)
_ui.TryCloseAll(uid, SharedAirAlarmInterfaceKey.Key);
}
- private void OnAtmosUpdate(EntityUid uid, AirAlarmComponent alarm, AtmosDeviceUpdateEvent args)
+ private void OnAtmosUpdate(EntityUid uid, AirAlarmComponent alarm, ref AtmosDeviceUpdateEvent args)
{
alarm.CurrentModeUpdater?.Update(uid);
}
SubscribeLocalEvent<AtmosMonitorComponent, AtmosDeviceEnabledEvent>(OnAtmosDeviceEnterAtmosphere);
}
- private void OnAtmosDeviceLeaveAtmosphere(EntityUid uid, AtmosMonitorComponent atmosMonitor, AtmosDeviceDisabledEvent args)
+ private void OnAtmosDeviceLeaveAtmosphere(EntityUid uid, AtmosMonitorComponent atmosMonitor, ref AtmosDeviceDisabledEvent args)
{
atmosMonitor.TileGas = null;
}
- private void OnAtmosDeviceEnterAtmosphere(EntityUid uid, AtmosMonitorComponent atmosMonitor, AtmosDeviceEnabledEvent args)
+ private void OnAtmosDeviceEnterAtmosphere(EntityUid uid, AtmosMonitorComponent atmosMonitor, ref AtmosDeviceEnabledEvent args)
{
atmosMonitor.TileGas = _atmosphereSystem.GetContainingMixture(uid, true);
}
}
}
- private void OnAtmosUpdate(EntityUid uid, AtmosMonitorComponent component, AtmosDeviceUpdateEvent args)
+ private void OnAtmosUpdate(EntityUid uid, AtmosMonitorComponent component, ref AtmosDeviceUpdateEvent args)
{
if (!this.IsPowered(uid, EntityManager))
return;
SubscribeLocalEvent<GasPassiveGateComponent, ExaminedEvent>(OnExamined);
}
- private void OnPassiveGateUpdated(EntityUid uid, GasPassiveGateComponent gate, AtmosDeviceUpdateEvent args)
+ private void OnPassiveGateUpdated(EntityUid uid, GasPassiveGateComponent gate, ref AtmosDeviceUpdateEvent args)
{
if (!EntityManager.TryGetComponent(uid, out NodeContainerComponent? nodeContainer))
return;
}
}
- private void OnPumpUpdated(EntityUid uid, GasPressurePumpComponent pump, AtmosDeviceUpdateEvent args)
+ private void OnPumpUpdated(EntityUid uid, GasPressurePumpComponent pump, ref AtmosDeviceUpdateEvent args)
{
if (!pump.Enabled
|| !EntityManager.TryGetComponent(uid, out NodeContainerComponent? nodeContainer)
}
}
- private void OnPumpLeaveAtmosphere(EntityUid uid, GasPressurePumpComponent pump, AtmosDeviceDisabledEvent args)
+ private void OnPumpLeaveAtmosphere(EntityUid uid, GasPressurePumpComponent pump, ref AtmosDeviceDisabledEvent args)
{
pump.Enabled = false;
UpdateAppearance(uid, pump);
SubscribeLocalEvent<GasRecyclerComponent, UpgradeExamineEvent>(OnUpgradeExamine);
}
- private void OnEnabled(EntityUid uid, GasRecyclerComponent comp, AtmosDeviceEnabledEvent args)
+ private void OnEnabled(EntityUid uid, GasRecyclerComponent comp, ref AtmosDeviceEnabledEvent args)
{
UpdateAppearance(uid, comp);
}
return alpha * (float)Math.Sqrt(inlet.Pressure - outlet.Pressure);
}
- private void OnDisabled(EntityUid uid, GasRecyclerComponent comp, AtmosDeviceDisabledEvent args)
+ private void OnDisabled(EntityUid uid, GasRecyclerComponent comp, ref AtmosDeviceDisabledEvent args)
{
comp.Reacting = false;
UpdateAppearance(uid, comp);
args.PushMarkup(str);
}
- private void OnVolumePumpUpdated(EntityUid uid, GasVolumePumpComponent pump, AtmosDeviceUpdateEvent args)
+ private void OnVolumePumpUpdated(EntityUid uid, GasVolumePumpComponent pump, ref AtmosDeviceUpdateEvent args)
{
if (!pump.Enabled
|| !TryComp(uid, out NodeContainerComponent? nodeContainer)
_ambientSoundSystem.SetAmbience(uid, removed.TotalMoles > 0f);
}
- private void OnVolumePumpLeaveAtmosphere(EntityUid uid, GasVolumePumpComponent pump, AtmosDeviceDisabledEvent args)
+ private void OnVolumePumpLeaveAtmosphere(EntityUid uid, GasVolumePumpComponent pump, ref AtmosDeviceDisabledEvent args)
{
pump.Enabled = false;
UpdateAppearance(uid, pump);
-namespace Content.Server.Atmos.Piping.Components
+using Content.Server.Atmos.Components;
+
+namespace Content.Server.Atmos.Piping.Components;
+
+/// <summary>
+/// Component for atmos devices which are updated in line with atmos, as part of a <see cref="GridAtmosphereComponent"/>
+/// </summary>
+[RegisterComponent]
+public sealed partial class AtmosDeviceComponent : Component
{
/// <summary>
- /// Adds itself to a <see cref="IAtmosphereComponent"/> to be updated by.
+ /// If true, this device must be anchored before it will receive any AtmosDeviceUpdateEvents.
/// </summary>
- [RegisterComponent]
- public sealed partial class AtmosDeviceComponent : Component
- {
- /// <summary>
- /// If true, this device must be anchored before it will receive any AtmosDeviceUpdateEvents.
- /// </summary>
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("requireAnchored")]
- public bool RequireAnchored { get; private set; } = true;
-
- /// <summary>
- /// If true, update even when there is no grid atmosphere. Normally, atmos devices only
- /// update when inside a grid atmosphere, because they work with gases in the environment
- /// and won't do anything useful if there is no environment. This is useful for devices
- /// like gas canisters whose contents can still react if the canister itself is not inside
- /// a grid atmosphere.
- /// </summary>
- [DataField("joinSystem")]
- public bool JoinSystem { get; private set; } = false;
-
- /// <summary>
- /// If non-null, the grid that this device is part of.
- /// </summary>
- public EntityUid? JoinedGrid { get; set; }
-
- /// <summary>
- /// Indicates that a device is not on a grid atmosphere but still being updated.
- /// </summary>
- [ViewVariables]
- public bool JoinedSystem { get; set; } = false;
-
- [ViewVariables]
- public TimeSpan LastProcess { get; set; } = TimeSpan.Zero;
- }
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField]
+ public bool RequireAnchored = true;
- public sealed class AtmosDeviceUpdateEvent : EntityEventArgs
+ /// <summary>
+ /// If true, update even when there is no grid atmosphere. Normally, atmos devices only
+ /// update when inside a grid atmosphere, because they work with gases in the environment
+ /// and won't do anything useful if there is no environment. This is useful for devices
+ /// like gas canisters whose contents can still react if the canister itself is not inside
+ /// a grid atmosphere.
+ /// </summary>
+ [DataField]
+ public bool JoinSystem = false;
+
+ /// <summary>
+ /// If non-null, the grid that this device is part of.
+ /// </summary>
+ [DataField]
+ public EntityUid? JoinedGrid = null;
+
+ /// <summary>
+ /// Indicates that a device is not on a grid atmosphere but still being updated.
+ /// </summary>
+ [ViewVariables]
+ public bool JoinedSystem = false;
+
+ [ViewVariables]
+ public TimeSpan LastProcess = TimeSpan.Zero;
+}
+
+/// <summary>
+/// Raised directed on an atmos device as part of the atmos update loop when the device should do processing.
+/// Use this for atmos devices instead of <see cref="EntitySystem.Update"/>.
+/// </summary>
+[ByRefEvent]
+public readonly struct AtmosDeviceUpdateEvent
+{
+ /// <summary>
+ /// Time elapsed since last update, in seconds. Multiply values used in the update handler
+ /// by this number to make them tickrate-invariant. Use this number instead of AtmosphereSystem.AtmosTime.
+ /// </summary>
+ public readonly float dt;
+
+ public AtmosDeviceUpdateEvent(float dt)
{
- /// <summary>
- /// Time elapsed since last update, in seconds. Multiply values used in the update handler
- /// by this number to make them tickrate-invariant. Use this number instead of AtmosphereSystem.AtmosTime.
- /// </summary>
- public float dt;
-
- public AtmosDeviceUpdateEvent(float dt)
- {
- this.dt = dt;
- }
+ this.dt = dt;
}
+}
- public sealed class AtmosDeviceEnabledEvent : EntityEventArgs
- {}
+/// <summary>
+/// Raised directed on an atmos device when it is enabled.
+/// </summary>
+[ByRefEvent]
+public record struct AtmosDeviceEnabledEvent;
- public sealed class AtmosDeviceDisabledEvent : EntityEventArgs
- {}
-}
+/// <summary>
+/// Raised directed on an atmos device when it is enabled.
+/// </summary>
+[ByRefEvent]
+public record struct AtmosDeviceDisabledEvent;
// Set of atmos devices that are off-grid but have JoinSystem set.
private readonly HashSet<Entity<AtmosDeviceComponent>> _joinedDevices = new();
+ private static AtmosDeviceDisabledEvent _disabledEv = new();
+ private static AtmosDeviceEnabledEvent _enabledEv = new();
+
public override void Initialize()
{
base.Initialize();
}
component.LastProcess = _gameTiming.CurTime;
- RaiseLocalEvent(ent, new AtmosDeviceEnabledEvent());
+ RaiseLocalEvent(ent, ref _enabledEv);
}
public void LeaveAtmosphere(Entity<AtmosDeviceComponent> ent)
}
component.LastProcess = TimeSpan.Zero;
- RaiseLocalEvent(ent, new AtmosDeviceDisabledEvent());
+ RaiseLocalEvent(ent, ref _disabledEv);
}
public void RejoinAtmosphere(Entity<AtmosDeviceComponent> component)
_timer -= _atmosphereSystem.AtmosTime;
var time = _gameTiming.CurTime;
+ var ev = new AtmosDeviceUpdateEvent(_atmosphereSystem.AtmosTime);
foreach (var device in _joinedDevices)
{
- RaiseLocalEvent(device, new AtmosDeviceUpdateEvent(_atmosphereSystem.AtmosTime));
+ RaiseLocalEvent(device, ref ev);
device.Comp.LastProcess = time;
}
}
UpdateAppearance(uid, filter);
}
- private void OnFilterUpdated(EntityUid uid, GasFilterComponent filter, AtmosDeviceUpdateEvent args)
+ private void OnFilterUpdated(EntityUid uid, GasFilterComponent filter, ref AtmosDeviceUpdateEvent args)
{
if (!filter.Enabled
|| !EntityManager.TryGetComponent(uid, out NodeContainerComponent? nodeContainer)
_atmosphereSystem.Merge(outletNode.Air, removed);
}
- private void OnFilterLeaveAtmosphere(EntityUid uid, GasFilterComponent filter, AtmosDeviceDisabledEvent args)
+ private void OnFilterLeaveAtmosphere(EntityUid uid, GasFilterComponent filter, ref AtmosDeviceDisabledEvent args)
{
filter.Enabled = false;
UpdateAppearance(uid, mixer);
}
- private void OnMixerUpdated(EntityUid uid, GasMixerComponent mixer, AtmosDeviceUpdateEvent args)
+ private void OnMixerUpdated(EntityUid uid, GasMixerComponent mixer, ref AtmosDeviceUpdateEvent args)
{
// TODO ATMOS: Cache total moles since it's expensive.
_ambientSoundSystem.SetAmbience(uid, true);
}
- private void OnMixerLeaveAtmosphere(EntityUid uid, GasMixerComponent mixer, AtmosDeviceDisabledEvent args)
+ private void OnMixerLeaveAtmosphere(EntityUid uid, GasMixerComponent mixer, ref AtmosDeviceDisabledEvent args)
{
mixer.Enabled = false;
UpdateAppearance(uid, comp);
}
- private void OnUpdate(EntityUid uid, PressureControlledValveComponent comp, AtmosDeviceUpdateEvent args)
+ private void OnUpdate(EntityUid uid, PressureControlledValveComponent comp, ref AtmosDeviceUpdateEvent args)
{
if (!EntityManager.TryGetComponent(uid, out NodeContainerComponent? nodeContainer)
|| !EntityManager.TryGetComponent(uid, out AtmosDeviceComponent? device)
_atmosphereSystem.Merge(outletNode.Air, removed);
}
- private void OnFilterLeaveAtmosphere(EntityUid uid, PressureControlledValveComponent comp, AtmosDeviceDisabledEvent args)
+ private void OnFilterLeaveAtmosphere(EntityUid uid, PressureControlledValveComponent comp, ref AtmosDeviceDisabledEvent args)
{
comp.Enabled = false;
UpdateAppearance(uid, comp);
private void OnCanisterChangeReleaseValve(EntityUid uid, GasCanisterComponent canister, GasCanisterChangeReleaseValveMessage args)
{
- var impact = LogImpact.High;
+ var impact = LogImpact.High;
// filling a jetpack with plasma is less important than filling a room with it
impact = canister.GasTankSlot.HasItem ? LogImpact.Medium : LogImpact.High;
DirtyUI(uid, canister);
}
- private void OnCanisterUpdated(EntityUid uid, GasCanisterComponent canister, AtmosDeviceUpdateEvent args)
+ private void OnCanisterUpdated(EntityUid uid, GasCanisterComponent canister, ref AtmosDeviceUpdateEvent args)
{
_atmos.React(canister.Air, canister);
{
MixContainerWithPipeNet(canister.Air, net.Air);
}
-
+
// Release valve is open, release gas.
if (canister.ReleaseValve)
{
}
// Preventing inserting a tank since if its locked you cant remove it.
- if (!CheckLocked(uid, component, args.User.Value))
+ if (!CheckLocked(uid, component, args.User.Value))
return;
-
+
args.Cancelled = true;
}
SubscribeLocalEvent<GasCondenserComponent, AtmosDeviceUpdateEvent>(OnCondenserUpdated);
}
- private void OnCondenserUpdated(EntityUid uid, GasCondenserComponent component, AtmosDeviceUpdateEvent args)
+ private void OnCondenserUpdated(EntityUid uid, GasCondenserComponent component, ref AtmosDeviceUpdateEvent args)
{
if (!(_power.IsPowered(uid) && TryComp<ApcPowerReceiverComponent>(uid, out var receiver))
|| !TryComp<NodeContainerComponent>(uid, out var nodeContainer)
_appearance.SetData(uid, OutletInjectorVisuals.Enabled, component.Enabled, appearance);
}
- private void OnOutletInjectorUpdated(EntityUid uid, GasOutletInjectorComponent injector, AtmosDeviceUpdateEvent args)
+ private void OnOutletInjectorUpdated(EntityUid uid, GasOutletInjectorComponent injector, ref AtmosDeviceUpdateEvent args)
{
if (!injector.Enabled)
return;
SubscribeLocalEvent<GasPassiveVentComponent, AtmosDeviceUpdateEvent>(OnPassiveVentUpdated);
}
- private void OnPassiveVentUpdated(EntityUid uid, GasPassiveVentComponent vent, AtmosDeviceUpdateEvent args)
+ private void OnPassiveVentUpdated(EntityUid uid, GasPassiveVentComponent vent, ref AtmosDeviceUpdateEvent args)
{
var environment = _atmosphereSystem.GetContainingMixture(uid, true, true);
SubscribeLocalEvent<GasThermoMachineComponent, DeviceNetworkPacketEvent>(OnPacketRecv);
}
- private void OnThermoMachineUpdated(EntityUid uid, GasThermoMachineComponent thermoMachine, AtmosDeviceUpdateEvent args)
+ private void OnThermoMachineUpdated(EntityUid uid, GasThermoMachineComponent thermoMachine, ref AtmosDeviceUpdateEvent args)
{
if (!(_power.IsPowered(uid) && TryComp<ApcPowerReceiverComponent>(uid, out var receiver))
|| !TryComp<NodeContainerComponent>(uid, out var nodeContainer)
SubscribeLocalEvent<GasVentPumpComponent, WeldableChangedEvent>(OnWeldChanged);
}
- private void OnGasVentPumpUpdated(EntityUid uid, GasVentPumpComponent vent, AtmosDeviceUpdateEvent args)
+ private void OnGasVentPumpUpdated(EntityUid uid, GasVentPumpComponent vent, ref AtmosDeviceUpdateEvent args)
{
//Bingo waz here
if (_weldable.IsWelded(uid))
}
}
- private void OnGasVentPumpLeaveAtmosphere(EntityUid uid, GasVentPumpComponent component, AtmosDeviceDisabledEvent args)
+ private void OnGasVentPumpLeaveAtmosphere(EntityUid uid, GasVentPumpComponent component, ref AtmosDeviceDisabledEvent args)
{
UpdateState(uid, component);
}
- private void OnGasVentPumpEnterAtmosphere(EntityUid uid, GasVentPumpComponent component, AtmosDeviceEnabledEvent args)
+ private void OnGasVentPumpEnterAtmosphere(EntityUid uid, GasVentPumpComponent component, ref AtmosDeviceEnabledEvent args)
{
UpdateState(uid, component);
}
SubscribeLocalEvent<GasVentScrubberComponent, WeldableChangedEvent>(OnWeldChanged);
}
- private void OnVentScrubberUpdated(EntityUid uid, GasVentScrubberComponent scrubber, AtmosDeviceUpdateEvent args)
+ private void OnVentScrubberUpdated(EntityUid uid, GasVentScrubberComponent scrubber, ref AtmosDeviceUpdateEvent args)
{
if (_weldable.IsWelded(uid))
{
return component.Air.Pressure >= component.MaxPressure;
}
- private void OnDeviceUpdated(EntityUid uid, PortableScrubberComponent component, AtmosDeviceUpdateEvent args)
+ private void OnDeviceUpdated(EntityUid uid, PortableScrubberComponent component, ref AtmosDeviceUpdateEvent args)
{
if (!TryComp(uid, out AtmosDeviceComponent? device))
return;
#region Atmos handler
- private void OnCryoPodUpdateAtmosphere(EntityUid uid, CryoPodComponent cryoPod, AtmosDeviceUpdateEvent args)
+ private void OnCryoPodUpdateAtmosphere(EntityUid uid, CryoPodComponent cryoPod, ref AtmosDeviceUpdateEvent args)
{
if (!TryComp(uid, out NodeContainerComponent? nodeContainer))
return;
}
}
- private void GeneratorUpdate(EntityUid uid, TegGeneratorComponent component, AtmosDeviceUpdateEvent args)
+ private void GeneratorUpdate(EntityUid uid, TegGeneratorComponent component, ref AtmosDeviceUpdateEvent args)
{
var tegGroup = GetNodeGroup(uid);
if (tegGroup is not { IsFullyBuilt: true })
SubscribeLocalEvent<GasPowerReceiverComponent, AtmosDeviceUpdateEvent>(OnDeviceUpdated);
}
- private void OnDeviceUpdated(EntityUid uid, GasPowerReceiverComponent component, AtmosDeviceUpdateEvent args)
+ private void OnDeviceUpdated(EntityUid uid, GasPowerReceiverComponent component, ref AtmosDeviceUpdateEvent args)
{
var timeDelta = args.dt;