GasMinerSystem.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. using System.Diagnostics.CodeAnalysis;
  2. using Content.Server.Atmos.Piping.Components;
  3. using Content.Shared.Atmos;
  4. using Content.Shared.Atmos.Components;
  5. using Content.Shared.Atmos.EntitySystems;
  6. using JetBrains.Annotations;
  7. using Robust.Server.GameObjects;
  8. namespace Content.Server.Atmos.EntitySystems;
  9. [UsedImplicitly]
  10. public sealed class GasMinerSystem : SharedGasMinerSystem
  11. {
  12. [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
  13. [Dependency] private readonly TransformSystem _transformSystem = default!;
  14. public override void Initialize()
  15. {
  16. base.Initialize();
  17. SubscribeLocalEvent<GasMinerComponent, AtmosDeviceUpdateEvent>(OnMinerUpdated);
  18. }
  19. private void OnMinerUpdated(Entity<GasMinerComponent> ent, ref AtmosDeviceUpdateEvent args)
  20. {
  21. var miner = ent.Comp;
  22. var oldState = miner.MinerState;
  23. float toSpawn;
  24. if (!GetValidEnvironment(ent, out var environment) || !Transform(ent).Anchored)
  25. {
  26. miner.MinerState = GasMinerState.Disabled;
  27. }
  28. // SpawnAmount is declared in mol/s so to get the amount of gas we hope to mine, we have to multiply this by
  29. // how long we have been waiting to spawn it and further cap the number according to the miner's state.
  30. else if ((toSpawn = CapSpawnAmount(ent, miner.SpawnAmount * args.dt, environment)) == 0)
  31. {
  32. miner.MinerState = GasMinerState.Idle;
  33. }
  34. else
  35. {
  36. miner.MinerState = GasMinerState.Working;
  37. // Time to mine some gas.
  38. var merger = new GasMixture(1) { Temperature = miner.SpawnTemperature };
  39. merger.SetMoles(miner.SpawnGas, toSpawn);
  40. _atmosphereSystem.Merge(environment, merger);
  41. }
  42. if (miner.MinerState != oldState)
  43. {
  44. Dirty(ent);
  45. }
  46. }
  47. private bool GetValidEnvironment(Entity<GasMinerComponent> ent, [NotNullWhen(true)] out GasMixture? environment)
  48. {
  49. var (uid, miner) = ent;
  50. var transform = Transform(uid);
  51. var position = _transformSystem.GetGridOrMapTilePosition(uid, transform);
  52. // Treat space as an invalid environment
  53. if (_atmosphereSystem.IsTileSpace(transform.GridUid, transform.MapUid, position))
  54. {
  55. environment = null;
  56. return false;
  57. }
  58. environment = _atmosphereSystem.GetContainingMixture((uid, transform), true, true);
  59. return environment != null;
  60. }
  61. private float CapSpawnAmount(Entity<GasMinerComponent> ent, float toSpawnTarget, GasMixture environment)
  62. {
  63. var (uid, miner) = ent;
  64. // How many moles could we theoretically spawn. Cap by pressure and amount.
  65. var allowableMoles = Math.Min(
  66. (miner.MaxExternalPressure - environment.Pressure) * environment.Volume / (miner.SpawnTemperature * Atmospherics.R),
  67. miner.MaxExternalAmount - environment.TotalMoles);
  68. var toSpawnReal = Math.Clamp(allowableMoles, 0f, toSpawnTarget);
  69. if (toSpawnReal < Atmospherics.GasMinMoles) {
  70. return 0f;
  71. }
  72. return toSpawnReal;
  73. }
  74. }