Files
test/Assets/PerfectWorld/Scripts/UI/Dialogs/CDlgSkillSubList.cs
T
vuong dinh hoang cf2f6625ff remove log
2026-05-20 15:43:43 +07:00

521 lines
17 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Linq;
using BrewMonster;
using BrewMonster.Scripts.Skills;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace BrewMonster.UI
{
[DisallowMultipleComponent]
public class CDlgSkillSubList : AUIDialog
{
[Header("Templates")]
[SerializeField] private AUISubDialog m_pSubRank;
[SerializeField] private CDlgSkillSubListItem m_pSubSkill;
[Header("Layout")]
[SerializeField] private RectTransform m_contentRoot;
[SerializeField] private RectTransform m_contentRootSkill;
[SerializeField] private ScrollRect m_scrollRect;
[SerializeField] private float m_windowScale = 1f;
[SerializeField] private TMP_Text totalSPText;
[Header("State")]
[SerializeField] private bool m_isEvil;
private readonly Dictionary<int, AUISubDialog> m_rankSubDialogs = new();
private readonly List<CDlgSkillSubListItem> m_skillSubDialogs = new();
private readonly Dictionary<int, CDlgSkillSubListItem> m_skillSubDialogsMap = new();
private int m_skillSubCount; // 当前显示的技能数量 / Current shown skill count
private float m_curBottom; // 当前底部位置 / Current bottom position
private float m_skillHeight; // 技能子对话高度 / Skill sub dialog height
private float m_rankHeight; // 阶位对话高度 / Rank dialog height
private float m_originWidth; // 初始宽度 / Initial width
private float m_originHeight; // 初始高度 / Initial height
private float m_originBottom; // 初始底部位置 / Initial bottom position
private bool m_bAllocRankDlgs; // 是否已创建阶位子对话 / Whether rank sub dialogs are allocated
private int m_selectedSkillId;
private void Awake()
{
if (m_contentRoot == null)
{
m_contentRoot = transform as RectTransform;
}
EventBus.Subscribe<CECSkillPanelChange>(OnModelChange);
CacheTemplateInfo();
HideTemplates();
}
public override void OnEnable()
{
base.OnEnable();
OnShowDialog();
}
private void OnShowDialog()
{
InitRankDlgs();
ResetDialog();
// 保留原始隐藏新图标逻辑 / Keep original "hide new" logic (pending port)
// GetGameUIMan()->m_pDlgSystem->ShowNewImg(false);
// GetGameUIMan()->m_pDlgSystemb->ShowNewImg(false);
// GetGameUIMan()->m_pDlgSystem5->ShowNewImg(false);
// GetGameUIMan()->m_pDlgSystem5b->ShowNewImg(false);
}
// 初始化模板尺寸 / Cache template sizing info
private void CacheTemplateInfo()
{
if (m_pSubRank != null)
{
m_rankHeight = m_pSubRank.GetSize().y;
m_originBottom = m_pSubRank.GetPos().y;
}
if (m_contentRoot != null)
{
m_originWidth = m_contentRoot.rect.width;
m_originHeight = m_contentRoot.rect.height;
}
}
private void HideTemplates()
{
if (m_pSubRank != null)
{
m_pSubRank.Show(false);
}
if (m_pSubSkill != null)
{
m_pSubSkill.Show(false);
}
}
// 初始化所有阶位子对话框 / Initialize all rank sub dialogs///
private void InitRankDlgs()
{
if (m_bAllocRankDlgs || m_pSubRank == null || m_contentRoot == null)
{
return;
}
m_bAllocRankDlgs = true;
for (CECTaoistRank taoistRank = CECTaoistRank.GetBaseRankBegin();
taoistRank != CECTaoistRank.GetBaseRankEnd();
taoistRank = taoistRank.GetNext())
{
CreateOneRankDlg(taoistRank);
}
for (CECTaoistRank taoistRank = CECTaoistRank.GetGodRankBegin();
taoistRank != CECTaoistRank.GetGodRankEnd();
taoistRank = taoistRank.GetNext())
{
CreateOneRankDlg(taoistRank);
}
for (CECTaoistRank taoistRank = CECTaoistRank.GetEvilRankBegin();
taoistRank != CECTaoistRank.GetEvilRankEnd();
taoistRank = taoistRank.GetNext())
{
CreateOneRankDlg(taoistRank);
}
}
// ʼڶԻһԷڴ / Initialize rank sub-dialogs once to avoid realloc
private void CreateOneRankDlg(CECTaoistRank taoistRank)
{
AUISubDialog pSubRank = Instantiate(m_pSubRank, m_contentRoot, transform);
pSubRank.SetName($"{m_pSubRank.GetName()}{taoistRank.GetID()}");
pSubRank.Show(false);
m_rankSubDialogs[taoistRank.GetID()] = pSubRank;
}
// Իв / Reset dialog with all rank/skill sub dialogs
public void ResetDialog()
{
m_skillSubDialogsMap.Clear();
m_skillSubCount = 0;
m_curBottom = m_originBottom;
foreach (var rank in m_rankSubDialogs.Values)
{
rank.Show(false);
}
foreach (var skill in m_skillSubDialogs)
{
skill.Show(false);
}
IReadOnlyDictionary<int, List<int>> allRankProfSkills = CECHostSkillModel.Instance?.GetAllRankProfSkills();
for (CECTaoistRank taoistRank = CECTaoistRank.GetBaseRankBegin();
taoistRank != CECTaoistRank.GetBaseRankEnd();
taoistRank = taoistRank.GetNext())
{
//BMLogger.LogError ("ResetDialog base rank " + taoistRank.GetName());
AddDlgsOfOneRank(taoistRank);
}
for (CECTaoistRank taoistRank = CECTaoistRank.GetGodRankBegin();
taoistRank != CECTaoistRank.GetGodRankEnd();
taoistRank = taoistRank.GetNext())
{
//BMLogger.LogError("ResetDialog base rank " + taoistRank.GetName());
AddDlgsOfOneRank(taoistRank);
}
for (CECTaoistRank taoistRank = CECTaoistRank.GetEvilRankBegin();
taoistRank != CECTaoistRank.GetEvilRankEnd();
taoistRank = taoistRank.GetNext())
{
//BMLogger.LogError("ResetDialog Evil rank " + taoistRank.GetName());
AddDlgsOfOneRank(taoistRank);
}
if (m_contentRoot != null)
{
FitSize();
ShowLastSelectedSkill();
}
UpdateTotalSPText();
}
public void UpdateTotalSPText()
{
if (totalSPText != null && GetHostPlayer() != null)
{
totalSPText.text = " <color=yellow>Nguyên Thần:</color> " + GetHostPlayer().GetBasicProps().iSP.ToString() + "</color>";
}
}
// ħ״̬ / Reset when switching between god/evil
public void ResetGodEvil()
{
if (isActiveAndEnabled)
{
ResetDialog();
}
}
// ޸ijһ״̬ / Refresh a single skill sub dialog
private void UpdateOneSubDlg(int skillID)
{
//BMLogger.LogError("UpdateOneSubDlg");
if (!m_skillSubDialogsMap.TryGetValue(skillID, out var pSub))
{
return;
}
CDlgSkillSubListItem subListItem = pSub;
if(subListItem == null )
{
return;
}
subListItem.UpdateSkill(skillID);
subListItem.Show(true);
if (GetSelectedSkillID() == skillID)
{
//GetGameUIMan()->m_pDlgSkillAction->ShowSkillTree(skillID);
}
}
// һԻ / Show a rank sub dialog
private void AddRankSubDig(int rankID)
{
if (!m_rankSubDialogs.TryGetValue(rankID, out var pSub))
{
return;
}
pSub.Show(true);
pSub.SetLabel(CECTaoistRank.GetTaoistRank(rankID).GetName());
//pSub.SetPos(0f, m_curBottom);
//m_curBottom += m_rankHeight * m_windowScale;
pSub.SetLabel(CECTaoistRank.GetTaoistRank(rankID).GetName());
}
// һܶԻ򣬵øúUpdateOneSubDlg / Add a skill sub dialog then update it
private void AddSkillSubDlg(int skillID, int rankID)
{
if (m_pSubSkill == null || m_contentRoot == null)
{
return;
}
if (m_skillSubCount >= m_skillSubDialogs.Count)
{
CDlgSkillSubListItem pSubSkill = Instantiate(m_pSubSkill, m_rankSubDialogs[rankID].transform);
m_skillSubDialogs.Add(pSubSkill);
}
CDlgSkillSubListItem curSubSkill = m_skillSubDialogs[m_skillSubCount];
curSubSkill?.SetHighlight(false);
m_skillSubDialogsMap[skillID] = curSubSkill;
m_skillSubCount++;
UpdateOneSubDlg(skillID);
}
// ijһӦмԻ / Add dialogs for one rank
private void AddDlgsOfOneRank(CECTaoistRank taoistRank)
{
CECHostSkillModel model = CECHostSkillModel.Instance;
IReadOnlyDictionary<int, List<int>> allRankProfSkills = model.GetAllRankProfSkills();
int rankID = taoistRank.GetID();
if (allRankProfSkills == null)
{
return;
}
if (IsEvil() && taoistRank.IsGodRank())
{
return;
}
else if (!IsEvil() && taoistRank.IsEvilRank())
{
return;
}
if (!allRankProfSkills.TryGetValue(rankID, out var rankItr) || rankItr == null || rankItr.Count == 0)
{
return;
}
List<int> rankSkills = new List<int>();
foreach (var skillID in rankItr)
{
if (ElementSkill.IsOverridden((uint)skillID))
{
BMLogger.LogError("HoangDev: AddDlgsOfOneRank ElementSkill.IsOverridden for skillID " + skillID);
continue;
}
/* bool bOnlyShowSkillCanLearn = GetGameUIMan()->m_pDlgSkillAction->IsOnlyShowSkillCanLearn();
if (bOnlyShowSkillCanLearn)
{
if (model.GetSkillFitLevel(skillID) == CECHostSkillModel::SKILL_NOT_FIT_LEVEL)
{
continue;
}
int curLevel = model.GetSkillCurrentLevel(skillID);
int requiredItem = model.GetRequiredBook(skillID, curLevel + 1);
if (requiredItem && !model.CheckPreItem(requiredItem))
{
continue;
}
}*/
rankSkills.Add(skillID);
}
if (rankSkills.Count == 0)
{
BMLogger.LogError("HoangDev: AddDlgsOfOneRank rankSkills.Count == 0");
return;
}
AddRankSubDig(rankID);
rankSkills.Sort();
foreach (int skillID in rankSkills)
{
AddSkillSubDlg(skillID , rankID);
}
}
private string GetRankName(int rankID)
{
// 尝试使用阶位名字,否则使用 ID / Use rank name if available, otherwise ID
// TODO: wire into localization table once available
return $"Rank {rankID}";
}
// λõȡֵ / Scroll helpers use the stored positions
public void ScrollToShowSelectedSkill()
{
if (m_scrollRect == null || GetSelectedSkillID() == 0)
{
return;
}
if (!m_skillSubDialogsMap.TryGetValue(GetSelectedSkillID(), out var sub))
{
return;
}
}
// ׼Ľ / Prepare for layout change
public bool OnChangeLayoutBegin()
{
foreach (var kv in m_rankSubDialogs)
{
Destroy(kv.Value.gameObject);
}
m_rankSubDialogs.Clear();
foreach (var dlg in m_skillSubDialogs)
{
Destroy(dlg.gameObject);
}
m_skillSubDialogs.Clear();
m_skillSubDialogsMap.Clear();
m_skillSubCount = 0;
m_curBottom = 0f;
return true;
}
// 布局变更结束时 / After layout change
public void OnChangeLayoutEnd(bool bAllDone)
{
if (isActiveAndEnabled)
{
InitRankDlgs();
FitSize();
ShowLastSelectedSkill();
}
}
private void FitSize()
{
if (m_contentRoot == null)
{
return;
}
float height = Mathf.Max(m_curBottom, m_originHeight);
m_contentRoot.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, height);
}
private void ShowLastSelectedSkill()
{
int originSelected = GetSelectedSkillID();
SetSelectedSkillID(0);
SelectSkill(originSelected);
ScrollToShowSelectedSkill();
}
public void SelectSkill(int skillID)
{
if (skillID != 0 && !m_skillSubDialogsMap.ContainsKey(skillID))
{
skillID = ConvertSkillID(skillID);
}
if (skillID != 0 && !m_skillSubDialogsMap.ContainsKey(skillID))
{
SetSelectedSkillID(0);
return;
}
int originSelectedSkillID = GetSelectedSkillID();
if (originSelectedSkillID != 0 && m_skillSubDialogsMap.TryGetValue(originSelectedSkillID, out var originSub))
{
originSub.GetComponent<CDlgSkillSubListItem>()?.SetHighlight(false);
}
if (skillID != 0 && m_skillSubDialogsMap.TryGetValue(skillID, out var newSub))
{
newSub.GetComponent<CDlgSkillSubListItem>()?.SetHighlight(true);
}
SetSelectedSkillID(skillID);
}
public void EnableUpgrade(bool bEnable)
{
foreach (var kv in m_skillSubDialogsMap)
{
kv.Value.GetComponent<CDlgSkillSubListItem>()?.EnableUpgrade(bEnable);
}
}
public int GetSelectedSkillID()
{
return m_selectedSkillId;
}
public void SetSelectedSkillID(int skillID)
{
m_selectedSkillId = skillID;
}
public bool IsEvil()
{
return m_isEvil;
}
public void SetEvil(bool value)
{
if (m_isEvil != value)
{
m_isEvil = value;
ResetGodEvil();
}
}
// ܱӦǷб / Check whether skill or its converted counterpart exists
public bool IsSkillOrConvertSkillExist(int skillID)
{
if (m_skillSubDialogsMap.ContainsKey(skillID))
{
return true;
}
int convertSkillID = ConvertSkillID(skillID);
return convertSkillID != 0 && m_skillSubDialogsMap.ContainsKey(convertSkillID);
}
private int ConvertSkillID(int skillID)
{
// 预留转换逻辑 / Placeholder for conversion logic
return skillID;
}
// мܱˣҪ / Handle model change notifications
public void OnModelChange(CECSkillPanelChange q)
{
/* if (!GetGameUIMan().m_pDlgSkillAction.IsShow())
{
return;
}*/
if (q.m_changeMask == CECSkillPanelChange.enumChangeMask.CHANGE_SKILL_OVERRIDDEN)
{
ResetDialog();
}
else if (q.m_changeMask == CECSkillPanelChange.enumChangeMask.CHANGE_SKILL_LEVEL_UP)
{
UpdateTotalSPText();
if (q.m_skillLevel == 1)
{
foreach (var kv in m_skillSubDialogsMap)
{
UpdateOneSubDlg(kv.Key);
}
}
else
{
UpdateOneSubDlg(q.m_skillID);
}
}
else if (q.m_changeMask == CECSkillPanelChange.enumChangeMask.CHANGE_SKILL_NPC)
{
//GetGameUIMan()->m_pDlgSkillAction->Show(false);
}
}
}
}