@@ -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 {
@@ -5731,7 +5736,23 @@ bool CClientPed::IsRunningAnimation()
57315736 }
57325737 return false ;
57335738 }
5734- return (m_AnimationCache.bLoop && m_pAnimationBlock);
5739+ return (m_AnimationCache.bLoop || m_AnimationCache.bFreezeLastFrame ) && m_pAnimationBlock;
5740+ }
5741+
5742+ bool CClientPed::IsAnimationInProgress ()
5743+ {
5744+ bool constAnim = m_AnimationCache.bLoop || m_AnimationCache.bFreezeLastFrame ;
5745+
5746+ if (!m_pAnimationBlock)
5747+ return constAnim;
5748+
5749+ float elapsedTime = static_cast <float >(GetTimestamp () - m_AnimationCache.startTime ) / 1000 .0f ;
5750+
5751+ auto animBlendHierarchy = g_pGame->GetAnimManager ()->GetAnimation (m_AnimationCache.strName .c_str (), m_pAnimationBlock);
5752+ if (!animBlendHierarchy)
5753+ return constAnim;
5754+
5755+ return constAnim || elapsedTime < animBlendHierarchy->GetTotalTime ();
57355756}
57365757
57375758void CClientPed::RunNamedAnimation (std::unique_ptr<CAnimBlock>& pBlock, const char * szAnimName, int iTime, int iBlend, bool bLoop, bool bUpdatePosition,
@@ -5819,10 +5840,6 @@ void CClientPed::RunNamedAnimation(std::unique_ptr<CAnimBlock>& pBlock, const ch
58195840 m_AnimationCache.bUpdatePosition = bUpdatePosition;
58205841 m_AnimationCache.bInterruptable = bInterruptable;
58215842 m_AnimationCache.bFreezeLastFrame = bFreezeLastFrame;
5822- m_AnimationCache.progress = 0 .0f ;
5823- m_AnimationCache.speed = 1 .0f ;
5824- m_AnimationCache.progressWaitForStreamIn = false ;
5825- m_AnimationCache.elapsedTime = 0 .0f ;
58265843}
58275844
58285845void CClientPed::KillAnimation ()
@@ -5861,39 +5878,45 @@ void CClientPed::RunAnimationFromCache()
58615878 if (!m_pAnimationBlock)
58625879 return ;
58635880
5864- bool needCalcProgress = m_AnimationCache.progressWaitForStreamIn ;
5865- float elapsedTime = m_AnimationCache.elapsedTime ;
5866-
58675881 // Copy our name incase it gets deleted
58685882 std::string animName = m_AnimationCache.strName ;
58695883
58705884 // Run our animation
58715885 RunNamedAnimation (m_pAnimationBlock, animName.c_str (), m_AnimationCache.iTime , m_AnimationCache.iBlend , m_AnimationCache.bLoop , m_AnimationCache.bUpdatePosition , m_AnimationCache.bInterruptable , m_AnimationCache.bFreezeLastFrame );
58725886
5873- auto animAssoc = g_pGame->GetAnimManager ()->RpAnimBlendClumpGetAssociation (GetClump (), animName.c_str ());
5887+ // Set anim progress & speed
5888+ m_AnimationCache.progressWaitForStreamIn = true ;
5889+ }
5890+
5891+ void CClientPed::UpdateAnimationProgressAndSpeed ()
5892+ {
5893+ if (!m_AnimationCache.progressWaitForStreamIn )
5894+ return ;
5895+
5896+ // Get current anim
5897+ auto animAssoc = g_pGame->GetAnimManager ()->RpAnimBlendClumpGetAssociation (GetClump (), m_AnimationCache.strName .c_str ());
58745898 if (!animAssoc)
58755899 return ;
58765900
5877- // If the anim is synced from the server side, we need to calculate the progress
5878- float progress = m_AnimationCache.progress ;
5879- if (needCalcProgress)
5880- {
5881- float animLength = animAssoc->GetLength ();
5901+ float animLength = animAssoc->GetLength ();
5902+ float progress = 0 .0f ;
5903+ float elapsedTime = static_cast <float >(GetTimestamp () - m_AnimationCache.startTime ) / 1000 .0f ;
58825904
5883- if (m_AnimationCache.bFreezeLastFrame ) // time and loop is ignored if freezeLastFrame is true
5884- progress = (elapsedTime / animLength) * m_AnimationCache.speed ;
5905+ if (m_AnimationCache.bFreezeLastFrame ) // time and loop is ignored if freezeLastFrame is true
5906+ progress = (elapsedTime / animLength) * m_AnimationCache.speed ;
5907+ else
5908+ {
5909+ if (m_AnimationCache.bLoop )
5910+ progress = std::fmod (elapsedTime * m_AnimationCache.speed , animLength) / animLength;
58855911 else
5886- {
5887- if (m_AnimationCache.bLoop )
5888- progress = std::fmod (elapsedTime * m_AnimationCache.speed , animLength) / animLength;
5889- else
5890- // For non-looped animations, limit duration to animLength if time exceeds it
5891- progress = (elapsedTime / (m_AnimationCache.iTime <= animLength ? m_AnimationCache.iTime : animLength)) * m_AnimationCache.speed ;
5892- }
5912+ // For non-looped animations, limit duration to animLength if time exceeds it
5913+ progress = (elapsedTime / (m_AnimationCache.iTime <= animLength ? m_AnimationCache.iTime : animLength)) * m_AnimationCache.speed ;
58935914 }
58945915
58955916 animAssoc->SetCurrentProgress (std::clamp (progress, 0 .0f , 1 .0f ));
58965917 animAssoc->SetCurrentSpeed (m_AnimationCache.speed );
5918+
5919+ m_AnimationCache.progressWaitForStreamIn = false ;
58975920}
58985921
58995922void CClientPed::PostWeaponFire ()
0 commit comments