1
0

AtmosphereSystem.Commands.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. using System.Linq;
  2. using Content.Server.Administration;
  3. using Content.Server.Atmos.Components;
  4. using Content.Shared.Administration;
  5. using Content.Shared.Atmos;
  6. using Content.Shared.Atmos.Components;
  7. using Robust.Shared.Console;
  8. using Robust.Shared.Map;
  9. using Robust.Shared.Map.Components;
  10. namespace Content.Server.Atmos.EntitySystems;
  11. public sealed partial class AtmosphereSystem
  12. {
  13. [Dependency] private readonly IConsoleHost _consoleHost = default!;
  14. private void InitializeCommands()
  15. {
  16. // Fix Grid Atmos command.
  17. _consoleHost.RegisterCommand("fixgridatmos",
  18. "Makes every tile on a grid have a roundstart gas mix.",
  19. "fixgridatmos <grid Ids>", FixGridAtmosCommand, FixGridAtmosCommandCompletions);
  20. }
  21. private void ShutdownCommands()
  22. {
  23. _consoleHost.UnregisterCommand("fixgridatmos");
  24. }
  25. [AdminCommand(AdminFlags.Debug)]
  26. private void FixGridAtmosCommand(IConsoleShell shell, string argstr, string[] args)
  27. {
  28. if (args.Length == 0)
  29. {
  30. shell.WriteError("Not enough arguments.");
  31. return;
  32. }
  33. var mixtures = new GasMixture[8];
  34. for (var i = 0; i < mixtures.Length; i++)
  35. mixtures[i] = new GasMixture(Atmospherics.CellVolume) { Temperature = Atmospherics.T20C };
  36. // 0: Air
  37. mixtures[0].AdjustMoles(Gas.Oxygen, Atmospherics.OxygenMolesStandard);
  38. mixtures[0].AdjustMoles(Gas.Nitrogen, Atmospherics.NitrogenMolesStandard);
  39. // 1: Vaccum
  40. // 2: Oxygen (GM)
  41. mixtures[2].AdjustMoles(Gas.Oxygen, Atmospherics.MolesCellGasMiner);
  42. // 3: Nitrogen (GM)
  43. mixtures[3].AdjustMoles(Gas.Nitrogen, Atmospherics.MolesCellGasMiner);
  44. // 4: Plasma (GM)
  45. mixtures[4].AdjustMoles(Gas.Plasma, Atmospherics.MolesCellGasMiner);
  46. // 5: Instant Plasmafire (r)
  47. mixtures[5].AdjustMoles(Gas.Oxygen, Atmospherics.MolesCellGasMiner);
  48. mixtures[5].AdjustMoles(Gas.Plasma, Atmospherics.MolesCellGasMiner);
  49. mixtures[5].Temperature = 5000f;
  50. // 6: (Walk-In) Freezer
  51. mixtures[6].AdjustMoles(Gas.Oxygen, Atmospherics.OxygenMolesFreezer);
  52. mixtures[6].AdjustMoles(Gas.Nitrogen, Atmospherics.NitrogenMolesFreezer);
  53. mixtures[6].Temperature = Atmospherics.FreezerTemp; // Little colder than an actual freezer but gives a grace period to get e.g. themomachines set up, should keep warm for a few door openings
  54. // 7: Nitrogen (101kpa) for vox rooms
  55. mixtures[7].AdjustMoles(Gas.Nitrogen, Atmospherics.MolesCellStandard);
  56. foreach (var arg in args)
  57. {
  58. if (!NetEntity.TryParse(arg, out var netEntity) || !TryGetEntity(netEntity, out var euid))
  59. {
  60. shell.WriteError($"Failed to parse euid '{arg}'.");
  61. return;
  62. }
  63. if (!TryComp(euid, out MapGridComponent? gridComp))
  64. {
  65. shell.WriteError($"Euid '{euid}' does not exist or is not a grid.");
  66. return;
  67. }
  68. if (!TryComp(euid, out GridAtmosphereComponent? gridAtmosphere))
  69. {
  70. shell.WriteError($"Grid \"{euid}\" has no atmosphere component, try addatmos.");
  71. continue;
  72. }
  73. // Force Invalidate & update air on all tiles
  74. Entity<GridAtmosphereComponent, GasTileOverlayComponent, MapGridComponent, TransformComponent> grid =
  75. new(euid.Value, gridAtmosphere, Comp<GasTileOverlayComponent>(euid.Value), gridComp, Transform(euid.Value));
  76. RebuildGridTiles(grid);
  77. var query = GetEntityQuery<AtmosFixMarkerComponent>();
  78. foreach (var (indices, tile) in gridAtmosphere.Tiles.ToArray())
  79. {
  80. if (tile.Air is not {Immutable: false} air)
  81. continue;
  82. air.Clear();
  83. var mixtureId = 0;
  84. var enumerator = _mapSystem.GetAnchoredEntitiesEnumerator(grid, grid, indices);
  85. while (enumerator.MoveNext(out var entUid))
  86. {
  87. if (query.TryComp(entUid, out var marker))
  88. mixtureId = marker.Mode;
  89. }
  90. var mixture = mixtures[mixtureId];
  91. Merge(air, mixture);
  92. air.Temperature = mixture.Temperature;
  93. }
  94. }
  95. }
  96. /// <summary>
  97. /// Clears & re-creates all references to <see cref="TileAtmosphere"/>s stored on a grid.
  98. /// </summary>
  99. private void RebuildGridTiles(
  100. Entity<GridAtmosphereComponent, GasTileOverlayComponent, MapGridComponent, TransformComponent> ent)
  101. {
  102. foreach (var indices in ent.Comp1.Tiles.Keys)
  103. {
  104. InvalidateVisuals((ent, ent), indices);
  105. }
  106. var atmos = ent.Comp1;
  107. atmos.MapTiles.Clear();
  108. atmos.ActiveTiles.Clear();
  109. atmos.ExcitedGroups.Clear();
  110. atmos.HotspotTiles.Clear();
  111. atmos.SuperconductivityTiles.Clear();
  112. atmos.HighPressureDelta.Clear();
  113. atmos.CurrentRunTiles.Clear();
  114. atmos.CurrentRunExcitedGroups.Clear();
  115. atmos.InvalidatedCoords.Clear();
  116. atmos.CurrentRunInvalidatedTiles.Clear();
  117. atmos.PossiblyDisconnectedTiles.Clear();
  118. atmos.Tiles.Clear();
  119. var volume = GetVolumeForTiles(ent);
  120. TryComp(ent.Comp4.MapUid, out MapAtmosphereComponent? mapAtmos);
  121. var enumerator = _map.GetAllTilesEnumerator(ent, ent);
  122. while (enumerator.MoveNext(out var tileRef))
  123. {
  124. var tile = GetOrNewTile(ent, ent, tileRef.Value.GridIndices);
  125. UpdateTileData(ent, mapAtmos, tile);
  126. UpdateAdjacentTiles(ent, tile, activate: true);
  127. UpdateTileAir(ent, tile, volume);
  128. }
  129. }
  130. private CompletionResult FixGridAtmosCommandCompletions(IConsoleShell shell, string[] args)
  131. {
  132. MapId? playerMap = null;
  133. if (shell.Player is { AttachedEntity: { } playerEnt })
  134. playerMap = Transform(playerEnt).MapID;
  135. var options = new List<CompletionOption>();
  136. if (playerMap == null)
  137. return CompletionResult.FromOptions(options);
  138. foreach (var grid in _mapManager.GetAllGrids(playerMap.Value).OrderBy(o => o.Owner))
  139. {
  140. var uid = grid.Owner;
  141. if (!TryComp(uid, out TransformComponent? gridXform))
  142. continue;
  143. options.Add(new CompletionOption(uid.ToString(), $"{MetaData(uid).EntityName} - Map {gridXform.MapID}"));
  144. }
  145. return CompletionResult.FromOptions(options);
  146. }
  147. }