using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; namespace DepthsOfGreed.HandbookUI { public sealed class HandbookUpgradesController : MonoBehaviour { [SerializeField] private Button[] rows, buyButtons, mapMarkers; [SerializeField] private TMP_Text[] names, effects, buyLabels, markerLabels; [SerializeField] private Image[] icons; [SerializeField] private TMP_Text resources, emptyMessage; [SerializeField] private float mapWorldExtent = 170; private TestPlacementController placement; private IHandbookGameplay backend; private readonly List sorted = new List(); private long selected, hovered; public int VisibleUpgradeCount => sorted.Count; public void Initialize(TestPlacementController p) { placement = p; backend = p.Backend; for (int i = 0; i < rows.Length; i++) { int n = i; rows[i].onClick.AddListener(() => { if (n < sorted.Count) { selected = sorted[n].instanceId; Highlights(); } }); buyButtons[i].onClick.AddListener(() => { if (n < sorted.Count) { selected = sorted[n].instanceId; backend.ExecuteUpgrade(selected); } }); var trigger = rows[i].GetComponent(); var enter = new EventTrigger.Entry { eventID = EventTriggerType.PointerEnter }; enter.callback.AddListener(_ => { hovered = n < sorted.Count ? sorted[n].instanceId : 0; Highlights(); }); trigger.triggers.Add(enter); var exit = new EventTrigger.Entry { eventID = EventTriggerType.PointerExit }; exit.callback.AddListener(_ => { hovered = 0; Highlights(); }); trigger.triggers.Add(exit); } for (int i = 0; i < mapMarkers.Length; i++) { int n = i; mapMarkers[i].onClick.AddListener(() => { if (n < backend.BuiltObjects.Count) { selected = backend.BuiltObjects[n].instanceId; Highlights(); } }); } backend.StateChanged += Rebuild; Rebuild(); } private void OnEnable() { if (backend != null) { selected = hovered = 0; Rebuild(); } } private void Rebuild() { resources.text = "Energie: " + backend.Energy + " · Gedärme: " + backend.Entrails; sorted.Clear(); foreach (var obj in backend.BuiltObjects) if (obj.type.upgradeable) sorted.Add(obj); sorted.Sort((a, b) => { int c = string.CompareOrdinal(a.type.id, b.type.id); return c != 0 ? c : a.instanceId.CompareTo(b.instanceId); }); if (sorted.Count > rows.Length || backend.BuiltObjects.Count > mapMarkers.Length) Debug.LogError("Upgrades: Vorbereitete Karten-/Markeranzahl erhöhen.", this); emptyMessage.gameObject.SetActive(sorted.Count == 0); for (int i = 0; i < rows.Length; i++) { rows[i].gameObject.SetActive(i < sorted.Count); if (i >= sorted.Count) continue; var obj = sorted[i]; names[i].text = obj.type.displayName + " #" + obj.instanceId + " · Stufe " + obj.upgradeLevel; icons[i].sprite = obj.type.icon; icons[i].gameObject.SetActive(obj.type.icon); bool max = obj.upgradeLevel >= obj.type.upgrades.Length; effects[i].text = max ? "Maximal verbessert" : obj.type.upgrades[obj.upgradeLevel].description; buyLabels[i].text = max ? "Maximum" : HandbookCostText.Format(obj.type.upgrades[obj.upgradeLevel].energyCost, obj.type.upgrades[obj.upgradeLevel].entrailsCost) is string price && price.Length > 0 ? price : "Verbessern"; buyButtons[i].interactable = !max && backend.CheckUpgrade(obj.instanceId).Allowed; } for (int i = 0; i < mapMarkers.Length; i++) { mapMarkers[i].gameObject.SetActive(i < backend.BuiltObjects.Count); if (i >= backend.BuiltObjects.Count) continue; var obj = backend.BuiltObjects[i]; markerLabels[i].text = obj.instanceId.ToString(); ((RectTransform)mapMarkers[i].transform).anchoredPosition = (Vector2)(obj.position - placement.AreaCenter) / placement.AreaRadius * mapWorldExtent; } Highlights(); } private void Highlights() { for (int i = 0; i < mapMarkers.Length && i < backend.BuiltObjects.Count; i++) { long id = backend.BuiltObjects[i].instanceId; mapMarkers[i].image.color = id == selected ? new Color(1, 0.7f, 0.1f) : id == hovered ? Color.white : new Color(0.35f, 0.35f, 0.35f); mapMarkers[i].transform.localScale = Vector3.one * (id == selected || id == hovered ? 1.25f : 1); } for (int i = 0; i < rows.Length && i < sorted.Count; i++) rows[i].image.color = sorted[i].instanceId == selected ? new Color(0.7f, 0.7f, 0.68f) : new Color(0.9f, 0.88f, 0.81f); } private void OnDestroy() { if (backend != null) backend.StateChanged -= Rebuild; } } }