633 lines
23 KiB
C#
633 lines
23 KiB
C#
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<uint, int> GetJunior()
|
||
{
|
||
return new Dictionary<uint, int>();
|
||
}
|
||
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<uint, int> GetRequiredSkill() => new Dictionary<uint, int>();
|
||
|
||
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; }
|
||
/// <summary>Common cooldown duration in milliseconds (C++ commoncooldowntime).</summary>
|
||
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<uint, int> GetComboSkActivated(ComboSkillState comboState)
|
||
{
|
||
var result = new Dictionary<uint, int>();
|
||
if (comboState.skillid == 0)
|
||
return result;
|
||
|
||
if (SkillStub.GetComboSkMap().TryGetValue(comboState.skillid, out List<uint> 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.money<s->GetRequiredMoney(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)
|
||
{
|
||
// [中文] C++ 实现同样忽略 profession,只按 id 查找
|
||
// [English] C++ impl also ignores profession; keyed by id only
|
||
GNET.VisibleState.TryGetValue(id, out var result);
|
||
return result;
|
||
}
|
||
}
|
||
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 GNET.TeamState.TryGetValue(id, out var s) ? s : null;
|
||
}
|
||
}
|
||
} |