Files

483 lines
18 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using BrewMonster.Assets.PerfectWorld.Scripts.Skills;
using CSNetwork.GPDataType;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Unity.VisualScripting;
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 entrys 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 string GetIntroduction(StringBuilder buf, int len, SkillStr table) { return ""; }
// ְҵ
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 virtual int GetRequiredRealmLevel() { return 0; }
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 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; }
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?5ID, 6δѡĿ
public int Condition(UseRequirement info)
{
return 0;
}
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;
}
// ܷڵǰ״̬ʹ // 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;
}
}
}