Major updates to the HUD and selectable objects

This commit is contained in:
Matt F 2026-05-11 23:57:35 -07:00
parent 5bc757b385
commit c100db52e5
23 changed files with 1615 additions and 614 deletions

View file

@ -60,6 +60,15 @@ namespace TD.UI.Minimap
// Outline added to builder icons so they read against same-color zone fill.
private static readonly Color BuilderOutline = new Color(1f, 1f, 1f, 0.85f);
// Viewport trapezoid (the "what the player sees" rectangle on the minimap).
// Drawn on top of all entities so it's always readable; matches WC3 visual style.
private static readonly Color ViewportColor = new Color(1f, 1f, 1f, 0.85f);
private const float ViewportLineWidth = 1.5f;
// Reused buffer for the camera's four world-space view corners. Heap-allocated
// once and refilled every repaint to avoid per-frame GC.
private readonly Vector3[] viewCornersBuf = new Vector3[4];
// ----- Refs -------------------------------------------------------
private readonly VisualElement container;
@ -309,12 +318,15 @@ namespace TD.UI.Minimap
private void HandleRightClickMove(Vector2 uiLocal)
{
// Right-click on the minimap = "send my builder there". Only meaningful when
// the LOCAL BUILDER is selected; a tower or enemy selection has no move action.
var selection = SelectionState.Instance;
if (selection == null || !selection.HasSelection) return;
var builder = selection?.SelectedBuilder;
if (builder == null) return;
Vector3 worldTarget = UIToWorld(uiLocal);
// Same RPC the world right-click uses; server validates and side-effects the queue.
selection.SelectedBuilder.RequestMoveAndPauseRpc(worldTarget);
builder.RequestMoveAndPauseRpc(worldTarget);
}
// ----- Zoom -------------------------------------------------------
@ -436,6 +448,40 @@ namespace TD.UI.Minimap
// (e.g., on a dedicated server or before the local client's builder arrives).
if (localBuilder != null)
DrawOneEntity(painter, localBuilder, pxPerWorld);
// Pass 3: the camera-viewport trapezoid sits on top of everything so the
// player can always see where they're looking, regardless of zone tint or
// unit density underneath.
DrawViewportRect(painter);
}
// Draws a thin white outline matching the camera's footprint on the buildable
// plane. Because the camera is angled, the on-plane footprint is a TRAPEZOID
// (far edge wider than near edge) — that's the visual we want, since it tells
// the player how much of the world they're actually seeing at the current pitch.
private void DrawViewportRect(Painter2D painter)
{
if (cameraController == null) return;
// Even when one or more corners can't be projected onto the plane (camera at
// the horizon), the fallback puts them at a far point along the ray. The
// resulting UI coords land outside the container and get clipped by
// overflow:hidden — perfectly acceptable visual.
cameraController.TryGetViewportWorldCorners(viewCornersBuf);
Vector2 a = WorldToUI(viewCornersBuf[0]);
Vector2 b = WorldToUI(viewCornersBuf[1]);
Vector2 c = WorldToUI(viewCornersBuf[2]);
Vector2 d = WorldToUI(viewCornersBuf[3]);
painter.strokeColor = ViewportColor;
painter.lineWidth = ViewportLineWidth;
painter.BeginPath();
painter.MoveTo(a);
painter.LineTo(b);
painter.LineTo(c);
painter.LineTo(d);
painter.ClosePath();
painter.Stroke();
}
private void DrawOneEntity(Painter2D p, IMinimapEntity entity, float pxPerWorld)