using System.Collections.Generic; using System.Text; using TMPro; using UnityEngine; using UnityEngine.UI; namespace DepthsOfGreed.HandbookUI { public sealed class HandbookIndexController : MonoBehaviour { [SerializeField] private Button[] filterButtons, entryButtons; [SerializeField] private TMP_Text[] entryNames; [SerializeField] private Image[] entryIcons; [SerializeField] private TMP_Text detailName, description, emptyMessage; [SerializeField] private Image detailIcon; [SerializeField] private Sprite placeholderIcon; private sealed class Item { public HandbookTowerEntry tower; public HandbookEnemyEntry enemy; public string Name => tower ? tower.displayName : enemy.displayName; public Sprite Icon => tower ? tower.icon : enemy.icon; } private readonly List all = new List(), filtered = new List(); public HandbookTowerEntry SelectedEntry { get; private set; } public HandbookEnemyEntry SelectedEnemy { get; private set; } public int VisibleEntryCount => filtered.Count; private int filter = -1; public void Initialize(HandbookTowerCatalog catalog) { if (catalog.towers != null) foreach (var t in catalog.towers) if (t) all.Add(new Item { tower = t }); if (catalog.enemies != null) foreach (var e in catalog.enemies) if (e) all.Add(new Item { enemy = e }); for (int i = 0; i < filterButtons.Length; i++) { int n = i; filterButtons[i].onClick.AddListener(() => SelectFilter(n)); } for (int i = 0; i < entryButtons.Length; i++) { int n = i; entryButtons[i].onClick.AddListener(() => SelectEntry(n)); } ResetForEntry(); } public void ResetForEntry() { SelectFilter(0, true); } public void SelectFilter(int value, bool force = false) { if (value < 0 || value > 4 || (!force && value == filter)) return; filter = value; filtered.Clear(); foreach (var item in all) if (value == 0 || (value == 1 && item.tower && (int)item.tower.menuGroup < 2) || (value == 2 && item.tower && item.tower.menuGroup == BuildMenuGroup.Anlagen) || (value == 3 && item.tower && item.tower.menuGroup == BuildMenuGroup.Einsaetze) || (value == 4 && item.enemy)) filtered.Add(item); ClearSelection(); Render(); for (int i = 0; i < filterButtons.Length; i++) { filterButtons[i].image.color = Color.white; var c = filterButtons[i].colors; c.normalColor = i == value ? new Color(1, 0.76f, 0.35f) : new Color(0.87f, 0.84f, 0.75f); c.selectedColor = c.normalColor; filterButtons[i].colors = c; } } private void Render() { if (filtered.Count > entryButtons.Length) Debug.LogError("Index: Anzahl vorbereiteter Auswahlfelder erhöhen.", this); for (int i = 0; i < entryButtons.Length; i++) { entryButtons[i].gameObject.SetActive(i < filtered.Count); if (i >= filtered.Count) continue; var item = filtered[i]; entryNames[i].text = item.Name; entryIcons[i].sprite = item.Icon ? item.Icon : placeholderIcon; entryIcons[i].color = item.Icon ? Color.white : Color.gray; bool active = (item.tower && item.tower == SelectedEntry) || (item.enemy && item.enemy == SelectedEnemy); entryButtons[i].image.color = active ? new Color(0.58f, 0.58f, 0.58f) : new Color(0.9f, 0.88f, 0.81f); } emptyMessage.gameObject.SetActive(filtered.Count == 0); } public void SelectEntry(int index) { if (index < 0 || index >= filtered.Count) return; var item = filtered[index]; SelectedEntry = item.tower; SelectedEnemy = item.enemy; detailName.text = item.Name; detailIcon.gameObject.SetActive(true); detailIcon.sprite = item.Icon ? item.Icon : placeholderIcon; detailIcon.color = item.Icon ? Color.white : Color.gray; var text = new StringBuilder(item.tower ? item.tower.description : item.enemy.description); if (item.tower) { var t = item.tower; text.Append("\n\nBaufläche: ").Append(t.region == BuildRegion.WallRing ? "Mauer" : t.region == BuildRegion.Interior ? "Innenfeld" : "Schleuse"); string price = HandbookCostText.Format(t.energyCost, t.entrailsCost); if (price.Length > 0) text.Append("\nKosten: ").Append(price); if (t.deploymentCooldown > 0) text.Append(" · Cooldown: ").Append(t.deploymentCooldown).Append(" s"); if (t.upgradeable) { text.Append("\n\nVerbesserungen:"); foreach (var u in t.upgrades) text.Append("\n").Append(u.title).Append(": ").Append(u.description).Append(HandbookCostText.Format(u.energyCost, u.entrailsCost) is string upgradePrice && upgradePrice.Length > 0 ? " (" + upgradePrice + ")" : ""); } } description.text = text.ToString(); Render(); } public void ClearSelection() { SelectedEntry = null; SelectedEnemy = null; detailIcon.gameObject.SetActive(false); detailName.text = ""; description.text = "Wähle links einen Eintrag aus."; } } }