using System.Numerics; using Content.Shared.Maps; using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Input; using Robust.Shared.Input; using Robust.Shared.Map; using Robust.Shared.Physics.Components; using Robust.Shared.Timing; namespace Content.Client.Maps; /// public sealed class GridDraggingSystem : SharedGridDraggingSystem { [Dependency] private readonly IEyeManager _eyeManager = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IInputManager _inputManager = default!; [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly InputSystem _inputSystem = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; public bool Enabled { get; set; } private EntityUid? _dragging; private Vector2 _localPosition; private MapCoordinates? _lastMousePosition; public override void Initialize() { base.Initialize(); SubscribeNetworkEvent(OnToggleMessage); } private void OnToggleMessage(GridDragToggleMessage ev) { if (Enabled == ev.Enabled) return; Enabled = ev.Enabled; if (!Enabled) StopDragging(); } private void StartDragging(EntityUid grid, Vector2 localPosition) { _dragging = grid; _localPosition = localPosition; if (TryComp(grid, out var body)) { RaiseNetworkEvent(new GridDragVelocityRequest() { Grid = grid, LinearVelocity = Vector2.Zero }); } } private void StopDragging() { if (_dragging == null) return; if (_lastMousePosition != null && TryComp(_dragging.Value, out var xform) && TryComp(_dragging.Value, out var body) && xform.MapID == _lastMousePosition.Value.MapId) { var tickTime = _gameTiming.TickPeriod; var distance = _lastMousePosition.Value.Position - _transform.GetWorldPosition(xform); RaiseNetworkEvent(new GridDragVelocityRequest() { Grid = _dragging.Value, LinearVelocity = distance.LengthSquared() > 0f ? (distance / (float) tickTime.TotalSeconds) * 0.25f : Vector2.Zero, }); } _dragging = null; _localPosition = Vector2.Zero; _lastMousePosition = null; } public override void Update(float frameTime) { base.Update(frameTime); if (!Enabled || !_gameTiming.IsFirstTimePredicted) return; var state = _inputSystem.CmdStates.GetState(EngineKeyFunctions.Use); if (state != BoundKeyState.Down) { StopDragging(); return; } var mouseScreenPos = _inputManager.MouseScreenPosition; var mousePos = _eyeManager.PixelToMap(mouseScreenPos); if (_dragging == null) { if (!_mapManager.TryFindGridAt(mousePos, out var gridUid, out var grid)) return; StartDragging(gridUid, _transform.GetInvWorldMatrix(gridUid).Transform(mousePos.Position)); } if (!TryComp(_dragging, out var xform)) { StopDragging(); return; } if (xform.MapID != mousePos.MapId) { StopDragging(); return; } var localToWorld = _transform.GetWorldMatrix(xform).Transform(_localPosition); if (localToWorld.EqualsApprox(mousePos.Position, 0.01f)) return; var requestedGridOrigin = mousePos.Position - _transform.GetWorldRotation(xform).RotateVec(_localPosition); _lastMousePosition = new MapCoordinates(requestedGridOrigin, mousePos.MapId); RaiseNetworkEvent(new GridDragRequestPosition() { Grid = _dragging.Value, WorldPosition = requestedGridOrigin, }); } }