AlignRCDConstruction.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. using System.Numerics;
  2. using Content.Client.Gameplay;
  3. using Content.Shared.Hands.Components;
  4. using Content.Shared.Interaction;
  5. using Content.Shared.RCD.Components;
  6. using Content.Shared.RCD.Systems;
  7. using Robust.Client.Placement;
  8. using Robust.Client.Player;
  9. using Robust.Client.State;
  10. using Robust.Shared.Map;
  11. using Robust.Shared.Map.Components;
  12. namespace Content.Client.RCD;
  13. public sealed class AlignRCDConstruction : PlacementMode
  14. {
  15. [Dependency] private readonly IEntityManager _entityManager = default!;
  16. [Dependency] private readonly IMapManager _mapManager = default!;
  17. private readonly SharedMapSystem _mapSystem;
  18. private readonly RCDSystem _rcdSystem;
  19. private readonly SharedTransformSystem _transformSystem;
  20. [Dependency] private readonly IPlayerManager _playerManager = default!;
  21. [Dependency] private readonly IStateManager _stateManager = default!;
  22. private const float SearchBoxSize = 2f;
  23. private const float PlaceColorBaseAlpha = 0.5f;
  24. private EntityCoordinates _unalignedMouseCoords = default;
  25. /// <summary>
  26. /// This placement mode is not on the engine because it is content specific (i.e., for the RCD)
  27. /// </summary>
  28. public AlignRCDConstruction(PlacementManager pMan) : base(pMan)
  29. {
  30. IoCManager.InjectDependencies(this);
  31. _mapSystem = _entityManager.System<SharedMapSystem>();
  32. _rcdSystem = _entityManager.System<RCDSystem>();
  33. _transformSystem = _entityManager.System<SharedTransformSystem>();
  34. ValidPlaceColor = ValidPlaceColor.WithAlpha(PlaceColorBaseAlpha);
  35. }
  36. public override void AlignPlacementMode(ScreenCoordinates mouseScreen)
  37. {
  38. _unalignedMouseCoords = ScreenToCursorGrid(mouseScreen);
  39. MouseCoords = _unalignedMouseCoords.AlignWithClosestGridTile(SearchBoxSize, _entityManager, _mapManager);
  40. var gridId = _transformSystem.GetGrid(MouseCoords);
  41. if (!_entityManager.TryGetComponent<MapGridComponent>(gridId, out var mapGrid))
  42. return;
  43. CurrentTile = _mapSystem.GetTileRef(gridId.Value, mapGrid, MouseCoords);
  44. float tileSize = mapGrid.TileSize;
  45. GridDistancing = tileSize;
  46. if (pManager.CurrentPermission!.IsTile)
  47. {
  48. MouseCoords = new EntityCoordinates(MouseCoords.EntityId, new Vector2(CurrentTile.X + tileSize / 2,
  49. CurrentTile.Y + tileSize / 2));
  50. }
  51. else
  52. {
  53. MouseCoords = new EntityCoordinates(MouseCoords.EntityId, new Vector2(CurrentTile.X + tileSize / 2 + pManager.PlacementOffset.X,
  54. CurrentTile.Y + tileSize / 2 + pManager.PlacementOffset.Y));
  55. }
  56. }
  57. public override bool IsValidPosition(EntityCoordinates position)
  58. {
  59. var player = _playerManager.LocalSession?.AttachedEntity;
  60. // If the destination is out of interaction range, set the placer alpha to zero
  61. if (!_entityManager.TryGetComponent<TransformComponent>(player, out var xform))
  62. return false;
  63. if (!_transformSystem.InRange(xform.Coordinates, position, SharedInteractionSystem.InteractionRange))
  64. {
  65. InvalidPlaceColor = InvalidPlaceColor.WithAlpha(0);
  66. return false;
  67. }
  68. // Otherwise restore the alpha value
  69. else
  70. {
  71. InvalidPlaceColor = InvalidPlaceColor.WithAlpha(PlaceColorBaseAlpha);
  72. }
  73. // Determine if player is carrying an RCD in their active hand
  74. if (!_entityManager.TryGetComponent<HandsComponent>(player, out var hands))
  75. return false;
  76. var heldEntity = hands.ActiveHand?.HeldEntity;
  77. if (!_entityManager.TryGetComponent<RCDComponent>(heldEntity, out var rcd))
  78. return false;
  79. // Retrieve the map grid data for the position
  80. if (!_rcdSystem.TryGetMapGridData(position, out var mapGridData))
  81. return false;
  82. // Determine if the user is hovering over a target
  83. var currentState = _stateManager.CurrentState;
  84. if (currentState is not GameplayStateBase screen)
  85. return false;
  86. var target = screen.GetClickedEntity(_transformSystem.ToMapCoordinates(_unalignedMouseCoords));
  87. // Determine if the RCD operation is valid or not
  88. if (!_rcdSystem.IsRCDOperationStillValid(heldEntity.Value, rcd, mapGridData.Value, target, player.Value, false))
  89. return false;
  90. return true;
  91. }
  92. }