Add requirement for play skill
Merge from develop
This commit is contained in:
@@ -132,7 +132,6 @@ namespace BrewMonster
|
||||
|
||||
public void LogPlayAttackEffectGfx(CECHostPlayer player, int skillId, int section = 0)
|
||||
{
|
||||
Debug.Log("LogPlayAttackEffectGfx: " + skillId + " " + section);
|
||||
if (player == null)
|
||||
return;
|
||||
AddGfxEventsFromComAct(player.GetSkillAttackComActRise(skillId, section), "Attack");
|
||||
@@ -152,18 +151,14 @@ namespace BrewMonster
|
||||
{
|
||||
if (string.IsNullOrEmpty(label) || comAct?.m_EventInfoLst == null)
|
||||
{
|
||||
Debug.Log("AddGfxEventsFromComAct: " + label + " " + comAct?.m_strName);
|
||||
return;
|
||||
}
|
||||
Debug.Log("AddGfxEventsFromComAct: " + label + " " + comAct?.m_strName + " " + comAct.m_EventInfoLst.Count);
|
||||
|
||||
var seen = new HashSet<string>();
|
||||
foreach (var ev in comAct.m_EventInfoLst)
|
||||
{
|
||||
Debug.Log("AddGfxEventsFromComAct: " + label + " " + comAct?.m_strName);
|
||||
if (ev is not FX_BASE_INFO gfx || gfx.m_strFilePaths == null)
|
||||
{
|
||||
Debug.Log("AddGfxEventsFromComAct Failed: " + label + " " + ev?.GetType().Name);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -173,7 +168,6 @@ namespace BrewMonster
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Debug.Log("AddGfxEventsFromComAct: " + label + " " + path);
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
continue;
|
||||
|
||||
|
||||
@@ -67,6 +67,14 @@ namespace BrewMonster
|
||||
[SerializeField]
|
||||
private LogPanelAnimeScene logPanelAnimeScene;
|
||||
|
||||
[Header("Channeling (time_type = 2)")]
|
||||
[Tooltip("Stops durative/channeling skill repeat and allows other skills again.")]
|
||||
[SerializeField] private Button channelCancelButton;
|
||||
|
||||
private Coroutine _channelingCoroutine;
|
||||
private int _channelingSkillId;
|
||||
private bool _isChanneling;
|
||||
|
||||
/// <summary>
|
||||
/// World position of the draggable target marker, read by CECSkillGfxMan.get_pos_by_id.
|
||||
/// 可拖动目标标记的世界坐标,由 CECSkillGfxMan.get_pos_by_id 读取。
|
||||
@@ -79,11 +87,19 @@ namespace BrewMonster
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
<<<<<<< HEAD
|
||||
SkillStubs.Init();
|
||||
=======
|
||||
if (channelCancelButton != null)
|
||||
channelCancelButton.onClick.AddListener(CancelChanneling);
|
||||
>>>>>>> 6fde1d1583 (Add requirement for play skill)
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (channelCancelButton != null)
|
||||
channelCancelButton.onClick.RemoveListener(CancelChanneling);
|
||||
StopChanneling();
|
||||
if (Instance == this)
|
||||
Instance = null;
|
||||
}
|
||||
@@ -455,10 +471,81 @@ namespace BrewMonster
|
||||
return root.GetComponentInChildren<Image>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops channeling repeat and clears pending attack events (wire to cancel button).
|
||||
/// 停止引导重复并清理挂起的攻击事件(绑定到取消按钮)。
|
||||
/// </summary>
|
||||
public void CancelChanneling()
|
||||
{
|
||||
StopChanneling();
|
||||
}
|
||||
|
||||
private void StopChanneling()
|
||||
{
|
||||
_isChanneling = false;
|
||||
_channelingSkillId = 0;
|
||||
|
||||
if (_channelingCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_channelingCoroutine);
|
||||
_channelingCoroutine = null;
|
||||
}
|
||||
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
player.StopSkillAttackAction();
|
||||
EventBus.PublishChannel(player.GetCharacterID(), new ClearComActFlagAllRankNodesEvent(true));
|
||||
|
||||
CECAttackerEvents attackerEvents =
|
||||
CECAttacksMan.Instance?.FindAttackByAttacker(player.GetPlayerInfo().cid);
|
||||
if (attackerEvents)
|
||||
attackerEvents.Signal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Durative skill: block other skills while an attack event has not fired yet.
|
||||
/// 引导技能:攻击事件尚未触发时,阻止其它技能。
|
||||
/// </summary>
|
||||
private bool ShouldBlockOtherSkillTrigger(CECSkill skill)
|
||||
{
|
||||
if (!_isChanneling || skill == null)
|
||||
return false;
|
||||
|
||||
if (skill.GetSkillID() == _channelingSkillId)
|
||||
return false;
|
||||
|
||||
return HasPendingChannelAttackEvent();
|
||||
}
|
||||
|
||||
private bool HasPendingChannelAttackEvent()
|
||||
{
|
||||
if (!_isChanneling || player == null)
|
||||
return false;
|
||||
|
||||
CECAttackerEvents attackerEvents =
|
||||
CECAttacksMan.Instance?.FindAttackByAttacker(player.GetPlayerInfo().cid);
|
||||
if (!attackerEvents)
|
||||
return false;
|
||||
|
||||
CECAttackEvent pAttack = attackerEvents.Find(_channelingSkillId, 0);
|
||||
return pAttack != null && !pAttack.m_bDoFired;
|
||||
}
|
||||
|
||||
public void LocalCastSkill(CECSkill skill)
|
||||
{
|
||||
if (player == null || skill == null)
|
||||
return;
|
||||
|
||||
if (ShouldBlockOtherSkillTrigger(skill))
|
||||
{
|
||||
Debug.LogWarning($"[SkillTriggerPanel] Blocked skill {skill.GetSkillID()} — channeling skill {_channelingSkillId} attack event pending.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_isChanneling)
|
||||
StopChanneling();
|
||||
|
||||
logPanelAnimeScene.Reset();
|
||||
int skillId = skill.GetSkillID();
|
||||
logPanelAnimeScene.AddCopyTextButton("ID", skillId.ToString());
|
||||
@@ -493,56 +580,112 @@ namespace BrewMonster
|
||||
// Debug.LogWarning($"[SkillTriggerPanel] composerMan is null — VFX skipped for skill {skillId}.");
|
||||
// }
|
||||
|
||||
// 3. After 2s, play the release / 施放起+落 attack animation chain (local-only).
|
||||
// 2 秒后播放施放攻击动画链(仅本地)。
|
||||
StartCoroutine(DelayedPlaySkillAttackAction(player, skillId));
|
||||
// 3. After delay, play the release / 施放起+落 attack animation chain (local-only).
|
||||
// 延迟后播放施放攻击动画链(仅本地)
|
||||
if (skill.IsDurative())
|
||||
{
|
||||
_isChanneling = true;
|
||||
_channelingSkillId = skillId;
|
||||
_channelingCoroutine = StartCoroutine(ChannelingSkillRoutine(player, skillId));
|
||||
}
|
||||
else
|
||||
{
|
||||
StartCoroutine(DelayedPlaySkillAttackAction(player, skillId, 2f, replayAttackAnim: false));
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator DelayedPlaySkillAttackAction(CECHostPlayer hostPlayer, int skillId)
|
||||
/// <summary>
|
||||
/// Durative (time_type = 2): first hit at 1s, then every 2s until cancel.
|
||||
/// 引导技能:1 秒首次命中,之后每 2 秒重复,直到按下取消。
|
||||
/// </summary>
|
||||
private IEnumerator ChannelingSkillRoutine(CECHostPlayer hostPlayer, int skillId)
|
||||
{
|
||||
|
||||
int attackTime = 0;
|
||||
yield return new WaitForSeconds(1f);
|
||||
if (!_isChanneling || hostPlayer == null)
|
||||
yield break;
|
||||
|
||||
TriggerLocalSkillAttack(hostPlayer, skillId, replayAttackAnim: false);
|
||||
|
||||
while (_isChanneling && hostPlayer != null)
|
||||
{
|
||||
yield return new WaitForSeconds(5f);
|
||||
if (!_isChanneling || hostPlayer == null)
|
||||
yield break;
|
||||
|
||||
while (_isChanneling && HasPendingChannelAttackEvent())
|
||||
yield return null;
|
||||
|
||||
if (!_isChanneling || hostPlayer == null)
|
||||
yield break;
|
||||
|
||||
TriggerLocalSkillAttack(hostPlayer, skillId, replayAttackAnim: true);
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator DelayedPlaySkillAttackAction(CECHostPlayer hostPlayer, int skillId, float delaySecs, bool replayAttackAnim)
|
||||
{
|
||||
yield return new WaitForSeconds(delaySecs);
|
||||
if (hostPlayer == null)
|
||||
yield break;
|
||||
|
||||
TriggerLocalSkillAttack(hostPlayer, skillId, replayAttackAnim);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Local-only skill hit: mirrors <see cref="CECPlayer.PlayAttackEffect"/> for debug panel.
|
||||
/// When <paramref name="replayAttackAnim"/> is true (channeling tick), signal prior attack so anim replays.
|
||||
/// 本地技能命中:与 PlayAttackEffect 一致;引导重复 tick 时先 Signal 再重播攻击动作。
|
||||
/// </summary>
|
||||
private void TriggerLocalSkillAttack(CECHostPlayer hostPlayer, int skillId, bool replayAttackAnim)
|
||||
{
|
||||
int attackTime = 0;
|
||||
CECAttackEvent pAttack = null;
|
||||
|
||||
// first try to find if there is already a skill attack event in attackman
|
||||
int targetId = targetMarker != null
|
||||
? targetMarker.GetNPCID()
|
||||
: EncodeDebugNpcId();
|
||||
|
||||
CECAttackerEvents attackerEvents = CECAttacksMan.Instance.FindAttackByAttacker(hostPlayer.GetPlayerInfo().cid);
|
||||
if (attackerEvents)
|
||||
{
|
||||
pAttack = attackerEvents.Find(skillId, 0);
|
||||
if (pAttack != null)
|
||||
{
|
||||
// Ãæ¹¥»÷µÄ·ÇµÚÒ»´ÎÉ˺¦ÏûÏ¢
|
||||
pAttack.AddTarget(DEBUG_TARGET_ID, 1, 1);
|
||||
goto EXIT;
|
||||
if (replayAttackAnim)
|
||||
attackerEvents.Signal();
|
||||
else
|
||||
{
|
||||
// 面攻击的非第一次伤害消息 / Non-first hit on same attack event
|
||||
pAttack.AddTarget(targetId, 1, 1);
|
||||
if (attackTime != 0)
|
||||
attackTime = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
attackerEvents.Signal();
|
||||
}
|
||||
}
|
||||
|
||||
if (ElementSkill.IsGoblinSkill((uint)skillId) &&
|
||||
ElementSkill.GetType((uint)skillId) == 2)
|
||||
ElementSkill.GetType((uint)skillId) == 2)
|
||||
{
|
||||
pAttack = CECAttacksMan.Instance.AddSkillAttack(
|
||||
hostPlayer.GetPlayerInfo().cid, hostPlayer.GetPlayerInfo().cid, hostPlayer.GetPlayerInfo().cid, hostPlayer.GetWeaponID(), skillId, 0, 0x0200, 0);
|
||||
hostPlayer.GetPlayerInfo().cid, hostPlayer.GetPlayerInfo().cid, hostPlayer.GetPlayerInfo().cid,
|
||||
hostPlayer.GetWeaponID(), skillId, 0, 0x0200, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// begin a skill attack
|
||||
pAttack = CECAttacksMan.Instance.AddSkillAttack(
|
||||
hostPlayer.GetPlayerInfo().cid, targetMarker.GetNPCID(), targetMarker.GetNPCID(), hostPlayer.GetWeaponID(), skillId, 0, 0x0200, 0);
|
||||
hostPlayer.GetPlayerInfo().cid, targetId, targetId,
|
||||
hostPlayer.GetWeaponID(), skillId, 0, 0x0200, 0);
|
||||
}
|
||||
|
||||
|
||||
bool ok = hostPlayer.PlaySkillAttackAction(skillId, 0, ref attackTime,0, pAttack);
|
||||
bool ok = hostPlayer.PlaySkillAttackAction(skillId, 0, ref attackTime, 0, pAttack);
|
||||
if (!ok)
|
||||
BMLogger.LogWarning($"[SkillTriggerPanel] PlaySkillAttackAction returned false for skill {skillId} after delay — attack anim may not play.");
|
||||
EXIT:
|
||||
// // For skill attacking, time is always set to 0
|
||||
BMLogger.LogWarning($"[SkillTriggerPanel] PlaySkillAttackAction returned false for skill {skillId} — attack anim may not play.");
|
||||
|
||||
if (attackTime != 0)
|
||||
attackTime = 0;
|
||||
}
|
||||
|
||||
@@ -2752,7 +2752,7 @@ namespace BrewMonster
|
||||
}
|
||||
}
|
||||
|
||||
if (!PlaySkillAttackActionWithName(idSkill, szAct, bHideFX, attackEvent))
|
||||
if (!PlaySkillAttackActionWithName(idSkill, szAct, bHideFX, attackEvent,(uint)COMACT_FLAG_MODE_ONCE_MULTIIGNOREGFX))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -2798,7 +2798,7 @@ namespace BrewMonster
|
||||
}
|
||||
}
|
||||
|
||||
if (!PlaySkillAttackActionWithName(idSkill, szAct, bHideFX, attackEvent))
|
||||
if (!PlaySkillAttackActionWithName(idSkill, szAct, bHideFX, attackEvent, (uint)COMACT_FLAG_MODE_ONCE_MULTIIGNOREGFX))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -2836,10 +2836,10 @@ namespace BrewMonster
|
||||
if (pTeam == null) return false;
|
||||
return pTeam.GetMemberByID(idPlayer) != null;
|
||||
}
|
||||
public bool PlaySkillAttackActionWithName(int idSkill, string szActName, bool bNoFX = false, CECAttackEvent attackEvent = null)
|
||||
public bool PlaySkillAttackActionWithName(int idSkill, string szActName, bool bNoFX = false, CECAttackEvent attackEvent = null, uint dwFlagMode = 0)
|
||||
{
|
||||
return m_pActionController != null
|
||||
&& m_pActionController.PlaySkillAttackActionWithName(idSkill, szActName, bNoFX, attackEvent, 0);
|
||||
&& m_pActionController.PlaySkillAttackActionWithName(idSkill, szActName, bNoFX, attackEvent, dwFlagMode);
|
||||
}
|
||||
|
||||
public bool QueueSkillAttackActionWithName(int idSkill, string szActName, int nTransTime = 200, bool bNoFX = false, bool bResetSpeed = false, bool bResetActFlag = false, CECAttackEvent attackEvent = null, uint dwNewFlagMode = 0)
|
||||
|
||||
@@ -67,6 +67,7 @@ public class FX_BINDING_BASE
|
||||
m_pDynData = pDynData;
|
||||
}
|
||||
public virtual bool IsStop() { return false; }
|
||||
public virtual bool IsStart() {return false;}
|
||||
public virtual void Stop() {}
|
||||
public virtual void Render() {}
|
||||
public virtual void UpdateParam(CECModel pECModel, int nDeltaTime) {}
|
||||
@@ -117,10 +118,6 @@ public class GFX_BINDING : FX_BINDING_BASE
|
||||
// Let the effect run one full loop cycle, then stop emitting. / 再播完一整圈循环后停发粒子
|
||||
// Longest main.duration under this GFX (loop period per particle system). / 取挂点下所有粒子的 duration 最大值作为一整圈时长
|
||||
float oneLoop = 0f;
|
||||
foreach (ParticleSystem psChild in go.GetComponentsInChildren<ParticleSystem>(true))
|
||||
oneLoop = Mathf.Max(oneLoop, psChild.main.duration);
|
||||
if (oneLoop > 2f)
|
||||
oneLoop = 2f;
|
||||
await UniTask.Delay(TimeSpan.FromSeconds(oneLoop), delayType, cancellationToken: ct);
|
||||
if (_ps != null && _ps.IsAlive(true))
|
||||
_ps.Stop(true, ParticleSystemStopBehavior.StopEmitting);
|
||||
@@ -156,6 +153,10 @@ public class GFX_BINDING : FX_BINDING_BASE
|
||||
if (!isStartPlaying)
|
||||
return false;
|
||||
return _ps == null || !_ps.isPlaying;
|
||||
}
|
||||
public override bool IsStart()
|
||||
{
|
||||
return isStartPlaying;
|
||||
}
|
||||
public override void Render() {
|
||||
if (m_pGfx == null)
|
||||
@@ -168,10 +169,6 @@ public class GFX_BINDING : FX_BINDING_BASE
|
||||
if (!string.IsNullOrEmpty(fx.m_strHookName))
|
||||
{
|
||||
hookT = host.GetHook(fx.m_strHookName, true);
|
||||
#if UNITY_EDITOR
|
||||
if (hookT == null)
|
||||
BMLogger.LogWarning($"[GFX_BINDING.Render] Hook '{fx.m_strHookName}' not found; GFX stays on character root.");
|
||||
#endif
|
||||
}
|
||||
|
||||
Quaternion eventLocalRot = _prefabLocalRot *
|
||||
@@ -188,7 +185,6 @@ public class GFX_BINDING : FX_BINDING_BASE
|
||||
m_pGfx.transform.SetParent(hookT, false);
|
||||
else
|
||||
{
|
||||
// Keep under model root; align to hook world pose once (no bone follow). / 不切到挂点,仅取挂点世界位姿对齐一次(不随骨骼动)
|
||||
m_pGfx.transform.SetPositionAndRotation(
|
||||
hookT.TransformPoint(hookLocalPos),
|
||||
hookT.rotation * eventLocalRot);
|
||||
@@ -225,8 +221,21 @@ public class GFX_BINDING : FX_BINDING_BASE
|
||||
if (m_pInfo != null && m_pInfo.m_dwStartTime <= nDeltaTime && !isStartPlaying)
|
||||
{
|
||||
Render();
|
||||
if (_ps != null)
|
||||
m_pInfo.m_dwTimeSpan = (int)(_ps.main.duration * 1000);
|
||||
|
||||
var PSes = m_pGfx.GetComponentsInChildren<ParticleSystem>();
|
||||
float span = -1;
|
||||
foreach(var PS in PSes)
|
||||
{
|
||||
var duration = PS.main.duration;
|
||||
//remove default duration and get max duration
|
||||
if( duration!= 5 && duration > span && span !=100000)
|
||||
{
|
||||
span = duration;
|
||||
}
|
||||
}
|
||||
m_dwTimeSpan = (int)span *1000;
|
||||
m_pInfo.m_dwTimeSpan = (int)m_pInfo.m_dwStartTime + (int)span *1000;
|
||||
|
||||
}
|
||||
}
|
||||
public void SetGfx(GameObject gfx, Quaternion prefabRotation, Vector3 prefabPosition) {
|
||||
@@ -419,7 +428,7 @@ public class A3DCombActDynData
|
||||
else if (prefab == null)
|
||||
{
|
||||
Debug.LogWarning("Missing gfx prefab, using placeholder: " + path);
|
||||
string path2 = "gfx/NullDefault";
|
||||
string path2 = "gfx/人物/技能/妖兽/NullDefault.gfx";
|
||||
GameObject prefab2 = await AddressableManager.Instance.LoadPrefabAsync(path2);
|
||||
var gfx = GameObject.Instantiate(prefab2, m_pECModel.transform);
|
||||
gfx.SetActive(false);
|
||||
@@ -498,6 +507,7 @@ public class A3DCombActDynData
|
||||
}
|
||||
public void Stop(bool bStopAct, bool bForceStopFx = false )
|
||||
{
|
||||
Debug.Log("[DefaultPolicy]Stop: " + m_pAct?.m_strName + " bStopAct: " + bStopAct + " bForceStopFx: " + bForceStopFx);
|
||||
RemoveAllActiveFx();
|
||||
if (ActiveAttackEvent != null)
|
||||
{
|
||||
@@ -617,24 +627,36 @@ public class A3DCombActDynData
|
||||
|
||||
static bool IsFxEnd(FX_BINDING_BASE pFx, int dwTimeSpan)
|
||||
{
|
||||
uint dwMax = 0xFFFFFFFF;
|
||||
int dwMax = -1;
|
||||
if (pFx.IsStop())
|
||||
return true;
|
||||
|
||||
// if (pFx.GetInfo().m_dwTimeSpan == dwMax)
|
||||
// return false;
|
||||
if (!pFx.IsStart())
|
||||
return false;
|
||||
if (pFx.GetInfo().m_dwTimeSpan > 10000 || pFx.GetInfo().m_dwTimeSpan == dwMax)
|
||||
return false;
|
||||
return false;
|
||||
//return dwTimeSpan >= pFx->GetInfo()->GetStartTime() + pFx->GetInfo()->GetTimeSpan();
|
||||
// Debug.Log( $"Span: {dwTimeSpan} TickTill{pFx.GetInfo().m_dwStartTime + pFx.GetInfo().m_dwTimeSpan}");
|
||||
// return dwTimeSpan >= pFx.GetInfo().m_dwStartTime + pFx.GetInfo().m_dwTimeSpan;
|
||||
}
|
||||
|
||||
bool IsCurActFinished(ACTION_INFO pCur)
|
||||
{
|
||||
return !pCur.IsInfinite() || m_nCurActLoop >= m_arrActLoopNum[m_nCurActIndex].GetLoopNum();
|
||||
}
|
||||
bool IsAllEventFinished() { return m_ActFxArray.Count == 0 ; }
|
||||
public bool IsActionStopped()
|
||||
{
|
||||
return m_pAct.m_ActLst.Count == 0 || (m_pAct.m_nLoops != -1 && m_nCurLoop >= m_pAct.m_nLoops);
|
||||
}
|
||||
public bool IsAllFinished()
|
||||
{
|
||||
return IsActionStopped() && IsAllEventFinished();
|
||||
}
|
||||
bool IsActionFinished()
|
||||
{
|
||||
return m_dwTimeSpan >= m_dwDynComActSpan;
|
||||
}
|
||||
|
||||
void LoopCurAct(ACTION_INFO pCur, uint dwDeltaTime)
|
||||
{
|
||||
m_dwTimeSpan = (int)(pCur.m_dwStartTime + m_dwTimeSpan - pCur.m_dwEndTime); // °Ñʱ¼äÉè»ØÈ¥
|
||||
@@ -655,6 +677,7 @@ public class A3DCombActDynData
|
||||
{
|
||||
if(fx != null)
|
||||
{
|
||||
Debug.Log("RemoveAllActiveFx: " + fx.GetInfo()?.m_pAct?.m_strName);
|
||||
fx.Stop();
|
||||
}
|
||||
}
|
||||
@@ -1493,7 +1516,7 @@ public class CECModel
|
||||
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;
|
||||
pNode.m_dwFlagMode = (int)dwFlagMode;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1505,7 +1528,7 @@ public class CECModel
|
||||
}
|
||||
return m_pMapModel.m_ActionMap.TryGetValue(szActName, out A3DCombinedAction combinedAction) ? combinedAction : null;
|
||||
}
|
||||
//Final trigger function
|
||||
//Final trigger function
|
||||
public int GetComActTimeSpanByName(string szActName)
|
||||
{
|
||||
A3DCombinedAction combinedAction = GetComActByName(szActName);
|
||||
@@ -1582,9 +1605,33 @@ public class CECModel
|
||||
EventBus.PublishChannel(iNFO.nid, new QueueNPCActionEvent(szActName));
|
||||
return true;
|
||||
}
|
||||
public void StopAllActions(bool bStopFx)
|
||||
{
|
||||
//ResetMaterialScale();
|
||||
StopChannelAction(0, true, bStopFx);
|
||||
//StopChildrenAct();
|
||||
}
|
||||
|
||||
public void StopChannelAction(int nChannel, byte rank, bool bStopAct, bool bStopFx = false)
|
||||
{
|
||||
ChannelAct ca = m_ChannelActs[nChannel];
|
||||
ChannelActNode pNode = ca.RemoveNodeByRank(rank);
|
||||
|
||||
if (pNode != null)
|
||||
{
|
||||
pNode.m_pActive.Stop(bStopAct, bStopFx);
|
||||
}
|
||||
}
|
||||
|
||||
public void StopChannelAction(int nChannel, bool bStopAct, bool bStopFx = false)
|
||||
{
|
||||
//TODO: Implement StopChannelAction
|
||||
ChannelAct ca = m_ChannelActs[nChannel];
|
||||
foreach (var node in ca.m_RankNodes)
|
||||
{
|
||||
Debug.Log("[DefaultPolicy]StopChannelAction: " + node.m_pActive?.GetComAct()?.m_strName);
|
||||
node.m_pActive.Stop(bStopAct, bStopFx);
|
||||
}
|
||||
ca.m_RankNodes.Clear();
|
||||
}
|
||||
public bool IsActionStopped(int nChannel =0)
|
||||
{
|
||||
@@ -1623,9 +1670,15 @@ public class CECModel
|
||||
var node = rankNodes[n];
|
||||
bool bActFinished = false;
|
||||
if (node.m_dwFlagMode == COMACT_FLAG_MODE_ONCE_IGNOREGFX || node.m_dwFlagMode == COMACT_FLAG_MODE_ONCE_MULTIIGNOREGFX)
|
||||
{
|
||||
BMLogger.Log("[DefaultPolicy] Checking IsActionStopped: " + node.m_pActive?.GetComAct()?.m_strName);
|
||||
bActFinished = node.m_pActive.IsActionStopped();
|
||||
}
|
||||
else
|
||||
bActFinished = node.m_pActive.IsActionStopped();
|
||||
{
|
||||
BMLogger.Log("[DefaultPolicy] Checking IsAllFinished: " + node.m_pActive?.GetComAct()?.m_strName);
|
||||
bActFinished = node.m_pActive.IsAllFinished();
|
||||
}
|
||||
if (bActFinished)
|
||||
{
|
||||
if (node.m_dwFlagMode != COMACT_FLAG_MODE_NONE && node.m_pActFlag)
|
||||
|
||||
@@ -165,6 +165,8 @@ namespace BrewMonster
|
||||
|
||||
public void StopSkillAttackAction()
|
||||
{
|
||||
BMLogger.Log("[DefaultPolicy]StopSkillAttackAction: " + m_bSkillAttackActionPlayed);
|
||||
BMLogger.Log("[DefaultPolicy]IsPlayingCastingSkillAction: " + m_actionPlayPolicy.IsPlayingCastingSkillAction());
|
||||
if (m_actionPlayPolicy != null && m_actionPlayPolicy.IsPlayingCastingSkillAction() && m_bSkillAttackActionPlayed)
|
||||
{
|
||||
m_actionPlayPolicy.StopSkillAction();
|
||||
|
||||
@@ -235,7 +235,7 @@ namespace BrewMonster
|
||||
|
||||
public bool IsPlayingCastingSkillAction()
|
||||
{
|
||||
return m_isCastingSkill;
|
||||
return IsPlayingAction((int)PLAYER_ACTION_TYPE.ACT_CASTSKILL);
|
||||
}
|
||||
|
||||
// Non-skill action
|
||||
@@ -379,44 +379,26 @@ namespace BrewMonster
|
||||
if (IsMoving()){
|
||||
return false;
|
||||
}
|
||||
BMLogger.Log("[DefaultPolicy] PlaySkillCastActionWithName:" + szActName);
|
||||
ClearComActFlagAllRankNodes(true);
|
||||
bool check = GetModel()!=null
|
||||
&& GetModel().PlayActionByName(szActName, 1.0f, true, 200, true);
|
||||
if (!check)
|
||||
{
|
||||
// BMLogger.LogError($"Fall back to base implementation: {szActName} failed");
|
||||
//fallback to base implementation(which is non policy based)
|
||||
base.PlaySkillCastActionWithName(idSkill, szActName, bNoFX);
|
||||
}
|
||||
&& GetModel().PlayActionByName(szActName, 1.0f, true, 200, true, (uint)PLAYER_ACTION_TYPE.ACT_CASTSKILL, bNoFX);
|
||||
return check;
|
||||
}
|
||||
public override bool PlaySkillAttackActionWithName(int idSkill, string szActName, bool bNoFX, CECAttackEvent attackEvent, uint dwFlagMode){
|
||||
if (IsMoving()){
|
||||
return false;
|
||||
}
|
||||
//LOG_DEBUG_INFO(AString().Format("PlaySkillAttackActionWithName:%s", szActName));
|
||||
BMLogger.Log("[DefaultPolicy] Checking PlaySkillAttackActionWithName:" + szActName);
|
||||
ClearComActFlagAllRankNodes(true);
|
||||
bool check = GetModel() != null
|
||||
&& GetModel().PlayActionByName(szActName, 1.0f, true, 200, true, (uint)PLAYER_ACTION_TYPE.ACT_CASTSKILL, bNoFX, attackEvent, dwFlagMode);
|
||||
if (!check)
|
||||
{
|
||||
//BMLogger.LogError($"Fall back to base implementation: {szActName} failed");
|
||||
//fallback to base implementation(which is non policy based)
|
||||
base.PlaySkillAttackActionWithName(idSkill, szActName, bNoFX, attackEvent, dwFlagMode);
|
||||
}
|
||||
return check;
|
||||
}
|
||||
|
||||
public override bool QueueSkillAttackActionWithName(int idSkill, string szActName, int nTransTime, bool bNoFX, bool bResetSpeed, bool bResetActFlag, CECAttackEvent attackEvent, uint dwNewFlagMode){
|
||||
//LOG_DEBUG_INFO(AString().Format("QueueSkillAttackActionWithName:%s", szActName));
|
||||
bool check = GetModel()!=null
|
||||
&& GetModel().QueueAction(szActName, nTransTime, (int)PLAYER_ACTION_TYPE.ACT_CASTSKILL, false, false, bNoFX, bResetSpeed, bResetActFlag, attackEvent, dwNewFlagMode);
|
||||
if (!check)
|
||||
{
|
||||
//BMLogger.LogError($"Fall back to base implementation: {szActName} failed");
|
||||
//fallback to base implementation(which is non policy based)
|
||||
base.QueueSkillAttackActionWithName(idSkill, szActName, nTransTime, bNoFX, bResetSpeed, bResetActFlag, attackEvent, dwNewFlagMode);
|
||||
}
|
||||
return check;
|
||||
}
|
||||
public override bool PlayWoundActionWithName(string szActName){
|
||||
@@ -433,12 +415,14 @@ namespace BrewMonster
|
||||
}
|
||||
public override void StopChannelAction(){
|
||||
if (GetModel()!=null){
|
||||
BMLogger.Log("[DefaultPolicy]StopChannelAction: " + GetModel().GetCurActionUserData());
|
||||
ClearComActFlagAllRankNodes(true);
|
||||
GetModel().StopChannelAction(0, true);
|
||||
}
|
||||
}
|
||||
public override void StopSkillAction(){
|
||||
if (GetModel()!=null && IsPlayingCastingSkillAction()){
|
||||
BMLogger.Log("[DefaultPolicy]StopSkillAction: " + GetModel().GetCurActionUserData());
|
||||
StopChannelAction();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user