@@ -2893,6 +2893,11 @@ void CClientPed::StreamedInPulse(bool bDoStandardPulses)
28932893 }
28942894 }
28952895
2896+ // Are we need to update anim speed & progress?
2897+ // We need to do it here because the anim starts on the next frame after calling RunNamedAnimation
2898+ if (m_pAnimationBlock && m_AnimationCache.progressWaitForStreamIn && IsAnimationInProgress ())
2899+ UpdateAnimationProgressAndSpeed ();
2900+
28962901 // Update our alpha
28972902 unsigned char ucAlpha = m_ucAlpha;
28982903 // Are we in a different interior to the camera? set our alpha to 0
@@ -3683,8 +3688,8 @@ void CClientPed::_CreateModel()
36833688 Kill (WEAPONTYPE_UNARMED, 0 , false , true );
36843689 }
36853690
3686- // Are we still playing animation?
3687- if ((m_AnimationCache. bLoop || m_AnimationCache. bFreezeLastFrame || m_AnimationCache. progressWaitForStreamIn ) && m_pAnimationBlock )
3691+ // Are we still playing a animation?
3692+ if (m_pAnimationBlock && IsAnimationInProgress () )
36883693 {
36893694 if (m_bisCurrentAnimationCustom)
36903695 {
@@ -3961,8 +3966,8 @@ void CClientPed::_ChangeModel()
39613966 }
39623967 m_bDontChangeRadio = false ;
39633968
3964- // Are we still playing a looped animation?
3965- if ((m_AnimationCache. bLoop || m_AnimationCache. bFreezeLastFrame || m_AnimationCache. progressWaitForStreamIn ) && m_pAnimationBlock )
3969+ // Are we still playing a animation?
3970+ if (m_pAnimationBlock && IsAnimationInProgress () )
39663971 {
39673972 if (m_bisCurrentAnimationCustom)
39683973 {
@@ -5729,7 +5734,23 @@ bool CClientPed::IsRunningAnimation()
57295734 }
57305735 return false ;
57315736 }
5732- return (m_AnimationCache.bLoop && m_pAnimationBlock);
5737+ return (m_AnimationCache.bLoop || m_AnimationCache.bFreezeLastFrame ) && m_pAnimationBlock;
5738+ }
5739+
5740+ bool CClientPed::IsAnimationInProgress ()
5741+ {
5742+ bool constAnim = m_AnimationCache.bLoop || m_AnimationCache.bFreezeLastFrame ;
5743+
5744+ if (!m_pAnimationBlock)
5745+ return constAnim;
5746+
5747+ float elapsedTime = static_cast <float >(GetTimestamp () - m_AnimationCache.startTime ) / 1000 .0f ;
5748+
5749+ auto animBlendHierarchy = g_pGame->GetAnimManager ()->GetAnimation (m_AnimationCache.strName .c_str (), m_pAnimationBlock);
5750+ if (!animBlendHierarchy)
5751+ return constAnim;
5752+
5753+ return constAnim || elapsedTime < animBlendHierarchy->GetTotalTime ();
57335754}
57345755
57355756void CClientPed::RunNamedAnimation (std::unique_ptr<CAnimBlock>& pBlock, const char * szAnimName, int iTime, int iBlend, bool bLoop, bool bUpdatePosition,
@@ -5817,10 +5838,6 @@ void CClientPed::RunNamedAnimation(std::unique_ptr<CAnimBlock>& pBlock, const ch
58175838 m_AnimationCache.bUpdatePosition = bUpdatePosition;
58185839 m_AnimationCache.bInterruptable = bInterruptable;
58195840 m_AnimationCache.bFreezeLastFrame = bFreezeLastFrame;
5820- m_AnimationCache.progress = 0 .0f ;
5821- m_AnimationCache.speed = 1 .0f ;
5822- m_AnimationCache.progressWaitForStreamIn = false ;
5823- m_AnimationCache.elapsedTime = 0 .0f ;
58245841}
58255842
58265843void CClientPed::KillAnimation ()
@@ -5859,39 +5876,45 @@ void CClientPed::RunAnimationFromCache()
58595876 if (!m_pAnimationBlock)
58605877 return ;
58615878
5862- bool needCalcProgress = m_AnimationCache.progressWaitForStreamIn ;
5863- float elapsedTime = m_AnimationCache.elapsedTime ;
5864-
58655879 // Copy our name incase it gets deleted
58665880 std::string animName = m_AnimationCache.strName ;
58675881
58685882 // Run our animation
58695883 RunNamedAnimation (m_pAnimationBlock, animName.c_str (), m_AnimationCache.iTime , m_AnimationCache.iBlend , m_AnimationCache.bLoop , m_AnimationCache.bUpdatePosition , m_AnimationCache.bInterruptable , m_AnimationCache.bFreezeLastFrame );
58705884
5871- auto animAssoc = g_pGame->GetAnimManager ()->RpAnimBlendClumpGetAssociation (GetClump (), animName.c_str ());
5885+ // Set anim progress & speed
5886+ m_AnimationCache.progressWaitForStreamIn = true ;
5887+ }
5888+
5889+ void CClientPed::UpdateAnimationProgressAndSpeed ()
5890+ {
5891+ if (!m_AnimationCache.progressWaitForStreamIn )
5892+ return ;
5893+
5894+ // Get current anim
5895+ auto animAssoc = g_pGame->GetAnimManager ()->RpAnimBlendClumpGetAssociation (GetClump (), m_AnimationCache.strName .c_str ());
58725896 if (!animAssoc)
58735897 return ;
58745898
5875- // If the anim is synced from the server side, we need to calculate the progress
5876- float progress = m_AnimationCache.progress ;
5877- if (needCalcProgress)
5878- {
5879- float animLength = animAssoc->GetLength ();
5899+ float animLength = animAssoc->GetLength ();
5900+ float progress = 0 .0f ;
5901+ float elapsedTime = static_cast <float >(GetTimestamp () - m_AnimationCache.startTime ) / 1000 .0f ;
58805902
5881- if (m_AnimationCache.bFreezeLastFrame ) // time and loop is ignored if freezeLastFrame is true
5882- progress = (elapsedTime / animLength) * m_AnimationCache.speed ;
5903+ if (m_AnimationCache.bFreezeLastFrame ) // time and loop is ignored if freezeLastFrame is true
5904+ progress = (elapsedTime / animLength) * m_AnimationCache.speed ;
5905+ else
5906+ {
5907+ if (m_AnimationCache.bLoop )
5908+ progress = std::fmod (elapsedTime * m_AnimationCache.speed , animLength) / animLength;
58835909 else
5884- {
5885- if (m_AnimationCache.bLoop )
5886- progress = std::fmod (elapsedTime * m_AnimationCache.speed , animLength) / animLength;
5887- else
5888- // For non-looped animations, limit duration to animLength if time exceeds it
5889- progress = (elapsedTime / (m_AnimationCache.iTime <= animLength ? m_AnimationCache.iTime : animLength)) * m_AnimationCache.speed ;
5890- }
5910+ // For non-looped animations, limit duration to animLength if time exceeds it
5911+ progress = (elapsedTime / (m_AnimationCache.iTime <= animLength ? m_AnimationCache.iTime : animLength)) * m_AnimationCache.speed ;
58915912 }
58925913
58935914 animAssoc->SetCurrentProgress (std::clamp (progress, 0 .0f , 1 .0f ));
58945915 animAssoc->SetCurrentSpeed (m_AnimationCache.speed );
5916+
5917+ m_AnimationCache.progressWaitForStreamIn = false ;
58955918}
58965919
58975920void CClientPed::PostWeaponFire ()
0 commit comments