server cast skill player processing
This commit is contained in:
@@ -2,6 +2,7 @@ using Animancer;
|
||||
using BrewMonster;
|
||||
using BrewMonster.Managers;
|
||||
using BrewMonster.Scripts.Managers;
|
||||
using BrewMonster.Scripts.Skills;
|
||||
using CSNetwork.GPDataType;
|
||||
using ModelRenderer.Scripts.GameData;
|
||||
using PerfectWorld.Scripts.Managers;
|
||||
@@ -13,6 +14,8 @@ using TMPro;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UIElements;
|
||||
using static CECPlayer;
|
||||
|
||||
public abstract class CECPlayer : CECObject
|
||||
{
|
||||
@@ -51,9 +54,13 @@ public abstract class CECPlayer : CECObject
|
||||
public bool m_bShowWeapon;
|
||||
private QueueActionEvent queueActionEvent;
|
||||
protected static PLAYER_LEVELEXP_CONFIG _player_levelup_exp;
|
||||
private CECPlayerActionController m_pActionController;
|
||||
private enumWingType m_wingType;
|
||||
|
||||
protected int NUM_WEAPON_TYPE = 15;
|
||||
public static readonly int[] m_sciStateIDForStateAction = { 117 };
|
||||
private static Dictionary<uint, PLAYER_ACTION_INFO_CONFIG> _default_skill_actions
|
||||
= new Dictionary<uint, PLAYER_ACTION_INFO_CONFIG>();
|
||||
|
||||
public MOVECONST m_MoveConst; // Const used when moving control
|
||||
public Move_Mode m_MoveMode;
|
||||
@@ -150,7 +157,7 @@ public abstract class CECPlayer : CECObject
|
||||
m_dwResFlags = 0;
|
||||
m_iFashionWeaponType = -1;
|
||||
m_uAttackType = DEFAULT_ACTION_TYPE;
|
||||
|
||||
|
||||
AttachWeapon();
|
||||
}
|
||||
|
||||
@@ -250,6 +257,63 @@ public abstract class CECPlayer : CECObject
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_turning_actions != null) _turning_actions = new PLAYER_ACTION[(int)PLAYER_ACTION_TYPE.ACT_MAX];
|
||||
_turning_actions = new PLAYER_ACTION[(int)PLAYER_ACTION_TYPE.ACT_MAX];
|
||||
if (actionMap.TryGetValue("自身旋转", out PLAYER_ACTION_INFO_CONFIG turningData))
|
||||
{
|
||||
for (int i = 0; i < (int)PLAYER_ACTION_TYPE.ACT_MAX; i++)
|
||||
{
|
||||
if (i < (int)PLAYER_ACTION_TYPE.ACT_GROUNDDIE ||
|
||||
i > (int)PLAYER_ACTION_TYPE.ACT_REVIVE)
|
||||
{
|
||||
// Dùng hành động xoay thay thế hành động thường
|
||||
_turning_actions[i].type = (PLAYER_ACTION_TYPE)i;
|
||||
_turning_actions[i].data = turningData;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dùng hành động mặc định
|
||||
_turning_actions[i] = _default_actions[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint idSkill = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
idSkill = ElementSkill.NextSkill(idSkill);
|
||||
if (idSkill == 0)
|
||||
break;
|
||||
|
||||
string skillName = ElementSkill.GetName(idSkill);
|
||||
|
||||
if (!string.IsNullOrEmpty(skillName))
|
||||
{
|
||||
if (skillActionMap.TryGetValue(skillName, out PLAYER_ACTION_INFO_CONFIG data1))
|
||||
{
|
||||
// ✅ Gán dữ liệu hành động cho skill tương ứng
|
||||
_default_skill_actions[idSkill] = data1;
|
||||
|
||||
#if DEBUG_OUTPUT_ACTIONS
|
||||
for (int n = 0; n < PlayerSkillAction.NUM_WEAPON_TYPE; n++)
|
||||
{
|
||||
var suffix = data.action_weapon_suffix[n].suffix;
|
||||
if (!string.IsNullOrEmpty(suffix))
|
||||
{
|
||||
Debug.Log($"{data.action_prefix}_Ò÷³ª_{suffix}");
|
||||
Debug.Log($"{data.action_prefix}_Ê©·ÅÆð_{suffix}");
|
||||
Debug.Log($"{data.action_prefix}_Ê©·ÅÂä_{suffix}");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// ❌ not found
|
||||
// Debug.LogWarning($"CECPlayer::BuildActionList() Failed to find skill action {idSkill}!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -606,7 +670,7 @@ public abstract class CECPlayer : CECObject
|
||||
// ==============================
|
||||
if (GetMoveEnv() == (int)MoveEnvironment.MOVEENV_GROUND)
|
||||
{
|
||||
|
||||
|
||||
// “起” 动作(挥起)
|
||||
szAct = EC_Utility.BuildActionName(action, weapon_type, "Æð");
|
||||
EventBus.PublishChannel(m_PlayerInfo.cid, new PlayActionEvent(szAct));
|
||||
@@ -719,7 +783,7 @@ public abstract class CECPlayer : CECObject
|
||||
{
|
||||
//todo: mr Hoang should double check it
|
||||
return 10;
|
||||
|
||||
|
||||
int weapon_type = 0;
|
||||
if (CanShowFashionWeapon((int)m_uAttackType, m_iFashionWeaponType) &&
|
||||
m_aEquips[(int)IndexOfIteminEquipmentInventory.EQUIPIVTR_FASHION_WEAPON] != 0)
|
||||
@@ -740,9 +804,10 @@ public abstract class CECPlayer : CECObject
|
||||
{
|
||||
return m_bWeaponAttached;
|
||||
}
|
||||
bool AttachWeapon(){
|
||||
bool AttachWeapon()
|
||||
{
|
||||
bool result = (false);
|
||||
|
||||
|
||||
/*while (GetPlayerModel() && (GetLeftHandWeapon() || GetRightHandWeapon())){
|
||||
A3DSkinModel *pSkinModel = GetPlayerModel()->GetA3DSkinModel();
|
||||
if (!pSkinModel ||
|
||||
@@ -804,7 +869,7 @@ public abstract class CECPlayer : CECObject
|
||||
BMLogger.LogError("CECPlayer::GetFashionConfig, Failed to load fashion weapon config");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int fashion_weapon_mask = (int)pConfig.Value.action_mask[fashion_weapon_type];
|
||||
return (fashion_weapon_mask & (1 << GetWeaponType(weapon_type))) != 0;
|
||||
}
|
||||
@@ -1064,7 +1129,50 @@ public abstract class CECPlayer : CECObject
|
||||
BubbleText(BUBBLE_HITMISSED, 0);*/
|
||||
}
|
||||
}
|
||||
public bool PlaySkillCastAction(int idSkill)
|
||||
{
|
||||
string szAct = "";
|
||||
|
||||
int weapon_type = GetShowingWeaponType();
|
||||
|
||||
PLAYER_ACTION_INFO_CONFIG data = _default_skill_actions[(uint)idSkill];
|
||||
|
||||
if (data.action_prefix == null || data.action_prefix.Length == 0 || data.action_prefix[0] == 0)
|
||||
{
|
||||
// Check if it's a target item skill
|
||||
if (ElementSkill.GetCommonCoolDown((uint)idSkill) > 1 << 4)
|
||||
{
|
||||
data = m_PlayerActions[(int)PLAYER_ACTION_TYPE.ACT_USING_TARGET_ITEM].data;
|
||||
|
||||
if (data.action_prefix == null || data.action_prefix.Length == 0 || data.action_prefix[0] == 0)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetMoveEnv() == (int)MoveEnvironment.MOVEENV_GROUND)
|
||||
{
|
||||
szAct = EC_Utility.BuildActionName(data, weapon_type, "_Ò÷³ª_");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if ((*//*UsingWing()*//*m_wingType == enumWingType.WINGTYPE_WING && IsFlying()) || (GetProfession() == PROF_ANGEL) || (GetProfession() == PROF_ARCHOR) || (GetProfession() == PROF_MONK) || (GetProfession() == PROF_GHOST))
|
||||
sprintf(szAct, "%s_¿ÕÖгá°ò_Ò÷³ª_%s", data->action_prefix, data->action_weapon_suffix[weapon_type].suffix);
|
||||
else
|
||||
sprintf(szAct, "%s_¿ÕÖзɽ£_Ò÷³ª_%s", data->action_prefix, data->action_weapon_suffix[weapon_type].suffix);*/
|
||||
}
|
||||
|
||||
bool bHideFX = false; /*!CECOptimize::Instance().GetGFX().CanShowCast(GetCharacterID(), GetClassID());*/
|
||||
if (!PlaySkillCastActionWithName(idSkill, szAct, bHideFX))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ShowWeaponByConfig(data);
|
||||
//UpdateWeaponHangerPosBySkillAction(idSkill);// ¸ù¾Ý¼¼Äܲ¥·ÅµÄ¶¯×÷£¬¸ü¸ÄÎäÆ÷Ðü¹ÒλÖã¨Ö»Äܼì²é²»ÅŶӶ¯×÷£©
|
||||
return true;
|
||||
}
|
||||
public bool OnDamaged(int skill)
|
||||
{
|
||||
var atkMan = CECAttacksMan.Instance;
|
||||
@@ -1084,7 +1192,11 @@ public abstract class CECPlayer : CECObject
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool PlaySkillCastActionWithName(int idSkill, string szActName, bool bNoFX/* =false */)
|
||||
{
|
||||
return m_pActionController != null
|
||||
&& m_pActionController.PlaySkillCastActionWithName(idSkill, szActName, bNoFX);
|
||||
}
|
||||
bool GetSkillStateActionName(int skill, int state, string name1, string name2)
|
||||
{
|
||||
/* for (int i = 0; i < (int)m_SkillStateActionVec.size(); i++)
|
||||
@@ -1179,6 +1291,13 @@ public struct INFO
|
||||
this.crc_e = crc_;
|
||||
}
|
||||
}
|
||||
public
|
||||
enum enumWingType
|
||||
{
|
||||
WINGTYPE_WING, // ·ÉÐÐÆ÷ÀàÐÍ£º³á°ò
|
||||
WINGTYPE_FLYSWORD, // ·ÉÐÐÆ÷ÀàÐÍ£º·É½£
|
||||
WINGTYPE_DOUBLEWHEEL, // ·ÉÐÐÆ÷ÀàÐÍ£ºË«½Å·ÉÐÐÆ÷
|
||||
};
|
||||
|
||||
public enum PlayerResourcesReadyFlag
|
||||
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
using System;
|
||||
|
||||
// CECPlayerActionController
|
||||
// 玩家动作控制器 / Player action controller
|
||||
public class CECPlayerActionController
|
||||
{
|
||||
// Action channels for split-body animation (kept for parity with C++)
|
||||
// 动作通道(保留与C++一致的接口语义) / Channels kept to mirror C++ API
|
||||
public const int ACT_CHANNEL_UPPERBODY = 0;
|
||||
public const int ACT_CHANNEL_LOWERBODY = 1;
|
||||
public const int ACT_CHANNEL_WOUND = 2;
|
||||
|
||||
private CECPlayer m_pPlayer;
|
||||
private CECModel m_pPlayerModel;
|
||||
private bool m_bSupportCastSkillWhenMove;
|
||||
private CECPlayerActionPlayPolicy m_actionPlayPolicy;
|
||||
private bool m_bSkillAttackActionPlayed;
|
||||
|
||||
public CECPlayerActionController()
|
||||
{
|
||||
m_pPlayer = null;
|
||||
m_pPlayerModel = null;
|
||||
m_bSupportCastSkillWhenMove = false;
|
||||
m_actionPlayPolicy = null;
|
||||
m_bSkillAttackActionPlayed = false;
|
||||
}
|
||||
|
||||
~CECPlayerActionController()
|
||||
{
|
||||
ReleaseActionPlayPolicy();
|
||||
}
|
||||
|
||||
public void Bind(CECPlayer player, CECModel playerModel)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (player == m_pPlayer && playerModel == m_pPlayerModel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ReleaseActionPlayPolicy();
|
||||
m_pPlayer = player;
|
||||
m_pPlayerModel = playerModel;
|
||||
|
||||
// 是否支持移动中施法(当前C#端未实现,统一设为false)
|
||||
// Support cast-while-move (not implemented in C# port -> false)
|
||||
m_bSupportCastSkillWhenMove = false;
|
||||
|
||||
if (!m_bSupportCastSkillWhenMove)
|
||||
{
|
||||
// 如果不支持,仍保留“受击”通道逻辑钩子(在C#里留空)
|
||||
// If not supported, keep the hook for wound channel (no-op in C#)
|
||||
}
|
||||
|
||||
InitializeActionPlayPolicy();
|
||||
}
|
||||
|
||||
public bool SupportCastSkillWhenMove()
|
||||
{
|
||||
return m_bSupportCastSkillWhenMove;
|
||||
}
|
||||
|
||||
public bool CanCombineWithMoveForSkill(int idSkill)
|
||||
{
|
||||
return m_actionPlayPolicy != null && m_actionPlayPolicy.CanCombineWithMoveForSkill(idSkill);
|
||||
}
|
||||
|
||||
private void InitializeActionPlayPolicy()
|
||||
{
|
||||
// 当前C#只提供默认策略(不拆分上下半身)
|
||||
// Use default policy in this C# port
|
||||
m_actionPlayPolicy = new CECPlayerActionPlayPolicy(m_pPlayer, m_pPlayerModel);
|
||||
}
|
||||
|
||||
private void ReleaseActionPlayPolicy()
|
||||
{
|
||||
m_actionPlayPolicy = null;
|
||||
}
|
||||
|
||||
// Build channels (C# no-op, return false to indicate not supported here)
|
||||
// 构建动作通道(C#未实现,返回false)
|
||||
private bool BuildChannelForCastSkillWhenMove()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool PlayNonSkillActionWithName(int iAction, string szActName, bool bRestart = true, int nTransTime = 200, bool bNoFx = false, bool[] pActFlag = null, uint dwFlagMode = 0)
|
||||
{
|
||||
return m_actionPlayPolicy != null
|
||||
&& m_actionPlayPolicy.PlayNonSkillActionWithName(iAction, szActName, bRestart, nTransTime, bNoFx, pActFlag, dwFlagMode);
|
||||
}
|
||||
|
||||
public bool QueueNonSkillActionWithName(int iAction, string szActName, int nTransTime = 200, bool bForceStopPrevAct = false, bool bNoFx = false, bool bResetSpeed = false, bool bResetActFlag = false, bool[] pNewActFlag = null, uint dwNewFlagMode = 0)
|
||||
{
|
||||
return m_actionPlayPolicy != null
|
||||
&& m_actionPlayPolicy.QueueNonSkillActionWithName(iAction, szActName, nTransTime, bForceStopPrevAct, bNoFx, bResetSpeed, bResetActFlag, pNewActFlag, dwNewFlagMode);
|
||||
}
|
||||
|
||||
public bool PlaySkillCastActionWithName(int idSkill, string szActName, bool bNoFX = false)
|
||||
{
|
||||
if (m_actionPlayPolicy != null
|
||||
&& m_actionPlayPolicy.PlaySkillCastActionWithName(idSkill, szActName, bNoFX))
|
||||
{
|
||||
m_bSkillAttackActionPlayed = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool PlaySkillAttackActionWithName(int idSkill, string szActName, bool bNoFX = false, bool[] pActFlag = null, uint dwFlagMode = 0)
|
||||
{
|
||||
if (m_actionPlayPolicy != null
|
||||
&& m_actionPlayPolicy.PlaySkillAttackActionWithName(idSkill, szActName, bNoFX, pActFlag, dwFlagMode))
|
||||
{
|
||||
m_bSkillAttackActionPlayed = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool QueueSkillAttackActionWithName(int idSkill, string szActName, int nTransTime = 200, bool bNoFX = false, bool bResetSpeed = false, bool bResetActFlag = false, bool[] pNewActFlag = null, uint dwNewFlagMode = 0)
|
||||
{
|
||||
return m_actionPlayPolicy != null
|
||||
&& m_actionPlayPolicy.QueueSkillAttackActionWithName(idSkill, szActName, nTransTime, bNoFX, bResetSpeed, bResetActFlag, pNewActFlag, dwNewFlagMode);
|
||||
}
|
||||
|
||||
public bool PlayWoundActionWithName(string szActName)
|
||||
{
|
||||
return m_actionPlayPolicy != null
|
||||
&& m_actionPlayPolicy.PlayWoundActionWithName(szActName);
|
||||
}
|
||||
|
||||
public void ClearComActFlagAllRankNodes(bool bSignalCurrent)
|
||||
{
|
||||
if (m_actionPlayPolicy != null)
|
||||
{
|
||||
m_actionPlayPolicy.ClearComActFlagAllRankNodes(bSignalCurrent);
|
||||
}
|
||||
}
|
||||
|
||||
public void StopChannelAction()
|
||||
{
|
||||
if (m_actionPlayPolicy != null)
|
||||
{
|
||||
m_actionPlayPolicy.StopChannelAction();
|
||||
}
|
||||
}
|
||||
|
||||
public void StopSkillCastAction()
|
||||
{
|
||||
if (m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction() && !m_bSkillAttackActionPlayed)
|
||||
{
|
||||
m_actionPlayPolicy.StopSkillAction();
|
||||
// LOG kept minimal in C#
|
||||
}
|
||||
}
|
||||
|
||||
public void StopSkillAttackAction()
|
||||
{
|
||||
if (m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction() && m_bSkillAttackActionPlayed)
|
||||
{
|
||||
m_actionPlayPolicy.StopSkillAction();
|
||||
// LOG kept minimal in C#
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPlayingAction(int iAction)
|
||||
{
|
||||
return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingAction(iAction);
|
||||
}
|
||||
|
||||
public bool IsPlayingCastingSkillAction()
|
||||
{
|
||||
return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction();
|
||||
}
|
||||
|
||||
public bool IsPlayingMoveAction()
|
||||
{
|
||||
return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingMoveAction();
|
||||
}
|
||||
|
||||
public int GetLowerBodyAction()
|
||||
{
|
||||
return m_actionPlayPolicy != null ? m_actionPlayPolicy.GetLowerBodyAction() : -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0afbacc947643442a7bb827ce5b8000
|
||||
@@ -0,0 +1,340 @@
|
||||
using System;
|
||||
|
||||
/*public class CECPlayerActionController
|
||||
{
|
||||
// Action channels for split-body animation (kept for parity with C++)
|
||||
// 动作通道(保留与C++一致的接口语义) / Channels kept to mirror C++ API
|
||||
public const int ACT_CHANNEL_UPPERBODY = 0;
|
||||
public const int ACT_CHANNEL_LOWERBODY = 1;
|
||||
public const int ACT_CHANNEL_WOUND = 2;
|
||||
|
||||
private CECPlayer m_pPlayer;
|
||||
private CECModel m_pPlayerModel;
|
||||
private bool m_bSupportCastSkillWhenMove;
|
||||
private CECPlayerActionPlayPolicy m_actionPlayPolicy;
|
||||
private bool m_bSkillAttackActionPlayed;
|
||||
|
||||
public CECPlayerActionController()
|
||||
{
|
||||
m_pPlayer = null;
|
||||
m_pPlayerModel = null;
|
||||
m_bSupportCastSkillWhenMove = false;
|
||||
m_actionPlayPolicy = null;
|
||||
m_bSkillAttackActionPlayed = false;
|
||||
}
|
||||
|
||||
~CECPlayerActionController()
|
||||
{
|
||||
ReleaseActionPlayPolicy();
|
||||
}
|
||||
|
||||
public void Bind(CECPlayer player, CECModel playerModel)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (player == m_pPlayer && playerModel == m_pPlayerModel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ReleaseActionPlayPolicy();
|
||||
m_pPlayer = player;
|
||||
m_pPlayerModel = playerModel;
|
||||
|
||||
// 是否支持移动中施法(当前C#端未实现,统一设为false)
|
||||
// Support cast-while-move (not implemented in C# port -> false)
|
||||
m_bSupportCastSkillWhenMove = false;
|
||||
|
||||
if (!m_bSupportCastSkillWhenMove)
|
||||
{
|
||||
// 如果不支持,仍保留“受击”通道逻辑钩子(在C#里留空)
|
||||
// If not supported, keep the hook for wound channel (no-op in C#)
|
||||
}
|
||||
|
||||
InitializeActionPlayPolicy();
|
||||
}
|
||||
|
||||
public bool SupportCastSkillWhenMove()
|
||||
{
|
||||
return m_bSupportCastSkillWhenMove;
|
||||
}
|
||||
|
||||
public bool CanCombineWithMoveForSkill(int idSkill)
|
||||
{
|
||||
return m_actionPlayPolicy != null && m_actionPlayPolicy.CanCombineWithMoveForSkill(idSkill);
|
||||
}
|
||||
|
||||
private void InitializeActionPlayPolicy()
|
||||
{
|
||||
// 当前C#只提供默认策略(不拆分上下半身)
|
||||
// Use default policy in this C# port
|
||||
m_actionPlayPolicy = new CECPlayerActionPlayPolicy(m_pPlayer, m_pPlayerModel);
|
||||
}
|
||||
|
||||
private void ReleaseActionPlayPolicy()
|
||||
{
|
||||
m_actionPlayPolicy = null;
|
||||
}
|
||||
|
||||
// Build channels (C# no-op, return false to indicate not supported here)
|
||||
// 构建动作通道(C#未实现,返回false)
|
||||
private bool BuildChannelForCastSkillWhenMove()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool PlayNonSkillActionWithName(int iAction, string szActName, bool bRestart = true, int nTransTime = 200, bool bNoFx = false, bool[] pActFlag = null, uint dwFlagMode = 0)
|
||||
{
|
||||
return m_actionPlayPolicy != null
|
||||
&& m_actionPlayPolicy.PlayNonSkillActionWithName(iAction, szActName, bRestart, nTransTime, bNoFx, pActFlag, dwFlagMode);
|
||||
}
|
||||
|
||||
public bool QueueNonSkillActionWithName(int iAction, string szActName, int nTransTime = 200, bool bForceStopPrevAct = false, bool bNoFx = false, bool bResetSpeed = false, bool bResetActFlag = false, bool[] pNewActFlag = null, uint dwNewFlagMode = 0)
|
||||
{
|
||||
return m_actionPlayPolicy != null
|
||||
&& m_actionPlayPolicy.QueueNonSkillActionWithName(iAction, szActName, nTransTime, bForceStopPrevAct, bNoFx, bResetSpeed, bResetActFlag, pNewActFlag, dwNewFlagMode);
|
||||
}
|
||||
|
||||
public bool PlaySkillCastActionWithName(int idSkill, string szActName, bool bNoFX = false)
|
||||
{
|
||||
if (m_actionPlayPolicy != null
|
||||
&& m_actionPlayPolicy.PlaySkillCastActionWithName(idSkill, szActName, bNoFX))
|
||||
{
|
||||
m_bSkillAttackActionPlayed = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool PlaySkillAttackActionWithName(int idSkill, string szActName, bool bNoFX = false, bool[] pActFlag = null, uint dwFlagMode = 0)
|
||||
{
|
||||
if (m_actionPlayPolicy != null
|
||||
&& m_actionPlayPolicy.PlaySkillAttackActionWithName(idSkill, szActName, bNoFX, pActFlag, dwFlagMode))
|
||||
{
|
||||
m_bSkillAttackActionPlayed = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool QueueSkillAttackActionWithName(int idSkill, string szActName, int nTransTime = 200, bool bNoFX = false, bool bResetSpeed = false, bool bResetActFlag = false, bool[] pNewActFlag = null, uint dwNewFlagMode = 0)
|
||||
{
|
||||
return m_actionPlayPolicy != null
|
||||
&& m_actionPlayPolicy.QueueSkillAttackActionWithName(idSkill, szActName, nTransTime, bNoFX, bResetSpeed, bResetActFlag, pNewActFlag, dwNewFlagMode);
|
||||
}
|
||||
|
||||
public bool PlayWoundActionWithName(string szActName)
|
||||
{
|
||||
return m_actionPlayPolicy != null
|
||||
&& m_actionPlayPolicy.PlayWoundActionWithName(szActName);
|
||||
}
|
||||
|
||||
public void ClearComActFlagAllRankNodes(bool bSignalCurrent)
|
||||
{
|
||||
if (m_actionPlayPolicy != null)
|
||||
{
|
||||
m_actionPlayPolicy.ClearComActFlagAllRankNodes(bSignalCurrent);
|
||||
}
|
||||
}
|
||||
|
||||
public void StopChannelAction()
|
||||
{
|
||||
if (m_actionPlayPolicy != null)
|
||||
{
|
||||
m_actionPlayPolicy.StopChannelAction();
|
||||
}
|
||||
}
|
||||
|
||||
public void StopSkillCastAction()
|
||||
{
|
||||
if (m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction() && !m_bSkillAttackActionPlayed)
|
||||
{
|
||||
m_actionPlayPolicy.StopSkillAction();
|
||||
// LOG kept minimal in C#
|
||||
}
|
||||
}
|
||||
|
||||
public void StopSkillAttackAction()
|
||||
{
|
||||
if (m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction() && m_bSkillAttackActionPlayed)
|
||||
{
|
||||
m_actionPlayPolicy.StopSkillAction();
|
||||
// LOG kept minimal in C#
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPlayingAction(int iAction)
|
||||
{
|
||||
return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingAction(iAction);
|
||||
}
|
||||
|
||||
public bool IsPlayingCastingSkillAction()
|
||||
{
|
||||
return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction();
|
||||
}
|
||||
|
||||
public bool IsPlayingMoveAction()
|
||||
{
|
||||
return m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingMoveAction();
|
||||
}
|
||||
|
||||
public int GetLowerBodyAction()
|
||||
{
|
||||
return m_actionPlayPolicy != null ? m_actionPlayPolicy.GetLowerBodyAction() : -1;
|
||||
}
|
||||
}*/
|
||||
public class CECPlayerActionPlayPolicy
|
||||
{
|
||||
protected readonly CECPlayer m_pPlayer;
|
||||
protected readonly CECModel m_pPlayerModel;
|
||||
|
||||
// 简单状态记录以支持“是否在施法中”的判断
|
||||
// Simple state to support IsPlayingCastingSkillAction
|
||||
private bool m_isCastingSkill;
|
||||
|
||||
public CECPlayerActionPlayPolicy(CECPlayer pPlayer, CECModel pPlayerModel)
|
||||
{
|
||||
m_pPlayer = pPlayer;
|
||||
m_pPlayerModel = pPlayerModel;
|
||||
m_isCastingSkill = false;
|
||||
}
|
||||
|
||||
public virtual bool CanCombineWithMoveForSkill(int idSkill)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public CECPlayer GetPlayer()
|
||||
{
|
||||
return m_pPlayer;
|
||||
}
|
||||
|
||||
public CECModel GetModel()
|
||||
{
|
||||
return m_pPlayerModel;
|
||||
}
|
||||
|
||||
public bool IsMoving()
|
||||
{
|
||||
return IsPlayingMoveAction() && (m_pPlayer != null && m_pPlayer.IsWorkMoveRunning());
|
||||
}
|
||||
|
||||
public static bool IsMoveAction(int action)
|
||||
{
|
||||
return action == (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_RUN
|
||||
|| action == (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_WALK
|
||||
|| action == (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_FLY
|
||||
|| action == (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_FLY_SWORD
|
||||
|| action == (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_SWIM
|
||||
|| action == (int)CECPlayer.PLAYER_ACTION_TYPE.ACT_SWIM_FOR_MOVESKILL;
|
||||
}
|
||||
|
||||
public bool IsPlayingCastingSkillAction()
|
||||
{
|
||||
return m_isCastingSkill;
|
||||
}
|
||||
|
||||
// Non-skill action
|
||||
public virtual bool PlayNonSkillActionWithName(int iAction, string szActName, bool bRestart, int nTransTime, bool bNoFx, bool[] pActFlag, uint dwFlagMode)
|
||||
{
|
||||
if (m_pPlayer == null || string.IsNullOrEmpty(szActName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
EventBus.PublishChannel(m_pPlayer.GetPlayerInfo().cid, new PlayActionEvent(szActName));
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool QueueNonSkillActionWithName(int iAction, string szActName, int nTransTime, bool bForceStopPrevAct, bool bNoFx, bool bResetSpeed, bool bResetActFlag, bool[] pNewActFlag, uint dwNewFlagMode)
|
||||
{
|
||||
// 当前实现:直接播放(队列行为由上层系统处理)
|
||||
// Current: just play, queue behavior handled by upper systems
|
||||
return PlayNonSkillActionWithName(iAction, szActName, false, nTransTime, bNoFx, pNewActFlag, dwNewFlagMode);
|
||||
}
|
||||
|
||||
// Skill actions
|
||||
public virtual bool PlaySkillCastActionWithName(int idSkill, string szActName, bool bNoFX)
|
||||
{
|
||||
if (m_pPlayer == null || string.IsNullOrEmpty(szActName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (IsMoving())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_isCastingSkill = true;
|
||||
EventBus.PublishChannel(m_pPlayer.GetPlayerInfo().cid, new PlayActionEvent(szActName));
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool PlaySkillAttackActionWithName(int idSkill, string szActName, bool bNoFX, bool[] pActFlag, uint dwFlagMode)
|
||||
{
|
||||
if (m_pPlayer == null || string.IsNullOrEmpty(szActName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (IsMoving())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_isCastingSkill = true;
|
||||
EventBus.PublishChannel(m_pPlayer.GetPlayerInfo().cid, new PlayActionEvent(szActName));
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool QueueSkillAttackActionWithName(int idSkill, string szActName, int nTransTime, bool bNoFX, bool bResetSpeed, bool bResetActFlag, bool[] pNewActFlag, uint dwNewFlagMode)
|
||||
{
|
||||
return PlaySkillAttackActionWithName(idSkill, szActName, bNoFX, pNewActFlag, dwNewFlagMode);
|
||||
}
|
||||
|
||||
public virtual bool PlayWoundActionWithName(string szActName)
|
||||
{
|
||||
if (m_pPlayer == null || string.IsNullOrEmpty(szActName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
EventBus.PublishChannel(m_pPlayer.GetPlayerInfo().cid, new PlayActionEvent(szActName));
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void ClearComActFlagAllRankNodes(bool bSignalCurrent)
|
||||
{
|
||||
if (m_pPlayer != null)
|
||||
{
|
||||
EventBus.PublishChannel(m_pPlayer.GetPlayerInfo().cid, new CECPlayer.CleearComActFlagAllRankNodesEvent(bSignalCurrent));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void StopChannelAction()
|
||||
{
|
||||
// 在C#端没有底层通道概念,做成清旗标即可
|
||||
// No channel concept here; clear act flags as a substitute
|
||||
ClearComActFlagAllRankNodes(true);
|
||||
}
|
||||
|
||||
public virtual void StopSkillAction()
|
||||
{
|
||||
m_isCastingSkill = false;
|
||||
StopChannelAction();
|
||||
}
|
||||
|
||||
public virtual bool IsPlayingAction(int iAction)
|
||||
{
|
||||
// C#动画系统由上层驱动,这里不跟踪具体动作,统一返回false
|
||||
// Not tracked here; return false by default
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool IsPlayingMoveAction()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual int GetLowerBodyAction()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2f3e916f6bf57b24db022c97379fffca
|
||||
@@ -151,6 +151,13 @@ namespace BrewMonster.Scripts.Skills
|
||||
return new Dictionary<uint, int>();
|
||||
}
|
||||
public virtual string GetName() { return null; }
|
||||
public static string GetName(uint id)
|
||||
{
|
||||
SkillStub s = SkillStub.GetStub(id);
|
||||
if (s != null)
|
||||
return s.GetName();
|
||||
return "";
|
||||
}
|
||||
public virtual byte[] GetNativeName() { return null; }
|
||||
// �������?,��skill_type
|
||||
public virtual byte GetType() { return 1; }
|
||||
@@ -225,6 +232,13 @@ namespace BrewMonster.Scripts.Skills
|
||||
// ��֧����
|
||||
public virtual int GetArrowCost() { 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��δѡ��Ŀ��
|
||||
|
||||
@@ -61,6 +61,7 @@ public partial class CECHostPlayer : CECPlayer
|
||||
private int m_iRoleCreateTime;
|
||||
private int m_iRoleLastLoginTime; // Role last login time
|
||||
private int m_iAccountTotalCash;
|
||||
private int m_idCurSkillTarget;
|
||||
|
||||
private List<CECObject> m_aTabSels = new List<CECObject>();
|
||||
private List<CECSkill> m_aPtSkills = new List<CECSkill>();
|
||||
@@ -68,8 +69,11 @@ public partial class CECHostPlayer : CECPlayer
|
||||
private List<CECSkill> m_aEquipSkills = new List<CECSkill>();
|
||||
private List<CECSkill> m_aGoblinSkills = new List<CECSkill>();
|
||||
|
||||
private bool m_bSpellDSkill;
|
||||
private bool m_bEnterGame;
|
||||
public CECSkill m_pPrepSkill;
|
||||
private CECSkill m_pCurSkill;
|
||||
private CECCounter m_IncantCnt;
|
||||
private float playerSpeed = 5.0f;
|
||||
private float jumpHeight = 1.5f;
|
||||
private float gravityValue = -9.81f;
|
||||
@@ -404,9 +408,398 @@ public partial class CECHostPlayer : CECPlayer
|
||||
case int value when value == EC_MsgDef.MSG_HST_SKILLDATA: OnMsgHstSkillData(Msg); break;
|
||||
case int value when value == EC_MsgDef.MSG_HST_DIED: OnMsgHstDied(Msg); break;
|
||||
case int value when value == EC_MsgDef.MSG_HST_GOTO: OnMsgHstGoto(Msg); break;
|
||||
case int value when value == EC_MsgDef.MSG_PM_CASTSKILL: OnMsgPlayerCastSkill(Msg); break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMsgPlayerCastSkill(ECMSG Msg)
|
||||
{
|
||||
// using namespace S2C;
|
||||
bool bDoOtherThing = false;
|
||||
int idTarget = 0;
|
||||
|
||||
bool bActionStartSkill = false;
|
||||
int iActionTime = 1000;
|
||||
//CECPlayerWrapper pWrapper = CECAutoPolicy.GetInstance().GetPlayerWrapper();
|
||||
BMLogger.LogError("HoangDev OnMsgPlayerCastSkill Msg.dwParam2 " + (int)Msg.dwParam2);
|
||||
switch ((int)Msg.dwParam2)
|
||||
{
|
||||
case CommandID.OBJECT_CAST_SKILL:
|
||||
{
|
||||
var pCmd = GPDataTypeHelper.FromBytes<cmd_object_cast_skill>((byte[])Msg.dwParam1);
|
||||
|
||||
if (m_pCurSkill != null)
|
||||
{
|
||||
m_pCurSkill.EndCharging();
|
||||
}
|
||||
|
||||
m_pCurSkill = GetPositiveSkillByID(pCmd.skill);
|
||||
if (m_pCurSkill == null) m_pCurSkill = GetEquipSkillByID(pCmd.skill);
|
||||
if (m_pCurSkill == null) m_pCurSkill = CECComboSkillState.Instance.GetInherentSkillByID((uint)pCmd.skill);
|
||||
if (m_pCurSkill == null)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(m_pCurSkill != null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pCurSkill.IsChargeable())
|
||||
m_pCurSkill.StartCharging(pCmd.time);
|
||||
|
||||
int iWaitTime = -1;
|
||||
if (m_pCurSkill.GetExecuteTime() >= 0)
|
||||
iWaitTime = pCmd.time + m_pCurSkill.GetExecuteTime();
|
||||
|
||||
var pWork = (CECHPWorkSpell)m_pWorkMan.CreateWork(CECHPWork.Host_work_ID.WORK_SPELLOBJECT);
|
||||
pWork.PrepareCast(pCmd.target, m_pCurSkill, iWaitTime);
|
||||
m_pWorkMan.StartWork_p1(pWork);
|
||||
|
||||
if (!m_pCurSkill.IsChargeable())
|
||||
{
|
||||
int iTime = pCmd.time;
|
||||
iTime = Math.Max(iTime, 10);
|
||||
m_IncantCnt.SetPeriod(iTime);
|
||||
m_IncantCnt.Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_IncantCnt.Reset(true);
|
||||
}
|
||||
|
||||
m_bSpellDSkill = false;
|
||||
|
||||
TurnFaceTo(pCmd.target);
|
||||
|
||||
m_idCurSkillTarget = pCmd.target;
|
||||
PlaySkillCastAction(m_pCurSkill.GetSkillID());
|
||||
|
||||
bActionStartSkill = true;
|
||||
iActionTime = iWaitTime;
|
||||
break;
|
||||
}
|
||||
|
||||
/* case CommandID.SKILL_PERFORM:
|
||||
{
|
||||
m_pPrepSkill = null;
|
||||
|
||||
if (m_pCurSkill != null && m_pCurSkill.IsDurative())
|
||||
m_bSpellDSkill = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CommandID.HOST_STOP_SKILL:
|
||||
{
|
||||
m_pPrepSkill = null;
|
||||
|
||||
CECSkill pSkillToMatch = m_pCurSkill;
|
||||
if (m_pCurSkill != null)
|
||||
{
|
||||
ClearComActFlagAllRankNodes(true);
|
||||
|
||||
if (((m_pComboSkill != null && !m_pComboSkill.IsStop()) ||
|
||||
m_pCurSkill.ChangeToMelee()) && !m_pWorkMan.HasDelayedWork())
|
||||
{
|
||||
bDoOtherThing = true;
|
||||
idTarget = m_idCurSkillTarget;
|
||||
}
|
||||
|
||||
m_pCurSkill.EndCharging();
|
||||
m_pCurSkill = null;
|
||||
}
|
||||
|
||||
AP_ActionEvent(AP_EVENT_STOPSKILL);
|
||||
|
||||
if (pSkillToMatch != null)
|
||||
{
|
||||
m_pWorkMan.FinishWork(new CECHPWorkSpellMatcher(pSkillToMatch));
|
||||
}
|
||||
StopSkillAttackAction();
|
||||
|
||||
m_idCurSkillTarget = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case CommandID.SELF_SKILL_INTERRUPTED:
|
||||
{
|
||||
int skill_id = 0;
|
||||
m_pPrepSkill = null;
|
||||
|
||||
CECSkill pSkillToMatch = m_pCurSkill;
|
||||
if (m_pCurSkill != null)
|
||||
{
|
||||
skill_id = m_pCurSkill.GetSkillID();
|
||||
|
||||
ClearComActFlagAllRankNodes(false);
|
||||
|
||||
if (((m_pComboSkill != null && !m_pComboSkill.IsStop()) ||
|
||||
m_pCurSkill.ChangeToMelee()) && !m_pWorkMan.HasDelayedWork())
|
||||
{
|
||||
bDoOtherThing = true;
|
||||
idTarget = m_idCurSkillTarget;
|
||||
}
|
||||
|
||||
m_pCurSkill.EndCharging();
|
||||
m_pCurSkill = null;
|
||||
}
|
||||
|
||||
m_idCurSkillTarget = 0;
|
||||
|
||||
if (pSkillToMatch != null)
|
||||
{
|
||||
m_pWorkMan.FinishWork(new CECHPWorkSpellMatcher(pSkillToMatch));
|
||||
}
|
||||
StopSkillCastAction();
|
||||
|
||||
g_pGame.GetGameRun().AddFixedMessage(FIXMSG_SKILLINTERRUPT);
|
||||
|
||||
AP_ActionEvent(AP_EVENT_STOPSKILL);
|
||||
|
||||
CECAutoPolicy.GetInstance().SendEvent_SkillInterrupt(skill_id);
|
||||
break;
|
||||
}
|
||||
|
||||
case CommandID.OBJECT_CAST_INSTANT_SKILL:
|
||||
{
|
||||
var pCmd = (S2C.cmd_object_cast_instant_skill)Msg.Param1;
|
||||
System.Diagnostics.Debug.Assert(pCmd.caster == m_PlayerInfo.cid);
|
||||
|
||||
CECSkill pSkill = GetPositiveSkillByID(pCmd.skill);
|
||||
if (pSkill == null) pSkill = GetEquipSkillByID(pCmd.skill);
|
||||
if (pSkill == null)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(pSkill != null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pCmd.target != 0 && pCmd.target != m_PlayerInfo.cid)
|
||||
TurnFaceTo(pCmd.target);
|
||||
|
||||
PlaySkillCastAction(pSkill.GetSkillID());
|
||||
bActionStartSkill = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case CommandID.OBJECT_CAST_POS_SKILL:
|
||||
{
|
||||
var pCmd = (S2C.cmd_object_cast_pos_skill)Msg.Param1;
|
||||
System.Diagnostics.Debug.Assert(pCmd.caster == m_PlayerInfo.cid);
|
||||
|
||||
CECSkill pSkill = GetNormalSkill(pCmd.skill);
|
||||
if (pSkill == null) pSkill = GetEquipSkillByID(pCmd.skill);
|
||||
if (pSkill == null)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(pSkill != null);
|
||||
break;
|
||||
}
|
||||
|
||||
TurnFaceTo(pCmd.target);
|
||||
|
||||
if (pSkill.GetRangeType() != CECSkill.RangeType.RANGE_SLEF &&
|
||||
pSkill.GetRangeType() != CECSkill.RangeType.RANGE_SELFSPHERE &&
|
||||
(pSkill.GetSkillID() == 1095 ||
|
||||
pSkill.GetSkillID() == 1278 ||
|
||||
pSkill.GetSkillID() == 1279 ||
|
||||
pSkill.GetSkillID() == 2313))
|
||||
{
|
||||
// Teleport-style placement
|
||||
A3DVECTOR3 vPos = pCmd.pos;
|
||||
if (!IsPosCollideFree(vPos))
|
||||
{
|
||||
vPos += g_vAxisY * 0.1f;
|
||||
}
|
||||
|
||||
A3DVECTOR3 vNormal;
|
||||
float vTerrainHeight = g_pGame.GetGameRun().GetWorld().GetTerrainHeight(vPos, out vNormal);
|
||||
if (vPos.y < vTerrainHeight)
|
||||
vPos.y = vTerrainHeight;
|
||||
|
||||
SetPos(vPos);
|
||||
|
||||
m_CDRInfo.vTPNormal = (vPos.y <= vTerrainHeight + 0.1f) ? vNormal : g_vOrigin;
|
||||
m_CDRInfo.fYVel = 0.0f;
|
||||
m_CDRInfo.vAbsVelocity.Clear();
|
||||
ResetJump();
|
||||
|
||||
m_MoveCtrl.SetHostLastPos(vPos);
|
||||
m_MoveCtrl.SetLastSevPos(vPos);
|
||||
|
||||
UpdateFollowCamera(false, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
var pWork = (CECHPWorkFMove)m_pWorkMan.CreateWork(CECHPWork.WORK_FLASHMOVE);
|
||||
|
||||
int nExecuteTime = pSkill.GetExecuteTime();
|
||||
nExecuteTime = Math.Max(nExecuteTime, 50);
|
||||
|
||||
if (pSkill.GetSkillID() == 1145 ||
|
||||
pSkill.GetSkillID() == 1314 ||
|
||||
pSkill.GetSkillID() == 1315 ||
|
||||
pSkill.GetSkillID() == 1362 ||
|
||||
pSkill.GetSkillID() == 1690 ||
|
||||
pSkill.GetSkillID() == 1691 ||
|
||||
pSkill.GetSkillID() == 1845 ||
|
||||
pSkill.GetSkillID() == 1844 ||
|
||||
pSkill.GetSkillID() == 1815 ||
|
||||
pSkill.GetSkillID() == 2272 ||
|
||||
pSkill.GetSkillID() == 2315 ||
|
||||
pSkill.GetSkillID() == 2285 ||
|
||||
pSkill.GetSkillID() == 2340 ||
|
||||
pSkill.GetSkillID() == 2341 ||
|
||||
pSkill.GetSkillID() == 2342 ||
|
||||
pSkill.GetSkillID() == 2553 ||
|
||||
pSkill.GetSkillID() == 2740 ||
|
||||
pSkill.GetSkillID() == 2741 ||
|
||||
pSkill.GetSkillID() == 2559 ||
|
||||
pSkill.GetSkillID() == 2752 ||
|
||||
pSkill.GetSkillID() == 2753)
|
||||
{
|
||||
A3DVECTOR3 vPos = pCmd.pos;
|
||||
if (!IsPosCollideFree(vPos))
|
||||
{
|
||||
vPos += g_vAxisY * 0.1f;
|
||||
}
|
||||
|
||||
A3DVECTOR3 vNormal;
|
||||
float vTerrainHeight = g_pGame.GetGameRun().GetWorld().GetTerrainHeight(vPos, out vNormal);
|
||||
if (vPos.y < vTerrainHeight)
|
||||
vPos.y = vTerrainHeight;
|
||||
|
||||
m_CDRInfo.vTPNormal = (vPos.y <= vTerrainHeight + 0.1f) ? vNormal : g_vOrigin;
|
||||
m_CDRInfo.fYVel = 0.0f;
|
||||
m_CDRInfo.vAbsVelocity.Clear();
|
||||
ResetJump();
|
||||
|
||||
pWork.PrepareMove(pCmd.pos, nExecuteTime * 0.001f, pSkill.GetSkillID());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pSkill.GetRangeType() == CECSkill.RangeType.RANGE_SLEF ||
|
||||
pSkill.GetRangeType() == CECSkill.RangeType.RANGE_SELFSPHERE)
|
||||
{
|
||||
m_CDRInfo.vTPNormal = m_MoveCtrl.m_vFlashTPNormal;
|
||||
}
|
||||
pWork.PrepareMove(pCmd.pos, nExecuteTime * 0.001f, 0);
|
||||
}
|
||||
|
||||
m_pWorkMan.StartWork_p2(pWork);
|
||||
iActionTime = nExecuteTime;
|
||||
}
|
||||
|
||||
bActionStartSkill = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case CommandID.PLAYER_CAST_RUNE_SKILL:
|
||||
{
|
||||
var pCmd = (S2C.cmd_player_cast_rune_skill)Msg.Param1;
|
||||
System.Diagnostics.Debug.Assert(pCmd.caster == m_PlayerInfo.cid);
|
||||
|
||||
if (m_pTargetItemSkill != null)
|
||||
{
|
||||
m_pTargetItemSkill = null;
|
||||
}
|
||||
|
||||
m_pTargetItemSkill = new CECSkill(pCmd.skill, pCmd.level);
|
||||
if (m_pTargetItemSkill == null)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(m_pTargetItemSkill != null);
|
||||
return;
|
||||
}
|
||||
|
||||
m_pCurSkill = m_pTargetItemSkill;
|
||||
|
||||
if (m_pCurSkill.IsChargeable())
|
||||
m_pCurSkill.StartCharging(pCmd.time);
|
||||
|
||||
int iWaitTime = -1;
|
||||
if (m_pCurSkill.GetExecuteTime() >= 0)
|
||||
iWaitTime = pCmd.time + m_pCurSkill.GetExecuteTime();
|
||||
|
||||
var pWork = (CECHPWorkSpell)m_pWorkMan.CreateWork(CECHPWork.WORK_SPELLOBJECT);
|
||||
pWork.PrepareCast(pCmd.target, m_pCurSkill, iWaitTime);
|
||||
m_pWorkMan.StartWork_p1(pWork);
|
||||
|
||||
if (!m_pCurSkill.IsChargeable())
|
||||
{
|
||||
int iTime = pCmd.time;
|
||||
iTime = Math.Max(iTime, 10);
|
||||
m_IncantCnt.SetPeriod(iTime);
|
||||
m_IncantCnt.Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_IncantCnt.Reset(true);
|
||||
}
|
||||
|
||||
m_bSpellDSkill = false;
|
||||
|
||||
TurnFaceTo(pCmd.target);
|
||||
|
||||
m_idCurSkillTarget = pCmd.target;
|
||||
PlaySkillCastAction(m_pCurSkill.GetSkillID());
|
||||
|
||||
bActionStartSkill = true;
|
||||
iActionTime = iWaitTime;
|
||||
g_pGame.RuntimeDebugInfo(0xffffffff, $"Cast skill({m_pCurSkill.GetSkillID()}): {g_pGame.GetSkillDesc().GetWideString(m_pCurSkill.GetSkillID() * 10)}");
|
||||
break;
|
||||
}
|
||||
|
||||
case CommandID.PLAYER_CAST_RUNE_INSTANT_SKILL:
|
||||
{
|
||||
var pCmd = (S2C.cmd_player_cast_rune_instant_skill)Msg.Param1;
|
||||
System.Diagnostics.Debug.Assert(pCmd.caster == m_PlayerInfo.cid);
|
||||
|
||||
if (m_pTargetItemSkill != null)
|
||||
{
|
||||
m_pTargetItemSkill = null;
|
||||
}
|
||||
|
||||
m_pTargetItemSkill = new CECSkill(pCmd.skill, pCmd.level);
|
||||
if (m_pTargetItemSkill == null)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(m_pTargetItemSkill != null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pCmd.target != 0 && pCmd.target != m_PlayerInfo.cid)
|
||||
TurnFaceTo(pCmd.target);
|
||||
|
||||
PlaySkillCastAction(m_pTargetItemSkill.GetSkillID());
|
||||
bActionStartSkill = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case CommandID.ERROR_MESSAGE:
|
||||
bDoOtherThing = true;
|
||||
// m_pPrepSkill = null;
|
||||
break;
|
||||
|
||||
default:
|
||||
System.Diagnostics.Debug.Assert(false);
|
||||
break;*/
|
||||
}
|
||||
|
||||
if (bActionStartSkill)
|
||||
AP_ActionEvent(AP_EVENT_STARTSKILL, iActionTime);
|
||||
|
||||
if (bDoOtherThing)
|
||||
{
|
||||
if (m_pComboSkill != null && !m_pComboSkill.IsStop())
|
||||
{
|
||||
if (CECAutoPolicy.GetInstance().IsAutoPolicyEnabled())
|
||||
g_pGame.GetGameRun().PostMessage(MSG_HST_CONTINUECOMBOSKILL, MAN_PLAYER, 0, 0, m_pComboSkill.GetGroupIndex());
|
||||
else
|
||||
m_pComboSkill.Continue(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (idTarget != 0 && idTarget != m_PlayerInfo.cid)
|
||||
NormalAttackObject(idTarget, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void OnMsgHstSkillData(ECMSG Msg)
|
||||
{
|
||||
cmd_skill_data pCmd = default;
|
||||
|
||||
@@ -116,6 +116,20 @@ public static class EC_Utility
|
||||
var tailFixed = FixGBKString(tail);
|
||||
return $"{prefix}_{suffix}{tailFixed}";
|
||||
}
|
||||
public static string BuildActionName(PLAYER_ACTION_INFO_CONFIG data, int weaponType, string midBody = "")
|
||||
{
|
||||
string prefix = data.ActionPrefix ?? string.Empty;
|
||||
string suffix = string.Empty;
|
||||
|
||||
if (data.action_weapon_suffix != null
|
||||
&& weaponType >= 0
|
||||
&& weaponType < data.action_weapon_suffix.Length)
|
||||
{
|
||||
suffix = data.action_weapon_suffix[weaponType].Suffix ?? string.Empty;
|
||||
}
|
||||
var midBodyFixed = FixGBKString(midBody);
|
||||
return $"{prefix}{midBodyFixed}{suffix}";
|
||||
}
|
||||
|
||||
// Build pvp mask
|
||||
public static byte glb_BuildPVPMask(bool bForceAttack)
|
||||
|
||||
Reference in New Issue
Block a user