B button launches upgrade menu

This commit is contained in:
Ian Woods 2026-06-03 20:53:01 -07:00
parent 79cd331141
commit 3ada934e41

View file

@ -25,39 +25,41 @@ namespace TD.UI
// ----- Inspector --------------------------------------------------
[Header("Scene References")]
[Tooltip("The local client's TowerPlacementController.")]
[SerializeField] private TowerPlacementController placementController;
[Header("Scene References")] [Tooltip("The local client's TowerPlacementController.")] [SerializeField]
private TowerPlacementController placementController;
[Tooltip("The local client's TowerPaintController (drives the Paint tab + paint cursor).")]
[SerializeField] private TowerPaintController paintController;
[Tooltip("The TowerPlacementManager NetworkObject in the scene.")]
[SerializeField] private TowerPlacementManager placementManager;
[Tooltip("The TowerPlacementManager NetworkObject in the scene.")] [SerializeField]
private TowerPlacementManager placementManager;
[Tooltip("The local client's CameraController. Used by the minimap for click-to-jump " +
"and drag-to-pan.")]
[SerializeField] private CameraController cameraController;
[SerializeField]
private CameraController cameraController;
[Header("Settings")]
[SerializeField] private float rejectionMessageDuration = 2.5f;
[Header("Settings")] [SerializeField] private float rejectionMessageDuration = 2.5f;
[Tooltip("Maximum visible height of the chat feed in pixels. Content past this " +
"height is clipped — older messages scroll off the top of the visible area " +
"but stay in history (scroll up while chat is open to view).")]
[SerializeField] private float chatMaxHeight = 280f;
[SerializeField]
private float chatMaxHeight = 280f;
[Tooltip("Maximum messages kept in chat history. Defaults to effectively unlimited " +
"(int.MaxValue) — every message sent during a match stays scrollable. " +
"Lower the value if a long match ever shows DOM perf issues; this field " +
"is the safety valve, not a normal-play limit.")]
[SerializeField] private int chatMaxMessages = int.MaxValue;
[SerializeField]
private int chatMaxMessages = int.MaxValue;
[Tooltip("Color used for SYSTEM chat messages (e.g. 'Life Lost', income changes).")]
[SerializeField] private Color chatSystemColor = new Color(1f, 0.7f, 0.2f);
[Tooltip("Color used for SYSTEM chat messages (e.g. 'Life Lost', income changes).")] [SerializeField]
private Color chatSystemColor = new Color(1f, 0.7f, 0.2f);
[Tooltip("Color used for PLAYER chat message bodies. Sender prefix uses the player's slot color.")]
[SerializeField] private Color chatPlayerColor = new Color(0.92f, 0.92f, 0.92f);
[SerializeField]
private Color chatPlayerColor = new Color(0.92f, 0.92f, 0.92f);
// ----- Cached UI element references -------------------------------
@ -72,6 +74,7 @@ namespace TD.UI
private Label levelLabel;
private VisualElement statLines;
private VisualElement commandGrid;
private VisualElement actionFrame; // hidden via display:none when no actions are available
private VisualElement commandTabs; // Build/Paint tab row — shown only for a Builder selection
private Button tabBuild;
@ -79,6 +82,7 @@ namespace TD.UI
private VisualElement buildProgressContainer; // info-panel sub-view, shown for BuildSiteVisual selections
private VisualElement buildProgressFill; // width driven each frame from progress
private Label buildProgressPercent;
private Label ttTitle;
private Label ttDesc;
private Label ttStats;
@ -158,8 +162,13 @@ namespace TD.UI
public readonly Key Key;
public readonly VisualElement Button; // for enabledSelf gating
public readonly System.Action Action;
public HotkeyBinding(Key k, VisualElement b, System.Action a)
{ Key = k; Button = b; Action = a; }
{
Key = k;
Button = b;
Action = a;
}
}
// ----- Static hit-test probe --------------------------------------
@ -255,6 +264,7 @@ namespace TD.UI
// Cache element references — log a warning for any that are missing
// so UXML/USS mismatches surface immediately.
goldLabel = Require<Label>(root, "gold-label");
waveLabel = Require<Label>(root, "wave-label");
livesLabel = Require<Label>(root, "lives-label");
@ -273,6 +283,7 @@ namespace TD.UI
if (tabBuild != null) tabBuild.clicked += () => SwitchTab(CommandTab.Build);
if (tabPaint != null) tabPaint.clicked += () => SwitchTab(CommandTab.Paint);
buildProgressContainer = Require<VisualElement>(root, "build-progress");
buildProgressFill = Require<VisualElement>(root, "build-progress-fill");
buildProgressPercent = Require<Label>(root, "build-progress-percent");
@ -357,6 +368,7 @@ namespace TD.UI
SelectionState.Instance.OnSelectionChanged -= HandleSelectionChanged;
selectionSubscribed = false;
}
if (matchStateSubscribed && MatchState.Instance != null)
{
MatchState.Instance.OnPhaseChanged -= HandlePhaseChanged;
@ -421,6 +433,7 @@ namespace TD.UI
buildProgressFill.style.width =
new StyleLength(new Length(progress * 100f, LengthUnit.Percent));
}
if (buildProgressPercent != null)
{
buildProgressPercent.text = $"{Mathf.RoundToInt(progress * 100f)}%";
@ -653,6 +666,7 @@ namespace TD.UI
// gated by the lobby), but the values do.
private static readonly System.Text.StringBuilder s_scoreboardSigBuf =
new System.Text.StringBuilder(64);
private string ComputeScoreboardSignature(System.Collections.Generic.List<PlayerMatchState> players)
{
s_scoreboardSigBuf.Clear();
@ -662,12 +676,14 @@ namespace TD.UI
var gm = PlayerGoldManager.GetForClient(pms.OwnerClientId);
int gold = gm != null ? gm.CurrentGold : 0;
int leaks = (wm != null && pms.Slot != PlayerSlot.None)
? wm.GetZoneLeakCount(pms.Slot) : 0;
? wm.GetZoneLeakCount(pms.Slot)
: 0;
s_scoreboardSigBuf.Append((int)pms.Slot).Append(':')
.Append(pms.DisplayName ?? string.Empty).Append(':')
.Append(gold).Append(':')
.Append(leaks).Append(';');
}
return s_scoreboardSigBuf.ToString();
}
@ -754,7 +770,9 @@ namespace TD.UI
cells[i] = CreateTowerButton(def, typeId, HotkeyLayout[i]);
i++;
}
}
cells[GRID_MAX - 1] = CreateBuffMenuButton(HotkeyLayout[GRID_MAX - 1]);
}
else if (selection is TowerInstance tower)
{
@ -908,6 +926,7 @@ namespace TD.UI
costLabel.pickingMode = PickingMode.Ignore;
btn.Add(costLabel);
}
return btn;
}
@ -919,7 +938,10 @@ namespace TD.UI
var btn = CreateActionButton(
costText: "", // tier cost unknown until upgrade system lands
hotkey: hotkey,
onClick: () => { /* TODO: upgrade flow */ });
onClick: () =>
{
/* TODO: upgrade flow */
});
btn.SetEnabled(false);
return btn;
}
@ -932,11 +954,22 @@ namespace TD.UI
var btn = CreateActionButton(
costText: sellValue > 0 ? $"+{sellValue}g" : "",
hotkey: hotkey,
onClick: () => { /* TODO: sell flow */ });
onClick: () =>
{
/* TODO: sell flow */
});
btn.SetEnabled(false);
return btn;
}
private VisualElement CreateBuffMenuButton(Key hotkey)
{
return CreateActionButton(
costText: "Buffs",
hotkey: hotkey,
onClick: () => ToggleBuffMenu());
}
// Cancel action for an in-progress build. Fires the owner-only RPC; the
// server cancels the matching job (or, for shelved sites, refunds + despawns
// directly), full gold is refunded, the BuildSiteVisual is despawned, and