using System.Collections.Generic; using Nox.UI; using UnityEngine; using Object = UnityEngine.Object; namespace Nox.Game.UI { public class PartyGuiView { private readonly Transform portraitsContainer; private readonly PartyMemberSlot slotPrefab; private readonly PortraitsHolder portraitsHolder; private readonly List activeSlots = new(); private PartyDefinition trackedParty; private int trackedMemberCount; public PartyGuiView(Transform portraitsContainer, PartyMemberSlot slotPrefab, PortraitsHolder portraitsHolder) { this.portraitsContainer = portraitsContainer; this.slotPrefab = slotPrefab; this.portraitsHolder = portraitsHolder; } public void Initialize(PartyDefinition party) { trackedParty = party; trackedMemberCount = 0; RebuildSlots(); } public void Tick() { if(trackedParty == null) { return; } // Rebuild if member count changed if(trackedParty.members.Count != trackedMemberCount) { RebuildSlots(); } // Update dynamic values (health, mana) for(int i = 0; i < activeSlots.Count && i < trackedParty.members.Count; i++) { var member = trackedParty.members[i]; var slot = activeSlots[i]; UpdateSlotStats(slot, member); } } private void RebuildSlots() { // Clear existing foreach(var slot in activeSlots) { Object.Destroy(slot.gameObject); } activeSlots.Clear(); if(trackedParty?.members == null) { return; } trackedMemberCount = trackedParty.members.Count; foreach(var member in trackedParty.members) { var slot = Object.Instantiate(slotPrefab, portraitsContainer); slot.gameObject.SetActive(true); // Portrait if(portraitsHolder != null && portraitsHolder.portraits.Length > 0) { var idx = Mathf.Clamp(member.PortraitIndex, 0, portraitsHolder.portraits.Length - 1); slot.portrait.sprite = portraitsHolder.portraits[idx]; } // Name if(slot.nameText != null) { slot.nameText.text = member.Name; } UpdateSlotStats(slot, member); activeSlots.Add(slot); } } private static void UpdateSlotStats(PartyMemberSlot slot, CharacterDefinition member) { var health = member.Stats.GetValue(StatType.Health); var mana = member.Stats.GetValue(StatType.Mana); if(slot.healthBar != null) { slot.healthBar.fillAmount = Mathf.Clamp01(health / 100f); } if(slot.healthText != null) { slot.healthText.text = health.ToString(); } if(slot.manaBar != null) { slot.manaBar.fillAmount = Mathf.Clamp01(mana / 100f); } if(slot.manaText != null) { slot.manaText.text = mana.ToString(); } } public void Dispose() { foreach(var slot in activeSlots) { if(slot != null) { Object.Destroy(slot.gameObject); } } activeSlots.Clear(); } } }