GasProducerAnomalySystem.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. using Content.Server.Atmos.EntitySystems;
  2. using Content.Server.Anomaly.Components;
  3. using Content.Shared.Anomaly.Components;
  4. using Content.Shared.Atmos;
  5. using Robust.Shared.Random;
  6. using System.Linq;
  7. using System.Numerics;
  8. using Robust.Shared.Map.Components;
  9. namespace Content.Server.Anomaly.Effects;
  10. /// <summary>
  11. /// This handles <see cref="GasProducerAnomalyComponent"/> and the events from <seealso cref="AnomalySystem"/>
  12. /// </summary>
  13. public sealed class GasProducerAnomalySystem : EntitySystem
  14. {
  15. [Dependency] private readonly AtmosphereSystem _atmosphere = default!;
  16. [Dependency] private readonly IRobustRandom _random = default!;
  17. [Dependency] private readonly SharedMapSystem _map = default!;
  18. public override void Initialize()
  19. {
  20. base.Initialize();
  21. SubscribeLocalEvent<GasProducerAnomalyComponent, AnomalySupercriticalEvent>(OnSupercritical);
  22. }
  23. private void OnSupercritical(EntityUid uid, GasProducerAnomalyComponent component, ref AnomalySupercriticalEvent args)
  24. {
  25. if (!component.ReleaseOnMaxSeverity)
  26. return;
  27. ReleaseGas(uid, component.ReleasedGas, component.SuperCriticalMoleAmount, component.spawnRadius, component.tileCount, component.tempChange);
  28. }
  29. public override void Update(float frameTime)
  30. {
  31. base.Update(frameTime);
  32. var query = EntityQueryEnumerator<GasProducerAnomalyComponent>();
  33. while (query.MoveNext(out var ent, out var comp))
  34. {
  35. if (!comp.ReleasePassively)
  36. continue;
  37. // Yes this is unused code since there are no anomalies that
  38. // release gas passively *yet*, but since I'm here I figured
  39. // I'd save someone some time and just add it for the future
  40. ReleaseGas(ent, comp.ReleasedGas, comp.PassiveMoleAmount * frameTime, comp.spawnRadius, comp.tileCount, comp.tempChange);
  41. }
  42. }
  43. private void ReleaseGas(EntityUid uid, Gas gas, float mols, float radius, int count, float temp)
  44. {
  45. var xform = Transform(uid);
  46. if (!TryComp<MapGridComponent>(xform.GridUid, out var grid))
  47. return;
  48. var localpos = xform.Coordinates.Position;
  49. var tilerefs = _map.GetLocalTilesIntersecting(
  50. xform.GridUid.Value,
  51. grid,
  52. new Box2(localpos + new Vector2(-radius, -radius), localpos + new Vector2(radius, radius)))
  53. .ToArray();
  54. if (tilerefs.Length == 0)
  55. return;
  56. var mixture = _atmosphere.GetTileMixture((uid, xform), true);
  57. if (mixture != null)
  58. {
  59. mixture.AdjustMoles(gas, mols);
  60. mixture.Temperature += temp;
  61. }
  62. if (count == 0)
  63. return;
  64. _random.Shuffle(tilerefs);
  65. var amountCounter = 0;
  66. foreach (var tileref in tilerefs)
  67. {
  68. var mix = _atmosphere.GetTileMixture(xform.GridUid, xform.MapUid, tileref.GridIndices, true);
  69. amountCounter++;
  70. if (mix is not { })
  71. continue;
  72. mix.AdjustMoles(gas, mols);
  73. mix.Temperature += temp;
  74. if (amountCounter >= count)
  75. return;
  76. }
  77. }
  78. }