using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class equipUpdate : MonoBehaviour { [Header("so")] public Player_SO playerSO; public equipmentSO eqp_p_SO; public eUpdate_mtrSO need_mtrSO; [Header("state objects")] public GameObject beforeObj; public GameObject toObj; public GameObject nextObj; [Header("dragging")] public GameObject dragPrev; [Header("transforms")] public Transform prevLevelEquip; public Transform nextLevelEquip; public GameObject eip; [Header("texts")] public Text prevLevelText; public Text nextLevelText; public Text reasonWhy; [Header("materials")] public GameObject mtrPrefab; public Transform mtrParent; public Text mtrInfo; [Header("sprites")] public Sprite MemoryFragmentSprite; public Sprite coinSprite; [Header("buttons")] public Button yesUpdateButton; private GameObject spawnedPrevLevelInstance; private GameObject spawnedNextLevelInstance; private equipmentSO nextLevelPreviewSO; private readonly List spawnedMaterialItems = new List(); private void Awake() { InitializeBindings(); SetDragPreviewVisible(false); ResetInitialSelectionState(); RefreshAll(); } private void OnEnable() { InitializeBindings(); SetDragPreviewVisible(false); ResetInitialSelectionState(); RefreshAll(); } private void OnDisable() { if (yesUpdateButton != null) { yesUpdateButton.onClick.RemoveListener(HandleYesUpdateClicked); } } private void InitializeBindings() { if (playerSO != null) { PlayerEconomyLedger.EnsureInstance().AttachPlayerData(playerSO); } if (yesUpdateButton != null) { yesUpdateButton.onClick.RemoveListener(HandleYesUpdateClicked); yesUpdateButton.onClick.AddListener(HandleYesUpdateClicked); } } public void SetDragPreviewVisible(bool visible) { if (dragPrev == null) { return; } if (!gameObject.activeInHierarchy) { dragPrev.SetActive(false); return; } if (dragPrev != null) { dragPrev.SetActive(visible); } } public bool IsPointerOverDropArea(Vector2 screenPoint, Camera eventCamera) { if (dragPrev == null || !dragPrev.activeInHierarchy) { return false; } RectTransform rectTransform = dragPrev.transform as RectTransform; if (rectTransform == null) { return false; } return RectTransformUtility.RectangleContainsScreenPoint(rectTransform, screenPoint, eventCamera); } public void AcceptDraggedEquipment(equipmentSO equipment) { if (equipment == null) { return; } eqp_p_SO = equipment; RefreshAll(); } private void RefreshAll() { RefreshPrevLevelPreview(); RefreshNextLevelPreview(); RefreshSelectionState(); RefreshPrevLevelText(); RefreshNextLevelText(); RefreshMaterialRequirements(); RefreshActionState(); } public void RefreshPrevLevelPreview() { DestroyPrevLevelPreview(); if (eqp_p_SO == null || eip == null || prevLevelEquip == null) { return; } GameObject instance = Instantiate(eip, prevLevelEquip); instance.name = $"{eqp_p_SO.name}_PrevLevel"; instance.SetActive(true); spawnedPrevLevelInstance = instance; equipItemPrefab item = instance.GetComponent(); if (item != null) { item.Bind(eqp_p_SO); item.SetInteractionOptions(false, false); } } private void RefreshNextLevelPreview() { DestroyNextLevelPreview(); if (!CanShowNextPreview()) { return; } nextLevelPreviewSO = Instantiate(eqp_p_SO); nextLevelPreviewSO.level = Mathf.Clamp(eqp_p_SO.level + 1, 0, 20); GameObject instance = Instantiate(eip, nextLevelEquip); instance.name = $"{eqp_p_SO.name}_NextLevel"; instance.SetActive(true); spawnedNextLevelInstance = instance; equipItemPrefab item = instance.GetComponent(); if (item != null) { item.Bind(nextLevelPreviewSO); item.SetInteractionOptions(false, false); } } private bool CanShowNextPreview() { if (eqp_p_SO == null || eip == null || nextLevelEquip == null) { return false; } int level = eqp_p_SO.level; if (level < 0 || level >= 20) { return false; } return !RequiresTour(level); } private void RefreshSelectionState() { bool hasSelection = eqp_p_SO != null && spawnedPrevLevelInstance != null; bool requiresTour = hasSelection && RequiresTour(eqp_p_SO.level); bool isMaxLevel = hasSelection && eqp_p_SO.level >= 20; bool isInvalidLevel = hasSelection && !IsLegalLevel(eqp_p_SO.level); if (beforeObj != null) { beforeObj.SetActive(true); } bool showProgressObjects = hasSelection && !requiresTour && !isMaxLevel && !isInvalidLevel; if (toObj != null) { toObj.SetActive(showProgressObjects); } if (nextObj != null) { nextObj.SetActive(showProgressObjects); } } private void RefreshPrevLevelText() { if (prevLevelText == null) { return; } if (eqp_p_SO == null) { prevLevelText.text = "选择一个记忆"; prevLevelText.color = Color.black; return; } prevLevelText.text = $"{Mathf.Max(0, eqp_p_SO.level)}追忆等级"; prevLevelText.color = ResolveEquipmentColor(eqp_p_SO.GetVisualQualityColorIndex()); } private void RefreshNextLevelText() { if (nextLevelText == null) { return; } if (!CanShowNextPreview() || nextLevelPreviewSO == null) { nextLevelText.text = string.Empty; return; } nextLevelText.text = $"{Mathf.Max(0, nextLevelPreviewSO.level)}追忆等级"; nextLevelText.color = ResolveEquipmentColor(nextLevelPreviewSO.GetVisualQualityColorIndex()); } private void RefreshMaterialRequirements() { ClearSpawnedMaterialItems(); if (mtrInfo != null) { mtrInfo.text = "需要指定记忆"; } if (eqp_p_SO == null || need_mtrSO == null) { return; } int level = eqp_p_SO.level; if (!IsLegalLevel(level)) { if (mtrInfo != null) { mtrInfo.text = "记忆不合法"; } return; } if (level == 20) { if (mtrInfo != null) { mtrInfo.text = "已完成全部追忆"; } return; } if (RequiresTour(level)) { if (mtrInfo != null) { mtrInfo.text = "需要巡演"; } return; } if (mtrInfo != null) { mtrInfo.text = string.Empty; } SpawnUpgradeMaterialItems(level); } private void SpawnUpgradeMaterialItems(int level) { if (mtrPrefab == null || mtrParent == null || need_mtrSO == null) { return; } int upgradeMaterialRequired = need_mtrSO.GetUpgradeMaterialRequired(level); int upgradeCoinsRequired = need_mtrSO.GetUpgradeCoinsRequired(level); int upgradeMemoryRequired = need_mtrSO.GetUpgradeMemoryFragmentRequired(level); if (upgradeMaterialRequired > 0 && need_mtrSO.upgradeMaterial != null) { SpawnMaterialItem( need_mtrSO.upgradeMaterial.consumableSprite, need_mtrSO.upgradeMaterial.consumableName, EquipmentConsumableLedger.EnsureInstance().GetCount(need_mtrSO.upgradeMaterial.consumableKind), upgradeMaterialRequired); } if (upgradeCoinsRequired > 0) { SpawnMaterialItem( coinSprite, "Coins", PlayerEconomyLedger.EnsureInstance().GetCoins(), upgradeCoinsRequired); } if (upgradeMemoryRequired > 0) { SpawnMaterialItem( MemoryFragmentSprite, "记忆碎片", PlayerEconomyLedger.EnsureInstance().GetMaterial(), upgradeMemoryRequired); } } private void SpawnMaterialItem(Sprite sprite, string displayName, int ownedAmount, int requiredAmount) { GameObject instance = Instantiate(mtrPrefab, mtrParent); instance.SetActive(true); spawnedMaterialItems.Add(instance); materialPrefab item = instance.GetComponent(); if (item != null) { item.BindOwnedRequired(sprite, displayName, ownedAmount, requiredAmount, true, false, null); item.SetSelected(true); if (item.materialButton != null) { item.materialButton.interactable = false; } } } private void RefreshActionState() { string failureReason = GetUpgradeFailureReason(); if (reasonWhy != null) { reasonWhy.text = string.IsNullOrEmpty(failureReason) ? string.Empty : failureReason; } if (yesUpdateButton == null) { return; } yesUpdateButton.interactable = string.IsNullOrEmpty(failureReason); } private bool CanUpgradeCurrent() { return string.IsNullOrEmpty(GetUpgradeFailureReason()); } private string GetUpgradeFailureReason() { if (eqp_p_SO == null) { return string.Empty; } if (need_mtrSO == null) { return "未配置升级规则"; } int level = eqp_p_SO.level; if (!IsLegalLevel(level)) { return "装备不合法"; } if (level >= 20) { return "此记忆已完成全部追忆"; } if (RequiresTour(level)) { return "当前等级需要巡演"; } int upgradeMaterialRequired = need_mtrSO.GetUpgradeMaterialRequired(level); int upgradeCoinsRequired = need_mtrSO.GetUpgradeCoinsRequired(level); int upgradeMemoryRequired = need_mtrSO.GetUpgradeMemoryFragmentRequired(level); if (upgradeMaterialRequired > 0) { if (need_mtrSO.upgradeMaterial == null) { return "未配置升级材料"; } int ownedConsumable = EquipmentConsumableLedger.EnsureInstance().GetCount(need_mtrSO.upgradeMaterial.consumableKind); if (ownedConsumable < upgradeMaterialRequired) { return "升级材料不足"; } } if (!PlayerEconomyLedger.EnsureInstance().HasEnoughCoins(upgradeCoinsRequired)) { return "硬币不足"; } if (!PlayerEconomyLedger.EnsureInstance().HasEnoughMaterial(upgradeMemoryRequired)) { return "记忆碎片不足"; } return string.Empty; } private void HandleYesUpdateClicked() { if (!CanUpgradeCurrent()) { RefreshActionState(); return; } int currentLevel = eqp_p_SO.level; int upgradeMaterialRequired = need_mtrSO.GetUpgradeMaterialRequired(currentLevel); int upgradeCoinsRequired = need_mtrSO.GetUpgradeCoinsRequired(currentLevel); int upgradeMemoryRequired = need_mtrSO.GetUpgradeMemoryFragmentRequired(currentLevel); if (upgradeMaterialRequired > 0) { if (need_mtrSO.upgradeMaterial == null || !EquipmentConsumableLedger.EnsureInstance().TryConsume(need_mtrSO.upgradeMaterial.consumableKind, upgradeMaterialRequired)) { RefreshAll(); return; } } if (upgradeCoinsRequired > 0 && !PlayerEconomyLedger.EnsureInstance().TrySpendCoins(upgradeCoinsRequired)) { if (upgradeMaterialRequired > 0 && need_mtrSO.upgradeMaterial != null) { EquipmentConsumableLedger.EnsureInstance().Add(need_mtrSO.upgradeMaterial.consumableKind, upgradeMaterialRequired); } RefreshAll(); return; } if (upgradeMemoryRequired > 0 && !PlayerEconomyLedger.EnsureInstance().TrySpendMaterial(upgradeMemoryRequired)) { if (upgradeCoinsRequired > 0) { PlayerEconomyLedger.EnsureInstance().AddCoins(upgradeCoinsRequired); } if (upgradeMaterialRequired > 0 && need_mtrSO.upgradeMaterial != null) { EquipmentConsumableLedger.EnsureInstance().Add(need_mtrSO.upgradeMaterial.consumableKind, upgradeMaterialRequired); } RefreshAll(); return; } eqp_p_SO.level = Mathf.Clamp(eqp_p_SO.level + 1, 0, 20); PersistEquipmentLevel(eqp_p_SO); RefreshAllEquipBags(); RefreshAll(); } private static void PersistEquipmentLevel(equipmentSO equipment) { if (equipment == null) { return; } #if UNITY_EDITOR UnityEditor.EditorUtility.SetDirty(equipment); if (!Application.isPlaying) { UnityEditor.AssetDatabase.SaveAssets(); } #endif } private static void RefreshAllEquipBags() { equipBag[] bags = Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None); for (int i = 0; i < bags.Length; i++) { if (bags[i] != null) { bags[i].Rebuild(); } } } private Color ResolveEquipmentColor(int colorIndex) { if (eip == null) { return Color.white; } equipItemPrefab itemPrefab = eip.GetComponent(); if (itemPrefab == null || itemPrefab.itemBtmColors == null || itemPrefab.itemBtmColors.Length == 0) { return Color.white; } int safeIndex = Mathf.Clamp(colorIndex, 0, itemPrefab.itemBtmColors.Length - 1); return itemPrefab.itemBtmColors[safeIndex]; } private static bool IsLegalLevel(int level) { return level >= 0 && level <= 20; } private static bool RequiresTour(int level) { return level == 4 || level == 9 || level == 14 || level == 19; } private void ResetInitialSelectionState() { DestroyPrevLevelPreview(); DestroyNextLevelPreview(); ClearSpawnedMaterialItems(); eqp_p_SO = null; } private void ClearSpawnedMaterialItems() { if (mtrParent != null) { for (int i = mtrParent.childCount - 1; i >= 0; i--) { Transform child = mtrParent.GetChild(i); if (child == null) { continue; } #if UNITY_EDITOR if (!Application.isPlaying) { Object.DestroyImmediate(child.gameObject); } else #endif { Object.Destroy(child.gameObject); } } } spawnedMaterialItems.Clear(); } private void DestroyPrevLevelPreview() { if (spawnedPrevLevelInstance == null) { return; } #if UNITY_EDITOR if (!Application.isPlaying) { Object.DestroyImmediate(spawnedPrevLevelInstance); } else #endif { Object.Destroy(spawnedPrevLevelInstance); } spawnedPrevLevelInstance = null; } private void DestroyNextLevelPreview() { if (spawnedNextLevelInstance != null) { #if UNITY_EDITOR if (!Application.isPlaying) { Object.DestroyImmediate(spawnedNextLevelInstance); } else #endif { Object.Destroy(spawnedNextLevelInstance); } spawnedNextLevelInstance = null; } if (nextLevelPreviewSO != null) { #if UNITY_EDITOR if (!Application.isPlaying) { Object.DestroyImmediate(nextLevelPreviewSO); } else #endif { Object.Destroy(nextLevelPreviewSO); } nextLevelPreviewSO = null; } } }