658 lines
17 KiB
C#
658 lines
17 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using Bansonic;
|
|
|
|
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<GameObject> spawnedMaterialItems = new List<GameObject>();
|
|
|
|
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<equipItemPrefab>();
|
|
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<equipItemPrefab>();
|
|
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,
|
|
"算力",
|
|
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<materialPrefab>();
|
|
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 (Application.isPlaying)
|
|
{
|
|
equipmentGenerator.SaveRuntimeEquipmentState(equipment);
|
|
return;
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
UnityEditor.EditorUtility.SetDirty(equipment);
|
|
if (!Application.isPlaying)
|
|
{
|
|
UnityEditor.AssetDatabase.SaveAssets();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
private static void RefreshAllEquipBags()
|
|
{
|
|
equipBag[] bags = Object.FindObjectsByType<equipBag>(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<equipItemPrefab>();
|
|
if (itemPrefab == null)
|
|
{
|
|
return Color.white;
|
|
}
|
|
|
|
return itemPrefab.GetAccentColorByVisualIndex(colorIndex);
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|