using BrewMonster.Assets.PerfectWorld.Scripts.Skills; using System.Collections.Generic; using System.Text; using UnityEngine; using UnityEngine.InputSystem; using static UnityEngine.Rendering.DebugUI; namespace BrewMonster.Scripts.Skills { public class Range { /// 0=point 1=line 2=self sphere 3=target sphere 4=cone 5=self public byte type; // 0�� 1�� 2������ 3Ŀ���� 4Բ׶�� 5���� public bool IsPoint() { return type == 0; } public bool IsLine() { return type == 1; } public bool IsSelfBall() { return type == 2; } public bool IsTargetBall() { return type == 3; } public bool IsSector() { return type == 4; } public bool IsSelf() { return type == 5; } public bool NoTarget() { return type == 2 || type == 5; } } // ռλ������ // Placeholder Skill class public class Skill : ElementSkill { protected SkillStub stub; protected PlayerWrapper player; protected uint id; protected uint level; Skill(uint i, SkillStub s) { id = i; stub = s; player = new PlayerWrapper(); } public static Skill Create(uint id, int n) { SkillStub stub = SkillStub.GetStub(id); if (stub == null) return null; Skill skill = new Skill(id, stub); int max = skill.GetMaxLevel(); if (n > max) skill.SetLevel(max); else skill.SetLevel(n); return skill; } public override int GetMaxLevel() { return stub.GetMaxLevel(); } public override int SetLevel(int l) { uint tmp = level; level = (uint)l; return (int)tmp; } public override int GetItemCost() { return stub.itemcost; } public int GetLevel() { return (int)level; } public PlayerWrapper GetPlayer() { return player; } public override int GetRank() { return stub.rank; } public override bool IsInstant() { return stub.time_type == 1; } public override int GetCls() { return stub.GetCls(); } public override Dictionary GetJunior() { return stub.is_senior != 0 ? stub.pre_skills : new Dictionary(); } public override int GetRangeType() { return stub.GetRange().type; } public override int GetRequiredLevel() { return stub.GetRequiredLevel(this); } public override void GetIntroduction(StringBuilder buf, SkillStr table) { int n = stub.GetIntroduction(this, buf, table.Find((int)stub.id * 10 + 1)); } public override int GetTargetType() { if (stub.restrict_corpse == 1) return 2; if (stub.restrict_corpse == 2) return 3; if (stub.type == (int)skill_type.TYPE_ATTACK || stub.type == (int)skill_type.TYPE_CURSE) return 1; if (stub.type == (int)skill_type.TYPE_BLESSPET) return 4; if (stub.GetRange().NoTarget()) return 0; return 1; } public override int GetComboSkPreSkill() { return stub.combosk_preskill; } public override byte GetType() { return stub.type; } public override int GetCommonCoolDown() { return stub.commoncooldown; } public override string GetIcon() { return stub.GetIcon(); } public int GetAbility() { return SkillWrapper.Instance.GetAbility(id); } // 检查施放时hp条件 // Check HP condition when casting public override bool CheckHpCondition(int hp, int max_hp) { return stub.CheckHpCondition(hp, max_hp); } public override bool CheckComboSkExtraCondition() { return stub.CheckComboSkExtraCondition(this); } public override byte GetAllowForms() { return stub.allow_forms; } public override int GetApCost() { return stub.apcost; } public override string GetName() { return stub.GetName(); } public override float GetPrayRange(float range, float prayplus) { player.SetRange(range); player.SetPrayrangeplus(prayplus); if (stub.type == (int)skill_type.TYPE_ATTACK || stub.type == (int)skill_type.TYPE_CURSE) { if (stub.auto_attack) { float r = 0.3f * stub.GetPraydistance(this); if (r >= 1.0) return stub.GetPraydistance(this) - 1.0f; else return (float)0.7 * stub.GetPraydistance(this); } else return stub.GetPraydistance(this); } if (stub.type == (int)skill_type.TYPE_JUMP) return stub.GetPraydistance(this); if (stub.GetRange().NoTarget()) return -1; else return stub.GetPraydistance(this); } public override int GetCoolingTime() { return stub.GetCoolingtime(this); } public int GetRequiredSp() { return stub.GetRequiredSp(this); } public int GetRequiredMoney() { return stub.GetRequiredMoney(this); } public override Dictionary GetRequiredSkill() { return stub.pre_skills; } public int GetRequiredRealmLevel() { return stub.GetRequiredRealmLevel(this); } public int GetMaxability() { return stub.GetMaxAbility(this); } public uint GetId() { return id; } public int GetComboSkInterval() { return stub.combosk_interval; } } public abstract class SkillStub { public const int MIN_LEVEL = 1; public const int MAX_LEVEL = 10; public uint id; // Ψһ���ֱ�ʶ // Unique identifier public int cls; // ְҵ // Class/Profession public string name; // �������� // Skill name public string nativename; // ������ // Native name public string icon; // ����ͼ�� // Skill icon public int max_level; // ������󼶱�? // Maximum level public byte type; // �������? 1�������� 2�������� 3�����ٻ� 4���� 5���� // Skill type: 1-Normal 2-Special 3-Partner 4-Mount 5-Other // Execute condition public bool allow_ride; // ������? // Allow while riding public short attr; // ����������, 1������2��3ľ��4ˮ��5��6�� ��ѡһ Ĭ�ϣ������� // Attribute: 1-Metal 2-Earth 3-Wood 4-Water 5-Fire 6-Special (Choose one, default none) public int rank; // ���漶�� // Rank public int eventflag; // Event flag public byte is_senior; // Senior flag public bool is_inherent; // �������ܣ�����ѧ������ // Inherent skill, cannot be learned public bool is_movingcast; // �ƶ�ʩ�� // Can cast while moving public int npcdelay; // NPC delay public int showorder; // Display order public byte allow_forms; // Allowed forms public int apcost; // AP cost public int apgain; // AP gain public byte doenchant; // Do enchant public byte dobless; // Do bless public int arrowcost; // Arrow cost public Dictionary pre_skills; // Execute condition public bool allow_land; // ½����Ч // Effective on land public bool allow_air; // ������Ч // Effective in air public bool allow_water; // ˮ����Ч // Effective in water public bool notuse_in_combat; // ս��״̬������ // Cannot use in combat state public int restrict_corpse; // ֻ��ʬ����Ч // Only effective on corpses public bool restrict_change; // �Ƿ���Ա��� // Whether can transform public bool restrict_attach; // �Ƿ���Ը��� // Whether can possess public bool auto_attack; // ʹ�ú��Ƿ��Զ����� // Whether to auto attack after use public byte time_type; // ˲������ // Instant cast type public byte long_range; public byte posdouble; // λ��ѡ�� // Position selection public int clslimit; // ְҵ���� // Class restriction public int commoncooldown; // ������ȴmask bit0-4 ������ȴ0-4 bit5-9 ��Ʒ��ȴ0-4 // Common cooldown mask bit0-4 skill cooldown 0-4 bit5-9 item cooldown 0-4 public int commoncooldowntime; // ��ȴʱ�䣬��λ���� // Cooldown time in milliseconds public int itemcost; // �ͷ�ʱ������Ʒ >0��Ч // Item cost when casting, effective if >0 public GfxMoveMode m_MoveMode = GfxMoveMode.enumLinearMove; public GfxTargetMode m_TargetMode = GfxTargetMode.enumHostToTarget; public GfxAttackMode m_AttFlyMode = GfxAttackMode.enumAttPoint; public GfxAttackMode m_AttHitMode = GfxAttackMode.enumAttPoint; public uint m_dwFlyTime = 0; public bool m_bTraceTarget = false; public uint m_FlyClusterCount = 1; public uint m_FlyClusterInterval = 0; public uint m_HitClusterCount = 1; public uint m_HitClusterInterval = 0; public bool m_bOneHit = true; public bool m_bFadeOut = false; public bool m_bRelScl = true; public float m_fDefTarScl = 1.8f; // ������� // Combo related public int combosk_preskill; public int combosk_interval; public int combosk_nobreak; public string effect; public string m_szFlyGfxPath = string.Empty; public string m_szHitGrndGfxPath = string.Empty; public string m_szHitGfxPath = string.Empty; public string aerial_effect; public Range range; public bool has_stateattack; public List restrict_weapons = new List(); public static Dictionary map = new Dictionary(); public static Dictionary GetMap() => map; public static Dictionary> comboSkillMap = new Dictionary>(); public static Dictionary> GetComboSkMap() => comboSkillMap; public static Dictionary> inheritSkillMap = new Dictionary>(); /*#if UNITY_EDITOR [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] private static void OnPlay() { BMLogger.LogError("SkillStub OnPlay Reset"); map = new Dictionary(); comboSkillMap = new Dictionary>(); inheritSkillMap = new Dictionary>(); } #endif*/ public SkillStub(uint i) { id = i; is_inherent = (false); is_movingcast = (false); itemcost = (0); combosk_preskill = (0); combosk_interval = (0); combosk_nobreak = (0); if (GetStub(id) == null) { GetMap().Add(id, this); } } public static List GetInherentSkillList(uint cls) { if (!inheritSkillMap.TryGetValue(cls, out List list)) { list = new List(); inheritSkillMap[cls] = list; } return list; } public static SkillStub GetStub(uint i) { return GetMap().TryGetValue(i, out var stub) ? stub : null; } public int GetItemCost() { return itemcost; } public static void InitStaticData() { var map = GetMap(); var comboMap = GetComboSkMap(); foreach (var skill in map) { SkillStub sk = skill.Value; if (sk.is_inherent) GetInherentSkillList((uint)sk.cls).Add(sk.id); if (sk.combosk_preskill > 0) { if (!comboMap.TryGetValue((uint)sk.combosk_preskill, out List comboList)) { comboList = new List(); comboMap[(uint)sk.combosk_preskill] = comboList; } comboList.Add(sk.id); } } } public List GetPostComboSkill(uint id) { var m = GetComboSkMap(); if (m.TryGetValue(id, out var list)) return list; return null; } // ����Ϊ��C++ת���Ľӿ� // The following methods are converted from C++ public uint GetId() { return id; } public int GetCls() { return cls; } public string GetName() { return name; } public string GetIcon() { return icon; } public int GetMaxLevel() { return max_level; } public Range GetRange() { return range; } public bool IsMovingSkill() { return is_movingcast; } public byte GetType() { return type; } // ����System.Object.GetType // Hide System.Object.GetType // ����ʱ����麯�� // Runtime-related virtual functions public virtual int GetCoolingtime(Skill skill) { return 5000; } public virtual int GetRequiredSp(Skill skill) { return 0; } public virtual int GetRequiredLevel(Skill skill) { return 0; } public virtual int GetMaxAbility(Skill skill) { return 0; } public virtual int GetRequiredItem(Skill skill) { return 0; } public virtual int GetRequiredMoney(Skill skill) { return 0; } public virtual int GetRequiredRealmLevel(Skill skill) { return 0; } public virtual float GetPraydistance(Skill skill) { return 0f; } public virtual float GetMpcost(Skill skill) { return 0f; } public virtual int GetExecutetime(Skill skill) { return 1000; } public virtual string Getm_szFlyGfxPath() { return m_szFlyGfxPath; } public virtual string Getm_szHitGrndGfxPath() { return m_szHitGrndGfxPath; } public virtual string Getm_szHitGfxPath() { return m_szHitGfxPath; } // 检查HP条件 // Check HP condition // 默认返回true,子类可以重写以检查HP百分比范围 // Default returns true, subclasses can override to check HP percentage range // 例如:return hp >= max_hp / 100.0f * minPercent && hp <= max_hp / 100.0f * maxPercent; public virtual bool CheckHpCondition(int hp, int max_hp) { return true; } // 检查连击技能额外条件 // Check combo skill extra condition // 默认返回true,子类可以重写以检查连击参数等条件 // Default returns true, subclasses can override to check combo arguments etc. // 例如:return skill.GetPlayer().GetComboarg().GetValue(0) == 5; public virtual bool CheckComboSkExtraCondition(Skill skill) { return true; } public virtual int GetIntroduction(Skill skill, StringBuilder descBuffer, string titleBuffer) { return 0; } // ������Ч�Լ�� // Validate weapon restriction public bool ValidWeapon(int weapon) { if (restrict_weapons != null) { int i; for (i = 0; i < restrict_weapons.Count; i++) { if (weapon == restrict_weapons[i]) return true; } if (i > 0 && i >= restrict_weapons.Count) return false; } return true; } } }