Files
test/Assets/PerfectWorld/Scripts/Skills/skill.cs
T
2026-02-24 18:45:24 +07:00

356 lines
16 KiB
C#
Raw 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 System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.InputSystem;
using static UnityEngine.Rendering.DebugUI;
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 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<uint, int> 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; // , 1256 ѡһ Ĭϣ // 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
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<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>> comboSkillMap = new Dictionary<uint, List<uint>>();
public static Dictionary<uint, List<uint>> GetComboSkMap() => comboSkillMap;
public static Dictionary<uint, List<uint>> inheritSkillMap = new Dictionary<uint, List<uint>>();
/*#if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void OnPlay()
{
BMLogger.LogError("SkillStub OnPlay Reset");
map = new Dictionary<uint, SkillStub>();
comboSkillMap = new Dictionary<uint, List<uint>>();
inheritSkillMap = new Dictionary<uint, List<uint>>();
}
#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<uint> GetInherentSkillList(uint cls)
{
if (!inheritSkillMap.TryGetValue(cls, out List<uint> list))
{
list = new List<uint>();
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<uint> comboList))
{
comboList = new List<uint>();
comboMap[(uint)sk.combosk_preskill] = comboList;
}
comboList.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 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;
}
}
}