|
|
|
@@ -13,6 +13,7 @@ using ECModelHookMap = System.Collections.Generic.Dictionary<string, object>;
|
|
|
|
|
using ActQueue = System.Collections.Generic.List<A3DCombActDynData>;
|
|
|
|
|
using BrewMonster;
|
|
|
|
|
using BrewMonster.Scripts.ECModel;
|
|
|
|
|
using Cysharp.Threading.Tasks;
|
|
|
|
|
using Unity.VisualScripting.FullSerializer;
|
|
|
|
|
public enum ECMScript
|
|
|
|
|
{
|
|
|
|
@@ -54,13 +55,243 @@ public enum ActionChannel
|
|
|
|
|
};
|
|
|
|
|
public class A3DCombActDynData
|
|
|
|
|
{
|
|
|
|
|
public A3DCombinedAction combinedAction;
|
|
|
|
|
public int nChannel;
|
|
|
|
|
public int m_dwUserData;
|
|
|
|
|
public bool IsAllActionFinished => m_EventNames.Count == 0;
|
|
|
|
|
public List<string> m_EventNames = new List<string>();
|
|
|
|
|
protected A3DCombinedAction m_pAct;
|
|
|
|
|
protected CECModel m_pECModel;
|
|
|
|
|
protected int m_dwTimeSpan;
|
|
|
|
|
protected float m_fWeight;
|
|
|
|
|
protected int m_nTransTime;
|
|
|
|
|
protected int m_dwUserData;
|
|
|
|
|
protected bool m_bAbsTrack;
|
|
|
|
|
protected bool m_bNoFx;
|
|
|
|
|
//ALISTPOSITION m_CurEventPos;
|
|
|
|
|
//const ChildActInfo* m_pParentInfo;
|
|
|
|
|
//CECModel* m_pParentModel;
|
|
|
|
|
protected int m_dwDeltaTime;
|
|
|
|
|
protected bool m_bStopPrevAct;
|
|
|
|
|
//important
|
|
|
|
|
//FxBindBaseList m_ActFxArray;
|
|
|
|
|
protected int m_nChannel;
|
|
|
|
|
|
|
|
|
|
protected int m_dwEventMask;
|
|
|
|
|
//ActDynArray m_arrActLoopNum;
|
|
|
|
|
protected int m_nCurActIndex;
|
|
|
|
|
protected int m_dwDynComActSpan;
|
|
|
|
|
protected bool m_bIsInfiniteComAct;
|
|
|
|
|
|
|
|
|
|
//important
|
|
|
|
|
//EventInfoMap m_mapDynAddedInfo;
|
|
|
|
|
|
|
|
|
|
/// <summary>Attack event tied to this combined action, if any. / 与此组合动作绑定的攻击事件(若有)
|
|
|
|
|
/// this is alternative for m_IdCaster to m_IsAttackAct in c++
|
|
|
|
|
/// </summary>
|
|
|
|
|
public CECAttackEvent ActiveAttackEvent;
|
|
|
|
|
|
|
|
|
|
public bool m_bResetPSWhenActionStop;
|
|
|
|
|
public bool m_bSetSpeedWhenActStart;
|
|
|
|
|
public float m_fModelScale;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public List<string> m_ActionNames = new List<string>();
|
|
|
|
|
public List<string> m_SFXNames = new List<string>();
|
|
|
|
|
public bool IsActionStopped() { return m_ActionNames.Count == 0; }
|
|
|
|
|
/// <summary>True when there is no attack or damage has been applied. / 无攻击事件或已造成伤害则为 true</summary>
|
|
|
|
|
public bool IsAllEventFinished() { return (ActiveAttackEvent == null || ActiveAttackEvent.m_bDoDamaged); }
|
|
|
|
|
/// <summary>Animations finished and attack-event phase finished. / 动画与攻击事件阶段均结束</summary>
|
|
|
|
|
public bool IsAllFinished()
|
|
|
|
|
{
|
|
|
|
|
if(IsActionStopped() && IsAllEventFinished())
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
public A3DCombActDynData(A3DCombinedAction pAct, CECModel pECModel, CECAttackEvent attackEvent)
|
|
|
|
|
{
|
|
|
|
|
m_pAct = pAct;
|
|
|
|
|
m_pECModel = pECModel;
|
|
|
|
|
// m_nCurLoop = 0;
|
|
|
|
|
// m_nCurActLoop = 0;
|
|
|
|
|
m_dwTimeSpan = 0;
|
|
|
|
|
m_fWeight = 1.0f;
|
|
|
|
|
m_nTransTime = 200;
|
|
|
|
|
m_dwUserData = 0;
|
|
|
|
|
m_bAbsTrack = false;
|
|
|
|
|
m_bNoFx = false;
|
|
|
|
|
// m_CurEventPos = 0;
|
|
|
|
|
// m_pParentInfo = 0;
|
|
|
|
|
// m_pParentModel = 0;
|
|
|
|
|
m_bStopPrevAct = false;
|
|
|
|
|
m_dwDeltaTime = 0;
|
|
|
|
|
m_nChannel = 0;
|
|
|
|
|
m_dwEventMask = -1;
|
|
|
|
|
//use active attack event instead of idCaster to m_IsAttackAct
|
|
|
|
|
ActiveAttackEvent = attackEvent;
|
|
|
|
|
// m_idCaster = 0;
|
|
|
|
|
// m_idCastTarget = 0;
|
|
|
|
|
// m_ptFixed = 0;
|
|
|
|
|
// m_SerialId = 0;
|
|
|
|
|
// m_IsAttackAct = false;
|
|
|
|
|
m_nCurActIndex = -1;
|
|
|
|
|
m_dwDynComActSpan = 0;
|
|
|
|
|
m_bIsInfiniteComAct = false;
|
|
|
|
|
m_bResetPSWhenActionStop = false;
|
|
|
|
|
m_bSetSpeedWhenActStart = false;
|
|
|
|
|
m_fModelScale = 1.0f;
|
|
|
|
|
var actInfoList = pAct.m_ActLst;
|
|
|
|
|
// {
|
|
|
|
|
// ActInfoList& actInfoList = pAct->m_ActLst;
|
|
|
|
|
// ALISTPOSITION pos = actInfoList.GetHeadPosition();
|
|
|
|
|
// while (pos)
|
|
|
|
|
// {
|
|
|
|
|
// PACTION_INFO pAct = actInfoList.GetNext(pos);
|
|
|
|
|
// int nDynLoopNum = pAct->CalcLoopNum();
|
|
|
|
|
// m_arrActLoopNum.Add(ACTIONDYN_DATA(nDynLoopNum, pAct));
|
|
|
|
|
// if (!m_bIsInfiniteComAct && nDynLoopNum < 0) m_bIsInfiniteComAct = true;
|
|
|
|
|
// }
|
|
|
|
|
// CalcDynComActSpan();
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <param name="triggerVisualAndFx">
|
|
|
|
|
/// When true, publishes <see cref="PlayActionEvent"/> for Animancer, tracks <see cref="m_EventNames"/>,
|
|
|
|
|
/// and plays combined-action sound FX from data (unless <paramref name="bNoFx"/> suppresses audio).
|
|
|
|
|
/// / 为 true 时发布 PlayActionEvent、维护 m_EventNames,并按数据播放组合动作音效(bNoFx 时跳过音效)。
|
|
|
|
|
/// </param>
|
|
|
|
|
public void Play(int nChannel, float fWeight, int nTransTime, int dwEventMask, bool bRestart, bool bAbsTrack, bool bNoFx,
|
|
|
|
|
bool bForceStopPrevious = false, byte channelRank = 0)
|
|
|
|
|
{
|
|
|
|
|
m_nChannel = nChannel;
|
|
|
|
|
m_fWeight = fWeight;
|
|
|
|
|
m_nTransTime = nTransTime;
|
|
|
|
|
m_dwEventMask = dwEventMask;
|
|
|
|
|
m_bAbsTrack = bAbsTrack;
|
|
|
|
|
m_bNoFx = bNoFx;
|
|
|
|
|
|
|
|
|
|
// if (bRestart)
|
|
|
|
|
// m_nCurLoop = 0;
|
|
|
|
|
|
|
|
|
|
m_fModelScale = 1; //Vm_pECModel.GetAllRootBonesScale();
|
|
|
|
|
|
|
|
|
|
PublishVisual(bForceStopPrevious, channelRank);
|
|
|
|
|
if (!m_bNoFx)
|
|
|
|
|
TriggerSFxFromEventList();
|
|
|
|
|
// Resume();
|
|
|
|
|
// UpdateAct(0);
|
|
|
|
|
// #ifdef _ANGELICA21
|
|
|
|
|
// UpdateEvent(0, 0);
|
|
|
|
|
// #endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Notify visual layer and fire combined-action audio using data on this instance.
|
|
|
|
|
/// / 通知表现层并根据本实例数据触发组合动作音效。
|
|
|
|
|
/// </summary>
|
|
|
|
|
void PublishVisual(bool bForceStopPrevious, byte channelRank)
|
|
|
|
|
{
|
|
|
|
|
if (m_pECModel == null || m_pAct == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
var actionInfos = m_pAct.m_ActLst;
|
|
|
|
|
if (actionInfos != null && actionInfos.Count > 0 && !string.IsNullOrEmpty(actionInfos[0].m_strName))
|
|
|
|
|
{
|
|
|
|
|
ChannelAct channelAct = m_pECModel.GetChannelAct(m_nChannel);
|
|
|
|
|
if (channelAct != null)
|
|
|
|
|
{
|
|
|
|
|
bool isLoop = m_pAct.m_nLoops == 1;
|
|
|
|
|
int ownerId = m_pECModel.GetId();
|
|
|
|
|
EventBus.PublishChannel(ownerId, new PlayActionEvent(ref channelAct, actionInfos[0].m_strName, m_nTransTime, bForceStopPrevious, ActiveAttackEvent, isLoop, channelRank));
|
|
|
|
|
m_ActionNames.Add(actionInfos[0].m_strName);
|
|
|
|
|
for(int i = 1; i < actionInfos.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
EventBus.PublishChannelClass(ownerId, new QueueActionEvent(ref channelAct, actionInfos[i].m_strName, null, false, null, m_nTransTime, false, isLoop, channelRank));
|
|
|
|
|
m_ActionNames.Add(actionInfos[i].m_strName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sound events embedded in combined action; skip gfx paths. / 组合动作内嵌音效事件;跳过 gfx 路径。
|
|
|
|
|
/// </summary>
|
|
|
|
|
void TriggerSFxFromEventList()
|
|
|
|
|
{
|
|
|
|
|
if (m_bNoFx || m_pAct == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
var eventInfoList = m_pAct.m_EventInfoLst;
|
|
|
|
|
if (eventInfoList == null || eventInfoList.Count == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
foreach (var eventInfo in eventInfoList)
|
|
|
|
|
{
|
|
|
|
|
if (eventInfo is FX_BASE_INFO sfx)
|
|
|
|
|
{
|
|
|
|
|
if (sfx.m_strFilePaths != null && sfx.m_strFilePaths.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
string soundpath = AFile.NormalizePath(sfx.m_strFilePaths[0], true);
|
|
|
|
|
if (soundpath.Contains("gfx"))
|
|
|
|
|
continue;
|
|
|
|
|
soundpath = soundpath.ToLower();
|
|
|
|
|
m_SFXNames.Add(soundpath);
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
SFXManager.Instance
|
|
|
|
|
.PlaySkillSfxAtPointAsync(soundpath, Vector3.zero).Forget();
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
// remove AFTER sound finished
|
|
|
|
|
m_SFXNames.Remove(soundpath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public void Stop(bool bStopAct, bool bForceStopFx = false )
|
|
|
|
|
{
|
|
|
|
|
// FlushDamageInfo();
|
|
|
|
|
|
|
|
|
|
// ClearParentInfo();
|
|
|
|
|
// m_nCurLoop = 0;
|
|
|
|
|
// m_nCurActLoop = 0;
|
|
|
|
|
|
|
|
|
|
// RemoveAllActiveFx(bForceStopFx);
|
|
|
|
|
// A3DSkinModel* pSkinModel = m_pECModel->GetA3DSkinModel();
|
|
|
|
|
|
|
|
|
|
// m_pECModel->GetStaticData()->OnScriptEndAction(m_pECModel, m_nChannel, m_pAct->GetName());
|
|
|
|
|
|
|
|
|
|
// if (IsResetPSWhenActStop())
|
|
|
|
|
// {
|
|
|
|
|
// m_pECModel->RemoveReplaceShader();
|
|
|
|
|
// SetResetPSWhenActStop(false);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// if (m_pAct->GetResetMaterialScale())
|
|
|
|
|
// m_pECModel->ResetMaterialScale();
|
|
|
|
|
|
|
|
|
|
// if (m_pAct->GetStopChildrenAct())
|
|
|
|
|
// m_pECModel->StopChildrenAct();
|
|
|
|
|
|
|
|
|
|
// if (pSkinModel == NULL || !bStopAct)
|
|
|
|
|
// return;
|
|
|
|
|
|
|
|
|
|
// A3DSMActionChannel* pChannel = pSkinModel->GetActionChannel(m_nChannel);
|
|
|
|
|
|
|
|
|
|
// if (pChannel)
|
|
|
|
|
// pChannel->StopAction(m_pAct->GetRank(m_nChannel));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetUserData(int dwUserData) { m_dwUserData = dwUserData; }
|
|
|
|
|
public void SetTransTime(int nTransTime) { m_nTransTime = nTransTime; }
|
|
|
|
|
public void SetStopPrevAct(bool bStopPrevAct) { m_bStopPrevAct = bStopPrevAct; }
|
|
|
|
|
public void SetNoFxFlag(bool bNoFx) { m_bNoFx = bNoFx; }
|
|
|
|
|
public void SetSpeedWhenActStart(bool bResetSpeed) { m_bSetSpeedWhenActStart = bResetSpeed; }
|
|
|
|
|
public bool GetStopPrevAct() { return m_bStopPrevAct; }
|
|
|
|
|
public int GetUserData() { return m_dwUserData; }
|
|
|
|
|
public int GetTransTime() { return m_nTransTime; }
|
|
|
|
|
public bool GetNoFxFlag() { return m_bNoFx; }
|
|
|
|
|
public bool IsSetSpeedWhenActStart() { return m_bSetSpeedWhenActStart; }
|
|
|
|
|
public A3DCombinedAction GetComAct() { return m_pAct; }
|
|
|
|
|
}
|
|
|
|
|
public class ChannelActNode
|
|
|
|
|
{
|
|
|
|
@@ -68,22 +299,22 @@ public class ChannelActNode
|
|
|
|
|
public A3DCombActDynData m_pActive;
|
|
|
|
|
public bool m_pActFlag;
|
|
|
|
|
public int m_dwFlagMode;
|
|
|
|
|
public ActQueue m_ActQueue;
|
|
|
|
|
public ActQueue m_QueuedActs;
|
|
|
|
|
public ChannelActNode()
|
|
|
|
|
{
|
|
|
|
|
m_Rank = 0;
|
|
|
|
|
m_pActive = null;
|
|
|
|
|
m_pActFlag = false;
|
|
|
|
|
m_dwFlagMode = 0;
|
|
|
|
|
if(m_ActQueue == null)
|
|
|
|
|
if(m_QueuedActs == null)
|
|
|
|
|
{
|
|
|
|
|
m_ActQueue = new ActQueue();
|
|
|
|
|
m_QueuedActs = new ActQueue();
|
|
|
|
|
}
|
|
|
|
|
m_ActQueue.Clear();
|
|
|
|
|
m_QueuedActs.Clear();
|
|
|
|
|
}
|
|
|
|
|
public void RemoveQueuedActs()
|
|
|
|
|
{
|
|
|
|
|
m_ActQueue.Clear();
|
|
|
|
|
m_QueuedActs.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public class ChannelAct
|
|
|
|
@@ -478,14 +709,27 @@ public class CECModel
|
|
|
|
|
private int m_nId = 0;
|
|
|
|
|
public GameObject m_pPlayerModel;
|
|
|
|
|
private const uint COMACT_FLAG_MODE_NONE = 0;
|
|
|
|
|
private const uint COMACT_FLAG_MODE_ONCE_IGNOREGFX = 2;
|
|
|
|
|
private const uint COMACT_FLAG_MODE_ONCE_MULTIIGNOREGFX = 3;
|
|
|
|
|
protected CECModelStaticData m_pMapModel = new CECModelStaticData();
|
|
|
|
|
public SkeletonBuilder m_skeletonBuilder;
|
|
|
|
|
private Dictionary<string, Transform> m_hookCache = new Dictionary<string, Transform>();
|
|
|
|
|
private Dictionary<string, Transform> m_hangerPositionCache = new Dictionary<string, Transform>();
|
|
|
|
|
private Dictionary<string, CECModel> m_childModels = new Dictionary<string, CECModel>();
|
|
|
|
|
private Transform m_transform;
|
|
|
|
|
private bool m_bAbsTrack = false;
|
|
|
|
|
public bool InheritParentId() => m_bInheritParentId;
|
|
|
|
|
public void SetId(int nId) => m_nId = nId;
|
|
|
|
|
public int GetId() => m_nId;
|
|
|
|
|
|
|
|
|
|
/// <summary>Channel playback container for combined actions. / 组合动作通道容器。</summary>
|
|
|
|
|
public ChannelAct GetChannelAct(int nChannel)
|
|
|
|
|
{
|
|
|
|
|
if (nChannel < 0 || nChannel >= m_ChannelActs.Length)
|
|
|
|
|
return null;
|
|
|
|
|
return m_ChannelActs[nChannel];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//16 is
|
|
|
|
|
ChannelAct[] m_ChannelActs = InitChannelActs();
|
|
|
|
|
private static ChannelAct[] InitChannelActs()
|
|
|
|
@@ -783,54 +1027,19 @@ public class CECModel
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
var actionInfos = combinedAction.m_ActLst;
|
|
|
|
|
var isLoop = combinedAction.m_nLoops == 1;
|
|
|
|
|
var node = m_ChannelActs[nChannel].GetNodeByRank(0);
|
|
|
|
|
if (node == null)
|
|
|
|
|
var pNode = m_ChannelActs[nChannel].GetNodeByRank(0);
|
|
|
|
|
if (pNode == null)
|
|
|
|
|
{
|
|
|
|
|
node = new ChannelActNode { m_Rank = 0 };
|
|
|
|
|
m_ChannelActs[nChannel].m_RankNodes.Add(node);
|
|
|
|
|
}
|
|
|
|
|
var actData = 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));
|
|
|
|
|
actData.m_EventNames.Add(actionInfos[0].m_strName);
|
|
|
|
|
|
|
|
|
|
for(int i = 1; i < actionInfos.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
EventBus.PublishChannelClass(m_nId, new QueueActionEvent(ref m_ChannelActs[nChannel], actionInfos[i].m_strName, null, false, attackEvent, nTransTime, false, isLoop, node.m_Rank));
|
|
|
|
|
actData.m_EventNames.Add(actionInfos[i].m_strName);
|
|
|
|
|
pNode = new ChannelActNode { m_Rank = 0 };
|
|
|
|
|
m_ChannelActs[nChannel].m_RankNodes.Add(pNode);
|
|
|
|
|
}
|
|
|
|
|
pNode.m_pActive = new A3DCombActDynData(combinedAction, this, attackEvent);
|
|
|
|
|
pNode.m_pActive.SetUserData((int)dwUserData);
|
|
|
|
|
pNode.m_pActive.Play(nChannel, fWeight, nTransTime, 0, bRestart, m_bAbsTrack, bNoFx, bForceStop,pNode.m_Rank);
|
|
|
|
|
m_bAbsTrack = false;
|
|
|
|
|
pNode.m_pActFlag = false;
|
|
|
|
|
pNode.m_dwFlagMode = 2;//COMACT_FLAG_MODE_ONCE_IGNOREGFX;
|
|
|
|
|
|
|
|
|
|
node.m_pActive = actData;
|
|
|
|
|
|
|
|
|
|
//Todo: should move those event logic to channel act because their control the animation life span.
|
|
|
|
|
var eventInfoList = combinedAction.m_EventInfoLst;
|
|
|
|
|
if(eventInfoList != null && eventInfoList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
foreach(var eventInfo in eventInfoList)
|
|
|
|
|
{
|
|
|
|
|
//0 is sound event
|
|
|
|
|
if (eventInfo is FX_BASE_INFO sfx)
|
|
|
|
|
{
|
|
|
|
|
if(sfx.m_strFilePaths != null && sfx.m_strFilePaths.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
string soundpath = AFile.NormalizePath(sfx.m_strFilePaths[0],true);
|
|
|
|
|
//we need to determine sfx and gfx. now we dont have logic for this path
|
|
|
|
|
if(soundpath.Contains("gfx"))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
soundpath = soundpath.ToLower();
|
|
|
|
|
SFXManager.Instance.PlaySkillSfxAtPointAsync(soundpath, Vector3.zero).Forget();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
public A3DCombinedAction GetComActByName(string szActName)
|
|
|
|
@@ -847,28 +1056,28 @@ public class CECModel
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
A3DCombinedAction combinedAction = GetComActByName(szActName);
|
|
|
|
|
if(combinedAction == null)
|
|
|
|
|
{
|
|
|
|
|
A3DCombinedAction pComAct = GetComActByName(szActName);
|
|
|
|
|
|
|
|
|
|
if (pComAct == null)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
var actionInfos = combinedAction.m_ActLst;
|
|
|
|
|
var isLoop = combinedAction.m_nLoops == 1;
|
|
|
|
|
var node = new ChannelActNode { m_Rank = (byte)m_ChannelActs[nChannel].m_RankNodes.Count};
|
|
|
|
|
m_ChannelActs[nChannel].m_RankNodes.Add(node);
|
|
|
|
|
var actData = 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(ref m_ChannelActs[nChannel], actionInfos[i].m_strName, null, false, attackEvent, nTransTime, false, isLoop, node.m_Rank));
|
|
|
|
|
actData.m_EventNames.Add(actionInfos[i].m_strName);
|
|
|
|
|
}
|
|
|
|
|
node.m_pActive = actData;
|
|
|
|
|
|
|
|
|
|
ChannelAct ca = m_ChannelActs[nChannel];
|
|
|
|
|
ChannelActNode pNode = ca.GetNodeByRank(0);
|
|
|
|
|
|
|
|
|
|
A3DCombActDynData pDynData = new A3DCombActDynData(pComAct, this, attackEvent);
|
|
|
|
|
pDynData.SetUserData((int)dwUserData);
|
|
|
|
|
pDynData.SetTransTime(nTransTime);
|
|
|
|
|
pDynData.SetStopPrevAct(bForceStopPrevAct);
|
|
|
|
|
pDynData.SetNoFxFlag(bNoFx);
|
|
|
|
|
pDynData.SetSpeedWhenActStart(bResetSpeed);
|
|
|
|
|
pNode.m_QueuedActs.Add(pDynData);
|
|
|
|
|
|
|
|
|
|
// 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(ref m_ChannelActs[nChannel], actionInfos[i].m_strName, null, false, attackEvent, nTransTime, false, isLoop, node.m_Rank));
|
|
|
|
|
// actData.m_EventNames.Add(actionInfos[i].m_strName);
|
|
|
|
|
// }
|
|
|
|
|
//todo: should add sfx and gfx logic to channel act. currently we dont have logic for queue action. only available for play action.
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@@ -880,11 +1089,12 @@ public class CECModel
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int GetCurActionUserData()
|
|
|
|
|
public int GetCurActionUserData(int channel = 0)
|
|
|
|
|
{
|
|
|
|
|
var returnValue = -1;
|
|
|
|
|
if (m_ChannelActs[0].GetHighestRankNode() != null)
|
|
|
|
|
returnValue = m_ChannelActs[0].GetHighestRankNode().m_pActive.GetUserData();
|
|
|
|
|
var nodeCh0 = m_ChannelActs[channel].GetHighestRankNode();
|
|
|
|
|
if (nodeCh0 != null)
|
|
|
|
|
returnValue = nodeCh0.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
|
|
|
|
@@ -911,6 +1121,85 @@ public class CECModel
|
|
|
|
|
AnimationName = animationName;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public bool Tick(uint dwDeltaTime)
|
|
|
|
|
{
|
|
|
|
|
UpdateChannelActs(dwDeltaTime);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
void UpdateChannelActs(uint dwUpdateTime)
|
|
|
|
|
{
|
|
|
|
|
if (dwUpdateTime == 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < (int)ActionChannel.ACTCHA_MAX; i++)
|
|
|
|
|
{
|
|
|
|
|
ChannelAct ca = m_ChannelActs[i];
|
|
|
|
|
var rankNodes = ca.m_RankNodes;
|
|
|
|
|
for (int n = rankNodes.Count - 1; n >= 0; n--)
|
|
|
|
|
{
|
|
|
|
|
var node = rankNodes[n];
|
|
|
|
|
bool bActFinished = false;
|
|
|
|
|
if (node.m_dwFlagMode == COMACT_FLAG_MODE_ONCE_IGNOREGFX || node.m_dwFlagMode == COMACT_FLAG_MODE_ONCE_MULTIIGNOREGFX)
|
|
|
|
|
bActFinished = node.m_pActive.IsActionStopped();
|
|
|
|
|
else
|
|
|
|
|
bActFinished = node.m_pActive.IsAllFinished();
|
|
|
|
|
|
|
|
|
|
if (bActFinished)
|
|
|
|
|
{
|
|
|
|
|
if (node.m_dwFlagMode != COMACT_FLAG_MODE_NONE && node.m_pActFlag)
|
|
|
|
|
{
|
|
|
|
|
node.m_pActFlag = true;
|
|
|
|
|
|
|
|
|
|
if (node.m_dwFlagMode != COMACT_FLAG_MODE_ONCE_MULTIIGNOREGFX)
|
|
|
|
|
node.m_dwFlagMode = (int)COMACT_FLAG_MODE_NONE;
|
|
|
|
|
|
|
|
|
|
node.m_pActFlag = false;
|
|
|
|
|
}
|
|
|
|
|
if (node.m_QueuedActs.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
A3DCombActDynData pNext = node.m_QueuedActs[0];
|
|
|
|
|
node.m_QueuedActs.RemoveAt(0);
|
|
|
|
|
|
|
|
|
|
if (pNext.GetStopPrevAct())
|
|
|
|
|
{
|
|
|
|
|
node.m_pActive.Stop(true);
|
|
|
|
|
//StopChildrenAct();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
node.m_pActive.Stop(false);
|
|
|
|
|
|
|
|
|
|
// script
|
|
|
|
|
//m_pMapModel->OnScriptPlayAction(this, i, pNext->GetComAct()->GetName());
|
|
|
|
|
|
|
|
|
|
// Èç¹ûQueueActionµÄʱºòÉèÖÃÁËResetSpeed£¬ÔòÕâÀォËÙ¶ÈÉèÖÃÖØÖã¬Ä¬ÈÏÇé¿öϸñê־Ϊfalse
|
|
|
|
|
//by2021 ÕâÀï¿ÉÐÞ¸Ä
|
|
|
|
|
if (pNext.IsSetSpeedWhenActStart())
|
|
|
|
|
SetPlaySpeedByChannel(i, pNext.GetComAct());
|
|
|
|
|
|
|
|
|
|
node.m_pActive = null;
|
|
|
|
|
node.m_pActive = pNext;
|
|
|
|
|
node.m_pActive.Play(i, 1f, node.m_pActive.GetTransTime(), 0/**m_EventMasks[i]*/, true, m_bAbsTrack, pNext.GetNoFxFlag());
|
|
|
|
|
//pNext.UpdateAct(dwUpdateTime);
|
|
|
|
|
m_bAbsTrack = false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
node.m_pActive.Stop(false);
|
|
|
|
|
rankNodes.RemoveAt(n);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// else
|
|
|
|
|
// node.m_pActive.UpdateAct(dwUpdateTime);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void SetPlaySpeedByChannel(int nChannel, A3DCombinedAction pComAct)
|
|
|
|
|
{
|
|
|
|
|
// if (m_nMainChannel == nChannel || 0 == nChannel)
|
|
|
|
|
// {
|
|
|
|
|
// m_fPlaySpeed = m_fDefPlaySpeed * pComAct.GetPlaySpeed();
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
public void PlayGfx(string szPath, string szHook, float fScale, bool bFadeOut, A3DVECTOR3 vOffset, float fPitch, float fYaw, float fRot, bool bUseECMHook, uint dwFadeOutTime)
|
|
|
|
|
{
|
|
|
|
|
if (!bFadeOut)
|
|
|
|
|