FixRotationsCommand.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. using Content.Server.Administration;
  2. using Content.Server.Power.Components;
  3. using Content.Shared.Administration;
  4. using Content.Shared.Construction;
  5. using Content.Shared.Tag;
  6. using Robust.Shared.Console;
  7. using Robust.Shared.Map.Components;
  8. namespace Content.Server.Construction.Commands;
  9. [AdminCommand(AdminFlags.Mapping)]
  10. public sealed class FixRotationsCommand : IConsoleCommand
  11. {
  12. [Dependency] private readonly IEntityManager _entManager = default!;
  13. // ReSharper disable once StringLiteralTypo
  14. public string Command => "fixrotations";
  15. public string Description => "Sets the rotation of all occluders, low walls and windows to south.";
  16. public string Help => $"Usage: {Command} <gridId> | {Command}";
  17. public void Execute(IConsoleShell shell, string argsOther, string[] args)
  18. {
  19. var player = shell.Player;
  20. EntityUid? gridId;
  21. var xformQuery = _entManager.GetEntityQuery<TransformComponent>();
  22. switch (args.Length)
  23. {
  24. case 0:
  25. if (player?.AttachedEntity is not { Valid: true } playerEntity)
  26. {
  27. shell.WriteError("Only a player can run this command.");
  28. return;
  29. }
  30. gridId = xformQuery.GetComponent(playerEntity).GridUid;
  31. break;
  32. case 1:
  33. if (!NetEntity.TryParse(args[0], out var idNet) || !_entManager.TryGetEntity(idNet, out var id))
  34. {
  35. shell.WriteError($"{args[0]} is not a valid entity.");
  36. return;
  37. }
  38. gridId = id;
  39. break;
  40. default:
  41. shell.WriteLine(Help);
  42. return;
  43. }
  44. if (!_entManager.TryGetComponent(gridId, out MapGridComponent? grid))
  45. {
  46. shell.WriteError($"No grid exists with id {gridId}");
  47. return;
  48. }
  49. if (!_entManager.EntityExists(gridId))
  50. {
  51. shell.WriteError($"Grid {gridId} doesn't have an associated grid entity.");
  52. return;
  53. }
  54. var changed = 0;
  55. var tagSystem = _entManager.EntitySysManager.GetEntitySystem<TagSystem>();
  56. var enumerator = xformQuery.GetComponent(gridId.Value).ChildEnumerator;
  57. while (enumerator.MoveNext(out var child))
  58. {
  59. if (!_entManager.EntityExists(child))
  60. {
  61. continue;
  62. }
  63. var valid = false;
  64. // Occluders should only count if the state of it right now is enabled.
  65. // This prevents issues with edge firelocks.
  66. if (_entManager.TryGetComponent<OccluderComponent>(child, out var occluder))
  67. {
  68. valid |= occluder.Enabled;
  69. }
  70. // low walls & grilles
  71. valid |= _entManager.HasComponent<SharedCanBuildWindowOnTopComponent>(child);
  72. // cables
  73. valid |= _entManager.HasComponent<CableComponent>(child);
  74. // anything else that might need this forced
  75. valid |= tagSystem.HasTag(child, "ForceFixRotations");
  76. // override
  77. valid &= !tagSystem.HasTag(child, "ForceNoFixRotations");
  78. // remove diagonal entities as well
  79. valid &= !tagSystem.HasTag(child, "Diagonal");
  80. if (!valid)
  81. continue;
  82. var childXform = xformQuery.GetComponent(child);
  83. if (childXform.LocalRotation != Angle.Zero)
  84. {
  85. childXform.LocalRotation = Angle.Zero;
  86. changed++;
  87. }
  88. }
  89. shell.WriteLine($"Changed {changed} entities. If things seem wrong, reconnect.");
  90. }
  91. }