280 lines
12 KiB
C#
280 lines
12 KiB
C#
using System.Collections.Generic;
|
||
|
||
namespace BrewMonster.Scripts.Skills
|
||
{
|
||
public class Range
|
||
{
|
||
/// <summary>0=point 1=line 2=self sphere 3=target sphere 4=cone 5=self</summary>
|
||
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<uint, int> GetJunior()
|
||
{
|
||
return stub.is_senior != 0 ? stub.pre_skills : new Dictionary<uint, int>();
|
||
}
|
||
public override int GetRangeType() { return stub.GetRange().type; }
|
||
|
||
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 byte GetType() { return stub.type; }
|
||
public override int GetCommonCoolDown() { return stub.commoncooldown; }
|
||
|
||
public override string GetIcon()
|
||
{
|
||
return stub.GetIcon();
|
||
}
|
||
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 abstract class SkillStub
|
||
{
|
||
public const int MIN_LEVEL = 1;
|
||
public const int MAX_LEVEL = 10;
|
||
|
||
// Base info
|
||
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<uint, int> 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
|
||
|
||
// ������� // Combo related
|
||
public int combosk_preskill;
|
||
public int combosk_interval;
|
||
public int combosk_nobreak;
|
||
|
||
public string effect;
|
||
public string aerial_effect;
|
||
|
||
public Range range;
|
||
public bool has_stateattack;
|
||
|
||
public List<int> restrict_weapons = new List<int>();
|
||
public static Dictionary<uint, SkillStub> map = new Dictionary<uint, SkillStub>();
|
||
public static Dictionary<uint, SkillStub> GetMap() => map;
|
||
|
||
public static Dictionary<uint, List<uint>> inheritSkillMap = new();
|
||
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<uint> GetInherentSkillList(uint cls)
|
||
{
|
||
return inheritSkillMap[cls];
|
||
}
|
||
|
||
public static Dictionary<uint, List<uint>> comboSkillMap;
|
||
public static Dictionary<uint, List<uint>> GetComboSkMap() => comboSkillMap;
|
||
|
||
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();
|
||
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) GetComboSkMap()[(uint)sk.combosk_preskill].Add(sk.id);
|
||
}
|
||
}
|
||
|
||
public List<uint> 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 0; }
|
||
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 bool CheckHpCondition(int hp, int max_hp) { return true; }
|
||
public virtual bool CheckComboSkExtraCondition(Skill skill) { return true; }
|
||
public virtual int GetIntroduction(Skill skill, ushort[] descBuffer, int descBufferLen, ushort[] 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;
|
||
}
|
||
}
|
||
} |