From 6b50c6ee7dbd3248c640a3d5d78fcb860152ee84 Mon Sep 17 00:00:00 2001
From: KoalaTrapLord <265133236+KoalaTrapLord@users.noreply.github.com>
Date: Thu, 19 Mar 2026 01:40:50 -0400
Subject: [PATCH] Add PreconListWrapper and CollectionResponse classes to
DeckGeneratorController
---
.../Scripts/UI/DeckGeneratorController.cs | 519 +++++++++---------
1 file changed, 273 insertions(+), 246 deletions(-)
diff --git a/unity-client/Assets/Scripts/UI/DeckGeneratorController.cs b/unity-client/Assets/Scripts/UI/DeckGeneratorController.cs
index ecbe1b5..57127d5 100644
--- a/unity-client/Assets/Scripts/UI/DeckGeneratorController.cs
+++ b/unity-client/Assets/Scripts/UI/DeckGeneratorController.cs
@@ -11,262 +11,289 @@ using CommanderAILab.Services;
namespace CommanderAILab.UI
{
- ///
- /// DeckGenerator scene — AI deck generation wizard:
- /// commander pick, strategy/budget inputs, precon base,
- /// streaming progress, result preview, save to DeckBuilder.
- ///
- public class DeckGeneratorController : MonoBehaviour
- {
- // ── Navigation ────────────────────────────────────────────────────
- [Header("Navigation")]
- [SerializeField] private Button backButton;
-
- // ── Step 1: Commander Selection ───────────────────────────────────
- [Header("Step 1 - Commander")]
- [SerializeField] private TMP_InputField commanderSearchInput;
- [SerializeField] private Button commanderSearchButton;
- [SerializeField] private Transform commanderResultParent;
- [SerializeField] private GameObject commanderResultRowPrefab;
- [SerializeField] private TMP_Text selectedCommanderLabel;
-
- // ── Step 2: Strategy & Budget ─────────────────────────────────────
- [Header("Step 2 - Strategy & Budget")]
- [SerializeField] private TMP_Dropdown strategyDropdown; // Aggro/Control/Combo/Midrange/Stax/Chaos
- [SerializeField] private TMP_Dropdown budgetDropdown; // Pauper/$50/$100/$250/No limit
- [SerializeField] private TMP_InputField synergiesInput; // free-text themes
- [SerializeField] private TMP_Dropdown preconBaseDropdown; // optional precon starting point
- [SerializeField] private Toggle ownedOnlyToggle; // restrict to owned cards
-
- // ── Step 3: Generate ──────────────────────────────────────────────
- [Header("Step 3 - Generate")]
- [SerializeField] private Button generateButton;
- [SerializeField] private GameObject progressPanel;
- [SerializeField] private Slider progressSlider;
- [SerializeField] private TMP_Text progressText;
-
- // ── Step 4: Result Preview ────────────────────────────────────────
- [Header("Step 4 - Result")]
- [SerializeField] private GameObject resultPanel;
- [SerializeField] private Transform resultCardListParent;
- [SerializeField] private GameObject resultCardRowPrefab;
- [SerializeField] private TMP_Text resultSummaryText;
- [SerializeField] private TMP_Text resultManaCurveText;
- [SerializeField] private Button saveToDeckBuilderButton;
- [SerializeField] private Button regenerateButton;
-
- // ── Error ─────────────────────────────────────────────────────────
- [Header("Error")]
- [SerializeField] private GameObject errorPanel;
- [SerializeField] private TMP_Text errorText;
- [SerializeField] private Button retryButton;
-
- // ── State ─────────────────────────────────────────────────────────
- private CardModel _selectedCommander;
- private DeckGenResponse _lastResult;
- private List _commanderRows = new();
- private List _resultRows = new();
- private List _preconNames = new();
-
- // ── Lifecycle ─────────────────────────────────────────────────────
- private void Start()
+ ///
+ /// DeckGenerator scene — AI deck generation wizard:
+ /// commander pick, strategy/budget inputs, precon base,
+ /// streaming progress, result preview, save to DeckBuilder.
+ ///
+ public class DeckGeneratorController : MonoBehaviour
{
- backButton.onClick.AddListener(() => SceneManager.LoadScene("MainMenu"));
+ // ── Navigation ────────────────────────────────────────────────────
+ [Header("Navigation")]
+ [SerializeField] private Button backButton;
- commanderSearchButton.onClick.AddListener(OnCommanderSearch);
- commanderSearchInput.onSubmit.AddListener(_ => OnCommanderSearch());
+ // ── Step 1: Commander Selection ───────────────────────────────────
+ [Header("Step 1 - Commander")]
+ [SerializeField] private TMP_InputField commanderSearchInput;
+ [SerializeField] private Button commanderSearchButton;
+ [SerializeField] private Transform commanderResultParent;
+ [SerializeField] private GameObject commanderResultRowPrefab;
+ [SerializeField] private TMP_Text selectedCommanderLabel;
- generateButton.onClick.AddListener(OnGenerate);
- saveToDeckBuilderButton.onClick.AddListener(OnSaveToDeckBuilder);
- regenerateButton.onClick.AddListener(OnGenerate);
- retryButton.onClick.AddListener(OnGenerate);
+ // ── Step 2: Strategy & Budget ─────────────────────────────────────
+ [Header("Step 2 - Strategy & Budget")]
+ [SerializeField] private TMP_Dropdown strategyDropdown; // Aggro/Control/Combo/Midrange/Stax/Chaos
+ [SerializeField] private TMP_Dropdown budgetDropdown; // Pauper/$50/$100/$250/No limit
+ [SerializeField] private TMP_InputField synergiesInput; // free-text themes
+ [SerializeField] private TMP_Dropdown preconBaseDropdown; // optional precon starting point
+ [SerializeField] private Toggle ownedOnlyToggle; // restrict to owned cards
- progressPanel.SetActive(false);
- resultPanel.SetActive(false);
- errorPanel.SetActive(false);
+ // ── Step 3: Generate ──────────────────────────────────────────────
+ [Header("Step 3 - Generate")]
+ [SerializeField] private Button generateButton;
+ [SerializeField] private GameObject progressPanel;
+ [SerializeField] private Slider progressSlider;
+ [SerializeField] private TMP_Text progressText;
- LoadPrecons();
- }
+ // ── Step 4: Result Preview ────────────────────────────────────────
+ [Header("Step 4 - Result")]
+ [SerializeField] private GameObject resultPanel;
+ [SerializeField] private Transform resultCardListParent;
+ [SerializeField] private GameObject resultCardRowPrefab;
+ [SerializeField] private TMP_Text resultSummaryText;
+ [SerializeField] private TMP_Text resultManaCurveText;
+ [SerializeField] private Button saveToDeckBuilderButton;
+ [SerializeField] private Button regenerateButton;
- // ── Precon list ───────────────────────────────────────────────────
- private void LoadPrecons()
- {
- ApiClient.Instance.GetPrecons(
- json =>
+ // ── Error ─────────────────────────────────────────────────────────
+ [Header("Error")]
+ [SerializeField] private GameObject errorPanel;
+ [SerializeField] private TMP_Text errorText;
+ [SerializeField] private Button retryButton;
+
+ // ── State ─────────────────────────────────────────────────────────
+ private CardModel _selectedCommander;
+ private DeckGenResponse _lastResult;
+ private List _commanderRows = new();
+ private List _resultRows = new();
+ private List _preconNames = new();
+
+ // ── Helper Models ─────────────────────────────────────────────────
+ [System.Serializable]
+ private class PreconListWrapper
{
- try
- {
- var wrapper = JsonConvert.DeserializeObject(json);
- _preconNames = wrapper?.precons ?? new List();
- }
- catch { _preconNames = new List(); }
-
- var options = new List { new("None (from scratch)") };
- foreach (var p in _preconNames) options.Add(new TMP_Dropdown.OptionData(p));
- preconBaseDropdown.options = options;
- preconBaseDropdown.value = 0;
- },
- err => Debug.LogWarning($"[DeckGen] Could not load precons: {err}"));
- }
-
- // ── Commander Search ──────────────────────────────────────────────
- private void OnCommanderSearch()
- {
- string q = commanderSearchInput.text.Trim();
- if (string.IsNullOrEmpty(q)) return;
- string path = $"/api/collection?search={UnityWebRequest.EscapeURL(q)}&type=Legendary+Creature&per_page=20";
- ApiClient.Instance.GetRaw(path,
- json => PopulateCommanderResults(json),
- err => ShowError($"Commander search failed:\n{err}"));
- }
-
- private void PopulateCommanderResults(string json)
- {
- foreach (var go in _commanderRows) if (go) Destroy(go);
- _commanderRows.Clear();
-
- List cards;
- try
- {
- var resp = JsonConvert.DeserializeObject(json);
- cards = resp?.cards ?? new List();
- }
- catch { return; }
-
- foreach (var card in cards)
- {
- var row = Instantiate(commanderResultRowPrefab, commanderResultParent);
- _commanderRows.Add(row);
- var label = row.GetComponentInChildren();
- if (label) label.text = $"{card.name} — {card.manaCost}";
- var btn = row.GetComponentInChildren