@@ -2895,6 +2895,11 @@ void CClientPed::StreamedInPulse(bool bDoStandardPulses)
28952895 }
28962896 }
28972897
2898+ // Are we need to update anim speed & progress?
2899+ // We need to do it here because the anim starts on the next frame after calling RunNamedAnimation
2900+ if (m_pAnimationBlock && m_AnimationCache.progressWaitForStreamIn && IsAnimationInProgress ())
2901+ UpdateAnimationProgressAndSpeed ();
2902+
28982903 // Update our alpha
28992904 unsigned char ucAlpha = m_ucAlpha;
29002905 // Are we in a different interior to the camera? set our alpha to 0
@@ -3685,8 +3690,8 @@ void CClientPed::_CreateModel()
36853690 Kill (WEAPONTYPE_UNARMED, 0 , false , true );
36863691 }
36873692
3688- // Are we still playing animation?
3689- if ((m_AnimationCache. bLoop || m_AnimationCache. bFreezeLastFrame || m_AnimationCache. progressWaitForStreamIn ) && m_pAnimationBlock )
3693+ // Are we still playing a animation?
3694+ if (m_pAnimationBlock && IsAnimationInProgress () )
36903695 {
36913696 if (m_bisCurrentAnimationCustom)
36923697 {
@@ -3963,8 +3968,8 @@ void CClientPed::_ChangeModel()
39633968 }
39643969 m_bDontChangeRadio = false ;
39653970
3966- // Are we still playing a looped animation?
3967- if ((m_AnimationCache. bLoop || m_AnimationCache. bFreezeLastFrame || m_AnimationCache. progressWaitForStreamIn ) && m_pAnimationBlock )
3971+ // Are we still playing a animation?
3972+ if (m_pAnimationBlock && IsAnimationInProgress () )
39683973 {
39693974 if (m_bisCurrentAnimationCustom)
39703975 {
@@ -5728,7 +5733,23 @@ bool CClientPed::IsRunningAnimation()
57285733 }
57295734 return false ;
57305735 }
5731- return (m_AnimationCache.bLoop && m_pAnimationBlock);
5736+ return (m_AnimationCache.bLoop || m_AnimationCache.bFreezeLastFrame && m_pAnimationBlock);
5737+ }
5738+
5739+ bool CClientPed::IsAnimationInProgress ()
5740+ {
5741+ bool constAnim = m_AnimationCache.bLoop || m_AnimationCache.bFreezeLastFrame ;
5742+
5743+ if (!m_pAnimationBlock)
5744+ return constAnim;
5745+
5746+ float elapsedTime = static_cast <float >(GetTimestamp () - m_AnimationCache.startTime ) / 1000 .0f ;
5747+
5748+ auto animBlendHierarchy = g_pGame->GetAnimManager ()->GetAnimation (m_AnimationCache.strName .c_str (), m_pAnimationBlock);
5749+ if (!animBlendHierarchy)
5750+ return constAnim;
5751+
5752+ return constAnim || elapsedTime < animBlendHierarchy->GetTotalTime ();
57325753}
57335754
57345755void CClientPed::RunNamedAnimation (std::unique_ptr<CAnimBlock>& pBlock, const char * szAnimName, int iTime, int iBlend, bool bLoop, bool bUpdatePosition,
@@ -5816,10 +5837,6 @@ void CClientPed::RunNamedAnimation(std::unique_ptr<CAnimBlock>& pBlock, const ch
58165837 m_AnimationCache.bUpdatePosition = bUpdatePosition;
58175838 m_AnimationCache.bInterruptable = bInterruptable;
58185839 m_AnimationCache.bFreezeLastFrame = bFreezeLastFrame;
5819- m_AnimationCache.progress = 0 .0f ;
5820- m_AnimationCache.speed = 1 .0f ;
5821- m_AnimationCache.progressWaitForStreamIn = false ;
5822- m_AnimationCache.elapsedTime = 0 .0f ;
58235840}
58245841
58255842void CClientPed::KillAnimation ()
@@ -5858,39 +5875,45 @@ void CClientPed::RunAnimationFromCache()
58585875 if (!m_pAnimationBlock)
58595876 return ;
58605877
5861- bool needCalcProgress = m_AnimationCache.progressWaitForStreamIn ;
5862- float elapsedTime = m_AnimationCache.elapsedTime ;
5863-
58645878 // Copy our name incase it gets deleted
58655879 std::string animName = m_AnimationCache.strName ;
58665880
58675881 // Run our animation
58685882 RunNamedAnimation (m_pAnimationBlock, animName.c_str (), m_AnimationCache.iTime , m_AnimationCache.iBlend , m_AnimationCache.bLoop , m_AnimationCache.bUpdatePosition , m_AnimationCache.bInterruptable , m_AnimationCache.bFreezeLastFrame );
58695883
5870- auto animAssoc = g_pGame->GetAnimManager ()->RpAnimBlendClumpGetAssociation (GetClump (), animName.c_str ());
5884+ // Set anim progress & speed
5885+ m_AnimationCache.progressWaitForStreamIn = true ;
5886+ }
5887+
5888+ void CClientPed::UpdateAnimationProgressAndSpeed ()
5889+ {
5890+ if (!m_AnimationCache.progressWaitForStreamIn )
5891+ return ;
5892+
5893+ // Get current anim
5894+ auto animAssoc = g_pGame->GetAnimManager ()->RpAnimBlendClumpGetAssociation (GetClump (), m_AnimationCache.strName .c_str ());
58715895 if (!animAssoc)
58725896 return ;
58735897
5874- // If the anim is synced from the server side, we need to calculate the progress
5875- float progress = m_AnimationCache.progress ;
5876- if (needCalcProgress)
5877- {
5878- float animLength = animAssoc->GetLength ();
5898+ float animLength = animAssoc->GetLength ();
5899+ float progress = 0 .0f ;
5900+ float elapsedTime = static_cast <float >(GetTimestamp () - m_AnimationCache.startTime ) / 1000 .0f ;
58795901
5880- if (m_AnimationCache.bFreezeLastFrame ) // time and loop is ignored if freezeLastFrame is true
5881- progress = (elapsedTime / animLength) * m_AnimationCache.speed ;
5902+ if (m_AnimationCache.bFreezeLastFrame ) // time and loop is ignored if freezeLastFrame is true
5903+ progress = (elapsedTime / animLength) * m_AnimationCache.speed ;
5904+ else
5905+ {
5906+ if (m_AnimationCache.bLoop )
5907+ progress = std::fmod (elapsedTime * m_AnimationCache.speed , animLength) / animLength;
58825908 else
5883- {
5884- if (m_AnimationCache.bLoop )
5885- progress = std::fmod (elapsedTime * m_AnimationCache.speed , animLength) / animLength;
5886- else
5887- // For non-looped animations, limit duration to animLength if time exceeds it
5888- progress = (elapsedTime / (m_AnimationCache.iTime <= animLength ? m_AnimationCache.iTime : animLength)) * m_AnimationCache.speed ;
5889- }
5909+ // For non-looped animations, limit duration to animLength if time exceeds it
5910+ progress = (elapsedTime / (m_AnimationCache.iTime <= animLength ? m_AnimationCache.iTime : animLength)) * m_AnimationCache.speed ;
58905911 }
58915912
58925913 animAssoc->SetCurrentProgress (std::clamp (progress, 0 .0f , 1 .0f ));
58935914 animAssoc->SetCurrentSpeed (m_AnimationCache.speed );
5915+
5916+ m_AnimationCache.progressWaitForStreamIn = false ;
58945917}
58955918
58965919void CClientPed::PostWeaponFire ()
0 commit comments