using BrewMonster.Assets.PerfectWorld.Scripts.Skills; using CSNetwork.GPDataType; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; namespace BrewMonster.Scripts.Skills { public enum skill_type { TYPE_ATTACK = 1, // Attack // �������� TYPE_BLESS = 2, // Blessing // ����ף�� TYPE_CURSE = 3, // Curse // �������� TYPE_SUMMON = 4, // Summon // ��Ʒ���� TYPE_PASSIVE = 5, // Passive // ���� TYPE_ENABLED = 6, // Enabled // �������� TYPE_LIVE = 7, // Live // ���� TYPE_JUMP = 8, // Jump // ˲�� TYPE_PRODUCE = 9, // Production (Crafting) // ����(����) TYPE_BLESSPET = 10, // Pet Blessing // ����ף�� TYPE_NEUTRALBLESS = 11, // Neutral Blessing // ����ף�� }; // Skill type 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, // ÖÐÐÔ×£¸£ }; public enum range_type { RANGE_POINT = 0, // µã RANGE_LINE, // Ïß RANGE_SELFSPHERE, // ×ÔÉíΪÖÐÐĵÄÇò RANGE_TARGETSPHERE, // Ä¿±êΪÖÐÐĵÄÇò RANGE_TAPER, // Ô²×¶ RANGE_SLEF, // ×ÔÉí }; [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct LearnRequirement { public int level; // �ȼ�Ҫ�� // Level requirement public int sp; // ���ܵ� // Skill points public int money; // ��Ǯ // Money public int profession; // ְҵ // Profession public int rank; // �׼��� // Rank level public int realm_level; // ����ȼ� // Realm level } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct PetRequirement { public int level; // �ȼ����� // Level requirement public int sp; // ���\�ܵ� // Pet skill points public int list; // ���\���б� // Pet skill list public int lsize; // �б���С // List size } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct GoblinRequirement { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public int[] genius; // С���鼼���츳 // Goblin skill talents public int profession; // ְҵ // Profession public int sp; // ����Ԫ�� // Spirit points public int money; // �����Ǯ // Money public int level; // С����ȼ� // Goblin level public int mp; // С���鵱ǰħ������ // Current magic points } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct ComboSkillState { public const int MAX_COMBO_ARG = 3; public uint skillid; [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_COMBO_ARG)] public int[] arg; } public struct UseRequirement { public int mp; //ħ�� // Magic points public int ap; //ŭ��ֵ // Anger points public int form; //����״̬ // Form state public int weapon; //���� // Weapon public int freepackage; //������ʣ����Ŀ // Remaining inventory slots public int arrow; //װ����֧��Ŀ // Number of arrows loaded public int move_env; //�ƶ����� // Movement environment public bool is_combat; //�Ƿ�ս��״̬ // Whether in combat state public int hp; //��ǰhp // Current HP public int max_hp; //���hp // Maximum HP public ComboSkillState combo_state; //���������� // Combo skill state }; public struct GoblinUseRequirement { public int mp; //����(Ԫ��) public int ap; //����(����) [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public int[] genius; //С���鼼���츳�� public int profession; //����ְҵ public int level; //С����ȼ������ڼ�����������? public int move_env; //���˵�ǰ�ƶ����� }; public class SkillStr { public virtual string Find(int id) { return ""; } } public enum SKILL_STATE { SKILL_PERFORM, SKILL_DONE, } public class ElementSkill { public const byte FORM_MASK_HIGH = 0xC0; public const byte FORM_NORMAL = 0; //��ͨ��̬ public const byte FORM_CLASS = 1; //ְҵ���� public const byte FORM_BEASTIE = 2; //��С���� static SkillStub s; static Skill skill; public static uint NextSkill(uint id = 0) { //TODO: Implement this var map = SkillStub.GetMap(); // if map is empty, return 0 if (map.Count == 0) return 0; // If start == 0, return the first entry’s value if (id == 0) { var first = map.First(); return first.Value.GetId(); } // Try to find 'start' key var keys = map.Keys.OrderBy(k => k).ToList(); int index = keys.IndexOf(id); if (index == -1 || index + 1 >= keys.Count) return 0; // no next skill var nextKey = keys[index + 1]; return map[nextKey].GetId(); } public static ElementSkill Create(uint id, int n) { return Skill.Create(id, n); } public virtual Dictionary GetJunior() { return new Dictionary(); } public virtual string GetName() { return null; } public static string GetName(uint id) { s = SkillStub.GetStub(id); if (s != null) return s.GetName(); return ""; } public virtual int GetItemCost() { return 0; } public virtual byte[] GetNativeName() { return null; } // �������?,��skill_type public virtual byte GetType() { return 1; } // ����ͼ�� public virtual string GetIcon() { return null; } public static string GetIcon(uint id) { s = SkillStub.GetStub(id); if (s != null) return s.GetIcon(); return ""; } // ����˵�� public virtual void GetIntroduction(StringBuilder buf, SkillStr table) { } // ����ְҵ���� public virtual int GetCls() { return -1; } // ������ȴʱ�䣬��λ���� public virtual int GetCoolingTime() { return 5000; } // ����ִ��ʱ�䣬��λ���� public virtual int GetExecuteTime() { return 1000; } // Ŀ����������, 0:����Ŀ�꣬1:��ҪĿ�꣬2:Ŀ��������?��, 3:Ŀ������?����, 4:Ŀ������?���� public virtual int GetTargetType() { return 0; } // ������Ч�ͷž���: <-0.001����Ŀ�� -0.001-0.001 Ĭ�Ϲ������룬>0.001 �ͷž��� public virtual float GetPrayRange(float range, float prayplus) { return 0; } public static bool IsGoblinSkill(uint id) { SkillStub s = SkillStub.GetStub(id); return s != null && (s.GetCls() == 258); } public static void LoadSkillData(cmd_skill_data data) { SkillWrapper.Instance.LoadData(data); } public static bool IsOverridden(uint id) { return SkillWrapper.Instance.IsOverridden(id); } public virtual int GetRank() { return 0; } // ѧϰn������Ҫ�����Ҽ��� public virtual int GetRequiredLevel() { return 0; } // ѧϰn��������Ҫ�ļ��ܵ� public static int GetRequiredSp(uint id, int level) { skill = Skill.Create(id, level); if (skill == null) return 0; int ret = skill.GetRequiredSp(); return ret; } // ѧϰn����Ҫ�ļ����� public virtual int GetRequiredBook() { return 0; } // ѧϰ��Ҫ��Ǯ public static int GetRequiredBook(uint id, int level) { skill = Skill.Create(id, level); if (skill == null) return 0; int ret = skill.GetRequiredBook(); return ret; } public static int GetRequiredLevel(uint id, int level) { Skill s = Skill.Create(id, level); if (s == null) return 0; int ret = s.GetRequiredLevel(); return ret; } public virtual int GetRequiredRealmLevel() { return 0; } public static int GetRequiredRealmLevel(uint id, int level) { Skill s = Skill.Create(id, level); if (s == null) return 0; int ret = s.GetRequiredRealmLevel(); return ret; } public virtual Dictionary GetRequiredSkill() => new Dictionary(); public virtual int GetShowOrder() { return 0; } public virtual int SetLevel(int level) { return 0; } public static int SetLevel(uint id, int level) { return SkillWrapper.Instance.SetLevel(id, level); } public virtual int GetMaxLevel() { return 0; } public static byte GetType(uint id) { SkillStub s = SkillStub.GetStub(id); if (s != null) return s.GetType(); return 0; } // �Ƿ��������� public virtual bool IsWarmup() { return false; } // ʹ�ú��Ƿ��Զ����� public virtual bool IsAutoAttack() { return false; } // ˲������ public virtual bool IsInstant() { return false; } // �Ƿ��������? public virtual bool IsDurative() { return false; } // ɱ�˷�Χ������ public virtual int GetRangeType() { return 0; } // �ͷŻ��������С����桢ˮ�� public virtual int GetCastEnv() { return 0; } // ��ȡС����ѧϰ���ͷż��������츳�� public virtual int GetRequiredGenius(int idSkill) { return 0; } // Ч���ļ��� public virtual string GetEffect() { return null; } public static string GetEffect(uint id) { SkillStub stub = SkillStub.GetStub(id); if (stub != null) return stub.effect; return ""; } public static (string,string,string) GetAllGFX(uint id) { SkillStub stub = SkillStub.GetStub(id); if (stub != null) return (stub.Getm_szFlyGfxPath(), stub.Getm_szHitGrndGfxPath(), stub.Getm_szHitGfxPath()); return (string.Empty, string.Empty, string.Empty); } public virtual byte[] GetElseEffect() { return null; } // ʹ����ҪMP public virtual int GetMpCost() { return 1; } // ʹ����ҪAP public virtual int GetApCost() { return 0; } // ��֧���� public virtual int GetArrowCost() { return 0; } public virtual int GetCommonCoolDown() { return 0; } /// Common cooldown duration in milliseconds (C++ commoncooldowntime). public virtual int GetCommonCoolDownTime() { return 0; } public static int GetCommonCoolDown(uint id) { SkillStub s = SkillStub.GetStub(id); if (s != null) return s.commoncooldown; return 0; } // ���������ж� public virtual bool ValidWeapon(int w) { return true; } // 0, �ɹ���1��������ƥ�䣻2, mp���㣻3��λ�����������㣻4���������������?5������ID, 6��δѡ��Ŀ�� public int Condition(uint id, UseRequirement info, int ilevel) { skill = Skill.Create(id, ilevel); if (skill == null) return 5; ComboArg arg = skill.GetPlayer().GetComboarg(); if (info.combo_state.arg != null) { for (int i = 0; i < ComboSkillState.MAX_COMBO_ARG; i++) { arg.SetValue((uint)i, info.combo_state.arg[i]); } } int ret = ((ElementSkill)skill).Condition(info); return ret; } public int Condition(UseRequirement info) { if (info.arrow < GetArrowCost()) return 9; if (!ValidWeapon(info.weapon)) return 1; if (info.mp < GetMpCost()) return 2; int form_type = (info.form & FORM_MASK_HIGH) >> 6; if ((GetAllowForms() & (1 << form_type)) == 0) return 7; if (info.ap < GetApCost()) return 8; if (info.freepackage == 0 && GetTargetType() == 3) return 10; // ÒÆ¶¯»·¾³ if ((info.move_env == 0 && !IsAllowLand()) || (info.move_env == 1 && !IsAllowWater()) || (info.move_env == 2 && !IsAllowAir())) return 3; if (info.is_combat && GetNotuseInCombat()) return 11; if (!CheckHpCondition(info.hp, info.max_hp)) return 12; int preskill = GetComboSkPreSkill(); if (preskill != 0) { if (info.combo_state.skillid != (uint)preskill || !CheckComboSkExtraCondition()) return 13; } return 0; } // 检查HP条件 // Check HP condition public virtual bool CheckHpCondition(int hp, int max_hp) { return true; } // 检查连击技能额外条件 // Check combo skill extra condition public virtual bool CheckComboSkExtraCondition() { return true; } public virtual bool IsAllowLand() { return true; } public virtual bool IsAllowWater() { return true; } public virtual bool IsAllowAir() { return true; } public virtual bool GetNotuseInCombat() { return false; } //�Ƿ��ƶ�ʩ�� // Whether it's a moving skill public virtual bool IsMovingSkill() { return false; } // �Ƿ�Ϊ�ƶ�ʩ���� // Check if skill ID is a moving skill public static bool IsMovingSkill(uint id) { SkillStub s = SkillStub.GetStub(id); if (s != null) return s.IsMovingSkill(); return false; } public static Dictionary GetComboSkActivated(ComboSkillState comboState) { var result = new Dictionary(); if (comboState.skillid == 0) return result; if (SkillStub.GetComboSkMap().TryGetValue(comboState.skillid, out List postSkills) && postSkills != null) { foreach (uint skillId in postSkills) { Skill skill = Skill.Create(skillId, 1); if (skill == null) continue; ref ComboArg comboArg = ref skill.GetPlayer().GetComboarg(); for (int i = 0; i < ComboArg.MAX_COMBO_ARG; i++) { int argValue = 0; if (comboState.arg != null && i < comboState.arg.Length) { argValue = comboState.arg[i]; } comboArg.SetValue((uint)i, argValue); } if (((ElementSkill)skill).CheckComboSkExtraCondition()) { result[skill.GetId()] = skill.GetComboSkInterval(); } } } return result; } // �����ܷ��ڵ�ǰ����״̬��ʹ�� // Whether skill can be used in current form state public bool IsValidForm(byte form) { byte form_type = (byte)((form & FORM_MASK_HIGH) >> 6); return ((GetAllowForms() & (1 << form_type)) != 0); } public virtual byte GetAllowForms() { return 0; } public virtual bool Interrupt() { return true; } public static int GetRequiredMoney(uint id, int level) { skill = Skill.Create(id, level); if (skill == null) return 0; int ret = skill.GetRequiredMoney(); return ret; } // 学习技能条件检查 // Learning skill condition check // 返回值 // Return values: // 0: 成功 // Success // 1: 技能点不够 // Not enough skill points // 2: 等级不够 // Level not enough // 3: 错误 // Error // 4: 职业不匹配 // Profession mismatch // 5: 技能ID // Skill ID error // 6: 钱不够 // Not enough money // 7: 阶级不符 // Rank mismatch // 9: 前置技能级别不够 // Prerequisite skill level not enough // 10: 熟练度不够 // Ability not enough // 11: 被覆盖 // Overridden // 12: 境界等级不够 // Realm level not enough public static int LearnCondition(uint id, LearnRequirement info, int ilevel) { skill = Skill.Create(id, ilevel); if (skill == null) return 5; int ret = 0; SkillWrapper wrapper = SkillWrapper.Instance; if (wrapper.IsOverridden(id)) return 11; int srank, prank; srank = skill.GetRank(); prank = info.rank; if (srank > prank) ret = 7; else { srank = (int)(srank * 0.1); prank = (int)(prank * 0.1); if (srank != prank && srank != 0) ret = 7; } if (ilevel < 1 || ilevel > skill.GetMaxLevel()) ret = 3; else if (info.profession != skill.GetCls() && skill.GetCls() != 255) ret = 4; else if (info.level < skill.GetRequiredLevel()) ret = 2; if (ret != 0) { return ret; } if (info.sp < skill.GetRequiredSp()) ret = 1; else if (info.money < skill.GetRequiredMoney()) ret = 6; var pre_skills = skill.GetRequiredSkill(); foreach (var kvp in pre_skills) { uint pre_id = kvp.Key; int pre_level = kvp.Value; if (pre_id > 0 && wrapper.GetLevel(pre_id) < pre_level && !wrapper.IsOverridden(pre_id)) { ret = 9; break; } } if (ilevel > 1) { skill.SetLevel(ilevel - 1); int ability = skill.GetMaxability(); if (ability > 0 && wrapper.GetAbility(id) < ability) ret = 10; } if (info.realm_level < skill.GetRequiredRealmLevel()) ret = 12; return ret; } // 0:�ɹ� 1:����SP���� 2:�����츳�㲻�� // 3:���� 4:���ܸ������� 5:����ID // 6:��Ǯ���� 7:��С���鼼�� 8:û�м����� // 9:�ȼ����� 10:�������޲��� 11:ְҵ��ƥ�� // 12:�������޲��㣬��ְҵ��ƥ�� public static int GoblinLearn(uint id, GoblinRequirement info, int level) { Skill s = Skill.Create(id, level); if (s == null) return 5; if (level < 1 || level > s.GetMaxLevel()) return 3; if (s.GetCls() != 258) return 7; int ret = 0; int[] iReqGen = new int[5] { 0, 0, 0, 0, 0 }; int iReqLevel = s.GetRequiredLevel(); // iReqLevelΪ7λ�����������λΪ�ȼ���ǰ5λΪ�츳���������λΪ�� int iLevelRequirement = iReqLevel % 100; if (info.level < iLevelRequirement) return 9; iReqLevel /= 100; int i; for (i = 0; i < 5; i++) { iReqGen[4 - i] = iReqLevel % 10; iReqLevel /= 10; } for (i = 0; i < 5; i++) { if (info.genius[i] < iReqGen[4 - i]) return 2; } if (info.sp < s.GetRequiredSp()) ret = 1; //else if(info.moneyGetRequiredMoney(id, level)) // ret = 6; if (info.mp < s.GetMpCost() && ((s.GetCls() != 0) && (((1 << info.profession) & s.GetCls()) == 0))) ret = 12; else if (info.mp < s.GetMpCost()) ret = 10; else if ((s.GetCls() != 0) && (((1 << info.profession) & s.GetCls()) == 0)) ret = 11; return ret; } public virtual int GetComboSkPreSkill() { return 0; } public static int GetComboSkPreSkill(uint id) { SkillStub s = SkillStub.GetStub(id); if (s != null) { return s.combosk_preskill; } return 0; } } public class VisibleState { public virtual int GetID() { return 0; } public virtual string GetName() { return null; } public virtual string GetHH() { return null; } public virtual string GetEffect() { return null; } public static VisibleState Query(int profession, int id) { return null; } } public class TeamState { public virtual int GetID() { return 0; } public virtual string GetName() { return null; } public virtual string GetIcon() { return null; } public static TeamState Query(int id) { return null; } } }