using System; using OTGIntegrated.Abilities; using OTGIntegrated.Core; using OTGIntegrated.Quests; using OTGIntegrated.Stats; using OTGIntegrated.Weapons; using UnityEngine; using UnityEngine.UI; namespace OTGIntegrated.UI { [Serializable] public sealed class AbilityHudSlot { public Text keyText; public Text nameText; public Text manaText; public Text cooldownText; public Image cooldownOverlay; public Image iconImage; } public sealed class HUDController : MonoBehaviour { [Header("Status")] public Image hpFill; public Image manaFill; public Image expFill; public Text hpText; public Text manaText; public Text expText; public Text levelText; [Header("Quest")] public Text questTitleText; public Text questBodyText; [Header("Abilities")] public AbilityHudSlot[] abilitySlots = new AbilityHudSlot[3]; [Header("Weapon")] public Text weaponNameText; public Text weaponDamageText; public Text weaponHintText; private PlayerStats stats; private LevelSystem levelSystem; private QuestManager questManager; private AbilityManager abilityManager; private WeaponManager weaponManager; public void Initialize(PlayerStats stats, LevelSystem levelSystem, QuestManager questManager, AbilityManager abilityManager, WeaponManager weaponManager) { this.stats = stats; this.levelSystem = levelSystem; this.questManager = questManager; this.abilityManager = abilityManager; this.weaponManager = weaponManager; if (stats != null) stats.OnStatsChanged += RefreshAll; if (levelSystem != null) { levelSystem.OnExperienceChanged += RefreshAll; levelSystem.OnLevelChanged += RefreshAll; } if (questManager != null) questManager.OnQuestsChanged += RefreshAll; if (abilityManager != null) abilityManager.OnAbilitiesChanged += RefreshAbilities; GameEvents.OnWeaponChanged += _ => RefreshWeapon(); GameEvents.OnStatsChanged += RefreshAll; RefreshAll(); } private void OnDestroy() { if (stats != null) stats.OnStatsChanged -= RefreshAll; if (levelSystem != null) { levelSystem.OnExperienceChanged -= RefreshAll; levelSystem.OnLevelChanged -= RefreshAll; } if (questManager != null) questManager.OnQuestsChanged -= RefreshAll; if (abilityManager != null) abilityManager.OnAbilitiesChanged -= RefreshAbilities; GameEvents.OnStatsChanged -= RefreshAll; } private void Update() { RefreshAbilities(); } public void RefreshAll() { RefreshStatus(); RefreshQuest(); RefreshAbilities(); RefreshWeapon(); } private void RefreshStatus() { if (stats != null) { if (hpFill != null) hpFill.fillAmount = stats.GetNormalizedHealth(); if (manaFill != null) manaFill.fillAmount = stats.GetNormalizedMana(); if (hpText != null) hpText.text = $"HP {Mathf.RoundToInt(stats.CurrentHealth)} / {Mathf.RoundToInt(stats.MaxHealth)}"; if (manaText != null) manaText.text = $"Mana {Mathf.RoundToInt(stats.CurrentMana)} / {Mathf.RoundToInt(stats.MaxMana)}"; } if (levelSystem != null) { if (expFill != null) expFill.fillAmount = levelSystem.GetNormalizedExp(); if (expText != null) expText.text = $"EXP {levelSystem.currentExp} / {levelSystem.expToNextLevel}"; if (levelText != null) levelText.text = $"Level {levelSystem.level}"; } } private void RefreshQuest() { if (questTitleText != null) { questTitleText.text = "Активная цель"; } if (questBodyText != null) { questBodyText.text = questManager != null ? questManager.GetPrimaryTrackerText() : "Нет активных квестов"; } } private void RefreshAbilities() { if (abilityManager == null || abilitySlots == null) { return; } for (int i = 0; i < abilitySlots.Length; i++) { AbilityHudSlot slot = abilitySlots[i]; if (slot == null) { continue; } AbilityData ability = i < abilityManager.LearnedAbilities.Count ? abilityManager.LearnedAbilities[i] : null; float remaining = abilityManager.GetCooldownRemaining(i); if (slot.keyText != null) slot.keyText.text = (i + 1).ToString(); if (slot.nameText != null) slot.nameText.text = ability != null ? ability.displayName : "-"; if (slot.manaText != null) slot.manaText.text = ability != null ? Mathf.RoundToInt(ability.manaCost).ToString() : string.Empty; if (slot.cooldownOverlay != null) slot.cooldownOverlay.fillAmount = abilityManager.GetCooldownNormalized(i); if (slot.cooldownText != null) slot.cooldownText.text = remaining > 0.05f ? remaining.ToString("0.0") : string.Empty; if (slot.iconImage != null) { slot.iconImage.sprite = ability != null ? ability.icon : null; slot.iconImage.color = ability != null && ability.icon != null ? Color.white : new Color(0.2f, 0.22f, 0.26f, 1f); } } } private void RefreshWeapon() { WeaponData weapon = weaponManager != null ? weaponManager.CurrentWeapon : null; if (weaponNameText != null) weaponNameText.text = weapon != null ? $"Weapon: {weapon.displayName}" : "Weapon: -"; if (weaponDamageText != null) weaponDamageText.text = weaponManager != null ? $"Damage: {weaponManager.CurrentFinalDamage:0}" : "Damage: -"; if (weaponHintText != null) weaponHintText.text = "LMB — Attack"; } } }