Adding new tower types and concept of tower deck

This commit is contained in:
Matt F 2026-06-23 21:55:12 -07:00
parent d1930a6b00
commit 117c77b4a8
16 changed files with 463 additions and 19 deletions

View file

@ -137,6 +137,8 @@ namespace TD.UI
private bool uiInitialized;
private bool selectionSubscribed; // true once we've successfully hooked SelectionState.OnSelectionChanged
private bool matchStateSubscribed; // true once OnPhaseChanged is hooked
private bool deckSubscribed; // true once we've hooked the local PlayerTowerDeck.OnDeckChanged
private PlayerTowerDeck subscribedDeck; // the deck we hooked, so we can unsubscribe the same instance
private MinimapView minimapView;
private IPanel myPanel; // tracked separately so OnDestroy only clears the static if it still points at us
@ -245,6 +247,26 @@ namespace TD.UI
matchStateSubscribed = true;
}
// Hook the local player's deck so the command grid rebuilds live when a draft
// grant lands while the builder is already selected. The local deck may not
// exist for the first few frames (spawn race) — retried each Update until it does.
private void TrySubscribeDeck()
{
var deck = PlayerTowerDeck.Local;
if (deck == null) return;
deck.OnDeckChanged += HandleDeckChanged;
subscribedDeck = deck;
deckSubscribed = true;
// The deck may have populated before we subscribed — rebuild now so the
// grid reflects the current contents.
PopulateGridForSelection(SelectionState.Instance?.SelectedObject);
}
private void HandleDeckChanged()
{
PopulateGridForSelection(SelectionState.Instance?.SelectedObject);
}
private void InitializeUI()
{
var doc = GetComponent<UIDocument>();
@ -374,6 +396,13 @@ namespace TD.UI
MatchState.Instance.OnPhaseChanged -= HandlePhaseChanged;
matchStateSubscribed = false;
}
if (deckSubscribed && subscribedDeck != null)
{
subscribedDeck.OnDeckChanged -= HandleDeckChanged;
}
deckSubscribed = false;
subscribedDeck = null;
}
private void TrySubscribeSelection()
@ -394,6 +423,9 @@ namespace TD.UI
if (!matchStateSubscribed)
TrySubscribeMatchState();
if (!deckSubscribed)
TrySubscribeDeck();
RefreshGoldDisplay();
RefreshMatchStateDisplays();
UpdateBuildProgressIfShown();
@ -763,14 +795,23 @@ namespace TD.UI
}
else
{
int i = 0;
foreach (var (def, typeId) in placementManager.GetAvailableDefinitions())
// Build buttons come from the LOCAL player's deck — the per-player
// unlocked set — not the global catalog. Each deck entry is a
// TowerTypeId resolved back to its definition via the catalog. The
// last grid slot is reserved for the Buffs button, so towers fill
// slots 0..GRID_MAX-2.
var deck = PlayerTowerDeck.Local;
if (deck != null)
{
if (i >= GRID_MAX) break;
cells[i] = CreateTowerButton(def, typeId, HotkeyLayout[i]);
i++;
int count = Mathf.Min(deck.Count, GRID_MAX - 1);
for (int i = 0; i < count; i++)
{
int typeId = deck.GetTypeIdAt(i);
var def = TowerPlacementManager.GetDefinition(typeId);
if (def != null)
cells[i] = CreateTowerButton(def, typeId, HotkeyLayout[i]);
}
}
}
cells[GRID_MAX - 1] = CreateBuffMenuButton(HotkeyLayout[GRID_MAX - 1]);
}