add chanelact logic

This commit is contained in:
Tran Hai Nam
2026-05-05 16:09:25 +07:00
parent 1341d6ca65
commit 4e99c4f842
10 changed files with 362 additions and 142 deletions
@@ -78,7 +78,7 @@ namespace BrewMonster.Network
// return m_dwRealTickTime;
// return Time.realtimeSinceStartup;
// 0.018f is value to make mining process run fit with player animation. if have any issue => discussing with Mr. Drimdar
return (Time.unscaledDeltaTime - 0.018f) * 1000f;//-0.001f
return Mathf.Abs(Time.unscaledDeltaTime - 0.018f) * 1000f;//-0.001f
}
}
}
@@ -4,7 +4,7 @@ using System.Collections.Generic;
using BrewMonster.Network;
using BrewMonster.Utils;
using Random = UnityEngine.Random;
using UnityEngine;
namespace BrewMonster.Scripts
{
using WorkList = System.Collections.Generic.List<CECEPWork>;
@@ -279,61 +279,56 @@ namespace BrewMonster.Scripts
// class CECEPWorkSpell
public class CECEPWorkSpell : CECEPWork
{
CECCounter m_SkillCnt;
CECSkill m_pCurSkill;
int m_idCurSkillTarget;
public CECEPWorkSpell(CECEPWorkMan pWorkMan, uint dwPeriod, CECSkill pSkill, int target) : base(CECEPWork.EP_work_ID.WORK_SPELL, pWorkMan)
CECCounter m_SkillCnt;
CECSkill m_pCurSkill;
int m_idCurSkillTarget;
public CECEPWorkSpell(CECEPWorkMan pWorkMan, uint dwPeriod, CECSkill pSkill, int target) : base(EP_work_ID.WORK_SPELL, pWorkMan)
{
m_pCurSkill = pSkill;
m_idCurSkillTarget = target;
if (m_SkillCnt == null){
m_SkillCnt = new CECCounter();
}
m_SkillCnt.SetPeriod(dwPeriod);
m_SkillCnt.Reset();
}
// public CECEWorkSpell(){
// if (m_pCurSkill != null){
// m_pCurSkill = null;
// }
// }
public override void Start()
{
GetPlayer().m_iMoveMode = (int)MoveMode.MOVE_STAND;
GetPlayer().m_iMoveMode = (int)MoveMode.MOVE_STAND;
}
public override void Tick(float dwDeltaTime)
{
//TO DO: fix later
//GetPlayer().m_FightCnt.IncCounter(dwDeltaTime);
//int iRealTime = g_pGame.GetRealTickTime();
//if (m_SkillCnt.IncCounter(iRealTime))
//{
// Finish();
//}
//else
//{
// if (m_idCurSkillTarget != 0)
// {
// GetPlayer().TurnFaceTo(m_idCurSkillTarget);
// }
// if (GetPlayer().IsPlayingMoveAction() && !GetPlayer().IsWorkMoveRunning())
// { // ƶʩֹͣƶһֱڳƶ˴ͣ
// GetPlayer().PlayAction(CECPlayer::ACT_FIGHTSTAND);
// }
// if (!GetPlayer().IsPlayingAction())
// {
// GetPlayer().PlayAction((int)CECPlayer.PLAYER_ACTION_TYPE.ACT_FIGHTSTAND); // ܶɺ󡢲սվ
// }
//}
public override void Tick(float dwDeltaTime){
GetPlayer().m_FightCnt.IncCounter(dwDeltaTime *1000);
float iRealTime = EC_Game.GetRealTickTime();
if (m_SkillCnt.IncCounter(Time.unscaledDeltaTime * 1000f, out float fCounter, out float fPeriod)){
Finish();
}else{
if (m_idCurSkillTarget != 0){
GetPlayer().TurnFaceTo(m_idCurSkillTarget);
}
if (GetPlayer().IsPlayingMoveAction() && !GetPlayer().IsWorkMoveRunning()){ // ´ÓÒÆ¶¯Ê©·¨µ½Í£Ö¹Òƶ¯¡¢»áÒ»Ö±ÔÚ³ÖÐø²¥·ÅÒÆ¶¯¶¯×÷£¬´Ë´¦ÔÝÍ£
GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_FIGHTSTAND);
}
if (!GetPlayer().IsPlayingAction()){
GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_FIGHTSTAND); // ¼¼Äܶ¯×÷²¥·ÅÍê³Éºó¡¢²¥·ÅÕ½¶·Õ¾Á¢¶¯×÷
}
}
}
public override void Cancel()
{
//TO DO: fix later
//if (m_pCurSkill != null)
//{
// m_pCurSkill = null;
//}
//m_idCurSkillTarget = 0;
//GetPlayer().StopSkillAttackAction();
//GetPlayer().TurnFaceTo(0);
public override void Cancel(){
if (m_pCurSkill != null){
m_pCurSkill = null;
}
m_idCurSkillTarget = 0;
GetPlayer().StopSkillAttackAction();
GetPlayer().TurnFaceTo(0);
}
public CECSkill GetSkill()
{
public CECSkill GetSkill(){
return m_pCurSkill;
}
}
}
public class CECEPWorkMan
@@ -898,4 +893,43 @@ namespace BrewMonster.Scripts
//GetPlayer().StopModelMove(GetPlayer().m_vStopDir, g_vAxisY, 150);
}
};
public class CECEPWorkFlashMove : CECEPWork
{
private A3DVECTOR3 m_vServerPos;
private float m_fMoveSpeed;
public CECEPWorkFlashMove(CECEPWorkMan pWorkMan, A3DVECTOR3 vServerPos, float fMoveSpeed)
: base(CECEPWork.EP_work_ID.WORK_FLASHMOVE, pWorkMan)
{
m_vServerPos = vServerPos;
m_fMoveSpeed = fMoveSpeed;
}
public override void Start()
{
GetPlayer().m_iMoveMode = (int)MoveMode.MOVE_MOVE;
GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_JUMP_START, true, 0);
GetPlayer().PlayAction((int)PLAYER_ACTION_TYPE.ACT_JUMP_LOOP, false, 0, true);
}
public override void Tick(float dwDeltaTime)
{
base.Tick(dwDeltaTime);
A3DVECTOR3 vCurPos = GetPlayer().GetPos();
A3DVECTOR3 vDir = m_vServerPos - vCurPos;
float fDist = vDir.Normalize();
float fMoveDelta = m_fMoveSpeed * dwDeltaTime * 0.001f;
if (fMoveDelta >= fDist)
{
GetPlayer().SetPos(m_vServerPos);
Finish();
}
else
{
vCurPos = vCurPos + vDir * fMoveDelta;
GetPlayer().SetPos(vCurPos);
}
}
public override void Cancel()
{
GetPlayer().SetPos(m_vServerPos);
}
}
}
@@ -111,6 +111,7 @@ namespace BrewMonster
private bool m_bCooling;
private int m_iChargeCnt;
private int m_iChargeMax;
public int ChargeMax => m_iChargeMax;
private bool m_bCharging;
private static CECSkillStr l_SkillStr = new CECSkillStr();
@@ -40,6 +40,13 @@ public class CECCounter
m_dwCounter += dwCounter;
return (m_dwCounter >= m_dwPeriod) ? true : false;
}
public bool IncCounter(float dwCounter, out float fCounter, out float fPeriod)
{
m_dwCounter += dwCounter;
fCounter = m_dwCounter;
fPeriod = m_dwPeriod;
return (m_dwCounter >= m_dwPeriod) ? true : false;
}
// Decrease counter
public void DecCounter(float dwCounter)
+34 -11
View File
@@ -2414,7 +2414,6 @@ namespace BrewMonster
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))
{
@@ -2448,7 +2447,8 @@ namespace BrewMonster
public bool IsHangerOn() { return m_bHangerOn; }
public bool IsPlayingAction()
{
return true /*GetLowerBodyAction() != -1*/ ;
var check = GetLowerBodyAction() != -1 ;
return check;
}
public bool PlaySkillCastActionWithName(int idSkill, string szActName, bool bNoFX/* =false */)
{
@@ -3932,26 +3932,32 @@ namespace BrewMonster
public struct PlayActionEvent
{
public ChannelAct ChannelAct;
public string AnimationName;
public int ITransTime;
public bool IsForceStopPrevious;
public bool IsLoop;
public CECAttackEvent AttackEvent;
public PlayActionEvent(string shapeName, string animationName, int iTransTime, bool isForceStopPrevious = false, CECAttackEvent attackEvent = null, bool isLoop = false)
{
this.AnimationName = shapeName + animationName;
ITransTime = iTransTime;
IsForceStopPrevious = isForceStopPrevious;
AttackEvent = attackEvent;
IsLoop = isLoop;
}
public byte Channel;
public PlayActionEvent(string animationName, int iTransTime, bool isForceStopPrevious = false, CECAttackEvent attackEvent = null, bool isLoop = false)
{
this.ChannelAct = null;
this.AnimationName = animationName;
ITransTime = iTransTime;
IsForceStopPrevious = isForceStopPrevious;
AttackEvent = attackEvent;
IsLoop = isLoop;
Channel = 0;
}
public PlayActionEvent(ref ChannelAct channelAct, string animationName, int iTransTime, bool isForceStopPrevious = false, CECAttackEvent attackEvent = null, bool isLoop = false, byte channel = 0)
{
this.ChannelAct = channelAct;
this.AnimationName = animationName;
ITransTime = iTransTime;
IsForceStopPrevious = isForceStopPrevious;
AttackEvent = attackEvent;
IsLoop = isLoop;
Channel = channel;
}
}
public struct PLAYER_ACTION
@@ -3961,16 +3967,19 @@ namespace BrewMonster
};
public class QueueActionEvent
{
public ChannelAct ChannelAct;
public string AnimationName;
public int ITransTime;
public Action<bool, CECAttackEvent> SetFlag;
public CECAttackEvent AttackEvent;
public bool IsHitAnim;
public bool IsForceStopPrevious;
public bool IsLoop;
public bool IsLoop;
public byte Channel;
public QueueActionEvent(string animationName, Action<bool, CECAttackEvent> setFlag, bool isHitAnim,
CECAttackEvent attackEvent, int iTransTime, bool isForceStopPrevious = false, bool isLoop = false)
{
this.ChannelAct = null;
this.AnimationName = animationName;
SetFlag = setFlag;
IsHitAnim = isHitAnim;
@@ -3978,6 +3987,20 @@ namespace BrewMonster
ITransTime = iTransTime;
IsForceStopPrevious = isForceStopPrevious;
IsLoop = isLoop;
Channel = 0;
}
public QueueActionEvent(ref ChannelAct channelAct, string animationName, Action<bool, CECAttackEvent> setFlag, bool isHitAnim,
CECAttackEvent attackEvent, int iTransTime, bool isForceStopPrevious = false, bool isLoop = false, byte channel = 0)
{
this.ChannelAct = channelAct;
this.AnimationName = animationName;
SetFlag = setFlag;
IsHitAnim = isHitAnim;
AttackEvent = attackEvent;
ITransTime = iTransTime;
IsForceStopPrevious = isForceStopPrevious;
IsLoop = isLoop;
Channel = channel;
}
public void SetData(string shapeName, string animationName, Action<bool, CECAttackEvent> setFlag, bool isHitAnim,
+150 -14
View File
@@ -10,6 +10,7 @@ using CombinedActMap = System.Collections.Generic.Dictionary<string, object>;
using CoGfxMap = System.Collections.Generic.Dictionary<string, object>;
using ConvexHullDataArray = System.Collections.Generic.List<object>;
using ECModelHookMap = System.Collections.Generic.Dictionary<string, object>;
using ActQueue = System.Collections.Generic.List<A3DCombActDynData>;
using BrewMonster;
using BrewMonster.Scripts.ECModel;
using Unity.VisualScripting.FullSerializer;
@@ -45,7 +46,109 @@ public enum ECMScriptVar
enumECMVarSelf,
enumECMVarCount
}
public enum ActionChannel
{
ACTCHA_DEFAULT = 0,
ACTCHA_WOUND = 1,
ACTCHA_MAX = 16, // Keep this value same with A3DSkinModelActionCore::ACTCHA_MAX
};
public class A3DCombActDynData
{
public A3DCombinedAction combinedAction;
public float fTime;
public int nChannel;
public int m_dwUserData;
public void SetUserData(int dwUserData) { m_dwUserData = dwUserData; }
public int GetUserData() { return m_dwUserData; }
}
public class ChannelActNode
{
public byte m_Rank;
public A3DCombActDynData m_pActive;
public bool m_pActFlag;
public int m_dwFlagMode;
public ActQueue m_ActQueue;
public ChannelActNode()
{
m_Rank = 0;
m_pActive = null;
m_pActFlag = false;
m_dwFlagMode = 0;
if(m_ActQueue == null)
{
m_ActQueue = new ActQueue();
}
m_ActQueue.Clear();
}
public void RemoveQueuedActs()
{
m_ActQueue.Clear();
}
}
public class ChannelAct
{
public List<ChannelActNode> m_RankNodes;
public ChannelAct()
{
Release();
}
public void Release()
{
if(m_RankNodes == null)
{
m_RankNodes = new List<ChannelActNode>();
}
m_RankNodes.Clear();
}
public ChannelActNode GetNodeByRank(byte rank)
{
if(m_RankNodes == null || m_RankNodes.Count == 0)
{
return null;
}
foreach(var node in m_RankNodes)
{
if(node.m_Rank == rank)
{
return node;
}
}
return null;
}
public ChannelActNode GetHighestRankNode()
{
if(m_RankNodes == null || m_RankNodes.Count == 0)
{
return null;
}
ChannelActNode highestNode = m_RankNodes[0];
foreach(var node in m_RankNodes)
{
if(node.m_Rank > highestNode.m_Rank)
{
highestNode = node;
}
}
return highestNode;
}
public ChannelActNode RemoveNodeByRank(byte rank)
{
foreach(var node in m_RankNodes)
{
if(node.m_Rank == rank)
{
m_RankNodes.Remove(node);
return node;
}
}
return null;
}
};
public static class CECModelConstants
{
public const int ECM_SCRIPT_MAX_VAR_COUNT = 8;
@@ -382,6 +485,15 @@ public class CECModel
private Transform m_transform;
public bool InheritParentId() => m_bInheritParentId;
public void SetId(int nId) => m_nId = nId;
//16 is
ChannelAct[] m_ChannelActs = InitChannelActs();
private static ChannelAct[] InitChannelActs()
{
var acts = new ChannelAct[(int)ActionChannel.ACTCHA_MAX];
for (int i = 0; i < acts.Length; i++)
acts[i] = new ChannelAct();
return acts;
}
public void ClearComActFlag(bool bSignalCurrent) { ClearComActFlag(0, bSignalCurrent); }
public void ClearComActFlag(int nChannel, bool bSignalCurrent)
{
@@ -671,10 +783,22 @@ public class CECModel
}
var actionInfos = combinedAction.m_ActLst;
var isLoop = combinedAction.m_nLoops == 1;
EventBus.PublishChannel(m_nId, new PlayActionEvent(actionInfos[0].m_strName, nTransTime, bForceStop, attackEvent, isLoop));
var node = m_ChannelActs[nChannel].GetNodeByRank(0);
if (node == null)
{
node = new ChannelActNode { m_Rank = 0 };
m_ChannelActs[nChannel].m_RankNodes.Add(node);
}
node.m_pActive = new A3DCombActDynData
{
combinedAction = combinedAction,
nChannel = nChannel,
m_dwUserData = (int)dwUserData
};
EventBus.PublishChannel(m_nId, new PlayActionEvent(ref m_ChannelActs[nChannel], actionInfos[0].m_strName, nTransTime, bForceStop, attackEvent, isLoop, node.m_Rank));
for(int i = 1; i < actionInfos.Count; i++)
{
EventBus.PublishChannelClass(m_nId, new QueueActionEvent(actionInfos[i].m_strName, null, false, attackEvent, nTransTime, false, isLoop));
EventBus.PublishChannelClass(m_nId, new QueueActionEvent(ref m_ChannelActs[nChannel], actionInfos[i].m_strName, null, false, attackEvent, nTransTime, false, isLoop, node.m_Rank));
}
var eventInfoList = combinedAction.m_EventInfoLst;
if(eventInfoList != null && eventInfoList.Count > 0)
@@ -715,25 +839,42 @@ public class CECModel
return false;
}
A3DCombinedAction combinedAction = GetComActByName(szActName);
if(combinedAction == null)
if(combinedAction == null)
{
return false;
}
var actionInfos = combinedAction.m_ActLst;
var isLoop = combinedAction.m_nLoops == 1;
EventBus.PublishChannelClass(m_nId, new QueueActionEvent(actionInfos[0].m_strName, null, false, attackEvent, nTransTime, bForceStopPrevAct, isLoop));
var node = new ChannelActNode { m_Rank = (byte)m_ChannelActs[nChannel].m_RankNodes.Count};
m_ChannelActs[nChannel].m_RankNodes.Add(node);
node.m_pActive = new A3DCombActDynData
{
// combinedAction = combinedAction, // not needed now
nChannel = nChannel,
m_dwUserData = (int)dwUserData
};
EventBus.PublishChannelClass(m_nId, new QueueActionEvent(ref m_ChannelActs[nChannel], actionInfos[0].m_strName, null, false, attackEvent, nTransTime, bForceStopPrevAct, isLoop, node.m_Rank));
for(int i = 1; i < actionInfos.Count; i++)
{
EventBus.PublishChannelClass(m_nId, new QueueActionEvent(actionInfos[i].m_strName, null, false, attackEvent, nTransTime, false, isLoop));
EventBus.PublishChannelClass(m_nId, new QueueActionEvent(ref m_ChannelActs[nChannel], actionInfos[i].m_strName, null, false, attackEvent, nTransTime, false, isLoop, node.m_Rank));
}
return true;
}
public bool ClearComActFlagAllRankNodes(bool bSignalCurrent){
EventBus.PublishChannel(m_nId, new ClearComActFlagAllRankNodesEvent(bSignalCurrent));
public bool ClearComActFlagAllRankNodes(bool bSignalCurrent)
{
foreach (var ca in m_ChannelActs)
ca?.Release();
//EventBus.PublishChannel(m_nId, new ClearComActFlagAllRankNodesEvent(bSignalCurrent));
return false;
}
public uint GetCurActionUserData(){
return 0;
public int GetCurActionUserData()
{
var returnValue = -1;
if (m_ChannelActs[0].GetHighestRankNode() != null)
returnValue = m_ChannelActs[0].GetHighestRankNode().m_pActive.GetUserData();
return returnValue;
}
public bool QueueAction(CECNPC.INFO iNFO, string szActName, ref bool pNewActFlag, int nTransTime = 200, uint dwUserData = 0, bool bForceStopPrevAct = false, bool bCheckTailDup = false, bool bNoFx = false, bool bResetSpeed = false
/*joslian*/, bool bResetActFlag = false, uint dwNewFlagMode = COMACT_FLAG_MODE_NONE)
@@ -845,8 +986,3 @@ public class CECModel
// m_CoGfxMap[strKey] = pInfo;
}
}
// Action channel
public enum ActionChannel
{
ACTCHA_WOUND = 1,
};
@@ -450,13 +450,14 @@ namespace BrewMonster
}
public override bool IsPlayingMoveAction(){
if (GetModel()!=null){
return IsMoveAction((int)GetModel().GetCurActionUserData());
var userData = GetModel().GetCurActionUserData();
return IsMoveAction((int)userData);
}
return false;
}
public override int GetLowerBodyAction(){
if (GetModel()!=null){
return (int)GetModel().GetCurActionUserData();
return GetModel().GetCurActionUserData();
}
return -1;
}
@@ -672,80 +672,70 @@ namespace BrewMonster
// Get skill object (else players don't have skill lists, so we create a temporary skill reference)
// For else players, we mainly need the skill ID for animation purposes
int skillID = pCmd.skill;
if ((m_pCurSkill = new CECSkill(pCmd.skill, pCmd.level)) == null)
{
BMLogger.LogError($"OnMsgPlayerCastSkill: Failed to create CECSkill for skillID={pCmd.skill}, level={pCmd.level}");
return;
}
// Store current skill target
m_idCurSkillTarget = pCmd.target;
// Face the target
TurnFaceTo(pCmd.target);
uint dwPeriod = (uint)(pCmd.time + m_pCurSkill.GetExecuteTime()) * 10;
m_pEPWorkMan.StartNormalWork(new CECEPWorkSpell(m_pEPWorkMan, dwPeriod, new CECSkill(pCmd.skill, pCmd.level), pCmd.target));
PlaySkillCastAction(m_pCurSkill.GetSkillID());
// // Face the target
// TurnFaceTo(pCmd.target);
// Play skill cast animation
PlaySkillCastAction(skillID);
// // Play skill cast animation
// PlaySkillCastAction(skillID);
// Create a temporary skill object for tracking (if needed)
// Note: Else players don't maintain skill lists like host player does
// We create a minimal skill object just for the current cast
if (m_pCurSkill == null || m_pCurSkill.GetSkillID() != skillID)
{
// Create a temporary skill object with level 1 (we don't know the actual level)
m_pCurSkill = new CECSkill(skillID, 1);
}
// // Create a temporary skill object for tracking (if needed)
// // Note: Else players don't maintain skill lists like host player does
// // We create a minimal skill object just for the current cast
// if (m_pCurSkill == null || m_pCurSkill.GetSkillID() != skillID)
// {
// // Create a temporary skill object with level 1 (we don't know the actual level)
// m_pCurSkill = new CECSkill(skillID, 1);
// }
// Enter fight state
EnterFightState();
// // Enter fight state
// EnterFightState();
break;
}
case CommandID.OBJECT_CAST_INSTANT_SKILL:
{
StopCurPosWork();
ClearCastingSkill();
m_pEPWorkMan.FinishWork(CECEPWork.EP_work_ID.WORK_SPELL);
cmd_object_cast_instant_skill pCmd =
GPDataTypeHelper.FromBytes<cmd_object_cast_instant_skill>((byte[])Msg.dwParam1);
int skillID = pCmd.skill;
m_idCurSkillTarget = pCmd.target;
TurnFaceTo(pCmd.target);
PlaySkillCastAction(skillID);
if (m_pCurSkill == null || m_pCurSkill.GetSkillID() != skillID)
{
m_pCurSkill = new CECSkill(skillID, 1);
}
EnterFightState();
PlaySkillCastAction(pCmd.skill);
break;
}
case CommandID.OBJECT_CAST_POS_SKILL:
{
StopCurPosWork();
ClearCastingSkill();
m_pEPWorkMan.FinishWork(CECEPWork.EP_work_ID.WORK_SPELL);
cmd_object_cast_pos_skill pCmd =
GPDataTypeHelper.FromBytes<cmd_object_cast_pos_skill>((byte[])Msg.dwParam1);
int skillID = pCmd.skill;
SetServerPos(pCmd.pos);
// For position-based skills, target is the position, not an object
// We still play the cast animation
PlaySkillCastAction(skillID);
if (m_pCurSkill == null || m_pCurSkill.GetSkillID() != skillID)
float fDist = A3d_Magnitude(pCmd.pos - GetPos());
if (fDist <= 0.0001f)
{
m_pCurSkill = new CECSkill(skillID, 1);
}
EnterFightState();
break;
}
case CommandID.SKILL_PERFORM:
{
// Skill perform - the skill has finished casting and is being executed
// For else players, we keep m_pCurSkill until attack result is received
// This allows PlayAttackEffect to use the skill information
// Durative skills (channeling) will continue until interrupted
if (m_pCurSkill != null && m_pCurSkill.IsDurative())
{
// For durative skills, we keep the skill active
// It will be cleared when SKILL_INTERRUPTED is received
SetPos(pCmd.pos);
return;
}
int nExecuteTime = ElementSkill.GetExecuteTime((uint)pCmd.skill, pCmd.level);
nExecuteTime = Mathf.Max(nExecuteTime, 50);
m_fMoveSpeed = 1.3f * fDist * 1000.0f / nExecuteTime;
m_pEPWorkMan.StartNormalWork(new CECEPWorkFlashMove(m_pEPWorkMan, pCmd.pos, m_fMoveSpeed));
break;
}
case CommandID.SKILL_INTERRUPTED:
@@ -753,13 +743,10 @@ namespace BrewMonster
// Skill was interrupted, clear current skill
cmd_skill_interrupted pCmd =
GPDataTypeHelper.FromBytes<cmd_skill_interrupted>((byte[])Msg.dwParam1);
if (m_pCurSkill != null)
{
StopSkillCastAction();
m_pCurSkill = null;
}
m_idCurSkillTarget = 0;
ClearComActFlagAllRankNodes(false);
ClearCastingSkill();
m_pEPWorkMan.FinishWork(CECEPWork.EP_work_ID.WORK_SPELL);
StopSkillCastAction();
break;
}
default:
@@ -768,7 +755,25 @@ namespace BrewMonster
}
}
}
private void ClearCastingSkill(){
if (m_pCurSkill != null){
m_pCurSkill = null;
}
m_idCurSkillTarget = 0;
}
private void StopCurPosWork()
{
if (m_pEPWorkMan.IsWorkRunning(CECEPWork.EP_work_ID.WORK_MOVE)){
m_pEPWorkMan.FinishRunningWork(CECEPWork.EP_work_ID.WORK_MOVE);
}
if (m_pEPWorkMan.IsWorkRunning(CECEPWork.EP_work_ID.WORK_PASSIVEMOVE)){
m_pEPWorkMan.FinishRunningWork(CECEPWork.EP_work_ID.WORK_PASSIVEMOVE);
}
if (m_pEPWorkMan.IsWorkRunning(CECEPWork.EP_work_ID.WORK_FLASHMOVE)){
m_pEPWorkMan.FinishRunningWork(CECEPWork.EP_work_ID.WORK_FLASHMOVE);
}
}
private async void LoadAppearGfx()
{
if (!m_pAppearGFX && m_iAppearFlag == (int)PlayerAppearFlag.APPEAR_ENTERWORLD)
@@ -196,6 +196,15 @@ namespace BrewMonster.Scripts.Skills
// ȴʱλ
public virtual int GetCoolingTime() { return 5000; }
// ִʱλ
public static int GetExecuteTime(uint id, int level)
{
Skill s = Skill.Create(id, level);
if (s == null)
return 0;
int ret = s.GetExecuteTime();
return ret;
}
public virtual int GetExecuteTime() { return 1000; }
// Ŀ, 0:Ŀ꣬1:ҪĿ꣬2:Ŀ?, 3:Ŀ?, 4:Ŀ?
public virtual int GetTargetType() { return 0; }
+15 -11
View File
@@ -14,6 +14,8 @@ namespace BrewMonster
public int ITransTime;
public CECAttackEvent AttackEvent;
public bool IsLoop;
public ChannelAct ChannelAct;
public byte Channel;
}
public class PlayerVisual : MonoBehaviour
{
@@ -48,14 +50,16 @@ namespace BrewMonster
{
AnimationName = @event.AnimationName,
IsForceStopPrevious = @event.IsForceStopPrevious,
AttackEvent = @event.AttackEvent
AttackEvent = @event.AttackEvent,
ChannelAct = @event.ChannelAct,
Channel = @event.Channel
});
_animationList = _animationQueue.Select(q => q.AnimationName).ToList();
return;
}
previousAnimationName = @event.AnimationName;
InternalPlayAnimation(@event.AnimationName, @event.ITransTime, FadeMode, @event.IsLoop);
ApplyAttackSignalOnAnimationEnd(@event.AttackEvent);
ApplyAnimationEndCallbacks(@event.AttackEvent, @event.ChannelAct, @event.Channel);
}
public void InitPlayerEventDoneHandler()
{
@@ -156,7 +160,9 @@ namespace BrewMonster
IsForceStopPrevious = @event.IsForceStopPrevious,
ITransTime = @event.ITransTime,
AttackEvent = @event.AttackEvent,
IsLoop = @event.IsLoop
IsLoop = @event.IsLoop,
ChannelAct = @event.ChannelAct,
Channel = @event.Channel
});
_animationList = _animationQueue.Select(q => q.AnimationName).ToList();
if (!isHit)
@@ -222,18 +228,16 @@ namespace BrewMonster
_animationList = _animationQueue.Select(q => q.AnimationName).ToList();
previousAnimationName = animationQueue.AnimationName;
InternalPlayAnimation(animationQueue.AnimationName, animationQueue.ITransTime, FadeMode, animationQueue.IsLoop);
ApplyAttackSignalOnAnimationEnd(animationQueue.AttackEvent);
ApplyAnimationEndCallbacks(animationQueue.AttackEvent, animationQueue.ChannelAct, animationQueue.Channel);
}
private void ApplyAttackSignalOnAnimationEnd(CECAttackEvent attackEvent)
{
if (attackEvent == null || _currentState == null)
{
return;
}
private void ApplyAnimationEndCallbacks(CECAttackEvent attackEvent, ChannelAct channelAct, byte channel)
{
if (_currentState == null) return;
_currentState.Events.OnEnd = () =>
{
attackEvent.m_bSignaled = true;
if (attackEvent != null)
attackEvent.m_bSignaled = true;
};
}
void ApplyDamage()