B button launches upgrade menu
This commit is contained in:
parent
79cd331141
commit
3ada934e41
1 changed files with 89 additions and 56 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue