Files
tbd-station-14/Content.Client/RCD/AlignRCDConstruction.cs
Nemanja 524725d378 HandsSystem Refactor (#38438)
* checkpoint

* pt 2

* pt... i forgot

* pt 4

* patch

* More test fixes

* optimization!!!

* the REAL hand system

* fix RetractableItemActionSystem.cs oversight

* the review

* test

* remove test usage of body prototype

* Update Content.IntegrationTests/Tests/Interaction/InteractionTest.cs

Co-authored-by: Tayrtahn <tayrtahn@gmail.com>

* hellcode

* hellcode 2

* Minor cleanup

* test

* Chasing the last of the bugs

* changes

---------

Co-authored-by: Tayrtahn <tayrtahn@gmail.com>
2025-06-25 15:13:03 +02:00

121 lines
4.6 KiB
C#

using System.Numerics;
using Content.Client.Gameplay;
using Content.Client.Hands.Systems;
using Content.Shared.Hands.Components;
using Content.Shared.Interaction;
using Content.Shared.RCD.Components;
using Content.Shared.RCD.Systems;
using Robust.Client.Placement;
using Robust.Client.Player;
using Robust.Client.State;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
namespace Content.Client.RCD;
public sealed class AlignRCDConstruction : PlacementMode
{
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
private readonly SharedMapSystem _mapSystem;
private readonly HandsSystem _handsSystem;
private readonly RCDSystem _rcdSystem;
private readonly SharedTransformSystem _transformSystem;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IStateManager _stateManager = default!;
private const float SearchBoxSize = 2f;
private const float PlaceColorBaseAlpha = 0.5f;
private EntityCoordinates _unalignedMouseCoords = default;
/// <summary>
/// This placement mode is not on the engine because it is content specific (i.e., for the RCD)
/// </summary>
public AlignRCDConstruction(PlacementManager pMan) : base(pMan)
{
IoCManager.InjectDependencies(this);
_mapSystem = _entityManager.System<SharedMapSystem>();
_handsSystem = _entityManager.System<HandsSystem>();
_rcdSystem = _entityManager.System<RCDSystem>();
_transformSystem = _entityManager.System<SharedTransformSystem>();
ValidPlaceColor = ValidPlaceColor.WithAlpha(PlaceColorBaseAlpha);
}
public override void AlignPlacementMode(ScreenCoordinates mouseScreen)
{
_unalignedMouseCoords = ScreenToCursorGrid(mouseScreen);
MouseCoords = _unalignedMouseCoords.AlignWithClosestGridTile(SearchBoxSize, _entityManager, _mapManager);
var gridId = _transformSystem.GetGrid(MouseCoords);
if (!_entityManager.TryGetComponent<MapGridComponent>(gridId, out var mapGrid))
return;
CurrentTile = _mapSystem.GetTileRef(gridId.Value, mapGrid, MouseCoords);
float tileSize = mapGrid.TileSize;
GridDistancing = tileSize;
if (pManager.CurrentPermission!.IsTile)
{
MouseCoords = new EntityCoordinates(MouseCoords.EntityId, new Vector2(CurrentTile.X + tileSize / 2,
CurrentTile.Y + tileSize / 2));
}
else
{
MouseCoords = new EntityCoordinates(MouseCoords.EntityId, new Vector2(CurrentTile.X + tileSize / 2 + pManager.PlacementOffset.X,
CurrentTile.Y + tileSize / 2 + pManager.PlacementOffset.Y));
}
}
public override bool IsValidPosition(EntityCoordinates position)
{
var player = _playerManager.LocalSession?.AttachedEntity;
// If the destination is out of interaction range, set the placer alpha to zero
if (!_entityManager.TryGetComponent<TransformComponent>(player, out var xform))
return false;
if (!_transformSystem.InRange(xform.Coordinates, position, SharedInteractionSystem.InteractionRange))
{
InvalidPlaceColor = InvalidPlaceColor.WithAlpha(0);
return false;
}
// Otherwise restore the alpha value
else
{
InvalidPlaceColor = InvalidPlaceColor.WithAlpha(PlaceColorBaseAlpha);
}
// Determine if player is carrying an RCD in their active hand
if (!_handsSystem.TryGetActiveItem(player.Value, out var heldEntity))
return false;
if (!_entityManager.TryGetComponent<RCDComponent>(heldEntity, out var rcd))
return false;
var gridUid = _transformSystem.GetGrid(position);
if (!_entityManager.TryGetComponent<MapGridComponent>(gridUid, out var mapGrid))
return false;
var tile = _mapSystem.GetTileRef(gridUid.Value, mapGrid, position);
var posVector = _mapSystem.TileIndicesFor(gridUid.Value, mapGrid, position);
// Determine if the user is hovering over a target
var currentState = _stateManager.CurrentState;
if (currentState is not GameplayStateBase screen)
return false;
var target = screen.GetClickedEntity(_transformSystem.ToMapCoordinates(_unalignedMouseCoords));
// Determine if the RCD operation is valid or not
if (!_rcdSystem.IsRCDOperationStillValid(heldEntity.Value, rcd, gridUid.Value, mapGrid, tile, posVector, target, player.Value, false))
return false;
return true;
}
}