534 lines
20 KiB
C#
534 lines
20 KiB
C#
// Filename : CECCastSkillWhenMove.cs
|
|
// Creator : Xu Wenbin
|
|
// Date : 2014/8/1
|
|
// Converted to C# from C++ by AI Assistant
|
|
|
|
using BrewMonster.Scripts.Skills;
|
|
using System.Linq;
|
|
|
|
namespace BrewMonster
|
|
{
|
|
// Constants from EC_RoleTypes.h
|
|
public static class RoleTypes
|
|
{
|
|
// 职业 // Profession
|
|
public const int PROF_WARRIOR = 0; // 武侠 // Warrior
|
|
public const int PROF_MAGE = 1; // 法师 // Mage
|
|
public const int PROF_MONK = 2; // 巫师 // Monk
|
|
public const int PROF_HAG = 3; // 妖精 // Hag
|
|
public const int PROF_ORC = 4; // 妖兽 // Orc
|
|
public const int PROF_GHOST = 5; // 刺客 // Ghost
|
|
public const int PROF_ARCHOR = 6; // 羽芒 // Archer
|
|
public const int PROF_ANGEL = 7; // 羽灵 // Angel
|
|
public const int PROF_JIANLING = 8; // 剑灵 // Jianling
|
|
public const int PROF_MEILING = 9; // 魅灵 // Meiling
|
|
public const int PROF_YEYING = 10; // 夜影 // Yeying
|
|
public const int PROF_YUEXIAN = 11; // 月仙 // Yuexian
|
|
public const int NUM_PROFESSION = 12;
|
|
|
|
// 性别 // Gender
|
|
public const int GENDER_MALE = 0;
|
|
public const int GENDER_FEMALE = 1;
|
|
public const int NUM_GENDER = 2;
|
|
}
|
|
|
|
// Constants from EC_Player.h
|
|
public static class PlayerModelType
|
|
{
|
|
public const int PLAYERMODEL_MAJOR = 0; // 主模型 // Major model
|
|
public const int PLAYERMODEL_PROFESSION = 1; // 职业变身 // Profession transformation
|
|
public const int PLAYERMODEL_DUMMYTYPE2 = 2; // Buff相关 // Buff related
|
|
public const int PLAYERMODEL_DUMMYTYPE3 = 3; // 未使用 // Not used
|
|
public const int PLAYERMODEL_MAX = 4;
|
|
public const int PLAYERMODEL_TYPEALL = unchecked((int)0xffffffff);
|
|
}
|
|
|
|
// Constants from EC_Resource.h
|
|
public static class ResourceModel
|
|
{
|
|
public const int RES_MOD_YUEXIAN_M = 0; // 月仙男标准模型 // Yuexian male standard model
|
|
public const int RES_MOD_YUEXIAN_F = 1; // 月仙女标准模型 // Yuexian female standard model
|
|
public const int RES_MOD_YUEXIAN_RESHAPE_M = 2; // 月仙男职业变身 // Yuexian male profession reshape
|
|
public const int RES_MOD_YUEXIAN_RESHAPE_F = 3; // 月仙女职业变身 // Yuexian female profession reshape
|
|
}
|
|
|
|
/// <summary>
|
|
/// 移动施法管理类 // Cast Skill When Move Manager
|
|
/// </summary>
|
|
public class CECCastSkillWhenMove : Singleton<CECCastSkillWhenMove>
|
|
{
|
|
// 朦胧 // Oboro
|
|
// 标准男性 UpperBody // Standard male upper body bones
|
|
private static readonly string[] s_szOboroMaleStandardUpperBodyBonesName = {
|
|
"Bip01 shangshen",
|
|
"Bip01 Spine",
|
|
"Bip01 Spine1",
|
|
"Bip01 Spine2",
|
|
"Bip01 Neck",
|
|
"Bip01 Head",
|
|
"Bip01 L Clavicle",
|
|
"Bip01 L UpperArm",
|
|
"Bip01 L Forearm",
|
|
"Bip01 L Hand",
|
|
"Bip01 L Finger0",
|
|
"Bip01 L Finger01",
|
|
"Bip01 L Finger1",
|
|
"Bip01 L Finger11",
|
|
"Bip01 R Clavicle",
|
|
"Bip01 R UpperArm",
|
|
"Bip01 R Forearm",
|
|
"Bip01 R Hand",
|
|
"Bip01 R Finger0",
|
|
"Bip01 R Finger01",
|
|
"Bip01 R Finger1",
|
|
"Bip01 R Finger11",
|
|
"Bone05",
|
|
};
|
|
|
|
// 标准男性 LowerBody // Standard male lower body bones
|
|
private static readonly string[] s_szOboroMaleStandardLowerBodyBonesName = {
|
|
"Bip01",
|
|
"Bip01 Pelvis",
|
|
"Bip01 xiashen",
|
|
"Bip01 L Thigh",
|
|
"Bip01 L Calf",
|
|
"Bip01 L Foot",
|
|
"Bip01 L Toe0",
|
|
"Bip01 R Thigh",
|
|
"Bip01 R Calf",
|
|
"Bip01 R Foot",
|
|
"Bip01 R Toe0",
|
|
"Bone01",
|
|
"Bone02",
|
|
"Bone03",
|
|
"Bone04",
|
|
};
|
|
|
|
// 职业变身男性 UpperBody // Profession reshape male upper body bones
|
|
private static readonly string[] s_szOboroMaleShape1UpperBodyBonesName = {
|
|
"Bip01 shangshen",
|
|
"Bip01 Spine",
|
|
"Bip01 Spine1",
|
|
"Bip01 Spine2",
|
|
"Bip01 Neck",
|
|
"Bip01 Head",
|
|
"Bip01 L Clavicle",
|
|
"Bip01 L UpperArm",
|
|
"Bip01 L Forearm",
|
|
"Bip01 L Hand",
|
|
"Bip01 L Finger0",
|
|
"Bip01 L Finger01",
|
|
"Bip01 L Finger1",
|
|
"Bip01 L Finger11",
|
|
"Bip01 R Clavicle",
|
|
"Bip01 R UpperArm",
|
|
"Bip01 R Forearm",
|
|
"Bip01 R Hand",
|
|
"Bip01 R Finger0",
|
|
"Bip01 R Finger01",
|
|
"Bip01 R Finger1",
|
|
"Bip01 R Finger11",
|
|
"Bone05",
|
|
"Bone13",
|
|
"Bone14",
|
|
"Bone15",
|
|
"Bone16",
|
|
"Bone17",
|
|
"Bone18",
|
|
};
|
|
|
|
// 职业变身男性 LowerBody // Profession reshape male lower body bones
|
|
private static readonly string[] s_szOboroMaleShape1LowerBodyBonesName = {
|
|
"Bip01",
|
|
"Bip01 Pelvis",
|
|
"Bip01 xiashen",
|
|
"Bip01 L Thigh",
|
|
"Bip01 L Calf",
|
|
"Bip01 L Foot",
|
|
"Bip01 L Toe0",
|
|
"Bip01 R Thigh",
|
|
"Bip01 R Calf",
|
|
"Bip01 R Foot",
|
|
"Bip01 R Toe0",
|
|
"Bone06",
|
|
"Bone07",
|
|
"Bone08",
|
|
"Bone09",
|
|
"Bone10",
|
|
"Bone11",
|
|
"Bone12",
|
|
"Bone19",
|
|
"Bone20",
|
|
"Bone21",
|
|
};
|
|
|
|
// 标准女性 UpperBody // Standard female upper body bones
|
|
private static readonly string[] s_szOboroFemaleStandardUpperBodyBonesName = {
|
|
"Bip01 Spine shangshen",
|
|
"Bip01 Spine",
|
|
"Bip01 Spine1",
|
|
"Bip01 Spine2",
|
|
"Bip01 Neck",
|
|
"Bip01 Head",
|
|
"Bip01 Ponytail1",
|
|
"Bip01 Ponytail11",
|
|
"Bip01 Ponytail12",
|
|
"Bip01 L Clavicle",
|
|
"Bip01 L UpperArm",
|
|
"Bip01 L Forearm",
|
|
"Bip01 L Hand",
|
|
"Bip01 L Finger0",
|
|
"Bip01 L Finger01",
|
|
"Bip01 L Finger1",
|
|
"Bip01 L Finger11",
|
|
"Bip01 R Clavicle",
|
|
"Bip01 R UpperArm",
|
|
"Bip01 R Forearm",
|
|
"Bip01 R Hand",
|
|
"Bip01 R Finger0",
|
|
"Bip01 R Finger01",
|
|
"Bip01 R Finger1",
|
|
"Bip01 R Finger11",
|
|
"Bone05",
|
|
"Bone01",
|
|
};
|
|
|
|
// 标准女性 LowerBody // Standard female lower body bones
|
|
private static readonly string[] s_szOboroFemaleStandardLowerBodyBonesName = {
|
|
"Bip01",
|
|
"Bip01 Pelvis",
|
|
"Bip01 Spine xiashen",
|
|
"Bip01 L Thigh",
|
|
"Bip01 L Calf",
|
|
"Bip01 L Foot",
|
|
"Bip01 L Toe0",
|
|
"Bip01 R Thigh",
|
|
"Bip01 R Calf",
|
|
"Bip01 R Foot",
|
|
"Bip01 R Toe0",
|
|
"Bone08",
|
|
"Bone09",
|
|
"Bone10",
|
|
"Bone02",
|
|
"Bone03",
|
|
"Bone04",
|
|
};
|
|
|
|
// 职业变身女性 UpperBody // Profession reshape female upper body bones
|
|
private static readonly string[] s_szOboroFemaleShape1UpperBodyBonesName = {
|
|
"Bip01 Spine shangshen",
|
|
"Bip01 Spine",
|
|
"Bip01 Spine1",
|
|
"Bip01 Spine2",
|
|
"Bip01 Neck",
|
|
"Bip01 Head",
|
|
"Bip01 Ponytail1",
|
|
"Bip01 Ponytail11",
|
|
"Bip01 Ponytail12",
|
|
"Bip01 L Clavicle",
|
|
"Bip01 L UpperArm",
|
|
"Bip01 L Forearm",
|
|
"Bip01 L Hand",
|
|
"Bip01 L Finger0",
|
|
"Bip01 L Finger01",
|
|
"Bip01 L Finger1",
|
|
"Bip01 L Finger11",
|
|
"Bip01 R Clavicle",
|
|
"Bip01 R UpperArm",
|
|
"Bip01 R Forearm",
|
|
"Bip01 R Hand",
|
|
"Bip01 R Finger0",
|
|
"Bip01 R Finger01",
|
|
"Bip01 R Finger1",
|
|
"Bip01 R Finger11",
|
|
"Bone05",
|
|
"Bone01",
|
|
"Bone14",
|
|
"Bone15",
|
|
"Bone16",
|
|
"Bone17",
|
|
"Bone18",
|
|
"Bone19",
|
|
"Bone20",
|
|
"Bone21",
|
|
"Bone22",
|
|
"Bone23",
|
|
"Bone24",
|
|
};
|
|
|
|
// 职业变身女性 LowerBody // Profession reshape female lower body bones
|
|
private static readonly string[] s_szOboroFemaleShape1LowerBodyBonesName = {
|
|
"Bip01",
|
|
"Bip01 Pelvis",
|
|
"Bip01 Spine xiashen",
|
|
"Bip01 L Thigh",
|
|
"Bip01 L Calf",
|
|
"Bip01 L Foot",
|
|
"Bip01 L Toe0",
|
|
"Bip01 R Thigh",
|
|
"Bip01 R Calf",
|
|
"Bip01 R Foot",
|
|
"Bip01 R Toe0",
|
|
"Bone08",
|
|
"Bone09",
|
|
"Bone10",
|
|
"Bone02",
|
|
"Bone03",
|
|
"Bone04",
|
|
"Bone06",
|
|
"Bone07",
|
|
"Bone11",
|
|
"Bone12",
|
|
"Bone13",
|
|
};
|
|
|
|
/// <summary>
|
|
/// 玩家信息 // Player information
|
|
/// </summary>
|
|
public class PlayerInfo
|
|
{
|
|
public int profession; // 职业 // Profession
|
|
public int gender; // 性别 // Gender
|
|
public int shapeType; // 变身类型 // Shape type
|
|
public int shapeID; // 变身ID // Shape ID
|
|
|
|
public PlayerInfo(int profession, int gender, int shapeType, int shapeID)
|
|
{
|
|
this.profession = profession;
|
|
this.gender = gender;
|
|
this.shapeType = shapeType;
|
|
this.shapeID = shapeID;
|
|
}
|
|
|
|
public PlayerInfo(CECPlayer pPlayer)
|
|
{
|
|
if (pPlayer != null)
|
|
{
|
|
this.profession = pPlayer.GetProfession();
|
|
this.gender = pPlayer.GetGender();
|
|
this.shapeType = pPlayer.GetShapeType();
|
|
this.shapeID = pPlayer.GetShapeID();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Singleton instance
|
|
private static readonly object s_lock = new object();
|
|
|
|
// Private constructor for singleton
|
|
public CECCastSkillWhenMove()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取单例实例 // Get singleton instance
|
|
/// </summary>
|
|
|
|
/// <summary>
|
|
/// 检查模型是否支持移动施法 // Check if model supports casting while moving
|
|
/// </summary>
|
|
private bool HasModelSupport(PlayerInfo player)
|
|
{
|
|
if (player.profession == RoleTypes.PROF_YUEXIAN)
|
|
{
|
|
switch (player.shapeType)
|
|
{
|
|
case PlayerModelType.PLAYERMODEL_MAJOR: // 标准模型 // Standard model
|
|
return true;
|
|
case PlayerModelType.PLAYERMODEL_PROFESSION: // 职业变身模型 // Profession reshape model
|
|
if (player.gender == RoleTypes.GENDER_MALE)
|
|
{
|
|
return player.shapeID == ResourceModel.RES_MOD_YUEXIAN_RESHAPE_M; // 男职业变身 // Male profession reshape
|
|
}
|
|
else
|
|
{
|
|
return player.shapeID == ResourceModel.RES_MOD_YUEXIAN_RESHAPE_F; // 女职业变身 // Female profession reshape
|
|
}
|
|
}
|
|
}
|
|
// 支持移动施法的ecm模型 // ecm models that support casting while moving
|
|
// 注意夜影 PROF_YEYING 模型也支持,但他们没有任何移动施法的技能,故此处不加,以避免不必要的开销
|
|
// Note: PROF_YEYING models also support this, but they don't have any moving cast skills, so not added here to avoid unnecessary overhead
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查技能是否支持移动施法 // Check if skill supports casting while moving
|
|
/// </summary>
|
|
private bool IsSkillSupported(int idSkill, PlayerInfo player)
|
|
{
|
|
// 支持移动施法的技能ID // Skill IDs that support casting while moving
|
|
return ElementSkill.IsMovingSkill((uint)idSkill);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查技能动作是否支持移动施法 // Check if skill action supports casting while moving
|
|
/// </summary>
|
|
private bool HasActionSupport(int idSkill, PlayerInfo player)
|
|
{
|
|
if (HasModelSupport(player))
|
|
{
|
|
const int SKILL_COUNT = 19;
|
|
int[] s_skills = new int[SKILL_COUNT] {
|
|
2571, 2572, 2579, 2580, 2588, 2591, // 2571素罗闪 2572朱雀闪 2579辞诗箫 2580沐仙曲 2588霜雪铃 2591夕月飞星
|
|
2627, 2619, 2620, 2621, 2622, 2787, // 2627镜花水月 2619天·素罗闪 2620地·素罗闪 2621天·朱雀闪 2622地·朱雀闪 2787天·辞诗箫
|
|
2788, 2789, 2790, 2805, 2806, 2811, // 2788地·辞诗箫 2789天·沐仙曲 2790地·沐仙曲 2805天·霜雪铃 2806地·霜雪铃 2811天·夕月飞星
|
|
2812 // 2812地·夕月飞星
|
|
};
|
|
return s_skills.Contains(idSkill);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取上半身骨骼名称 // Get upper body bones name
|
|
/// </summary>
|
|
private bool GetUpperBodyBonesName(PlayerInfo player, out int bonesNameCount, out string[] szBonesName)
|
|
{
|
|
bonesNameCount = 0;
|
|
szBonesName = null;
|
|
bool result = false;
|
|
|
|
if (HasModelSupport(player))
|
|
{
|
|
switch (player.shapeType)
|
|
{
|
|
case PlayerModelType.PLAYERMODEL_MAJOR:
|
|
if (RoleTypes.GENDER_MALE == player.gender)
|
|
{
|
|
szBonesName = s_szOboroMaleStandardUpperBodyBonesName;
|
|
bonesNameCount = s_szOboroMaleStandardUpperBodyBonesName.Length;
|
|
}
|
|
else
|
|
{
|
|
szBonesName = s_szOboroFemaleStandardUpperBodyBonesName;
|
|
bonesNameCount = s_szOboroFemaleStandardUpperBodyBonesName.Length;
|
|
}
|
|
break;
|
|
case PlayerModelType.PLAYERMODEL_PROFESSION:
|
|
if (RoleTypes.GENDER_MALE == player.gender)
|
|
{
|
|
if (ResourceModel.RES_MOD_YUEXIAN_RESHAPE_M == player.shapeID)
|
|
{
|
|
szBonesName = s_szOboroMaleShape1UpperBodyBonesName;
|
|
bonesNameCount = s_szOboroMaleShape1UpperBodyBonesName.Length;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (ResourceModel.RES_MOD_YUEXIAN_RESHAPE_F == player.shapeID)
|
|
{
|
|
szBonesName = s_szOboroFemaleShape1UpperBodyBonesName;
|
|
bonesNameCount = s_szOboroFemaleShape1UpperBodyBonesName.Length;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
// ASSERT(false);
|
|
break;
|
|
}
|
|
result = true;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取下半身骨骼名称 // Get lower body bones name
|
|
/// </summary>
|
|
private bool GetLowerBodyBonesName(PlayerInfo player, out int bonesNameCount, out string[] szBonesName)
|
|
{
|
|
bonesNameCount = 0;
|
|
szBonesName = null;
|
|
bool result = false;
|
|
|
|
if (HasModelSupport(player))
|
|
{
|
|
switch (player.shapeType)
|
|
{
|
|
case PlayerModelType.PLAYERMODEL_MAJOR:
|
|
if (RoleTypes.GENDER_MALE == player.gender)
|
|
{
|
|
szBonesName = s_szOboroMaleStandardLowerBodyBonesName;
|
|
bonesNameCount = s_szOboroMaleStandardLowerBodyBonesName.Length;
|
|
}
|
|
else
|
|
{
|
|
szBonesName = s_szOboroFemaleStandardLowerBodyBonesName;
|
|
bonesNameCount = s_szOboroFemaleStandardLowerBodyBonesName.Length;
|
|
}
|
|
break;
|
|
case PlayerModelType.PLAYERMODEL_PROFESSION:
|
|
if (RoleTypes.GENDER_MALE == player.gender)
|
|
{
|
|
if (ResourceModel.RES_MOD_YUEXIAN_RESHAPE_M == player.shapeID)
|
|
{
|
|
szBonesName = s_szOboroMaleShape1LowerBodyBonesName;
|
|
bonesNameCount = s_szOboroMaleShape1LowerBodyBonesName.Length;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (ResourceModel.RES_MOD_YUEXIAN_RESHAPE_F == player.shapeID)
|
|
{
|
|
szBonesName = s_szOboroFemaleShape1LowerBodyBonesName;
|
|
bonesNameCount = s_szOboroFemaleShape1LowerBodyBonesName.Length;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
// ASSERT(false);
|
|
break;
|
|
}
|
|
result = true;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// Public methods that accept CECPlayer
|
|
/// <summary>
|
|
/// 检查玩家模型是否支持移动施法 // Check if player model supports casting while moving
|
|
/// </summary>
|
|
public bool HasModelSupport(CECPlayer pPlayer)
|
|
{
|
|
return pPlayer != null && HasModelSupport(new PlayerInfo(pPlayer));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查技能是否支持移动施法 // Check if skill supports casting while moving
|
|
/// </summary>
|
|
public bool IsSkillSupported(int idSkill, CECPlayer pPlayer)
|
|
{
|
|
return pPlayer != null && IsSkillSupported(idSkill, new PlayerInfo(pPlayer));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查技能动作是否支持移动施法 // Check if skill action supports casting while moving
|
|
/// </summary>
|
|
public bool HasActionSupport(int idSkill, CECPlayer pPlayer)
|
|
{
|
|
return pPlayer != null && HasActionSupport(idSkill, new PlayerInfo(pPlayer));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取玩家上半身骨骼名称 // Get player upper body bones name
|
|
/// </summary>
|
|
public bool GetUpperBodyBonesName(CECPlayer pPlayer, out int bonesNameCount, out string[] szBonesName)
|
|
{
|
|
bonesNameCount = 0;
|
|
szBonesName = null;
|
|
return pPlayer != null && GetUpperBodyBonesName(new PlayerInfo(pPlayer), out bonesNameCount, out szBonesName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取玩家下半身骨骼名称 // Get player lower body bones name
|
|
/// </summary>
|
|
public bool GetLowerBodyBonesName(CECPlayer pPlayer, out int bonesNameCount, out string[] szBonesName)
|
|
{
|
|
bonesNameCount = 0;
|
|
szBonesName = null;
|
|
return pPlayer != null && GetLowerBodyBonesName(new PlayerInfo(pPlayer), out bonesNameCount, out szBonesName);
|
|
}
|
|
}
|
|
}
|
|
|