using System; using System.Collections.Generic; using Bansonic; using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif public class idolSkillsHub : MonoBehaviour { [Header("objects")] public GameObject deSkillPrefab; public Transform deSkillContainer; [Header("fallbacks")] public Sprite unlock_sprite; [Header("displaying")] public Material disgot_grayMtr; public Sprite enabled_btmSprite; public Sprite disabled_btmSprite; public Sprite unlock_btmSprite; public Color enabled_btmColor = Color.white; public Color disabled_btmColor = Color.white; public Color unlock_btmColor = Color.gray; [Header("bool")] public bool display_ungotten = true; [Header("runtime")] public AllyHero_SO currentHero; private int selectedDetailSkillGroupId = -1; private readonly List spawnedSkillItems = new List(); public void SetHero(AllyHero_SO hero) { bool heroChanged = currentHero == null || hero == null || currentHero.ally_heroID != hero.ally_heroID; currentHero = hero; if (currentHero != null) { currentHero.LoadEquippedSkillsFromLocal(); } if (heroChanged) { selectedDetailSkillGroupId = GetDefaultDetailSkillGroupId(currentHero); } Rebuild(); } public void Rebuild() { ClearItems(); if (currentHero == null || deSkillPrefab == null || deSkillContainer == null || currentHero.skillGroups == null) { return; } currentHero.LoadEquippedSkillsFromLocal(); int currentTierNumber = GetCurrentTierNumber(currentHero); int maxSkillSlots = AllyHeroLevelRuntimeResolver.GetEffectiveSkillSlotLimit(currentHero); int equippedCount = GetEquippedCount(); int visibleIndex = 0; for (int i = 0; i < currentHero.skillGroups.Length; i++) { SkillGroup group = currentHero.skillGroups[i]; if (group == null) { continue; } bool unlocked = currentTierNumber >= Mathf.Clamp(group.thisSkill_levelLimit, 1, 4); bool equipped = IsEquipped(group.skillGroupID); bool slotAvailable = equipped || equippedCount < maxSkillSlots; string enableText; bool enableToggleValue; if (!unlocked) { enableText = "\u9700\u8981\u7b49\u7ea7" + GetTierName(group.thisSkill_levelLimit); enableToggleValue = false; } else if (!slotAvailable) { enableText = "\u6280\u80fd\u69fd\u4f4d\u5df2\u6ee1"; enableToggleValue = false; } else { enableText = "\u6280\u80fd\u53ef\u7528"; enableToggleValue = true; } string equipText = equipped ? "\u5df2\u88c5\u914d\u6b64\u6280\u80fd" : "\u6280\u80fd\u672a\u88c5\u914d"; bool equipToggleValue = equipped; bool hideLockedIdentity = !unlocked && !display_ungotten; Sprite displaySprite = unlocked ? group.groupIcon : (display_ungotten ? group.groupIcon : unlock_sprite); string displayName = hideLockedIdentity ? "\u672a\u89e3\u9501\u6280\u80fd" : (group.groupName ?? string.Empty); string detailName = displayName; string detailDescription = hideLockedIdentity ? "\u6b64\u6280\u80fd\u5c1a\u672a\u89e3\u9501\u3002" : (group.skillDescriptionsText ?? string.Empty); Sprite bottomSprite = equipped ? enabled_btmSprite : (unlocked ? disabled_btmSprite : unlock_btmSprite); Color bottomColor = equipped ? enabled_btmColor : (unlocked ? disabled_btmColor : unlock_btmColor); Material iconMaterial = unlocked ? null : disgot_grayMtr; GameObject instance = GetOrCreateSkillItem(visibleIndex); visibleIndex++; deSkillPrefab item = instance.GetComponent(); if (item == null) { continue; } bool hoverToShowDetails = item.display_DP_ungotten; bool allowDetailsHover = item.display_DP_ungotten; bool showDetailsNow = !item.display_DP_ungotten && unlocked && selectedDetailSkillGroupId == group.skillGroupID; item.Bind( displaySprite, displaySprite, displayName, detailName, detailDescription, bottomSprite, bottomColor, iconMaterial, enableToggleValue, enableText, equipToggleValue, equipText, equipped, true, showDetailsNow, hoverToShowDetails, allowDetailsHover, () => HandleSkillClicked(group)); } } private void HandleSkillClicked(SkillGroup group) { if (currentHero == null || group == null) { return; } int currentTierNumber = GetCurrentTierNumber(currentHero); if (currentTierNumber < Mathf.Clamp(group.thisSkill_levelLimit, 1, 4)) { selectedDetailSkillGroupId = -1; Rebuild(); gNotice.warning.display("\u9700\u8981\u7b49\u7ea7" + GetTierName(group.thisSkill_levelLimit)); return; } selectedDetailSkillGroupId = group.skillGroupID; List equipped = new List(currentHero.equippedSkillGroupIDs ?? Array.Empty()); equipped.RemoveAll(id => id == 0); if (equipped.Contains(group.skillGroupID)) { equipped.Remove(group.skillGroupID); ApplyEquippedSkillGroupIds(equipped); Rebuild(); return; } int maxSkillSlots = AllyHeroLevelRuntimeResolver.GetEffectiveSkillSlotLimit(currentHero); if (equipped.Count >= maxSkillSlots) { Rebuild(); gNotice.warning.display("\u6280\u80fd\u69fd\u4f4d\u5df2\u6ee1"); return; } equipped.Add(group.skillGroupID); ApplyEquippedSkillGroupIds(equipped); Rebuild(); } private void ApplyEquippedSkillGroupIds(List equippedIds) { currentHero.equippedSkillGroupIDs = equippedIds != null ? equippedIds.ToArray() : Array.Empty(); currentHero.SaveEquippedSkillsToLocal(); currentHero.LoadEquippedSkillsFromLocal(); #if UNITY_EDITOR if (!Application.isPlaying) { EditorUtility.SetDirty(currentHero); AssetDatabase.SaveAssets(); } #endif } private bool IsEquipped(int skillGroupId) { if (currentHero == null || currentHero.equippedSkillGroupIDs == null) { return false; } for (int i = 0; i < currentHero.equippedSkillGroupIDs.Length; i++) { if (currentHero.equippedSkillGroupIDs[i] == skillGroupId) { return true; } } return false; } private int GetEquippedCount() { if (currentHero == null || currentHero.equippedSkillGroupIDs == null) { return 0; } int count = 0; for (int i = 0; i < currentHero.equippedSkillGroupIDs.Length; i++) { if (currentHero.equippedSkillGroupIDs[i] != 0) { count++; } } return count; } private int GetDefaultDetailSkillGroupId(AllyHero_SO hero) { if (hero == null) { return -1; } hero.LoadEquippedSkillsFromLocal(); if (hero.equippedSkillGroupIDs != null) { for (int i = 0; i < hero.equippedSkillGroupIDs.Length; i++) { int groupId = hero.equippedSkillGroupIDs[i]; if (groupId == 0) { continue; } SkillGroup group = hero.GetSkillGroupByID(groupId); if (group != null && GetCurrentTierNumber(hero) >= Mathf.Clamp(group.thisSkill_levelLimit, 1, 4)) { return groupId; } } } return -1; } private static int GetCurrentTierNumber(AllyHero_SO hero) { if (hero == null) { return 1; } return AllyHeroLevelRuntimeResolver.GetCurrentTierNumber(hero); } private static string GetTierName(int tierNumber) { switch (Mathf.Clamp(tierNumber, 1, 4)) { case 1: return "C"; case 2: return "B"; case 3: return "A"; case 4: return "S"; default: return "C"; } } private void ClearItems() { for (int i = spawnedSkillItems.Count - 1; i >= 0; i--) { GameObject item = spawnedSkillItems[i]; if (item == null) { continue; } if (item.activeSelf) { item.SetActive(false); } } } private GameObject GetOrCreateSkillItem(int index) { while (spawnedSkillItems.Count <= index) { GameObject instance = Instantiate(deSkillPrefab, deSkillContainer); spawnedSkillItems.Add(instance); } GameObject item = spawnedSkillItems[index]; if (item != null) { item.transform.SetParent(deSkillContainer, false); item.transform.SetSiblingIndex(index); if (!item.activeSelf) { item.SetActive(true); } UI_OrderedEntryAnimator.PlaySingle(item, index, 0.16f, 0.018f, -10f, 0.97f, true); } return item; } }