LungTest.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. using Content.Server.Atmos.Components;
  2. using Content.Server.Atmos.EntitySystems;
  3. using Content.Server.Body.Components;
  4. using Content.Server.Body.Systems;
  5. using Content.Shared.Body.Components;
  6. using Robust.Server.GameObjects;
  7. using Robust.Shared;
  8. using Robust.Shared.Configuration;
  9. using Robust.Shared.GameObjects;
  10. using Robust.Shared.Map;
  11. using Robust.Shared.Map.Components;
  12. using System.Linq;
  13. using System.Numerics;
  14. using Robust.Shared.EntitySerialization.Systems;
  15. using Robust.Shared.Utility;
  16. namespace Content.IntegrationTests.Tests.Body
  17. {
  18. [TestFixture]
  19. [TestOf(typeof(LungSystem))]
  20. public sealed class LungTest
  21. {
  22. [TestPrototypes]
  23. private const string Prototypes = @"
  24. - type: entity
  25. name: HumanLungDummy
  26. id: HumanLungDummy
  27. components:
  28. - type: SolutionContainerManager
  29. - type: Body
  30. prototype: Human
  31. - type: MobState
  32. allowedStates:
  33. - Alive
  34. - type: Damageable
  35. - type: ThermalRegulator
  36. metabolismHeat: 5000
  37. radiatedHeat: 400
  38. implicitHeatRegulation: 5000
  39. sweatHeatRegulation: 5000
  40. shiveringHeatRegulation: 5000
  41. normalBodyTemperature: 310.15
  42. thermalRegulationTemperatureThreshold: 25
  43. - type: Respirator
  44. damage:
  45. types:
  46. Asphyxiation: 1.5
  47. damageRecovery:
  48. types:
  49. Asphyxiation: -1.5
  50. ";
  51. [Test]
  52. public async Task AirConsistencyTest()
  53. {
  54. // --- Setup
  55. await using var pair = await PoolManager.GetServerClient();
  56. var server = pair.Server;
  57. await server.WaitIdleAsync();
  58. var entityManager = server.ResolveDependency<IEntityManager>();
  59. var mapLoader = entityManager.System<MapLoaderSystem>();
  60. var mapSys = entityManager.System<SharedMapSystem>();
  61. EntityUid? grid = null;
  62. BodyComponent body = default;
  63. RespiratorComponent resp = default;
  64. EntityUid human = default;
  65. GridAtmosphereComponent relevantAtmos = default;
  66. var startingMoles = 0.0f;
  67. var testMapName = new ResPath("Maps/Test/Breathing/3by3-20oxy-80nit.yml");
  68. await server.WaitPost(() =>
  69. {
  70. mapSys.CreateMap(out var mapId);
  71. Assert.That(mapLoader.TryLoadGrid(mapId, testMapName, out var gridEnt));
  72. grid = gridEnt!.Value.Owner;
  73. });
  74. Assert.That(grid, Is.Not.Null, $"Test blueprint {testMapName} not found.");
  75. float GetMapMoles()
  76. {
  77. var totalMapMoles = 0.0f;
  78. foreach (var tile in relevantAtmos.Tiles.Values)
  79. {
  80. totalMapMoles += tile.Air?.TotalMoles ?? 0.0f;
  81. }
  82. return totalMapMoles;
  83. }
  84. await server.WaitAssertion(() =>
  85. {
  86. var center = new Vector2(0.5f, 0.5f);
  87. var coordinates = new EntityCoordinates(grid.Value, center);
  88. human = entityManager.SpawnEntity("HumanLungDummy", coordinates);
  89. relevantAtmos = entityManager.GetComponent<GridAtmosphereComponent>(grid.Value);
  90. startingMoles = 100f; // Hardcoded because GetMapMoles returns 900 here for some reason.
  91. #pragma warning disable NUnit2045
  92. Assert.That(entityManager.TryGetComponent(human, out body), Is.True);
  93. Assert.That(entityManager.TryGetComponent(human, out resp), Is.True);
  94. #pragma warning restore NUnit2045
  95. });
  96. // --- End setup
  97. var inhaleCycles = 100;
  98. for (var i = 0; i < inhaleCycles; i++)
  99. {
  100. // Breathe in
  101. await PoolManager.WaitUntil(server, () => resp.Status == RespiratorStatus.Exhaling);
  102. Assert.That(
  103. GetMapMoles(), Is.LessThan(startingMoles),
  104. "Did not inhale in any gas"
  105. );
  106. // Breathe out
  107. await PoolManager.WaitUntil(server, () => resp.Status == RespiratorStatus.Inhaling);
  108. Assert.That(
  109. GetMapMoles(), Is.EqualTo(startingMoles).Within(0.0002),
  110. "Did not exhale as much gas as was inhaled"
  111. );
  112. }
  113. await pair.CleanReturnAsync();
  114. }
  115. [Test]
  116. public async Task NoSuffocationTest()
  117. {
  118. await using var pair = await PoolManager.GetServerClient();
  119. var server = pair.Server;
  120. var mapManager = server.ResolveDependency<IMapManager>();
  121. var entityManager = server.ResolveDependency<IEntityManager>();
  122. var cfg = server.ResolveDependency<IConfigurationManager>();
  123. var mapLoader = entityManager.System<MapLoaderSystem>();
  124. var mapSys = entityManager.System<SharedMapSystem>();
  125. EntityUid? grid = null;
  126. RespiratorComponent respirator = null;
  127. EntityUid human = default;
  128. var testMapName = new ResPath("Maps/Test/Breathing/3by3-20oxy-80nit.yml");
  129. await server.WaitPost(() =>
  130. {
  131. mapSys.CreateMap(out var mapId);
  132. Assert.That(mapLoader.TryLoadGrid(mapId, testMapName, out var gridEnt));
  133. grid = gridEnt!.Value.Owner;
  134. });
  135. Assert.That(grid, Is.Not.Null, $"Test blueprint {testMapName} not found.");
  136. await server.WaitAssertion(() =>
  137. {
  138. var center = new Vector2(0.5f, 0.5f);
  139. var coordinates = new EntityCoordinates(grid.Value, center);
  140. human = entityManager.SpawnEntity("HumanLungDummy", coordinates);
  141. var mixture = entityManager.System<AtmosphereSystem>().GetContainingMixture(human);
  142. #pragma warning disable NUnit2045
  143. Assert.That(mixture.TotalMoles, Is.GreaterThan(0));
  144. Assert.That(entityManager.HasComponent<BodyComponent>(human), Is.True);
  145. Assert.That(entityManager.TryGetComponent(human, out respirator), Is.True);
  146. Assert.That(respirator.SuffocationCycles, Is.LessThanOrEqualTo(respirator.SuffocationCycleThreshold));
  147. #pragma warning restore NUnit2045
  148. });
  149. var increment = 10;
  150. // 20 seconds
  151. var total = 20 * cfg.GetCVar(CVars.NetTickrate);
  152. for (var tick = 0; tick < total; tick += increment)
  153. {
  154. await server.WaitRunTicks(increment);
  155. await server.WaitAssertion(() =>
  156. {
  157. Assert.That(respirator.SuffocationCycles, Is.LessThanOrEqualTo(respirator.SuffocationCycleThreshold),
  158. $"Entity {entityManager.GetComponent<MetaDataComponent>(human).EntityName} is suffocating on tick {tick}");
  159. });
  160. }
  161. await pair.CleanReturnAsync();
  162. }
  163. }
  164. }