装备系统完结,修复并加入很多

This commit is contained in:
FloatGaming
2026-04-03 19:15:02 +08:00
parent 538085b64f
commit d9376833b6
378 changed files with 62464 additions and 16756 deletions
+77 -8
View File
@@ -59,7 +59,7 @@ public class UI_Idols : MonoBehaviour
public idolDocument ido;
public idolSkillsHub ish;
public idolSkins isk;
public idolWeapon iw;
public idolEquipments ieqpmt;
public idolUpgrade iu;
[Header("left toggles")]
@@ -87,12 +87,14 @@ public class UI_Idols : MonoBehaviour
private void Start()
{
BindQuitButton();
InitializeSectionToggles();
RebuildCards();
}
private void OnEnable()
{
BindQuitButton();
btmandtopController.GlobalOverlayPanelVisibilityChanged += HandleOverlayPanelsVisibilityChanged;
AllyHeroDeployLedger.EnsureInstance().OnHeroGrowthChanged += HandleHeroGrowthChanged;
InitializeSectionToggles();
@@ -102,6 +104,7 @@ public class UI_Idols : MonoBehaviour
private void OnDisable()
{
UnbindQuitButton();
btmandtopController.GlobalOverlayPanelVisibilityChanged -= HandleOverlayPanelsVisibilityChanged;
if (AllyHeroDeployLedger.Instance != null)
{
@@ -115,6 +118,32 @@ public class UI_Idols : MonoBehaviour
UnbindSectionToggles();
}
private void BindQuitButton()
{
if (quitButton == null)
{
return;
}
quitButton.onClick.RemoveListener(HandleQuitClicked);
quitButton.onClick.AddListener(HandleQuitClicked);
}
private void UnbindQuitButton()
{
if (quitButton == null)
{
return;
}
quitButton.onClick.RemoveListener(HandleQuitClicked);
}
private void HandleQuitClicked()
{
gameObject.SetActive(false);
}
private void InitializeSectionToggles()
{
BindSectionToggles();
@@ -401,6 +430,11 @@ public class UI_Idols : MonoBehaviour
ish.SetHero(hero);
}
if (ieqpmt != null)
{
ieqpmt.SetHero(hero);
}
if (rightPanel != null)
{
rightPanel.SetActive(hero != null);
@@ -444,7 +478,7 @@ public class UI_Idols : MonoBehaviour
SetText(finishGameTimes, FormatSevenDigitCount(hero.ally_finishCount));
SetText(mvpGetTimes, FormatSevenDigitCount(hero.ally_mvpCount));
SetText(joinTeamTimes, FormatJoinDate(hero.ally_joinDateUtcTicks));
ApplyLevelDetails(hero.GetEffectiveLevelForCurrentEXP());
ApplyLevelDetails(hero.GetEffectiveLevelInfoWithEquipment(hero.GetEffectiveLevelForCurrentEXP()));
ApplyBehaviourRadar(hero);
PopulateSpecialSkills(hero);
@@ -834,12 +868,15 @@ public class UI_Idols : MonoBehaviour
return;
}
SetText(il.hp, levelInfo.maxHP.ToString());
SetText(il.attack, levelInfo.attack.ToString());
SetText(il.mana, levelInfo.maxMana.ToString());
SetText(il.damageResistant, FormatPercent(levelInfo.damageResistance));
SetText(il.scoreEfficency, FormatPercent(levelInfo.scoreEfficiency));
SetText(il.slotAmount, levelInfo.skill_slot_limited.ToString());
AllyHero_SO.AllyLevelInfo baseLevelInfo = currentSelectedHero != null ? currentSelectedHero.GetEffectiveLevelForCurrentEXP() : levelInfo;
SetText(il.hp, FormatGrowthInt(baseLevelInfo != null ? baseLevelInfo.maxHP : levelInfo.maxHP, levelInfo.maxHP));
SetText(il.attack, FormatGrowthInt(baseLevelInfo != null ? baseLevelInfo.attack : levelInfo.attack, levelInfo.attack));
SetText(il.mana, FormatGrowthInt(baseLevelInfo != null ? baseLevelInfo.maxMana : levelInfo.maxMana, levelInfo.maxMana));
SetText(il.damageResistant, FormatGrowthPercent(baseLevelInfo != null ? baseLevelInfo.damageResistance : levelInfo.damageResistance, levelInfo.damageResistance));
SetText(il.scoreEfficency, FormatGrowthPercent(baseLevelInfo != null ? baseLevelInfo.scoreEfficiency : levelInfo.scoreEfficiency, levelInfo.scoreEfficiency));
int baseSlotAmount = baseLevelInfo != null ? baseLevelInfo.skill_slot_limited : levelInfo.skill_slot_limited;
int effectiveSlotAmount = currentSelectedHero != null ? currentSelectedHero.GetEffectiveSkillSlotLimit() : levelInfo.skill_slot_limited;
SetText(il.slotAmount, FormatGrowthInt(baseSlotAmount, effectiveSlotAmount));
SetText(il.miss_mr, levelInfo.manaGainOnMiss.ToString());
SetText(il.good_mr, levelInfo.manaGainGood.ToString());
SetText(il.great_mr, levelInfo.manaGainGreat.ToString());
@@ -850,6 +887,11 @@ public class UI_Idols : MonoBehaviour
SetText(il.miss_hl, FormatNumber(levelInfo.missHpLossBase));
}
public void RefreshCurrentHeroDetails()
{
ApplyHeroDetails(currentSelectedHero, false);
}
private void ApplyBehaviourRadar(AllyHero_SO hero)
{
if (ido == null || ido.idol_rader == null)
@@ -940,6 +982,33 @@ public class UI_Idols : MonoBehaviour
return Mathf.RoundToInt(value * 100f) + "%";
}
private static string FormatGrowthInt(int baseValue, int effectiveValue)
{
int growth = effectiveValue - baseValue;
if (growth == 0)
{
return baseValue.ToString();
}
string sign = growth > 0 ? "+" : "-";
string color = growth > 0 ? "#7CFF6B" : "#FF5A5A";
return $"{baseValue} <color={color}>{sign} {Mathf.Abs(growth)}</color>";
}
private static string FormatGrowthPercent(float baseValue, float effectiveValue)
{
float growth = effectiveValue - baseValue;
string baseText = FormatPercent(baseValue);
if (Mathf.Approximately(growth, 0f))
{
return baseText;
}
string sign = growth > 0f ? "+" : "-";
string color = growth > 0f ? "#7CFF6B" : "#FF5A5A";
return $"{baseText} <color={color}>{sign} {FormatPercent(Mathf.Abs(growth))}</color>";
}
private static string FormatNumber(float value)
{
if (Mathf.Approximately(value, Mathf.Round(value)))
+883
View File
@@ -0,0 +1,883 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using Bansonic;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class idolEquipments : MonoBehaviour
{
private enum EquipFilterMode
{
All,
HasSpecialSkill,
HasIllusionSkill,
HasAnySkill,
HasNoSkill,
HasDualSkill,
Type0,
Type1,
Type2,
Type3,
Type4,
Type5,
Type6,
Type7
}
private enum EquipOrderMode
{
AcquireAsc,
AcquireDesc,
QualityAsc,
QualityDesc
}
[Header("objects")]
public GameObject eqpmtItemPrefab;
public Transform eqpmtToPut;
[Header("INFO")]
public Text this_eqpmtName;
public Text this_eqpmtType;
public Text this_eqpmtLevel;
public Text this_eqpmtID;
[Header("waitingList")]
public int i_batch = 16;
public Transform eqpmtBagParent;
[Header("filter")]
public Toggle onlyCanEquip;
public Dropdown orderFilter;
public Dropdown typeFilter;
[Header("emptyText")]
public Text emptyText;
public Scrollbar eqpmtBagScrollbar;
[Header("source paths")]
public string runtimeEquipmentFolder = "so/uEquip";
public string editorEquipmentFolder = "Assets/Resources/so/uEquip";
private readonly List<GameObject> spawnedBagItems = new List<GameObject>();
private Coroutine rebuildRoutine;
private equipmentSO equippedEquipment;
private GameObject equippedItemInstance;
private AllyHero_SO currentHero;
private float pendingScrollbarValue = 1f;
private Coroutine restoreScrollbarRoutine;
private bool suppressDropdownCallbacks;
private static readonly (EquipFilterMode mode, string label)[] FilterOptions =
{
(EquipFilterMode.All, "全部"),
(EquipFilterMode.HasSpecialSkill, "含特效技能"),
(EquipFilterMode.HasIllusionSkill, "含巡演技能"),
(EquipFilterMode.HasAnySkill, "含技能"),
(EquipFilterMode.HasNoSkill, "不含技能"),
(EquipFilterMode.HasDualSkill, "含双技能"),
(EquipFilterMode.Type0, equipmentSO.EquipmentSkillType..ToString()),
(EquipFilterMode.Type1, equipmentSO.EquipmentSkillType..ToString()),
(EquipFilterMode.Type2, equipmentSO.EquipmentSkillType..ToString()),
(EquipFilterMode.Type3, equipmentSO.EquipmentSkillType..ToString()),
(EquipFilterMode.Type4, equipmentSO.EquipmentSkillType..ToString()),
(EquipFilterMode.Type5, equipmentSO.EquipmentSkillType..ToString()),
(EquipFilterMode.Type6, equipmentSO.EquipmentSkillType..ToString()),
(EquipFilterMode.Type7, equipmentSO.EquipmentSkillType..ToString())
};
private static readonly (EquipOrderMode mode, string label)[] OrderOptions =
{
(EquipOrderMode.AcquireAsc, "获取时间升序"),
(EquipOrderMode.AcquireDesc, "获取时间降序"),
(EquipOrderMode.QualityAsc, "品质升序"),
(EquipOrderMode.QualityDesc, "品质降序")
};
private void Start()
{
InitializeDropdowns();
InitializeOnlyCanEquipToggle();
BindControls();
RestoreEquippedFromHero();
RebuildBag();
RefreshEquippedSlot();
}
private void OnEnable()
{
InitializeDropdowns();
InitializeOnlyCanEquipToggle();
BindControls();
RestoreEquippedFromHero();
RebuildBag();
RefreshEquippedSlot();
}
private void OnDisable()
{
UnbindControls();
if (rebuildRoutine != null)
{
StopCoroutine(rebuildRoutine);
rebuildRoutine = null;
}
if (restoreScrollbarRoutine != null)
{
StopCoroutine(restoreScrollbarRoutine);
restoreScrollbarRoutine = null;
}
}
private void BindControls()
{
if (onlyCanEquip != null)
{
onlyCanEquip.onValueChanged.RemoveListener(HandleFilterChanged);
onlyCanEquip.onValueChanged.AddListener(HandleFilterChanged);
}
if (orderFilter != null)
{
orderFilter.onValueChanged.RemoveListener(HandleOrderChanged);
orderFilter.onValueChanged.AddListener(HandleOrderChanged);
}
if (typeFilter != null)
{
typeFilter.onValueChanged.RemoveListener(HandleTypeChanged);
typeFilter.onValueChanged.AddListener(HandleTypeChanged);
}
}
private void UnbindControls()
{
if (onlyCanEquip != null)
{
onlyCanEquip.onValueChanged.RemoveListener(HandleFilterChanged);
}
if (orderFilter != null)
{
orderFilter.onValueChanged.RemoveListener(HandleOrderChanged);
}
if (typeFilter != null)
{
typeFilter.onValueChanged.RemoveListener(HandleTypeChanged);
}
}
private void HandleFilterChanged(bool _)
{
if (!suppressDropdownCallbacks)
{
RebuildBag();
}
}
private void HandleOrderChanged(int _)
{
if (!suppressDropdownCallbacks)
{
RebuildBag();
}
}
private void HandleTypeChanged(int _)
{
if (!suppressDropdownCallbacks)
{
RebuildBag();
}
}
private void InitializeDropdowns()
{
InitializeTypeFilterDropdown();
InitializeOrderDropdown();
}
private void InitializeTypeFilterDropdown()
{
if (typeFilter == null)
{
return;
}
suppressDropdownCallbacks = true;
typeFilter.onValueChanged.RemoveListener(HandleTypeChanged);
typeFilter.ClearOptions();
typeFilter.AddOptions(FilterOptions.Select(option => new Dropdown.OptionData(option.label)).ToList());
typeFilter.value = 0;
typeFilter.RefreshShownValue();
typeFilter.onValueChanged.AddListener(HandleTypeChanged);
suppressDropdownCallbacks = false;
}
private void InitializeOrderDropdown()
{
if (orderFilter == null)
{
return;
}
suppressDropdownCallbacks = true;
orderFilter.onValueChanged.RemoveListener(HandleOrderChanged);
orderFilter.ClearOptions();
orderFilter.AddOptions(OrderOptions.Select(option => new Dropdown.OptionData(option.label)).ToList());
orderFilter.value = 3;
orderFilter.RefreshShownValue();
orderFilter.onValueChanged.AddListener(HandleOrderChanged);
suppressDropdownCallbacks = false;
}
private void InitializeOnlyCanEquipToggle()
{
if (onlyCanEquip == null)
{
return;
}
onlyCanEquip.SetIsOnWithoutNotify(true);
}
public void RebuildBag()
{
CacheScrollbarValue();
if (rebuildRoutine != null)
{
StopCoroutine(rebuildRoutine);
rebuildRoutine = null;
}
ClearBagItems();
if (eqpmtItemPrefab == null || eqpmtBagParent == null)
{
RefreshEmptyState(0);
return;
}
List<equipmentSO> equipments = LoadEquipments()
.Where(e => e != null)
.Where(e => !equipSmelt.IsEquipmentAssignedToSmeltPool(e) && !equipSmelt.ShouldHideConsumedEquipment(e))
.Where(e => equippedEquipment == null || e != equippedEquipment)
.Where(MatchesCurrentFilters)
.ToList();
SortEquipments(equipments);
RefreshEmptyState(equipments.Count);
if (Application.isPlaying && isActiveAndEnabled && gameObject.activeInHierarchy)
{
rebuildRoutine = StartCoroutine(RebuildBagAsync(equipments));
return;
}
SpawnBagItemsImmediate(equipments);
RestoreScrollbarValueImmediate();
}
private IEnumerator RebuildBagAsync(List<equipmentSO> equipments)
{
int batchSize = Mathf.Max(1, i_batch);
for (int i = 0; i < equipments.Count; i++)
{
SpawnBagItem(equipments[i]);
if ((i + 1) % batchSize == 0)
{
yield return null;
}
}
rebuildRoutine = null;
BeginRestoreScrollbarValue();
}
private void SpawnBagItemsImmediate(List<equipmentSO> equipments)
{
for (int i = 0; i < equipments.Count; i++)
{
SpawnBagItem(equipments[i]);
}
}
private void SpawnBagItem(equipmentSO equipment)
{
if (equipment == null || eqpmtItemPrefab == null || eqpmtBagParent == null)
{
return;
}
GameObject instance = Instantiate(eqpmtItemPrefab, eqpmtBagParent);
instance.name = string.IsNullOrWhiteSpace(equipment.GetDisplayTierName()) ? equipment.name : equipment.GetDisplayTierName();
equipItemPrefab item = instance.GetComponent<equipItemPrefab>();
if (item != null)
{
item.Bind(equipment, null, HandleBagItemRightClicked);
item.allowDrag = false;
item.allowQuickTransfer = false;
if (item.itemButton != null)
{
item.itemButton.interactable = true;
}
}
spawnedBagItems.Add(instance);
}
private bool HandleBagItemRightClicked(equipmentSO equipment)
{
if (equipment == null)
{
return false;
}
if (IsEquippedByOtherHero(equipment, out AllyHero_SO occupiedHero))
{
string heroName = occupiedHero != null ? occupiedHero.ally_heroName : "其他角色";
gNotice.warning.display($"该记忆已被{heroName}装备");
return true;
}
EquipEquipment(equipment);
return true;
}
private bool HandleEquippedItemRightClicked(equipmentSO equipment)
{
if (equipment == null || equippedEquipment == null || equipment != equippedEquipment)
{
return false;
}
UnequipEquipment();
return true;
}
private void EquipEquipment(equipmentSO equipment)
{
equippedEquipment = equipment;
if (currentHero != null)
{
currentHero.SetEquippedEquipment(equipment);
}
RefreshAllIdolPanels();
RefreshEquippedSlot();
RebuildBag();
}
private void UnequipEquipment()
{
equippedEquipment = null;
if (currentHero != null)
{
currentHero.ClearEquippedEquipment();
}
RefreshAllIdolPanels();
RefreshEquippedSlot();
RebuildBag();
}
public void SetHero(AllyHero_SO hero)
{
currentHero = hero;
RestoreEquippedFromHero();
RefreshEquippedSlot();
RebuildBag();
}
private void RestoreEquippedFromHero()
{
if (currentHero == null)
{
equippedEquipment = null;
return;
}
currentHero.LoadEquippedEquipmentFromLocal();
equippedEquipment = currentHero.GetEquippedEquipmentResolved();
}
private void RefreshEquippedSlot()
{
if (equippedItemInstance != null)
{
Destroy(equippedItemInstance);
equippedItemInstance = null;
}
if (equippedEquipment != null && eqpmtItemPrefab != null && eqpmtToPut != null)
{
equippedItemInstance = Instantiate(eqpmtItemPrefab, eqpmtToPut);
equippedItemInstance.name = string.IsNullOrWhiteSpace(equippedEquipment.GetDisplayTierName()) ? equippedEquipment.name : equippedEquipment.GetDisplayTierName();
equipItemPrefab item = equippedItemInstance.GetComponent<equipItemPrefab>();
if (item != null)
{
item.Bind(equippedEquipment, null, HandleEquippedItemRightClicked);
item.allowDrag = false;
item.allowQuickTransfer = false;
if (item.itemButton != null)
{
item.itemButton.interactable = true;
}
}
}
RefreshInfoPanel();
}
private void HandleEquipmentClicked(equipmentSO equipment)
{
if (equipment == null)
{
return;
}
if (this_eqpmtName != null)
{
this_eqpmtName.text = equipment.GetDisplayTierName();
this_eqpmtName.color = ResolveEquipmentColor(equipment.GetVisualQualityColorIndex());
}
if (this_eqpmtType != null)
{
this_eqpmtType.text = $"<b>{equipment.skillType}</b> 类装备";
}
if (this_eqpmtLevel != null)
{
this_eqpmtLevel.text = $"{equipment.level}追忆等阶";
}
if (this_eqpmtID != null)
{
this_eqpmtID.text = $"记忆编号{BuildDisplayEquipmentId(equipment)}";
}
}
private void RefreshInfoPanel()
{
if (equippedEquipment == null)
{
if (this_eqpmtName != null)
{
this_eqpmtName.text = "可装配一个记忆";
this_eqpmtName.color = new Color32(0x32, 0x32, 0x32, 0xFF);
}
if (this_eqpmtType != null) this_eqpmtType.text = "请选择记忆";
if (this_eqpmtLevel != null) this_eqpmtLevel.text = string.Empty;
if (this_eqpmtID != null) this_eqpmtID.text = "请选择记忆";
return;
}
HandleEquipmentClicked(equippedEquipment);
}
private bool IsEquippedByOtherHero(equipmentSO equipment, out AllyHero_SO occupiedHero)
{
occupiedHero = null;
if (equipment == null)
{
return false;
}
AllyHero_SO[] heroes = LoadHeroAssetsForOwnershipCheck();
for (int i = 0; i < heroes.Length; i++)
{
AllyHero_SO hero = heroes[i];
if (hero == null || hero == currentHero)
{
continue;
}
hero.LoadEquippedEquipmentFromLocal();
equipmentSO equipped = hero.GetEquippedEquipmentResolved();
if (equipped == equipment || (!string.IsNullOrWhiteSpace(equipped?.name) && equipped.name == equipment.name))
{
occupiedHero = hero;
return true;
}
}
return false;
}
private AllyHero_SO[] LoadHeroAssetsForOwnershipCheck()
{
#if UNITY_EDITOR
if (!Application.isPlaying)
{
if (string.IsNullOrWhiteSpace("Assets/Resources/so/ally") || !AssetDatabase.IsValidFolder("Assets/Resources/so/ally"))
{
return Array.Empty<AllyHero_SO>();
}
string[] guids = AssetDatabase.FindAssets("t:AllyHero_SO", new[] { "Assets/Resources/so/ally" });
var result = new List<AllyHero_SO>(guids.Length);
for (int i = 0; i < guids.Length; i++)
{
string path = AssetDatabase.GUIDToAssetPath(guids[i]);
AllyHero_SO hero = AssetDatabase.LoadAssetAtPath<AllyHero_SO>(path);
if (hero != null)
{
result.Add(hero);
}
}
return result.ToArray();
}
#endif
return Resources.LoadAll<AllyHero_SO>("so/ally");
}
private Color ResolveEquipmentColor(int colorIndex)
{
if (eqpmtItemPrefab == null)
{
return Color.white;
}
equipItemPrefab prefab = eqpmtItemPrefab.GetComponent<equipItemPrefab>();
if (prefab == null || prefab.itemBtmColors == null || prefab.itemBtmColors.Length == 0)
{
return Color.white;
}
int safeIndex = Mathf.Clamp(colorIndex, 0, prefab.itemBtmColors.Length - 1);
return prefab.itemBtmColors[safeIndex];
}
private void RefreshEmptyState(int count)
{
if (emptyText != null)
{
emptyText.text = count > 0 ? string.Empty : "暂无装备";
}
}
private void RefreshAllIdolPanels()
{
UI_Idols[] panels = FindObjectsByType<UI_Idols>(FindObjectsInactive.Include, FindObjectsSortMode.None);
for (int i = 0; i < panels.Length; i++)
{
UI_Idols panel = panels[i];
if (panel != null)
{
panel.RefreshCurrentHeroDetails();
}
}
}
private void ClearBagItems()
{
for (int i = eqpmtBagParent != null ? eqpmtBagParent.childCount - 1 : -1; i >= 0; i--)
{
Transform child = eqpmtBagParent.GetChild(i);
if (child != null)
{
Destroy(child.gameObject);
}
}
spawnedBagItems.Clear();
}
private void CacheScrollbarValue()
{
if (eqpmtBagScrollbar == null)
{
pendingScrollbarValue = 1f;
return;
}
pendingScrollbarValue = eqpmtBagScrollbar.value;
}
private void BeginRestoreScrollbarValue()
{
if (!Application.isPlaying || !isActiveAndEnabled || !gameObject.activeInHierarchy)
{
RestoreScrollbarValueImmediate();
return;
}
if (restoreScrollbarRoutine != null)
{
StopCoroutine(restoreScrollbarRoutine);
}
restoreScrollbarRoutine = StartCoroutine(RestoreScrollbarValueNextFrame());
}
private IEnumerator RestoreScrollbarValueNextFrame()
{
yield return null;
Canvas.ForceUpdateCanvases();
yield return null;
Canvas.ForceUpdateCanvases();
RestoreScrollbarValueImmediate();
restoreScrollbarRoutine = null;
}
private void RestoreScrollbarValueImmediate()
{
if (eqpmtBagScrollbar == null)
{
return;
}
ScrollRect scrollRect = eqpmtBagScrollbar.GetComponentInParent<ScrollRect>();
if (scrollRect != null && scrollRect.verticalScrollbar == eqpmtBagScrollbar)
{
scrollRect.verticalNormalizedPosition = pendingScrollbarValue;
}
eqpmtBagScrollbar.value = pendingScrollbarValue;
}
private bool MatchesCurrentFilters(equipmentSO equipment)
{
if (equipment == null)
{
return false;
}
if (onlyCanEquip != null && onlyCanEquip.isOn && !IsEquipmentUsableByCurrentHero(equipment))
{
return false;
}
EquipFilterMode mode = GetSelectedFilterMode();
bool hasSpecialSkill = equipment.sa_skillID > 0;
bool hasIllusionSkill = equipment.ia_skillID > 0;
switch (mode)
{
case EquipFilterMode.All:
return true;
case EquipFilterMode.HasSpecialSkill:
return hasSpecialSkill;
case EquipFilterMode.HasIllusionSkill:
return hasIllusionSkill;
case EquipFilterMode.HasAnySkill:
return hasSpecialSkill || hasIllusionSkill;
case EquipFilterMode.HasNoSkill:
return !hasSpecialSkill && !hasIllusionSkill;
case EquipFilterMode.HasDualSkill:
return hasSpecialSkill && hasIllusionSkill;
case EquipFilterMode.Type0:
return equipment.skillType == equipmentSO.EquipmentSkillType.;
case EquipFilterMode.Type1:
return equipment.skillType == equipmentSO.EquipmentSkillType.;
case EquipFilterMode.Type2:
return equipment.skillType == equipmentSO.EquipmentSkillType.;
case EquipFilterMode.Type3:
return equipment.skillType == equipmentSO.EquipmentSkillType.;
case EquipFilterMode.Type4:
return equipment.skillType == equipmentSO.EquipmentSkillType.;
case EquipFilterMode.Type5:
return equipment.skillType == equipmentSO.EquipmentSkillType.;
case EquipFilterMode.Type6:
return equipment.skillType == equipmentSO.EquipmentSkillType.;
case EquipFilterMode.Type7:
return equipment.skillType == equipmentSO.EquipmentSkillType.;
default:
return true;
}
}
private bool IsEquipmentUsableByCurrentHero(equipmentSO equipment)
{
if (equipment == null || currentHero == null)
{
return false;
}
if (equipment.GetVisualTierPresentation() == null || string.IsNullOrWhiteSpace(equipment.GetDisplayTierName()))
{
return false;
}
return !IsEquippedByOtherHero(equipment, out _);
}
private void SortEquipments(List<equipmentSO> equipments)
{
if (equipments == null)
{
return;
}
EquipOrderMode mode = GetSelectedOrderMode();
switch (mode)
{
case EquipOrderMode.AcquireAsc:
equipments.Sort((a, b) => CompareAcquire(a, b, false));
break;
case EquipOrderMode.AcquireDesc:
equipments.Sort((a, b) => CompareAcquire(a, b, true));
break;
case EquipOrderMode.QualityAsc:
equipments.Sort((a, b) => CompareQuality(a, b, false));
break;
case EquipOrderMode.QualityDesc:
equipments.Sort((a, b) => CompareQuality(a, b, true));
break;
default:
equipments.Sort((a, b) => CompareAcquire(a, b, false));
break;
}
}
private EquipFilterMode GetSelectedFilterMode()
{
int index = typeFilter != null ? Mathf.Clamp(typeFilter.value, 0, FilterOptions.Length - 1) : 0;
return FilterOptions[index].mode;
}
private EquipOrderMode GetSelectedOrderMode()
{
int index = orderFilter != null ? Mathf.Clamp(orderFilter.value, 0, OrderOptions.Length - 1) : 0;
return OrderOptions[index].mode;
}
private equipmentSO[] LoadEquipments()
{
var results = new List<equipmentSO>();
#if UNITY_EDITOR
if (!Application.isPlaying)
{
results.AddRange(LoadEditorEquipments());
}
else
#endif
{
results.AddRange(Resources.LoadAll<equipmentSO>(runtimeEquipmentFolder).Where(e => e != null));
}
IReadOnlyList<equipmentSO> runtimeGenerated = equipmentGenerator.GetRuntimeGeneratedEquipments();
if (runtimeGenerated != null)
{
for (int i = 0; i < runtimeGenerated.Count; i++)
{
equipmentSO equipment = runtimeGenerated[i];
if (equipment != null && !results.Contains(equipment))
{
results.Add(equipment);
}
}
}
return results.ToArray();
}
private static int CompareAcquire(equipmentSO left, equipmentSO right, bool descending)
{
ParseEquipmentSortKey(left, out long leftDate, out long leftId);
ParseEquipmentSortKey(right, out long rightDate, out long rightId);
int dateCompare = leftDate.CompareTo(rightDate);
if (dateCompare != 0)
{
return descending ? -dateCompare : dateCompare;
}
int idCompare = leftId.CompareTo(rightId);
if (idCompare != 0)
{
return descending ? -idCompare : idCompare;
}
string leftName = left != null ? left.GetDisplayTierName() : string.Empty;
string rightName = right != null ? right.GetDisplayTierName() : string.Empty;
int nameCompare = string.Compare(leftName, rightName, StringComparison.Ordinal);
return descending ? -nameCompare : nameCompare;
}
private static int CompareQuality(equipmentSO left, equipmentSO right, bool descending)
{
int qualityCompare = left.GetVisualQualityColorIndex().CompareTo(right.GetVisualQualityColorIndex());
if (qualityCompare != 0)
{
return descending ? -qualityCompare : qualityCompare;
}
return CompareAcquire(left, right, true);
}
private static void ParseEquipmentSortKey(equipmentSO equipment, out long datePart, out long idPart)
{
datePart = 0L;
idPart = 0L;
if (equipment == null || string.IsNullOrWhiteSpace(equipment.name))
{
return;
}
string raw = equipment.name;
if (raw.StartsWith("type", StringComparison.OrdinalIgnoreCase))
{
int firstUnderscore = raw.IndexOf('_');
if (firstUnderscore >= 0 && firstUnderscore + 1 < raw.Length)
{
raw = raw.Substring(firstUnderscore + 1);
}
}
string[] parts = raw.Split('_');
if (parts.Length >= 2)
{
long.TryParse(parts[0], out datePart);
long.TryParse(parts[1], out idPart);
}
}
#if UNITY_EDITOR
private equipmentSO[] LoadEditorEquipments()
{
if (string.IsNullOrWhiteSpace(editorEquipmentFolder) || !AssetDatabase.IsValidFolder(editorEquipmentFolder))
{
return Array.Empty<equipmentSO>();
}
string[] guids = AssetDatabase.FindAssets("t:equipmentSO", new[] { editorEquipmentFolder });
var result = new List<equipmentSO>(guids.Length);
for (int i = 0; i < guids.Length; i++)
{
string path = AssetDatabase.GUIDToAssetPath(guids[i]);
equipmentSO equipment = AssetDatabase.LoadAssetAtPath<equipmentSO>(path);
if (equipment != null)
{
result.Add(equipment);
}
}
return result.ToArray();
}
#endif
private static string BuildDisplayEquipmentId(equipmentSO equipment)
{
if (equipment == null || string.IsNullOrWhiteSpace(equipment.name))
{
return string.Empty;
}
string raw = equipment.name.Replace("(Clone)", string.Empty).Replace("(Preview)", string.Empty).Replace("(TourPreview)", string.Empty);
return raw.StartsWith("type", StringComparison.OrdinalIgnoreCase) && raw.Length > 4 ? raw.Substring(4) : raw;
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0c2884ea76fe5ad43a42c2a110586df7
+2 -4
View File
@@ -57,8 +57,7 @@ public class idolSkillsHub : MonoBehaviour
currentHero.LoadEquippedSkillsFromLocal();
int currentTierNumber = GetCurrentTierNumber(currentHero);
AllyHero_SO.AllyLevelInfo currentLevelInfo = currentHero.GetEffectiveLevelForCurrentEXP();
int maxSkillSlots = currentLevelInfo != null ? Mathf.Max(0, currentLevelInfo.skill_slot_limited) : 0;
int maxSkillSlots = currentHero.GetEffectiveSkillSlotLimit();
for (int i = 0; i < currentHero.skillGroups.Length; i++)
{
@@ -164,8 +163,7 @@ public class idolSkillsHub : MonoBehaviour
return;
}
AllyHero_SO.AllyLevelInfo currentLevelInfo = currentHero.GetEffectiveLevelForCurrentEXP();
int maxSkillSlots = currentLevelInfo != null ? Mathf.Max(0, currentLevelInfo.skill_slot_limited) : 0;
int maxSkillSlots = currentHero.GetEffectiveSkillSlotLimit();
if (equipped.Count >= maxSkillSlots)
{
Rebuild();
-6
View File
@@ -1,6 +0,0 @@
using UnityEngine;
public class idolWeapon : MonoBehaviour
{
}
-2
View File
@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: ec553633425055d4399ed3514af6e3c1
@@ -1456,7 +1456,6 @@ public class idolUpgrade : MonoBehaviour
List<string> others = recipientSummaries.GetRange(1, recipientSummaries.Count - 1);
return string.Format("雨露均沾生效:{0};同时为{1}提供经验", primary, string.Join("", others.ToArray()));
}
private static string GetPendingDebtKey(int heroId)
{
return "idol_upgrade_pending_debt_" + heroId;
@@ -51,6 +51,15 @@ public class materialPrefab : MonoBehaviour
}
}
public void BindOwnedRequired(Sprite sprite, string displayName, int ownedAmount, int requiredAmount, bool selected, bool interactable, Action onClick)
{
string ownedText = ownedAmount < requiredAmount
? $"<color=#FF4D4D>{Mathf.Max(0, ownedAmount)}</color>"
: Mathf.Max(0, ownedAmount).ToString();
string amountText = $"{ownedText}/{Mathf.Max(0, requiredAmount)}";
Bind(sprite, displayName, amountText, selected, interactable, onClick);
}
public void SetSelected(bool selected)
{
if (boarder != null)