Handbuch Scroll-Listen entfernt. Handbuch offen und tabs eingefügt. Upgrades eingefügt. "Garage" eingefügt. Anbindung eines echten Gameplaymanager möglich (theoretisch)
This commit is contained in:
@@ -1,150 +1,69 @@
|
||||
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<Item> all = new List<Item>(), filtered = new List<Item>();
|
||||
public HandbookTowerEntry SelectedEntry { get; private set; }
|
||||
public int VisibleEntryCount => currentFilter == 2 ? 0 : entries.Count;
|
||||
public ScrollRect ListScroll => scroll;
|
||||
private ScrollRect scroll;
|
||||
private Button[] filters;
|
||||
private readonly List<HandbookTowerEntry> entries = new List<HandbookTowerEntry>();
|
||||
private readonly List<Button> rows = new List<Button>();
|
||||
private TMP_Text detailName, description, emptyMessage;
|
||||
private Image detailIcon;
|
||||
private Sprite placeholder;
|
||||
private Color placeholderColor;
|
||||
private int currentFilter;
|
||||
|
||||
public HandbookEnemyEntry SelectedEnemy { get; private set; }
|
||||
public int VisibleEntryCount => filtered.Count;
|
||||
private int filter = -1;
|
||||
public void Initialize(HandbookTowerCatalog catalog)
|
||||
{
|
||||
scroll = transform.Find("IndexLeft/EntryScrollView").GetComponent<ScrollRect>();
|
||||
filters = new[] {
|
||||
transform.Find("IndexLeft/FilterBar/Filter_All").GetComponent<Button>(),
|
||||
transform.Find("IndexLeft/FilterBar/Filter_Towers").GetComponent<Button>(),
|
||||
transform.Find("IndexLeft/FilterBar/Filter_Enemies").GetComponent<Button>()
|
||||
};
|
||||
detailName = transform.Find("IndexRight/DetailNameText").GetComponent<TMP_Text>();
|
||||
description = transform.Find("IndexRight/DetailDescriptionText").GetComponent<TMP_Text>();
|
||||
detailIcon = transform.Find("IndexRight/DetailIcon").GetComponent<Image>();
|
||||
placeholder = detailIcon.sprite;
|
||||
placeholderColor = detailIcon.color;
|
||||
var template = scroll.content.GetChild(0).GetComponent<Button>();
|
||||
if (catalog && catalog.towers != null)
|
||||
foreach (var entry in catalog.towers)
|
||||
{
|
||||
if (!entry) continue;
|
||||
int index = entries.Count;
|
||||
entries.Add(entry);
|
||||
var row = Instantiate(template, scroll.content);
|
||||
row.name = "IndexEntry_" + entry.id;
|
||||
row.gameObject.SetActive(true);
|
||||
row.image.color = Color.white;
|
||||
var label = row.transform.Find("NameText").GetComponent<TMP_Text>();
|
||||
label.text = entry.displayName;
|
||||
label.color = Color.black;
|
||||
label.raycastTarget = false;
|
||||
label.enableAutoSizing = true;
|
||||
label.fontSizeMin = 16;
|
||||
label.fontSizeMax = 24;
|
||||
var icon = row.transform.Find("Icon").GetComponent<Image>();
|
||||
if (entry.icon) { icon.sprite = entry.icon; icon.color = Color.white; }
|
||||
icon.preserveAspect = true;
|
||||
icon.raycastTarget = false;
|
||||
row.onClick.RemoveAllListeners();
|
||||
row.onClick.AddListener(() => SelectEntry(index));
|
||||
rows.Add(row);
|
||||
}
|
||||
template.gameObject.SetActive(false);
|
||||
var empty = new GameObject("EmptyListMessage", typeof(RectTransform), typeof(TextMeshProUGUI), typeof(LayoutElement));
|
||||
empty.transform.SetParent(scroll.content, false);
|
||||
emptyMessage = empty.GetComponent<TMP_Text>();
|
||||
emptyMessage.font = description.font;
|
||||
emptyMessage.fontSize = 22;
|
||||
emptyMessage.color = new Color(0.3f, 0.3f, 0.3f);
|
||||
emptyMessage.alignment = TextAlignmentOptions.MidlineLeft;
|
||||
emptyMessage.raycastTarget = false;
|
||||
empty.GetComponent<LayoutElement>().preferredHeight = 70;
|
||||
for (int i = 0; i < filters.Length; i++)
|
||||
{
|
||||
int index = i;
|
||||
filters[i].onClick.AddListener(() => SelectFilter(index));
|
||||
}
|
||||
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()
|
||||
public void ResetForEntry() { SelectFilter(0, true); }
|
||||
public void SelectFilter(int value, bool force = false)
|
||||
{
|
||||
SelectFilter(0, true);
|
||||
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; }
|
||||
}
|
||||
|
||||
public void SelectFilter(int index, bool force = false)
|
||||
private void Render()
|
||||
{
|
||||
if (index < 0 || index > 2 || (!force && currentFilter == index)) return;
|
||||
currentFilter = index;
|
||||
foreach (var row in rows) row.gameObject.SetActive(index != 2);
|
||||
bool empty = index == 2 || rows.Count == 0;
|
||||
emptyMessage.gameObject.SetActive(empty);
|
||||
emptyMessage.text = index == 2 ? "Noch keine Gegner-Einträge" : "Noch keine Einträge";
|
||||
for (int i = 0; i < filters.Length; i++)
|
||||
if (filtered.Count > entryButtons.Length) Debug.LogError("Index: Anzahl vorbereiteter Auswahlfelder erhöhen.", this);
|
||||
for (int i = 0; i < entryButtons.Length; i++)
|
||||
{
|
||||
filters[i].image.color = Color.white;
|
||||
var colors = filters[i].colors;
|
||||
colors.normalColor = i == index ? new Color(1, 0.72f, 0.2f) : new Color(0.82f, 0.82f, 0.82f);
|
||||
colors.highlightedColor = i == index ? new Color(1, 0.82f, 0.4f) : Color.white;
|
||||
colors.selectedColor = colors.normalColor;
|
||||
filters[i].colors = colors;
|
||||
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);
|
||||
}
|
||||
ClearSelection();
|
||||
ResetScroll();
|
||||
emptyMessage.gameObject.SetActive(filtered.Count == 0);
|
||||
}
|
||||
|
||||
public void SelectEntry(int index)
|
||||
{
|
||||
if (currentFilter == 2 || index < 0 || index >= entries.Count) return;
|
||||
SelectedEntry = entries[index];
|
||||
detailName.text = SelectedEntry.displayName;
|
||||
description.text = SelectedEntry.description;
|
||||
detailIcon.gameObject.SetActive(true);
|
||||
detailIcon.sprite = SelectedEntry.icon ? SelectedEntry.icon : placeholder;
|
||||
detailIcon.color = SelectedEntry.icon ? Color.white : placeholderColor;
|
||||
detailIcon.preserveAspect = true;
|
||||
RefreshSelectionColors();
|
||||
}
|
||||
|
||||
public void ClearSelection()
|
||||
{
|
||||
SelectedEntry = null;
|
||||
detailIcon.gameObject.SetActive(false);
|
||||
detailName.text = "";
|
||||
description.text = "Wähle links einen Eintrag aus.";
|
||||
RefreshSelectionColors();
|
||||
}
|
||||
|
||||
private void RefreshSelectionColors()
|
||||
{
|
||||
for (int i = 0; i < rows.Count; i++)
|
||||
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)
|
||||
{
|
||||
bool selected = entries[i] == SelectedEntry;
|
||||
var colors = rows[i].colors;
|
||||
colors.normalColor = selected ? new Color(0.58f, 0.58f, 0.58f) : new Color(0.86f, 0.86f, 0.86f);
|
||||
colors.highlightedColor = selected ? new Color(0.64f, 0.64f, 0.64f) : new Color(0.94f, 0.94f, 0.94f);
|
||||
colors.selectedColor = colors.normalColor;
|
||||
rows[i].colors = colors;
|
||||
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 ResetScroll()
|
||||
{
|
||||
scroll.StopMovement();
|
||||
Canvas.ForceUpdateCanvases();
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(scroll.content);
|
||||
scroll.verticalNormalizedPosition = 1f;
|
||||
}
|
||||
public void ClearSelection() { SelectedEntry = null; SelectedEnemy = null; detailIcon.gameObject.SetActive(false); detailName.text = ""; description.text = "Wähle links einen Eintrag aus."; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user