diff --git a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs index 908b2c2db7..6de2a7a585 100644 --- a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs @@ -1,22 +1,21 @@ -using System; using System.Numerics; -using Content.Client.Station; // Frontier using Content.Client.Weapons.Ranged.Systems; using Content.Shared.Projectiles; using Content.Shared.Shuttles.BUIStates; using Content.Shared.Shuttles.Components; using Content.Shared.Shuttles.Systems; -using Content.Shared.Weapons.Ranged.Components; using JetBrains.Annotations; using Robust.Client.AutoGenerated; using Robust.Client.Graphics; using Robust.Client.UserInterface; using Robust.Client.UserInterface.XAML; +using Robust.Shared.Collections; using Robust.Shared.Input; using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Physics; using Robust.Shared.Physics.Components; +using Robust.Shared.Utility; namespace Content.Client.Shuttles.UI; @@ -41,7 +40,7 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl public bool ShowIFF { get; set; } = true; public bool ShowDocks { get; set; } = true; public bool RotateWithEntity { get; set; } = true; - public float FieldOfView = MathF.Tau; + public float FieldOfView = MathF.Tau; // WD EDIT /// /// Raised if the user left-clicks on the radar control with the relevant entitycoordinates. @@ -55,8 +54,8 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl RobustXamlLoader.Load(this); _shuttles = EntManager.System(); _transform = EntManager.System(); - _lookup = EntManager.System(); // WWDP EDIT - _gun = EntManager.System(); // WWDP EDIT + _lookup = EntManager.System(); // WD EDIT + _gun = EntManager.System(); // WD EDIT } public void SetMatrix(EntityCoordinates? coordinates, Angle? angle) @@ -122,7 +121,7 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl _docks = state.Docks; - FieldOfView = state.FieldOfView; // WWDP EDIT + FieldOfView = state.FieldOfView; // WD EDIT NfUpdateState(state); // Frontier Update State } @@ -132,6 +131,7 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl base.Draw(handle); DrawBacking(handle); + DrawCircles(handle); // No data if (_coordinates == null || _rotation == null) @@ -143,8 +143,6 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl var fixturesQuery = EntManager.GetEntityQuery(); var bodyQuery = EntManager.GetEntityQuery(); - _gun.TryGetGun(_coordinates.Value.EntityId, out _, out var ourGunComp); // WWDP EDIT - if (!xformQuery.TryGetComponent(_coordinates.Value.EntityId, out var xform) || xform.MapID == MapId.Nullspace) { @@ -156,8 +154,8 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl var posMatrix = Matrix3Helpers.CreateTransform(offset, _rotation.Value); var ourEntRot = RotateWithEntity ? _transform.GetWorldRotation(xform) : _rotation.Value; var ourEntMatrix = Matrix3Helpers.CreateTransform(_transform.GetWorldPosition(xform), ourEntRot); - var ourWorldPos = ourEntMatrix.Translation; // WD EDIT - Matrix3x2.Invert(ourEntMatrix, out var ourWorldMatrixInvert); + var ourWorldMatrix = Matrix3x2.Multiply(posMatrix, ourEntMatrix); + Matrix3x2.Invert(ourWorldMatrix, out var ourWorldMatrixInvert); // Draw our grid in detail var ourGridId = xform.GridUid; @@ -189,7 +187,6 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl }; handle.DrawPrimitives(DrawPrimitiveTopology.TriangleFan, radarPosVerts, Color.Lime); - //handle.DrawLine(ScalePosition(radarPos), ScalePosition(radarPos - Vector2.UnitY * 20), Color.Lime); var rot = ourEntRot + _rotation.Value; var viewBounds = new Box2Rotated(new Box2(-WorldRange, -WorldRange, WorldRange, WorldRange).Translated(mapPos.Position), rot, mapPos.Position); @@ -197,7 +194,9 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl _grids.Clear(); _mapManager.FindGridsIntersecting(xform.MapID, new Box2(mapPos.Position - MaxRadarRangeVector, mapPos.Position + MaxRadarRangeVector), ref _grids, approx: true, includeMap: false); + List<(Vector2, string, Color)> IFFLabels = new(); // WD EDIT + // Draw other grids... differently foreach (var grid in _grids) { @@ -213,7 +212,9 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl var gridMatrix = _transform.GetWorldMatrix(gUid); var matty = Matrix3x2.Multiply(gridMatrix, ourWorldMatrixInvert); - var color = _shuttles.GetIFFColor(grid, self: false, iff); + + var labelColor = _shuttles.GetIFFColor(grid, self: false, iff); + var coordColor = new Color(labelColor.R * 0.8f, labelColor.G * 0.8f, labelColor.B * 0.8f, 0.5f); // Others default: // Color.FromHex("#FFC000FF") @@ -225,35 +226,59 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl var gridInCone = Vector2.Normalize(gridCentre).Y >= MathF.Cos(FieldOfView / 2) || FieldOfView >= MathF.Tau; // WD EDITN END - if (ShowIFF && - labelName != null) + if (ShowIFF && labelName != null && gridInCone) // WD EDIT { var gridBounds = grid.Comp.LocalAABB; - if (gridInCone) // WD EDIT + gridCentre.Y = -gridCentre.Y; + + var distance = gridCentre.Length(); + var labelText = Loc.GetString("shuttle-console-iff-label", ("name", labelName), + ("distance", $"{distance:0.0}")); + + var mapCoords = _transform.GetWorldPosition(gUid); + var coordsText = $"({mapCoords.X:0.0}, {mapCoords.Y:0.0})"; + + // yes 1.0 scale is intended here. + var labelDimensions = handle.GetDimensions(Font, labelText, 1f); + var coordsDimensions = handle.GetDimensions(Font, coordsText, 0.7f); + + // y-offset the control to always render below the grid (vertically) + var yOffset = Math.Max(gridBounds.Height, gridBounds.Width) * MinimapScale / 1.8f; + + // The actual position in the UI. We centre the label by offsetting the matrix position + // by half the label's width, plus the y-offset + var gridScaledPosition = ScalePosition(gridCentre) - new Vector2(0, -yOffset); + + // Normalize the grid position if it exceeds the viewport bounds + // normalizing it instead of clamping it preserves the direction of the vector and prevents corner-hugging + var gridOffset = gridScaledPosition / PixelSize - new Vector2(0.5f, 0.5f); + var offsetMax = Math.Max(Math.Abs(gridOffset.X), Math.Abs(gridOffset.Y)) * 2f; + if (offsetMax > 1) { - gridCentre.Y = -gridCentre.Y; - var distance = gridCentre.Length(); - var labelText = Loc.GetString("shuttle-console-iff-label", ("name", labelName), - ("distance", $"{distance:0.0}")); + gridOffset = new Vector2(gridOffset.X / offsetMax, gridOffset.Y / offsetMax); - // yes 1.0 scale is intended here. - var labelDimensions = handle.GetDimensions(Font, labelText, 1f); - - // y-offset the control to always render below the grid (vertically) - var yOffset = Math.Max(gridBounds.Height, gridBounds.Width) * MinimapScale / 1.8f; - - // The actual position in the UI. We offset the matrix position to render it off by half its width - // plus by the offset. - var uiPosition = ScalePosition(gridCentre) - new Vector2(labelDimensions.X / 2f, -yOffset); - - // Look this is uggo so feel free to cleanup. We just need to clamp the UI position to within the viewport. - uiPosition = new Vector2(Math.Clamp(uiPosition.X, 0f, PixelWidth - labelDimensions.X), - Math.Clamp(uiPosition.Y, 0f, PixelHeight - labelDimensions.Y)); - - IFFLabels.Add((uiPosition, labelText, color)); // WD EDIT - //handle.DrawString(Font, uiPosition, labelText, color); + gridScaledPosition = (gridOffset + new Vector2(0.5f, 0.5f)) * PixelSize; } + + var labelUiPosition = gridScaledPosition - new Vector2(labelDimensions.X / 2f, 0); + var coordUiPosition = gridScaledPosition - new Vector2(coordsDimensions.X / 2f, -labelDimensions.Y); + + // clamp the IFF label's UI position to within the viewport extents so it hugs the edges of the viewport + // coord label intentionally isn't clamped so we don't get ugly clutter at the edges + var controlExtents = PixelSize - new Vector2(labelDimensions.X, labelDimensions.Y); //new Vector2(labelDimensions.X * 2f, labelDimensions.Y); + labelUiPosition = Vector2.Clamp(labelUiPosition, Vector2.Zero, controlExtents); + + // draw IFF label + handle.DrawString(Font, labelUiPosition, labelText, labelColor); + + // only draw coords label if close enough + if (offsetMax < 1) + { + handle.DrawString(Font, coordUiPosition, coordsText, 0.7f, coordColor); + } + + IFFLabels.Add((coordUiPosition, labelText, labelColor)); // WD EDIT } // Detailed view @@ -263,10 +288,11 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl if (!gridAABB.Intersects(viewAABB)) continue; - DrawGrid(handle, matty, grid, color); + DrawGrid(handle, matty, grid, labelColor); DrawDocks(handle, gUid, matty); - // WWDP EDIT START + // WD EDIT START + _gun.TryGetGun(_coordinates.Value.EntityId, out _, out var ourGunComp); // Leading pip if (ourGunComp is not { } gun || !gridInCone) continue; @@ -277,7 +303,7 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl var u1 = gridBody.LinearVelocity.Length(); var u2 = gun.ProjectileSpeedModified; - var dirToGrid = (float)Angle.FromWorldVec(gridCenterWorld - ourWorldPos).Theta; + var dirToGrid = (float)Angle.FromWorldVec(gridCenterWorld - ourEntMatrix.Translation).Theta; var sinBeta = u1 / u2 * (float) Math.Sin(-Angle.FromWorldVec(-gridBody.LinearVelocity) + dirToGrid); if (!(sinBeta > -1) || !(sinBeta < 1)) continue; @@ -285,7 +311,7 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl var beta = MathF.Asin(sinBeta) + dirToGrid; var shootDir = new Vector2(MathF.Sin(beta), MathF.Cos(beta)); - var t = (gridCenterWorld - ourWorldPos).Length() / (-gridBody.LinearVelocity + shootDir * gun.ProjectileSpeedModified).Length(); + var t = (gridCenterWorld - ourEntMatrix.Translation).Length() / (-gridBody.LinearVelocity + shootDir * gun.ProjectileSpeedModified).Length(); if (!(gridBody.LinearVelocity.Length() * t <= 250)) // arbitrary continue; @@ -293,12 +319,12 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl var leadPos = Vector2.Transform(leadPosWorld, ourWorldMatrixInvert); var scaledLeadPos = ScalePositionFlipY(leadPos); - handle.DrawDottedLine(ScalePosition(gridCentre), scaledLeadPos, color, 0, 2, 8); - handle.DrawCircle(scaledLeadPos, 4, color, false); - // WWDP EDIT END + handle.DrawDottedLine(ScalePosition(gridCentre), scaledLeadPos, labelColor, 0, 2, 8); + handle.DrawCircle(scaledLeadPos, 4, labelColor, false); + // WD EDIT END } - // WWDP EDIT START + // WD EDIT START var multiply = Matrix3x2.Multiply(ourWorldMatrixInvert, Matrix3x2.CreateScale(new Vector2(1,-1))); var projectiles = _lookup.GetEntitiesInRange(_coordinates.Value, 256f); var verts = new Vector2[projectiles.Count*4]; @@ -338,7 +364,7 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl handle.DrawString(Font, uiPos, label, color); } DrawCircles(handle); - // WWDP EDIT END + // WD EDIT END } private void DrawDocks(DrawingHandleScreen handle, EntityUid uid, Matrix3x2 matrix)