using BrewMonster.Network; using BrewMonster.Scripts.Skills; using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace BrewMonster { // CECSkillStr class - inherits from SkillStr public class CECSkillStr : SkillStr { public override string Find(int id) { // TODO: Implement GetNameDisplay - requires game instance access BrewMonster.CECStringTab pStrTab = EC_Game.GetSkillDesc(); string str = pStrTab.GetWideString(id); return string.IsNullOrEmpty(str) ? string.Empty : str; } } // Skill array wrapper structure public struct SkillArrayWrapper { public Dictionary skillDic; public SkillArrayWrapper(Dictionary rhs) { skillDic = rhs ?? new Dictionary(); RemoveInvalid(); } // Remove invalid skills (for example, those with ID == 0) public void RemoveInvalid() { if (skillDic == null) return; var invalidKeys = skillDic .Where(kv => kv.Key == 0) .Select(kv => kv.Key) .ToList(); foreach (var key in invalidKeys) skillDic.Remove(key); } public bool Find(uint id) { return skillDic != null && skillDic.ContainsKey(id); } public bool Empty() { return skillDic == null || skillDic.Count == 0; } public int Count() { return skillDic?.Count ?? 0; } public uint this[int index] { get { if (skillDic == null || index < 0 || index >= skillDic.Count) throw new System.IndexOutOfRangeException(); return skillDic.ElementAt(index).Key; } } } // CECSkill class public class CECSkill { // Skill type enum public enum SkillType { TYPE_ATTACK = 1, // 攻击技能 TYPE_BLESS, // 祝福技能 TYPE_CURSE, // 诅咒技能 TYPE_SUMMON, // 召唤 TYPE_PASSIVE, // 被动 TYPE_ENABLED, // 启用 TYPE_LIVE, // 生活 TYPE_FLASHMOVE, // 瞬移 TYPE_PRODUCE, // 生产 TYPE_BLESSPET, // 宠物祝福 TYPE_NEUTRALBLESS, // 中立祝福 } // Range type enum public enum RangeType { RANGE_POINT = 0, // 点 RANGE_LINE, // 线 RANGE_SELFSPHERE, // 自身为圆心的圆 RANGE_TARGETSPHERE, // 目标为圆心的圆 RANGE_TAPER, // 圆锥 RANGE_SLEF, // 自身 } private ElementSkill m_pSkillCore; private int m_idSkill; private int m_iLevel; private int m_iCoolCnt; private int m_iCoolTime; private bool m_bCooling; private int m_iChargeCnt; private int m_iChargeMax; public int ChargeMax => m_iChargeMax; private bool m_bCharging; private static CECSkillStr l_SkillStr = new CECSkillStr(); public ElementSkill SkillCore => m_pSkillCore; // Constructor public CECSkill(int id, int iLevel) { if (iLevel < 0) return; m_pSkillCore = ElementSkill.Create((uint)id, iLevel); if (m_pSkillCore == null) { // Fallback to default skill m_pSkillCore = ElementSkill.Create(1, 1); } m_idSkill = id; m_iLevel = iLevel; m_iCoolTime = m_pSkillCore != null ? m_pSkillCore.GetCoolingTime() : 0; m_iCoolCnt = 0; m_bCooling = false; m_iChargeCnt = 0; m_iChargeMax = 0; m_bCharging = false; } // Tick routine public void Tick(float deltaTime) { // Convert deltaTime (seconds) to milliseconds int tickTime = (int)(deltaTime * 1000f); if (m_bCooling) { m_iCoolCnt -= tickTime; if (m_iCoolCnt <= 0) { m_iCoolCnt = 0; m_bCooling = false; // TODO: do something here ? } } if (m_bCharging) { // In charging state m_iChargeCnt += tickTime; if (m_iChargeCnt >= m_iChargeMax) { m_iChargeCnt = m_iChargeMax; m_bCharging = false; // TODO: do something here ? } } } // Skill level up public void LevelUp() { m_iLevel++; if (m_pSkillCore != null) { m_pSkillCore.SetLevel(m_iLevel); } } // Set Skill level public void SetLevel(int iLevel) { m_iLevel = iLevel; if (m_pSkillCore != null) { m_pSkillCore.SetLevel(m_iLevel); } } // Start into cooling state // iTotalTime: total cooling time, 0 means to use cooling time in database public void StartCooling(int iTotalTime, int iStartCnt) { m_iCoolTime = iTotalTime != 0 ? iTotalTime : GetCoreCoolingTime(); m_iCoolCnt = iStartCnt; m_bCooling = true; } public bool ValidWeapon(int idWeapon) { return m_pSkillCore.ValidWeapon(idWeapon); } // Ready to be cast ? public bool ReadyToCast() { return !m_bCooling; } // Get cooling time counter public int GetCoolingCnt() { return m_iCoolCnt; } // Get total cooling time public int GetCoolingTime() { return m_iCoolTime; } // Start charging public void StartCharging(int iChargeMax) { if (m_pSkillCore != null && m_pSkillCore.IsWarmup()) { m_iChargeMax = iChargeMax; m_iChargeCnt = 0; m_bCharging = true; } } // End charging public void EndCharging() { m_bCharging = false; } // Get charging flag public bool IsCharging() { return m_bCharging; } // Get charging counter public int GetChargingCnt() { return m_iChargeCnt; } // Get charging maximum count public int GetChargingMax() { return m_iChargeMax; } // Charge full public bool ChargeFull() { return m_pSkillCore != null && m_pSkillCore.IsWarmup() && m_iChargeCnt >= m_iChargeMax; } // Get skill ID public int GetSkillID() { return m_idSkill; } // Get skill level public int GetSkillLevel() { return m_iLevel; } // Get skill icon file public string GetIconFile() { return m_pSkillCore != null ? m_pSkillCore.GetIcon() ?? string.Empty : string.Empty; } public string GetName() { return m_pSkillCore != null ? m_pSkillCore.GetName() ?? string.Empty : string.Empty; } public string GetNameDisplay() { return EC_Game.GetSkillDesc().GetWideString(GetSkillID() * 10); } public StringBuilder GetDesc() { if (m_pSkillCore == null || l_SkillStr == null) return null; StringBuilder sb = new StringBuilder(1024); m_pSkillCore.GetIntroduction(sb, l_SkillStr); return sb; } public static StringBuilder GetDesc(int idSkill, int iLevel, StringBuilder szText, int iBufLen) { if (szText == null || iBufLen == 0) return null; CECSkill pSkill = new CECSkill(idSkill, iLevel); if (pSkill == null) { return null; } szText = pSkill.GetDesc(); return szText; } public int GetCoreCoolingTime() { return m_pSkillCore != null ? m_pSkillCore.GetCoolingTime() : 0; } public int GetComboSkPreSkill() { return m_pSkillCore.GetComboSkPreSkill(); } public int GetExecuteTime() { return m_pSkillCore != null ? m_pSkillCore.GetExecuteTime() : 0; } public int GetCommonCoolDown() { return m_pSkillCore.GetCommonCoolDown(); } public int GetType() { return m_pSkillCore != null ? m_pSkillCore.GetType() : 0; } public int GetRangeType() { return m_pSkillCore != null ? m_pSkillCore.GetRangeType() : 0; } public float GetCastRange(float fAtkDist, float fPrayDistancePlus) { return m_pSkillCore != null ? m_pSkillCore.GetPrayRange(fAtkDist, fPrayDistancePlus) : 0f; } public string GetEffect() { return m_pSkillCore != null ? m_pSkillCore.GetEffect() ?? string.Empty : string.Empty; } public int GetTargetType() { return m_pSkillCore != null ? m_pSkillCore.GetTargetType() : 0; } public int GetCastEnv() { return m_pSkillCore != null ? m_pSkillCore.GetCastEnv() : 0; } /* public int[] GetRequiredGenius() { return m_pSkillCore != null ? m_pSkillCore.GetRequiredGenius(m_idSkill) ?? new int[0] : new int[0]; }*/ public int GetShowOrder() { return m_pSkillCore != null ? m_pSkillCore.GetShowOrder() : 0; } public bool IsChargeable() { return m_pSkillCore != null && m_pSkillCore.IsWarmup(); } /* public string GetNativeName() { return m_pSkillCore != null ? m_pSkillCore.GetNativeName() ?? string.Empty : string.Empty; }*/ /* public bool ValidShape(int iShape) { return m_pSkillCore != null && m_pSkillCore.IsValidForm((char)iShape); }*/ public bool ChangeToMelee() { return m_pSkillCore != null && m_pSkillCore.IsAutoAttack(); } public bool IsInstant() { return m_pSkillCore != null && m_pSkillCore.IsInstant(); } public bool IsDurative() { return m_pSkillCore != null && m_pSkillCore.IsDurative(); } public SkillArrayWrapper GetJunior() { var juniorList = m_pSkillCore.GetJunior(); return new SkillArrayWrapper(juniorList); } public int GetRequiredLevel() { return m_pSkillCore != null ? m_pSkillCore.GetRequiredLevel() : 0; } public int GetRequiredBook() { return m_pSkillCore != null ? m_pSkillCore.GetRequiredBook() : 0; } /* public SkillArrayWrapper GetRequiredSkill() { return m_pSkillCore != null ? m_pSkillCore.GetRequiredSkill() : new SkillArrayWrapper(new List()); }*/ /* public int GetRequiredItem() { return m_pSkillCore != null ? m_pSkillCore.GetItemCost() : 0; }*/ // 获取技能公共冷却mask,其中bit0-4为技能公共冷却,bit5-9为物品公共冷却 /* public int GetCommonCoolDown() { return m_pSkillCore != null ? m_pSkillCore.GetCommonCoolDown() : 0; }*/ // 获取技能公共冷却时间,单位毫秒 /* public int GetCommonCoolDownTime() { return m_pSkillCore != null ? m_pSkillCore.GetCommonCoolDownTime() : 0; }*/ // Check skill type public bool IsGoblinSkill() { return m_pSkillCore != null && m_pSkillCore.GetCls() == 258; } public bool IsPlayerSkill() { // TODO: NUM_PROFESSION should be defined elsewhere const int NUM_PROFESSION = 256; // Placeholder int cls = m_pSkillCore != null ? m_pSkillCore.GetCls() : -1; return cls >= 0 && cls < NUM_PROFESSION; } public bool IsGeneralSkill() { return GetCls() == 255; } public int GetCls() { return m_pSkillCore != null ? m_pSkillCore.GetCls() : -1; } // 技能等级 public int GetRank() { return m_pSkillCore != null ? m_pSkillCore.GetRank() : 0; } // 技能最大等级 public int GetMaxLevel() { return m_pSkillCore != null ? m_pSkillCore.GetMaxLevel() : 0; } /* public int GetComboSkPreSkill() { return m_pSkillCore != null ? m_pSkillCore.GetComboSkPreSkill() : 0; }*/ public bool IsPositiveSkill() { int t = GetType(); return t != (int)SkillType.TYPE_PASSIVE && t != (int)SkillType.TYPE_PRODUCE && t != (int)SkillType.TYPE_LIVE; } } }