Files
wwdpublic/Content.Server/Atmos/Piping/Binary/EntitySystems/GasRecyclerSystem.cs
VMSolidus 96ac353f4a Reimplement Part Upgrading (#917)
# Description

By extremely popular demand(Both internally, and from our downstreams),
this PR reimplements Part Upgrading. Since some of the systems that this
PR touches were substantially changed since the removal of Parts, I had
to do a lot of very in depth by-hand edits of individual systems.
Shockingly, the only one that really proved any trouble was Cloning
System, so I'm genuinely surprised wizden didn't substantially touch any
of these codes since removing parts..

# Changelog

🆑
- add: Part Upgrading has returned!

---------

Signed-off-by: VMSolidus <evilexecutive@gmail.com>
Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com>
2024-10-19 13:15:15 +07:00

139 lines
6.0 KiB
C#

using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Piping.Binary.Components;
using Content.Server.Atmos.Piping.Components;
using Content.Server.Construction;
using Content.Server.NodeContainer;
using Content.Server.NodeContainer.EntitySystems;
using Content.Server.NodeContainer.Nodes;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Piping;
using Content.Shared.Audio;
using Content.Shared.Examine;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
namespace Content.Server.Atmos.Piping.Binary.EntitySystems
{
[UsedImplicitly]
public sealed class GasReyclerSystem : EntitySystem
{
[Dependency] private readonly AppearanceSystem _appearance = default!;
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
[Dependency] private readonly SharedAmbientSoundSystem _ambientSoundSystem = default!;
[Dependency] private readonly NodeContainerSystem _nodeContainer = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<GasRecyclerComponent, AtmosDeviceEnabledEvent>(OnEnabled);
SubscribeLocalEvent<GasRecyclerComponent, AtmosDeviceUpdateEvent>(OnUpdate);
SubscribeLocalEvent<GasRecyclerComponent, AtmosDeviceDisabledEvent>(OnDisabled);
SubscribeLocalEvent<GasRecyclerComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<GasRecyclerComponent, RefreshPartsEvent>(OnRefreshParts);
SubscribeLocalEvent<GasRecyclerComponent, UpgradeExamineEvent>(OnUpgradeExamine);
}
private void OnEnabled(EntityUid uid, GasRecyclerComponent comp, ref AtmosDeviceEnabledEvent args)
{
UpdateAppearance(uid, comp);
}
private void OnExamined(Entity<GasRecyclerComponent> ent, ref ExaminedEvent args)
{
var comp = ent.Comp;
if (!EntityManager.GetComponent<TransformComponent>(ent).Anchored || !args.IsInDetailsRange) // Not anchored? Out of range? No status.
return;
if (!_nodeContainer.TryGetNode(ent.Owner, comp.InletName, out PipeNode? inlet))
return;
using (args.PushGroup(nameof(GasRecyclerComponent)))
{
if (comp.Reacting)
{
args.PushMarkup(Loc.GetString("gas-recycler-reacting"));
}
else
{
if (inlet.Air.Pressure < comp.MinPressure)
{
args.PushMarkup(Loc.GetString("gas-recycler-low-pressure"));
}
if (inlet.Air.Temperature < comp.MinTemp)
{
args.PushMarkup(Loc.GetString("gas-recycler-low-temperature"));
}
}
}
}
private void OnUpdate(Entity<GasRecyclerComponent> ent, ref AtmosDeviceUpdateEvent args)
{
var comp = ent.Comp;
if (!_nodeContainer.TryGetNodes(ent.Owner, comp.InletName, comp.OutletName, out PipeNode? inlet, out PipeNode? outlet))
{
_ambientSoundSystem.SetAmbience(ent, false);
return;
}
// The gas recycler is a passive device, so it permits gas flow even if nothing is being reacted.
comp.Reacting = inlet.Air.Temperature >= comp.MinTemp && inlet.Air.Pressure >= comp.MinPressure;
var removed = inlet.Air.RemoveVolume(PassiveTransferVol(inlet.Air, outlet.Air));
if (comp.Reacting)
{
var nCO2 = removed.GetMoles(Gas.CarbonDioxide);
removed.AdjustMoles(Gas.CarbonDioxide, -nCO2);
removed.AdjustMoles(Gas.Oxygen, nCO2);
var nN2O = removed.GetMoles(Gas.NitrousOxide);
removed.AdjustMoles(Gas.NitrousOxide, -nN2O);
removed.AdjustMoles(Gas.Nitrogen, nN2O);
}
_atmosphereSystem.Merge(outlet.Air, removed);
UpdateAppearance(ent, comp);
_ambientSoundSystem.SetAmbience(ent, true);
}
public float PassiveTransferVol(GasMixture inlet, GasMixture outlet)
{
if (inlet.Pressure < outlet.Pressure)
{
return 0;
}
float overPressConst = 300; // pressure difference (in atm) to get 200 L/sec transfer rate
float alpha = Atmospherics.MaxTransferRate * _atmosphereSystem.PumpSpeedup() / (float)Math.Sqrt(overPressConst*Atmospherics.OneAtmosphere);
return alpha * (float)Math.Sqrt(inlet.Pressure - outlet.Pressure);
}
private void OnDisabled(EntityUid uid, GasRecyclerComponent comp, ref AtmosDeviceDisabledEvent args)
{
comp.Reacting = false;
UpdateAppearance(uid, comp);
}
private void UpdateAppearance(EntityUid uid, GasRecyclerComponent? comp = null)
{
if (!Resolve(uid, ref comp, false))
return;
_appearance.SetData(uid, PumpVisuals.Enabled, comp.Reacting);
}
private void OnRefreshParts(EntityUid uid, GasRecyclerComponent component, RefreshPartsEvent args)
{
var ratingTemp = args.PartRatings[component.MachinePartMinTemp];
var ratingPressure = args.PartRatings[component.MachinePartMinPressure];
component.MinTemp = component.BaseMinTemp * MathF.Pow(component.PartRatingMinTempMultiplier, ratingTemp - 1);
component.MinPressure = component.BaseMinPressure * MathF.Pow(component.PartRatingMinPressureMultiplier, ratingPressure - 1);
}
private void OnUpgradeExamine(EntityUid uid, GasRecyclerComponent component, UpgradeExamineEvent args)
{
args.AddPercentageUpgrade("gas-recycler-upgrade-min-temp", component.MinTemp / component.BaseMinTemp);
args.AddPercentageUpgrade("gas-recycler-upgrade-min-pressure", component.MinPressure / component.BaseMinPressure);
}
}
}