fix gfx hit not sych with animation. Fix wrong animation timing with long weapon. Add animation scaling speed

This commit is contained in:
Tran Hai Nam
2026-05-17 15:48:29 +07:00
parent 285697bf8b
commit c851c46292
9 changed files with 10163 additions and 300 deletions
+104 -116
View File
@@ -1,4 +1,4 @@
using BrewMonster.Managers;
using BrewMonster.Managers;
using BrewMonster.Network;
using BrewMonster.PerfectWorld.Scripts.Vfx;
using BrewMonster.Scripts;
@@ -1688,20 +1688,20 @@ namespace BrewMonster
}
// melee attack
CECAttackEvent pAttack1 = CECAttacksMan.Instance.AddMeleeAttack(
CECAttackEvent pAttack = CECAttacksMan.Instance.AddMeleeAttack(
GetPlayerInfo().cid, idTarget, idWeapon, dwModifier, nDamage, nTimeFly);
if (pAttack1 != null)
if (pAttack != null)
{
if (!IsDead() && (dwModifier & (uint)MOD.MOD_RETORT) == 0
&& (dwModifier & (uint)MOD.MOD_ATTACK_AURA) == 0
&& PlayAttackAction(nAttackSpeed, ref piAttackTime, pAttack1)
&& PlayAttackAction(nAttackSpeed, ref piAttackTime, pAttack)
&& (dwModifier & (uint)MOD.MOD_BEAT_BACK) == 0)
{
}
else
{
pAttack1.m_bSignaled = true;
pAttack.m_bSignaled = true;
}
}
}
@@ -1721,11 +1721,11 @@ namespace BrewMonster
CECAttackerEvents attackerEvents = CECAttacksMan.Instance.FindAttackByAttacker(GetPlayerInfo().cid);
if (attackerEvents)
{
CECAttackEvent pAttack1 = attackerEvents.Find(idSkill, nSection);
if (pAttack1 != null)
pAttack = attackerEvents.Find(idSkill, nSection);
if (pAttack != null)
{
// Ãæ¹¥»÷µÄ·ÇµÚÒ»´ÎÉ˺¦ÏûÏ¢
pAttack1.AddTarget(idTarget, dwModifier, nDamage);
pAttack.AddTarget(idTarget, dwModifier, nDamage);
goto EXIT;
}
else
@@ -1755,7 +1755,6 @@ namespace BrewMonster
&& PlaySkillAttackAction(idSkill, nAttackSpeed, ref unusedInt, nSection, pAttack)
&& (dwModifier & (uint)MOD.MOD_BEAT_BACK) == 0)
{
pAttack.m_bSignaled = true;
}
else
{
@@ -1805,38 +1804,30 @@ namespace BrewMonster
// ==============================
if (GetMoveEnv() == (int)MoveEnvironment.MOVEENV_GROUND)
{
string szActRise = EC_Utility.BuildActionName(action, weapon_type, "起");
string szActFall = EC_Utility.BuildActionName(action, weapon_type, "落");
nTime1 = m_pPlayerCECModel.GetComActTimeSpanByName(szActRise);
nTime2 = m_pPlayerCECModel.GetComActTimeSpanByName(szActFall);
// 调整动画速度以匹配攻击速度 / Adjust animation speed to match attack speed
if (nAttackSpeed > 0)
{
float vScale = (nTime1 + nTime2) / (float)nAttackSpeed;
if (vScale > 0f)
m_pPlayerCECModel.SetPlaySpeed(vScale);
}
// “起? 动作(挥起)
szAct = EC_Utility.BuildActionName(action, weapon_type, "起");
int iTransTime = 200;
m_pActionController.PlayNonSkillActionWithName(iAction, szAct, true, iTransTime, bHideFX, attackEvent,COMACT_FLAG_MODE_ONCE_MULTIIGNOREGFX);
//swing sfx
//workaround for sound effect delay, it need to trigger via weapon combine action
SFXManager.Instance.PlaySkillSfxAtPointAsync(soundPath, Vector3.zero,iTransTime/1000f).Forget();
m_pActionController.PlayNonSkillActionWithName(iAction, szActRise, true, iTransTime, bHideFX, attackEvent, COMACT_FLAG_MODE_ONCE_MULTIIGNOREGFX);
// if (pRightHandWeapon != null && IsUsingMagicWeapon())
// pRightHandWeapon.PlayActionByName(_GenWeaponActionName(szActRise, m_iGender), 1.0f, true, iTransTime, true, iAction, bHideFX);
SFXManager.Instance.PlaySkillSfxAtPointAsync(soundPath, Vector3.zero, iTransTime / 1000f).Forget();
szAct = EC_Utility.BuildActionName(action, weapon_type, "落");
m_pActionController.QueueNonSkillActionWithName(iAction, szAct, 0, false, bHideFX);
//hit sfx
//workaround for sound effect delay, it need to trigger via weapon combine action
//.1f is a magic number to make sure the sound effect is triggered after the action is finished
SFXManager.Instance.PlaySkillSfxAtPointAsync(hitSoundPath, Vector3.zero,iTransTime/1000f+.1f).Forget();
//PlayNonSkillActionWithName(iAction, szAct, true, 200, true, ref pActFlag, COMACT_FLAG_MODE_ONCE_MULTIIGNOREGFX);gagága
/*
if (pRightHandWeapon != null && IsUsingMagicWeapon())
pRightHandWeapon.PlayActionByName(_GenWeaponActionName(szAct, m_iGender), 1.0f, true, 200, true, iAction, bHideFX);
nTime1 = _pPlayerModel.GetComActTimeSpanByName(szAct);
// “收” 动作(挥下)
szAct = $"{action.data.action_prefix}_{action.data.action_weapon_suffix[weapon_type].suffix}Âä";
QueueNonSkillActionWithName(iAction, szAct, 0, false, bHideFX);
if (pRightHandWeapon != null && IsUsingMagicWeapon())
pRightHandWeapon.QueueAction(_GenWeaponActionName(szAct, m_iGender), 0, iAction, false, false, bHideFX);
nTime2 = _pPlayerModel.GetComActTimeSpanByName(szAct);*/
m_pActionController.QueueNonSkillActionWithName(iAction, szActFall, 0, false, bHideFX);
// if (pRightHandWeapon != null && IsUsingMagicWeapon())
// pRightHandWeapon.QueueAction(_GenWeaponActionName(szActFall, m_iGender), 0, iAction, false, false, bHideFX);
SFXManager.Instance.PlaySkillSfxAtPointAsync(hitSoundPath, Vector3.zero, iTransTime / 1000f + .1f).Forget();
}
// ==============================
// Air Attack
@@ -1851,59 +1842,49 @@ namespace BrewMonster
GetProfession() == (int)PROFESSION.PROF_MONK ||
GetProfession() == (int)PROFESSION.PROF_GHOST)
{
szActionMiddleName = "空中翅膀"; // tấn công trên không
szActionMiddleName = "空中翅膀"; // Air with wings / 空中翅膀
}
else
{
szActionMiddleName = "空中飞剑"; // rơi xuống hoặc bay
szActionMiddleName = "空中飞剑"; // Air with sword / 空中飞剑
}
szAct = EC_Utility.BuildActionName(action, weapon_type, "起", szActionMiddleName);
//EventBus.PublishChannel(m_PlayerInfo.cid, new PlayActionEvent(szShapeName, szAct, 200, true));
m_pActionController.PlayNonSkillActionWithName(iAction, szAct, true, 200);
string szActRiseAir = EC_Utility.BuildActionName(action, weapon_type, "起", szActionMiddleName);
string szActFallAir = EC_Utility.BuildActionName(action, weapon_type, "落", szActionMiddleName);
nTime1 = m_pPlayerCECModel.GetComActTimeSpanByName(szActRiseAir);
nTime2 = m_pPlayerCECModel.GetComActTimeSpanByName(szActFallAir);
// 调整动画速度以匹配攻击速度 / Adjust animation speed to match attack speed
if (nAttackSpeed > 0)
{
float vScale = (nTime1 + nTime2) / (float)nAttackSpeed;
if (vScale > 0f)
m_pPlayerCECModel.SetPlaySpeed(vScale);
}
m_pActionController.PlayNonSkillActionWithName(iAction, szActRiseAir, true, 200);
// if (pRightHandWeapon != null && IsUsingMagicWeapon())
// pRightHandWeapon.PlayActionByName(_GenWeaponActionName(szAct, m_iGender), 1.0f, true, 200, true, iAction, bHideFX);
// nTime1 = m_pPlayerModel.GetComActTimeSpanByName(szAct);
szAct = EC_Utility.BuildActionName(action, weapon_type, "落", szActionMiddleName);
//EventBus.PublishChannelClass(m_PlayerInfo.cid, queueActionEvent);
m_pActionController.QueueNonSkillActionWithName(iAction, szAct, 0, false, false, true, false);
// pRightHandWeapon.PlayActionByName(_GenWeaponActionName(szActRiseAir, m_iGender), 1.0f, true, 200, true, iAction, bHideFX);
m_pActionController.QueueNonSkillActionWithName(iAction, szActFallAir, 0, false, false, true, false);
// if (pRightHandWeapon != null && IsUsingMagicWeapon())
// pRightHandWeapon.QueueAction(_GenWeaponActionName(szAct, m_iGender), 0, iAction, false, false, bHideFX);
// nTime2 = m_pPlayerModel.GetComActTimeSpanByName(szAct);
// pRightHandWeapon.QueueAction(_GenWeaponActionName(szActFallAir, m_iGender), 0, iAction, false, false, bHideFX);
}
// ==============================
// Kết thúc bằng FightStand
// Queue FightStand / 结束动作
// ==============================
PLAYER_ACTION stand_action = m_PlayerActions[(int)PLAYER_ACTION_TYPE.ACT_FIGHTSTAND];
szAct = EC_Utility.BuildActionName(stand_action, 0);
int iTranstime = 300;
m_pActionController.QueueNonSkillActionWithName(iAction, szAct, iTranstime, false, false, true, false);
/* QueueNonSkillActionWithName(ACT_FIGHTSTAND, szAct, 300, false, bHideFX, true);
m_pActionController.QueueNonSkillActionWithName(iAction, szAct, 300, false, false, true, false);
// if (pRightHandWeapon != null && IsUsingMagicWeapon())
// pRightHandWeapon.QueueAction(_GenWeaponActionName(szAct, m_iGender), 300, iAction, false, false, bHideFX, true);
if (pRightHandWeapon != null && IsUsingMagicWeapon())
pRightHandWeapon.QueueAction(_GenWeaponActionName(szAct, m_iGender), 300, iAction, false, false, bHideFX, true);*/
// if (pRightHandWeapon != null && IsUsingMagicWeapon())
// pRightHandWeapon.SetPlaySpeed(vScale);
// ==============================
// Điều chỉnh tốc độ phát animation theo tốc độ tấn công
// ==============================
/* if (nAttackSpeed > 0)
{
float vScale = (nTime1 + nTime2) / (float)nAttackSpeed;
if (vScale > 0f)
{
m_pPlayerModel.SetPlaySpeed(vScale);
if (pRightHandWeapon != null && IsUsingMagicWeapon())
pRightHandWeapon.SetPlaySpeed(vScale);
}
}
attackTime = nTime1 + nTime2;*/
attackTime = nTime1 + nTime2;
// ==============================
// Cập nhật vị trí weapon hanger (vũ khí)
@@ -2601,29 +2582,38 @@ namespace BrewMonster
var atkMan = CECAttacksMan.Instance;
// int nExecuteTime = GNET::ElementSkill::GetExecuteTime(idSkill, 0); // 获取技能执行时间 / Get skill execute time
int nExecuteTime = ElementSkill.GetExecuteTime((uint)idSkill, 0); // 临时值 / Temporary value
if (GetMoveEnv() == (int)MoveEnvironment.MOVEENV_GROUND)
{
szAct = EC_Utility.BuildActionName(data, weapon_type, "_施放起_");
GetSkillSectionActionName(ref szAct, idSkill, nSection);
nTime1 = m_pPlayerCECModel.GetComActTimeSpanByName(szAct); // 获取动作时长 / Get action time span
var pAct = m_pPlayerCECModel.GetComActByName(szAct);
if (pAct!=null) bInfinite |= pAct.IsLooping();
string szAct2 = EC_Utility.BuildActionName(data, weapon_type, "_施放落_");
GetSkillSectionActionName(ref szAct2, idSkill, nSection);
nTime2 = m_pPlayerCECModel.GetComActTimeSpanByName(szAct2);
pAct = m_pPlayerCECModel.GetComActByName(szAct2);
if (pAct!=null) bInfinite |= pAct.IsLooping();
// 调整动画速度以匹配攻击速度 / Adjust animation speed to match attack speed
if (!bInfinite && nExecuteTime > 0)
{
float vScale = (nTime1 + nTime2) / (float)nExecuteTime;
if (vScale > 0)
{
m_pPlayerCECModel.SetPlaySpeed(vScale * 1.2f);
}
}
if (!PlaySkillAttackActionWithName(idSkill, szAct, bHideFX, attackEvent))
{
return false;
}
// nTime1 = m_pPlayerModel.GetComActTimeSpanByName(szAct); // 获取动作时长 / Get action time span
// pAct = m_pPlayerModel.GetComActByName(szAct);
// if (pAct) bInfinite |= pAct.IsInfinite();
nTime1 = 1000; // 临时值 / Temporary value
szAct = EC_Utility.BuildActionName(data, weapon_type, "_施放落_");
GetSkillSectionActionName(ref szAct, idSkill, nSection);
QueueSkillAttackActionWithName(idSkill, szAct, 0, bHideFX);
// nTime2 = m_pPlayerModel.GetComActTimeSpanByName(szAct);
// pAct = m_pPlayerModel.GetComActByName(szAct);
// if (pAct) bInfinite |= pAct.IsInfinite();
nTime2 = 1000; // 临时值 / Temporary value
QueueSkillAttackActionWithName(idSkill, szAct2, 0, bHideFX);
}
else
{
@@ -2645,6 +2635,25 @@ namespace BrewMonster
szActionMiddleName += "_施放起_";
szAct = EC_Utility.BuildActionName(data, weapon_type, szActionMiddleName);
GetSkillSectionActionName(ref szAct, idSkill, nSection);
nTime1 = m_pPlayerCECModel.GetComActTimeSpanByName(szAct);
var pAct = m_pPlayerCECModel.GetComActByName(szAct);
if (pAct!=null) bInfinite |= pAct.IsLooping();
string szAct2Air = $"{data.ActionPrefix}_{szActionMiddleName}_施法行_{data.action_weapon_suffix[weapon_type].Suffix}";
GetSkillSectionActionName(ref szAct2Air, idSkill, nSection);
nTime2 = m_pPlayerCECModel.GetComActTimeSpanByName(szAct2Air);
pAct = m_pPlayerCECModel.GetComActByName(szAct2Air);
if (pAct!=null) bInfinite |= pAct.IsLooping();
// 调整动画速度以匹配攻击速度 / Adjust animation speed to match attack speed
if (!bInfinite && nExecuteTime > 0)
{
float vScale = (nTime1 + nTime2) / (float)nExecuteTime;
if (vScale > 0)
{
m_pPlayerCECModel.SetPlaySpeed(vScale * 1.2f);
}
}
if (!PlaySkillAttackActionWithName(idSkill, szAct, bHideFX, attackEvent))
{
@@ -2654,39 +2663,15 @@ namespace BrewMonster
// if (pRightHandWeapon && IsUsingMagicWeapon())
// pRightHandWeapon.PlayActionByName(_GenWeaponActionName(szAct, m_iGender), 1.0f, true, 200, true, ACT_CASTSKILL, bHideFX);
// nTime1 = m_pPlayerModel.GetComActTimeSpanByName(szAct);
// pAct = m_pPlayerModel.GetComActByName(szAct);
// if (pAct) bInfinite |= pAct.IsInfinite();
nTime1 = 1000; // 临时值 / Temporary value
szAct = $"{data.ActionPrefix}_{szActionMiddleName}_施法行_{data.action_weapon_suffix[weapon_type].Suffix}";
GetSkillSectionActionName(ref szAct, idSkill, nSection);
QueueSkillAttackActionWithName(idSkill, szAct, 0, bHideFX);
QueueSkillAttackActionWithName(idSkill, szAct2Air, 0, bHideFX);
// if (pRightHandWeapon && IsUsingMagicWeapon())
// pRightHandWeapon.QueueAction(_GenWeaponActionName(szAct, m_iGender), 0, ACT_CASTSKILL, false, false, bHideFX);
// nTime2 = m_pPlayerModel.GetComActTimeSpanByName(szAct);
// pAct = m_pPlayerModel.GetComActByName(szAct);
// if (pAct) bInfinite |= pAct.IsInfinite();
nTime2 = 1000; // 临时值 / Temporary value
}
// int nExecuteTime = GNET::ElementSkill::GetExecuteTime(idSkill, 0); // 获取技能执行时间 / Get skill execute time
int nExecuteTime = 2000; // 临时值 / Temporary value
// 调整动画速度以匹配攻击速度 / Adjust animation speed to match attack speed
if (!bInfinite)
{
if (nExecuteTime > 0)
{
float vScale = (nTime1 + nTime2) / (float)nExecuteTime;
// m_pPlayerModel.SetPlaySpeed(vScale * 1.2f);
// if (pRightHandWeapon && IsUsingMagicWeapon())
// pRightHandWeapon.SetPlaySpeed(vScale * 1.2f);
}
piAttackTime = nTime1 + nTime2;
}
else
@@ -4091,7 +4076,8 @@ namespace BrewMonster
public bool IsLoop;
public CECAttackEvent AttackEvent;
public int Rank;
public PlayActionEvent(string animationName, int iTransTime, bool isForceStopPrevious = false, CECAttackEvent attackEvent = null, bool isLoop = false)
public float PlaySpeed;
public PlayActionEvent(string animationName, int iTransTime, bool isForceStopPrevious = false, CECAttackEvent attackEvent = null, bool isLoop = false, float playSpeed = 1.0f)
{
this.ChannelAct = null;
this.AnimationName = animationName;
@@ -4100,8 +4086,9 @@ namespace BrewMonster
AttackEvent = attackEvent;
IsLoop = isLoop;
Rank = 0;
PlaySpeed = playSpeed;
}
public PlayActionEvent(ref ChannelAct channelAct, string animationName, int iTransTime, bool isForceStopPrevious = false, CECAttackEvent attackEvent = null, bool isLoop = false, int rank = 0)
public PlayActionEvent(ref ChannelAct channelAct, string animationName, int iTransTime, bool isForceStopPrevious = false, CECAttackEvent attackEvent = null, bool isLoop = false, int rank = 0, float playSpeed = 1.0f)
{
this.ChannelAct = channelAct;
this.AnimationName = animationName;
@@ -4110,6 +4097,7 @@ namespace BrewMonster
AttackEvent = attackEvent;
IsLoop = isLoop;
Rank = rank;
PlaySpeed = playSpeed;
}
}
public struct PLAYER_ACTION