Radar changes (#14783)

This commit is contained in:
metalgearsloth
2023-03-23 16:52:20 +11:00
committed by GitHub
parent a0a96da4c9
commit ca94c1748e

View File

@@ -1,10 +1,13 @@
using Content.Shared.Shuttles.BUIStates; using Content.Shared.Shuttles.BUIStates;
using Content.Shared.Shuttles.Components; using Content.Shared.Shuttles.Components;
using JetBrains.Annotations;
using Content.Shared.Shuttles.Systems; using Content.Shared.Shuttles.Systems;
using Robust.Client.Graphics; using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Client.UserInterface; using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.Controls;
using Robust.Shared.Collections; using Robust.Shared.Collections;
using Robust.Shared.Input;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Map.Components; using Robust.Shared.Map.Components;
using Robust.Shared.Physics; using Robust.Shared.Physics;
@@ -71,6 +74,11 @@ public sealed class RadarControl : Control
public Action<float>? OnRadarRangeChanged; public Action<float>? OnRadarRangeChanged;
/// <summary>
/// Raised if the user left-clicks on the radar control with the relevant entitycoordinates.
/// </summary>
public Action<EntityCoordinates>? OnRadarClick;
public RadarControl() public RadarControl()
{ {
IoCManager.InjectDependencies(this); IoCManager.InjectDependencies(this);
@@ -103,6 +111,43 @@ public sealed class RadarControl : Control
} }
} }
protected override void KeyBindUp(GUIBoundKeyEventArgs args)
{
base.KeyBindUp(args);
if (_coordinates == null || _rotation == null || args.Function != EngineKeyFunctions.UIClick ||
OnRadarClick == null)
{
return;
}
var a = InverseScalePosition(args.RelativePosition);
var relativeWorldPos = new Vector2(a.X, -a.Y);
relativeWorldPos = _rotation.Value.RotateVec(relativeWorldPos);
var coords = _coordinates.Value.Offset(relativeWorldPos);
OnRadarClick?.Invoke(coords);
}
/// <summary>
/// Gets the entitycoordinates of where the mouseposition is, relative to the control.
/// </summary>
[PublicAPI]
public EntityCoordinates GetMouseCoordinates(ScreenCoordinates screen)
{
if (_coordinates == null || _rotation == null)
{
return EntityCoordinates.Invalid;
}
var pos = screen.Position / UIScale - GlobalPosition;
var a = InverseScalePosition(pos);
var relativeWorldPos = new Vector2(a.X, -a.Y);
relativeWorldPos = _rotation.Value.RotateVec(relativeWorldPos);
var coords = _coordinates.Value.Offset(relativeWorldPos);
return coords;
}
protected override void MouseWheel(GUIMouseWheelEventArgs args) protected override void MouseWheel(GUIMouseWheelEventArgs args)
{ {
base.MouseWheel(args); base.MouseWheel(args);
@@ -169,17 +214,18 @@ public sealed class RadarControl : Control
var offset = _coordinates.Value.Position; var offset = _coordinates.Value.Position;
var offsetMatrix = Matrix3.CreateInverseTransform( var offsetMatrix = Matrix3.CreateInverseTransform(
mapPosition.Position, mapPosition.Position,
xform.WorldRotation - _rotation.Value); xform.WorldRotation + _rotation.Value);
// Draw our grid in detail // Draw our grid in detail
var ourGridId = _coordinates.Value.GetGridUid(_entManager); var ourGridId = _coordinates.Value.GetGridUid(_entManager);
if (_entManager.TryGetComponent<MapGridComponent>(ourGridId, out var ourGrid)) if (_entManager.TryGetComponent<MapGridComponent>(ourGridId, out var ourGrid) &&
fixturesQuery.TryGetComponent(ourGridId, out var ourFixturesComp))
{ {
var ourGridMatrix = xformQuery.GetComponent(ourGridId.Value).WorldMatrix; var ourGridMatrix = xformQuery.GetComponent(ourGridId.Value).WorldMatrix;
Matrix3.Multiply(in ourGridMatrix, in offsetMatrix, out var matrix); Matrix3.Multiply(in ourGridMatrix, in offsetMatrix, out var matrix);
DrawGrid(handle, matrix, ourGrid, Color.MediumSpringGreen, true); DrawGrid(handle, matrix, ourFixturesComp, ourGrid, Color.MediumSpringGreen, true);
DrawDocks(handle, ourGridId.Value, matrix); DrawDocks(handle, ourGridId.Value, matrix);
} }
@@ -196,7 +242,7 @@ public sealed class RadarControl : Control
foreach (var grid in _mapManager.FindGridsIntersecting(mapPosition.MapId, foreach (var grid in _mapManager.FindGridsIntersecting(mapPosition.MapId,
new Box2(mapPosition.Position - MaxRadarRange, mapPosition.Position + MaxRadarRange))) new Box2(mapPosition.Position - MaxRadarRange, mapPosition.Position + MaxRadarRange)))
{ {
if (grid.Owner == ourGridId) if (grid.Owner == ourGridId || !fixturesQuery.TryGetComponent(grid.Owner, out var fixturesComp))
continue; continue;
var gridBody = bodyQuery.GetComponent(grid.Owner); var gridBody = bodyQuery.GetComponent(grid.Owner);
@@ -278,7 +324,7 @@ public sealed class RadarControl : Control
} }
// Detailed view // Detailed view
DrawGrid(handle, matty, grid, color, true); DrawGrid(handle, matty, fixturesComp, grid, color, true);
DrawDocks(handle, grid.Owner, matty); DrawDocks(handle, grid.Owner, matty);
} }
@@ -349,32 +395,29 @@ public sealed class RadarControl : Control
} }
} }
private void DrawGrid(DrawingHandleScreen handle, Matrix3 matrix, MapGridComponent grid, Color color, bool drawInterior) private void DrawGrid(DrawingHandleScreen handle, Matrix3 matrix, FixturesComponent fixturesComp, MapGridComponent grid, Color color, bool drawInterior)
{ {
var rator = grid.GetAllTilesEnumerator(); var rator = grid.GetAllTilesEnumerator();
var edges = new ValueList<Vector2>(); var edges = new ValueList<Vector2>();
var tileTris = new ValueList<Vector2>(); var tileTris = new ValueList<Vector2>();
Span<Vector2> tileVerts = new Vector2[4];
// Originally I used fixtures but this was a massive hassle if (drawInterior)
// Long-term it's probably better due to less data getting drawn but this is what it is for now.
while (rator.MoveNext(out var tileRef))
{ {
var tileVec = (Vector2) tileRef.Value.GridIndices * grid.TileSize; var interiorTris = new ValueList<Vector2>();
// TODO: Engine pr
Span<Vector2> verts = new Vector2[8];
if (drawInterior) foreach (var fixture in fixturesComp.Fixtures.Values)
{ {
tileVerts[0] = tileVec;
tileVerts[1] = tileVec + new Vector2(grid.TileSize, 0f);
tileVerts[2] = tileVec + new Vector2(grid.TileSize, grid.TileSize);
tileVerts[3] = tileVec + new Vector2(0f, grid.TileSize);
// If the fixture has any points out of range we won't draw any of it.
var invalid = false; var invalid = false;
var poly = (PolygonShape) fixture.Shape;
for (var i = 0; i < 4; i++) for (var i = 0; i < poly.VertexCount; i++)
{ {
var vert = matrix.Transform(tileVerts[i]); var vert = poly.Vertices[i];
vert = new Vector2(MathF.Round(vert.X), MathF.Round(vert.Y));
vert = matrix.Transform(vert);
if (vert.Length > RadarRange) if (vert.Length > RadarRange)
{ {
@@ -382,22 +425,41 @@ public sealed class RadarControl : Control
break; break;
} }
vert.Y = -vert.Y; verts[i] = vert;
tileVerts[i] = ScalePosition(vert);
} }
if (invalid) if (invalid)
continue; continue;
tileTris.Add(tileVerts[0]); Vector2 AdjustedVert(Vector2 vert)
tileTris.Add(tileVerts[1]); {
tileTris.Add(tileVerts[3]); if (vert.Length > RadarRange)
{
vert = vert.Normalized * RadarRange;
}
tileTris.Add(tileVerts[1]); vert.Y = -vert.Y;
tileTris.Add(tileVerts[3]); return ScalePosition(vert);
tileTris.Add(tileVerts[2]); }
interiorTris.Add(AdjustedVert(verts[0]));
interiorTris.Add(AdjustedVert(verts[1]));
interiorTris.Add(AdjustedVert(verts[3]));
interiorTris.Add(AdjustedVert(verts[1]));
interiorTris.Add(AdjustedVert(verts[2]));
interiorTris.Add(AdjustedVert(verts[3]));
} }
handle.DrawPrimitives(DrawPrimitiveTopology.TriangleList, interiorTris.Span, color.WithAlpha(0.05f));
}
while (rator.MoveNext(out var tileRef))
{
// TODO: Short-circuit interior chunk nodes
// This can be optimised a lot more if required.
Vector2? tileVec = null;
// Iterate edges and see which we can draw // Iterate edges and see which we can draw
for (var i = 0; i < 4; i++) for (var i = 0; i < 4; i++)
{ {
@@ -409,26 +471,27 @@ public sealed class RadarControl : Control
Vector2 start; Vector2 start;
Vector2 end; Vector2 end;
tileVec ??= (Vector2) tileRef.Value.GridIndices * grid.TileSize;
// Draw line // Draw line
// Could probably rotate this but this might be faster? // Could probably rotate this but this might be faster?
switch (dir) switch (dir)
{ {
case DirectionFlag.South: case DirectionFlag.South:
start = tileVec; start = tileVec.Value;
end = tileVec + new Vector2(grid.TileSize, 0f); end = tileVec.Value + new Vector2(grid.TileSize, 0f);
break; break;
case DirectionFlag.East: case DirectionFlag.East:
start = tileVec + new Vector2(grid.TileSize, 0f); start = tileVec.Value + new Vector2(grid.TileSize, 0f);
end = tileVec + new Vector2(grid.TileSize, grid.TileSize); end = tileVec.Value + new Vector2(grid.TileSize, grid.TileSize);
break; break;
case DirectionFlag.North: case DirectionFlag.North:
start = tileVec + new Vector2(grid.TileSize, grid.TileSize); start = tileVec.Value + new Vector2(grid.TileSize, grid.TileSize);
end = tileVec + new Vector2(0f, grid.TileSize); end = tileVec.Value + new Vector2(0f, grid.TileSize);
break; break;
case DirectionFlag.West: case DirectionFlag.West:
start = tileVec + new Vector2(0f, grid.TileSize); start = tileVec.Value + new Vector2(0f, grid.TileSize);
end = tileVec; end = tileVec.Value;
break; break;
default: default:
throw new NotImplementedException(); throw new NotImplementedException();
@@ -456,4 +519,9 @@ public sealed class RadarControl : Control
{ {
return value * MinimapScale + MidPoint; return value * MinimapScale + MidPoint;
} }
private Vector2 InverseScalePosition(Vector2 value)
{
return (value - MidPoint) / MinimapScale;
}
} }