mech nitrogen filtering 2 (#19868)
* target oxygen logic * filter out nitrogen when low on oxygen * vvrw and datafield for everything * :trollface: * bruh does work * tagless chicken * move into atmos, make it not depend on mech * update mech prototype --------- Co-authored-by: deltanedas <@deltanedas:kde.org>
This commit is contained in:
@@ -1,80 +0,0 @@
|
||||
using Content.Server.Atmos;
|
||||
using Content.Server.Atmos.Piping.Components;
|
||||
using Content.Server.Mech.Components;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Mech.Components;
|
||||
|
||||
namespace Content.Server.Mech.Systems;
|
||||
|
||||
// TODO: this could be reused for gasmask or something if MechAir wasnt a thing
|
||||
public sealed partial class MechSystem
|
||||
{
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
|
||||
private void InitializeFiltering()
|
||||
{
|
||||
SubscribeLocalEvent<MechAirIntakeComponent, AtmosDeviceUpdateEvent>(OnIntakeUpdate);
|
||||
SubscribeLocalEvent<MechAirFilterComponent, AtmosDeviceUpdateEvent>(OnFilterUpdate);
|
||||
}
|
||||
|
||||
private void OnIntakeUpdate(EntityUid uid, MechAirIntakeComponent intake, AtmosDeviceUpdateEvent args)
|
||||
{
|
||||
if (!TryComp<MechComponent>(uid, out var mech) || !mech.Airtight || !TryComp<MechAirComponent>(uid, out var mechAir))
|
||||
return;
|
||||
|
||||
// if the mech is filled there is nothing to do
|
||||
if (mechAir.Air.Pressure >= intake.Pressure)
|
||||
return;
|
||||
|
||||
var environment = _atmosphere.GetContainingMixture(uid, true, true);
|
||||
// nothing to intake from
|
||||
if (environment == null)
|
||||
return;
|
||||
|
||||
// absolute maximum pressure change
|
||||
var pressureDelta = args.dt * intake.TargetPressureChange;
|
||||
pressureDelta = MathF.Min(pressureDelta, intake.Pressure - mechAir.Air.Pressure);
|
||||
if (pressureDelta <= 0)
|
||||
return;
|
||||
|
||||
// how many moles to transfer to change internal pressure by pressureDelta
|
||||
// ignores temperature difference because lazy
|
||||
var transferMoles = pressureDelta * mechAir.Air.Volume / (environment.Temperature * Atmospherics.R);
|
||||
_atmosphere.Merge(mechAir.Air, environment.Remove(transferMoles));
|
||||
}
|
||||
|
||||
private void OnFilterUpdate(EntityUid uid, MechAirFilterComponent filter, AtmosDeviceUpdateEvent args)
|
||||
{
|
||||
if (!TryComp<MechComponent>(uid, out var mech) || !mech.Airtight || !TryComp<MechAirComponent>(uid, out var mechAir))
|
||||
return;
|
||||
|
||||
var ratio = MathF.Min(1f, args.dt * filter.TransferRate / mechAir.Air.Volume);
|
||||
var removed = mechAir.Air.RemoveRatio(ratio);
|
||||
// nothing left to remove from the mech
|
||||
if (MathHelper.CloseToPercent(removed.TotalMoles, 0f))
|
||||
return;
|
||||
|
||||
|
||||
var coordinates = Transform(uid).MapPosition;
|
||||
GasMixture? destination = null;
|
||||
if (_map.TryFindGridAt(coordinates, out var gridId, out var grid))
|
||||
{
|
||||
var tile = _mapSystem.GetTileRef(gridId, grid, coordinates);
|
||||
destination = _atmosphere.GetTileMixture(tile.GridUid, null, tile.GridIndices, true);
|
||||
}
|
||||
|
||||
if (destination != null)
|
||||
{
|
||||
_atmosphere.ScrubInto(removed, destination, filter.Gases);
|
||||
}
|
||||
else
|
||||
{
|
||||
// filtering into space/planet so just discard them
|
||||
foreach (var gas in filter.Gases)
|
||||
{
|
||||
removed.SetMoles(gas, 0f);
|
||||
}
|
||||
}
|
||||
_atmosphere.Merge(mechAir.Air, removed);
|
||||
}
|
||||
}
|
||||
@@ -47,8 +47,6 @@ public sealed partial class MechSystem : SharedMechSystem
|
||||
|
||||
_sawmill = Logger.GetSawmill("mech");
|
||||
|
||||
InitializeFiltering();
|
||||
|
||||
SubscribeLocalEvent<MechComponent, InteractUsingEvent>(OnInteractUsing);
|
||||
SubscribeLocalEvent<MechComponent, EntInsertedIntoContainerMessage>(OnInsertBattery);
|
||||
SubscribeLocalEvent<MechComponent, MapInitEvent>(OnMapInit);
|
||||
@@ -69,6 +67,8 @@ public sealed partial class MechSystem : SharedMechSystem
|
||||
SubscribeLocalEvent<MechPilotComponent, ExhaleLocationEvent>(OnExhale);
|
||||
SubscribeLocalEvent<MechPilotComponent, AtmosExposedGetAirEvent>(OnExpose);
|
||||
|
||||
SubscribeLocalEvent<MechAirComponent, GetFilterAirEvent>(OnGetFilterAir);
|
||||
|
||||
#region Equipment UI message relays
|
||||
SubscribeLocalEvent<MechComponent, MechGrabberEjectMessage>(ReceiveEquipmentUiMesssages);
|
||||
SubscribeLocalEvent<MechComponent, MechSoundboardPlayMessage>(ReceiveEquipmentUiMesssages);
|
||||
@@ -423,5 +423,17 @@ public sealed partial class MechSystem : SharedMechSystem
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnGetFilterAir(EntityUid uid, MechAirComponent comp, ref GetFilterAirEvent args)
|
||||
{
|
||||
if (args.Air != null)
|
||||
return;
|
||||
|
||||
// only airtight mechs get internal air
|
||||
if (!TryComp<MechComponent>(uid, out var mech) || !mech.Airtight)
|
||||
return;
|
||||
|
||||
args.Air = comp.Air;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user