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