using System.Collections.Generic; using BrewMonster; using BrewMonster.Scripts.Skills; using BrewMonster.UI; using UnityEngine; using UnityEngine.UI; using TMPro; using BrewMonster.Assets.PerfectWorld.Scripts.UI.GamePlay; using BrewMonster.Network; namespace BrewMonster.UI { /// /// Skill dialog sub-other panel - displays combo skills, fixed skills, item skills, and produce skills /// Converted from DlgSkillSubOther.cpp/h /// [DisallowMultipleComponent] public class CDlgSkillSubOther : AUIDialog { private const int ITEM_SKILL_MAX_COUNT = 8; private const int FIXED_SKILL_MAX_COUNT = 4; [Header("Combo Skill Images")] [SerializeField] private List m_comboSkillImages = new List(); [Header("Fixed Skill Components")] [SerializeField] private List m_fixedImgPics = new List(); [SerializeField] private List m_fixedTxts = new List(); [Header("Item Skill Images")] [SerializeField] private List m_itemSkillImages = new List(); [Header("Produce Skill Components")] [SerializeField] private List m_produceImgIcons = new List(); [SerializeField] private List m_produceNameLabels = new List(); [SerializeField] private List m_produceSkilledTxtLabels = new List(); [SerializeField] private List m_produceSkilledExpLabels = new List(); [SerializeField] private List m_produceLevelLabels = new List(); [Header("Buttons")] [SerializeField] private Button m_btnEdit; [SerializeField] private Button m_btnDelete; [SerializeField] private Button m_btnNew; private int m_nComboSelect = 0; private readonly List m_fixedSkills = new List(); private readonly List m_produceSkills = new List(); private void Awake() { // Initialize fixed skills - 167 is return skill m_fixedSkills.Add(167); // Initialize produce skills - respectively: weapon crafting, armor crafting, accessory crafting, alchemy m_produceSkills.Add(158); m_produceSkills.Add(159); m_produceSkills.Add(160); m_produceSkills.Add(161); // Setup button listeners if (m_btnEdit != null) m_btnEdit.onClick.AddListener(OnCommandEdit); if (m_btnDelete != null) m_btnDelete.onClick.AddListener(OnCommandDelete); if (m_btnNew != null) m_btnNew.onClick.AddListener(OnCommandNew); } public override void OnShowDialogue() { base.OnShowDialogue(); Debug.Log("CDlgSkillSubOther::OnShowDialog()"); UpdateComboSkill(); UpdateFixedSkill(); UpdateItemSkill(); UpdateProduceSkill(); } /*public override bool Render() { if (!base.Render()) return false; if (!gameObject.activeInHierarchy) return true; // Item skills and produce skills may change, update them UpdateItemSkill(); UpdateProduceSkill(); // Update fixed skill cooldowns CECHostPlayer host = GetHostPlayer(); for (int i = 0; i < m_fixedSkills.Count && i < m_fixedImgPics.Count; i++) { if (m_fixedImgPics[i] != null && host != null) { CECSkill pSkill = host.GetPositiveSkillByID(m_fixedSkills[i]); UpdateImagePictureCD(m_fixedImgPics[i], pSkill); } } // Update item skill cooldowns int equipSkillNum = host != null ? host.GetEquipSkillNum() : 0; for (int i = 0; i < equipSkillNum && i < ITEM_SKILL_MAX_COUNT && i < m_itemSkillImages.Count; i++) { if (m_itemSkillImages[i] != null && host != null) { CECSkill pSkill = host.GetEquipSkillByIndex(i); UpdateImagePictureCD(m_itemSkillImages[i], pSkill); } } return true; }*/ // Edit combo skill - called from DlgSkill public void OnCommandEdit() { // TODO: Implement DlgSkillEdit equivalent // GetGameUIMan()->m_pDlgSkillEdit->SetData(m_nComboSelect); // GetGameUIMan()->m_pDlgSkillEdit->Show(true); Debug.Log($"OnCommandEdit: combo select = {m_nComboSelect}"); } // New combo skill - called from DlgSkill public void OnCommandNew() { // TODO: Implement DlgSkillEdit equivalent // GetGameUIMan()->m_pDlgSkillEdit->SetData(0); // GetGameUIMan()->m_pDlgSkillEdit->Show(true); Debug.Log("OnCommandNew"); } // Delete combo skill - called from DlgSkill public void OnCommandDelete() { if (m_nComboSelect < 0 || m_nComboSelect > EC_ConfigConstants.EC_COMBOSKILL_NUM) return; CECConfigs configs = EC_Game.GetConfigs(); if (configs == null) return; EC_VIDEO_SETTING setting = configs.GetVideoSettings(); setting.comboSkill[m_nComboSelect - 1].nIcon = 0; m_nComboSelect = 0; configs.SetVideoSettings(setting); UpdateComboSkill(); } // Helper dictionary to store combo skill data private Dictionary m_comboSkillData = new Dictionary(); // Helper dictionary to store skill data for images private Dictionary m_skillData = new Dictionary(); // Update combo skill icons - called from DlgSkill public void UpdateComboSkill() { // TODO:em hai lam /* CECConfigs configs = EC_Game.GetConfigs(); if (configs == null) return; EC_VIDEO_SETTING setting = configs.GetVideoSettings(); CECGameUIMan gameUIMan = GetGameUIMan(); for (int i = 0; i < EC_ConfigConstants.EC_COMBOSKILL_NUM; i++) { AUIImagePicture pImage = m_comboSkillImages[i]; if (pImage != null) { if (setting.comboSkill[i].nIcon != 0) { // TODO: Set icon from sprite sheet //pImage->SetCover(GetGameUIMan()->m_pA2DSpriteIcons[CECGameUIMan::ICONS_SKILLGRP], // setting.comboSkill[i].nIcon + 1); m_comboSkillData[pImage] = (uint)(i + 1); //pImage.SetDataPtr(new object(), "ptr_Valid"); // Equivalent to (void*)1 string hintText = GetStringFromTable(804); if (!string.IsNullOrEmpty(hintText)) { hintText = string.Format(hintText, i); // TODO: Set hint text // pImage->SetHint(hintText); } } else { // TODO: Clear icon // pImage->SetCover(NULL, -1); m_comboSkillData[pImage] = 0; pImage.SetDataPtr(null); // pImage->SetHint(""); } } }*/ } // Update fixed skill display public void UpdateFixedSkill() { // First hide all fixed skill components /*for (int i = 0; i < FIXED_SKILL_MAX_COUNT; i++) { if (i < m_fixedImgPics.Count && m_fixedImgPics[i] != null) m_fixedImgPics[i].gameObject.SetActive(false); if (i < m_fixedTxts.Count && m_fixedTxts[i] != null) m_fixedTxts[i].gameObject.SetActive(false); } Debug.Assert(m_fixedSkills.Count <= FIXED_SKILL_MAX_COUNT, "Fixed skills count exceeds max"); CECHostPlayer host = GetHostPlayer(); for (int i = 0; i < m_fixedSkills.Count; i++) { if (i < m_fixedImgPics.Count && m_fixedImgPics[i] != null) m_fixedImgPics[i].gameObject.SetActive(true); if (i < m_fixedTxts.Count && m_fixedTxts[i] != null) m_fixedTxts[i].gameObject.SetActive(true); CECSkill pSkill = host?.GetPositiveSkillByID(m_fixedSkills[i]); if (pSkill != null) { SetImage(m_fixedImgPics[i], pSkill); if (i < m_fixedTxts.Count && m_fixedTxts[i] != null) m_fixedTxts[i].text = pSkill.GetNameDisplay(); } else { if (i < m_fixedImgPics.Count && m_fixedImgPics[i] != null) { m_fixedImgPics[i].gameObject.SetActive(false); SetImage(m_fixedImgPics[i], null); } if (i < m_fixedTxts.Count && m_fixedTxts[i] != null) m_fixedTxts[i].gameObject.SetActive(false); } }*/ } // Update item skill display public void UpdateItemSkill() { CECHostPlayer host = GetHostPlayer(); if (host == null) return; int equipSkillNum = host.GetEquipSkillNum(); for (int i = 0; i < ITEM_SKILL_MAX_COUNT && i < m_itemSkillImages.Count; i++) { AUIImagePicture pImgPic = m_itemSkillImages[i]; if (pImgPic != null) { if (i < equipSkillNum) { CECSkill pSkill = host.GetEquipSkillByIndex(i); SetImage(pImgPic, pSkill); } else { SetImage(pImgPic, null); } } } } // Update produce skill display public void UpdateProduceSkill() { CECHostPlayer host = GetHostPlayer(); if (host == null) return; for (int i = 0; i < m_produceSkills.Count; i++) { AUIImagePicture imgIcon = i < m_produceImgIcons.Count ? m_produceImgIcons[i] : null; TextMeshProUGUI lblName = i < m_produceNameLabels.Count ? m_produceNameLabels[i] : null; TextMeshProUGUI lblSkilledTxt = i < m_produceSkilledTxtLabels.Count ? m_produceSkilledTxtLabels[i] : null; TextMeshProUGUI lblSkilledExp = i < m_produceSkilledExpLabels.Count ? m_produceSkilledExpLabels[i] : null; TextMeshProUGUI lblLevel = i < m_produceLevelLabels.Count ? m_produceLevelLabels[i] : null; if (imgIcon != null) imgIcon.gameObject.SetActive(true); if (lblName != null) lblName.gameObject.SetActive(true); //CECSkill pSkill = host.GetPassiveSkillByID(m_produceSkills[i]); /* if (pSkill == null) { if (lblSkilledTxt != null) lblSkilledTxt.gameObject.SetActive(false); if (lblSkilledExp != null) lblSkilledExp.gameObject.SetActive(false); if (lblLevel != null) lblLevel.gameObject.SetActive(false); if (imgIcon != null) { // Set gray color Image img = imgIcon.GetComponent(); if (img != null) img.color = new Color(0.5f, 0.5f, 0.5f, 1f); // RGB(128, 128, 128) } CECSkill tmpSkill = new CECSkill(m_produceSkills[i], 1); SetImage(imgIcon, tmpSkill); if (lblName != null) lblName.text = tmpSkill.GetNameDisplay(); } else { if (lblSkilledTxt != null) lblSkilledTxt.gameObject.SetActive(true); if (lblSkilledExp != null) lblSkilledExp.gameObject.SetActive(true); if (lblLevel != null) lblLevel.gameObject.SetActive(true); if (imgIcon != null) { // Set white color Image img = imgIcon.GetComponent(); if (img != null) img.color = Color.white; // RGB(255, 255, 255) } SetImage(imgIcon, pSkill); if (lblName != null) lblName.text = pSkill.GetNameDisplay();*/ /* int maxAbility = ElementSkill.GetMaxAbility(m_produceSkills[i], pSkill.GetSkillLevel()); int ability = ElementSkill.GetAbility(m_produceSkills[i]);*/ /* if (lblSkilledExp != null) lblSkilledExp.text = $"{ability}/{maxAbility}";*/ /*if (lblLevel != null) { string levelFormat = GetStringFromTable(11323); if (!string.IsNullOrEmpty(levelFormat)) lblLevel.text = string.Format(levelFormat, pSkill.GetSkillLevel()); }*/ //} } } // Get combo skill data for an image private uint GetComboSkillData(AUIImagePicture pImage) { if (pImage == null) return 0; return m_comboSkillData.TryGetValue(pImage, out uint data) ? data : 0; } // Handle combo skill icon click for drag - called from DlgSkill public void OnEventLButtonDownCombo(AUIImagePicture pObj) { uint data = GetComboSkillData(pObj); if (pObj == null || data == 0) return; // TODO: Implement drag and drop // A3DVIEWPORTPARAM *p = m_pA3DEngine->GetActiveViewport()->GetParam(); // POINT pt = { GET_X_LPARAM(lParam) - p->X, GET_Y_LPARAM(lParam) - p->Y }; // GetGameUIMan()->m_ptLButtonDown = pt; // GetGameUIMan()->InvokeDragDrop(this, pObj, pt); Debug.Log($"OnEventLButtonDownCombo: combo skill {data}"); } // Handle fixed skill icon click for drag public void OnEventLButtonDownFixed(AUIImagePicture pObj) { if (pObj == null) return; /* CECSkill skill = GetSkillFromImage(pObj); if (skill == null) return;*/ // TODO: Implement drag and drop // GetGameUIMan()->m_ptLButtonDown = ...; // GetGameUIMan()->InvokeDragDrop(this, pObj, GetGameUIMan()->m_ptLButtonDown); Debug.Log("OnEventLButtonDownFixed"); } // Handle item skill icon click for drag public void OnEventLButtonDownItem(AUIImagePicture pObj) { if (pObj == null) return; /* CECSkill skill = GetSkillFromImage(pObj); if (skill == null) return;*/ // TODO: Implement drag and drop // GetGameUIMan()->m_ptLButtonDown = ...; // GetGameUIMan()->InvokeDragDrop(this, pObj, GetGameUIMan()->m_ptLButtonDown); Debug.Log("OnEventLButtonDownItem"); } // Select combo skill - called from DlgSkill public void SelectComboSkill(int n) { if (n < 1 || n > m_comboSkillImages.Count) return; if (m_nComboSelect == n) { // Deselect AUIImagePicture pImage = m_comboSkillImages[n - 1]; if (pImage != null) { Image img = pImage.GetComponent(); if (img != null) img.color = Color.white; // RGB(255, 255, 255) } m_nComboSelect = 0; } else { // Deselect previous if (m_nComboSelect != 0 && m_nComboSelect <= m_comboSkillImages.Count) { AUIImagePicture pImage = m_comboSkillImages[m_nComboSelect - 1]; if (pImage != null) { Image img = pImage.GetComponent(); if (img != null) img.color = Color.white; // RGB(255, 255, 255) } } // Select new m_nComboSelect = n; AUIImagePicture pNewImage = m_comboSkillImages[n - 1]; if (pNewImage != null) { Image img = pNewImage.GetComponent(); if (img != null) img.color = new Color(0.627f, 0.627f, 0.627f, 1f); // RGB(160, 160, 160) } } } // Set image for an AUIImagePicture with a skill - called from DlgSkill public void SetImage(AUIImagePicture pImage, CECSkill pSkill) { if (pImage == null) return; if (pSkill != null) { // TODO: Set icon from sprite sheet // AString strFile; // af_GetFileTitle(pSkill->GetIconFile(), strFile); // strFile.MakeLower(); // pImage->SetCover( // GetGameUIMan()->m_pA2DSpriteIcons[CECGameUIMan::ICONS_SKILL], // GetGameUIMan()->m_IconMap[CECGameUIMan::ICONS_SKILL][strFile]); // Store skill in dictionary for retrieval m_skillData[pImage] = pSkill; // Try to set as shortcut if possible /* if (pSkill is CECShortcut shortcut) pImage.SetDataPtr(shortcut, "ptr_CECSkill");*/ // TODO: Set hint // pImage->SetHint(pSkill->GetDesc()); } else { // TODO: Clear icon // pImage->SetCover(NULL, -1); m_skillData.Remove(pImage); pImage.SetDataPtr(null); // pImage->SetHint(""); } } // Get skill from image /* private CECSkill GetSkillFromImage(AUIImagePicture pImage) { if (pImage == null) return null; // Try dictionary first if (m_skillData.TryGetValue(pImage, out CECSkill skill)) return skill; // Try shortcut CECShortcut shortcut = pImage.GetDataPtr(); return shortcut as CECSkill; }*/ // Update image picture cooldown display private void UpdateImagePictureCD(AUIImagePicture pImgPic, CECSkill pSkill) { if (pImgPic == null) return; CECHostPlayer pHost = GetHostPlayer(); if (pHost == null) return; AUIClockIcon pClock = pImgPic.GetClockIcon(); if (pClock == null) return; Image img = pImgPic.GetComponent(); if (img == null) return; if (pSkill != null && pSkill.ReadyToCast() && pHost.GetPrepSkill() != pSkill) { if (pHost.CheckSkillCastCondition(pSkill) == 0) img.color = Color.white; // RGB(255, 255, 255) else img.color = new Color(0.5f, 0.5f, 0.5f, 1f); // RGB(128, 128, 128) } else { // Set clock color Image clockImg = pClock.GetClockIcon(); if (clockImg != null) clockImg.color = new Color(0, 0, 0, 0.5f); // RGBA(0, 0, 0, 128) } if (pSkill != null && (pSkill.GetCoolingTime() > 0 || pHost.GetPrepSkill() == pSkill)) { pClock.SetProgressRange(0, pSkill.GetCoolingTime()); if (pHost.GetPrepSkill() == pSkill) pClock.SetProgressPos(0); else pClock.SetProgressPos(pSkill.GetCoolingTime() - pSkill.GetCoolingCnt()); } } } }