GasCondenserSystem.cs 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. using Content.Server.Atmos.EntitySystems;
  2. using Content.Server.Atmos.Piping.Components;
  3. using Content.Server.Atmos.Piping.Unary.Components;
  4. using Content.Server.NodeContainer;
  5. using Content.Server.NodeContainer.EntitySystems;
  6. using Content.Server.NodeContainer.Nodes;
  7. using Content.Server.Power.Components;
  8. using Content.Server.Power.EntitySystems;
  9. using Content.Shared.Atmos;
  10. using Content.Shared.Chemistry.EntitySystems;
  11. using Content.Shared.FixedPoint;
  12. using JetBrains.Annotations;
  13. namespace Content.Server.Atmos.Piping.Unary.EntitySystems;
  14. [UsedImplicitly]
  15. public sealed class GasCondenserSystem : EntitySystem
  16. {
  17. [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
  18. [Dependency] private readonly PowerReceiverSystem _power = default!;
  19. [Dependency] private readonly NodeContainerSystem _nodeContainer = default!;
  20. [Dependency] private readonly SharedSolutionContainerSystem _solution = default!;
  21. public override void Initialize()
  22. {
  23. base.Initialize();
  24. SubscribeLocalEvent<GasCondenserComponent, AtmosDeviceUpdateEvent>(OnCondenserUpdated);
  25. }
  26. private void OnCondenserUpdated(Entity<GasCondenserComponent> entity, ref AtmosDeviceUpdateEvent args)
  27. {
  28. if (!(TryComp<ApcPowerReceiverComponent>(entity, out var receiver) && _power.IsPowered(entity, receiver))
  29. || !_nodeContainer.TryGetNode(entity.Owner, entity.Comp.Inlet, out PipeNode? inlet)
  30. || !_solution.ResolveSolution(entity.Owner, entity.Comp.SolutionId, ref entity.Comp.Solution, out var solution))
  31. {
  32. return;
  33. }
  34. if (solution.AvailableVolume == 0 || inlet.Air.TotalMoles == 0)
  35. return;
  36. var molesToConvert = NumberOfMolesToConvert(receiver, inlet.Air, args.dt);
  37. var removed = inlet.Air.Remove(molesToConvert);
  38. for (var i = 0; i < Atmospherics.TotalNumberOfGases; i++)
  39. {
  40. var moles = removed[i];
  41. if (moles <= 0)
  42. continue;
  43. if (_atmosphereSystem.GetGas(i).Reagent is not { } gasReagent)
  44. continue;
  45. var moleToReagentMultiplier = entity.Comp.MolesToReagentMultiplier;
  46. var amount = FixedPoint2.Min(FixedPoint2.New(moles * moleToReagentMultiplier), solution.AvailableVolume);
  47. if (amount <= 0)
  48. continue;
  49. solution.AddReagent(gasReagent, amount);
  50. // if we have leftover reagent, then convert it back to moles and put it back in the mixture.
  51. inlet.Air.AdjustMoles(i, moles - (amount.Float() / moleToReagentMultiplier));
  52. }
  53. _solution.UpdateChemicals(entity.Comp.Solution.Value);
  54. }
  55. public float NumberOfMolesToConvert(ApcPowerReceiverComponent comp, GasMixture mix, float dt)
  56. {
  57. var hc = _atmosphereSystem.GetHeatCapacity(mix, true);
  58. var alpha = 0.8f; // tuned to give us 1-ish u/second of reagent conversion
  59. // ignores the energy needed to cool down the solution to the condensation point, but that probably adds too much difficulty and so let's not simulate that
  60. var energy = comp.Load * dt;
  61. return energy / (alpha * hc);
  62. }
  63. }