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