@@ -3719,9 +3719,9 @@ bool CClientGame::StaticAssocGroupCopyAnimationHandler ( CAnimBlendStaticAssocia
37193719 return g_pClientGame->AssocGroupCopyAnimationHandler ( pOutAnimStaticAssoc, pAnimAssoc, pClump, pAnimAssocGroup, animID );
37203720}
37213721
3722- bool CClientGame::StaticBlendAnimationHierarchyHandler ( CAnimBlendAssociationSAInterface * pAnimAssoc, CAnimBlendHierarchySAInterface ** pOutAnimHierarchy, RpClump * pClump )
3722+ bool CClientGame::StaticBlendAnimationHierarchyHandler ( CAnimBlendAssociationSAInterface * pAnimAssoc, CAnimBlendHierarchySAInterface ** pOutAnimHierarchy, int * pFlags, RpClump * pClump )
37233723{
3724- return g_pClientGame->BlendAnimationHierarchyHandler ( pAnimAssoc, pOutAnimHierarchy, pClump );
3724+ return g_pClientGame->BlendAnimationHierarchyHandler ( pAnimAssoc, pOutAnimHierarchy, pFlags, pClump );
37253725}
37263726
37273727void CClientGame::StaticPreWorldProcessHandler ( void )
@@ -4038,7 +4038,6 @@ typedef void (__thiscall* hCAnimBlendStaticAssociation_Init)
40384038bool CClientGame::AssocGroupCopyAnimationHandler ( CAnimBlendStaticAssociationSAInterface * pOutAnimStaticAssoc, CAnimBlendAssociationSAInterface * pAnimAssoc, RpClump * pClump, CAnimBlendAssocGroupSAInterface * pAnimAssocGroup, AnimationId animID )
40394039{
40404040 auto CAnimBlendStaticAssociation_Init = (hCAnimBlendStaticAssociation_Init)0x4CEC20 ;
4041-
40424041 bool isCustomAnimationToPlay = false ;
40434042
40444043 CAnimManager * pAnimationManager = g_pGame->GetAnimManager ();
@@ -4047,7 +4046,7 @@ bool CClientGame::AssocGroupCopyAnimationHandler ( CAnimBlendStaticAssociationSA
40474046 CClientPed * pClientPed = GetClientPedByClump ( *pClump );
40484047 if ( pClientPed != nullptr )
40494048 {
4050- auto pReplacedAnimation = pClientPed->getReplacedAnimation ( pOriginalAnimStaticAssoc->pAnimHeirarchy );
4049+ auto pReplacedAnimation = pClientPed->GetReplacedAnimation ( pOriginalAnimStaticAssoc->pAnimHeirarchy );
40514050 if ( pReplacedAnimation != nullptr )
40524051 {
40534052 std::shared_ptr < CIFPAnimations > pIFPAnimations = pReplacedAnimation->pIFP ->GetIFPAnimationsPointer ();
@@ -4071,55 +4070,46 @@ bool CClientGame::AssocGroupCopyAnimationHandler ( CAnimBlendStaticAssociationSA
40714070 // Total bones in clump. GTA SA is using 32 bones for peds/players
40724071 pOutAnimStaticAssoc->nNumBlendNodes = pOriginalAnimStaticAssoc->nNumBlendNodes ;
40734072 pOutAnimStaticAssoc->sFlags = pOriginalAnimStaticAssoc->sFlags ;
4074-
4075- printf (" CClientGame::AssocGroupCopyAnimationHandler: About to return sAnimGroup: %d | sAnimID: %d !\n " , pOutAnimStaticAssoc->sAnimGroup , pOutAnimStaticAssoc->sAnimID );
4076-
40774073 return isCustomAnimationToPlay;
40784074}
40794075
40804076
4081- bool CClientGame::BlendAnimationHierarchyHandler ( CAnimBlendAssociationSAInterface * pAnimAssoc, CAnimBlendHierarchySAInterface ** pOutAnimHierarchy, RpClump * pClump )
4077+ bool CClientGame::BlendAnimationHierarchyHandler ( CAnimBlendAssociationSAInterface * pAnimAssoc, CAnimBlendHierarchySAInterface ** pOutAnimHierarchy, int * pFlags, RpClump * pClump )
40824078{
40834079 bool isCustomAnimationToPlay = false ;
40844080
40854081 CAnimManager * pAnimationManager = g_pGame->GetAnimManager ();
40864082 CClientPed * pClientPed = GetClientPedByClump ( *pClump );
40874083 if ( pClientPed != nullptr )
40884084 {
4089- printf (" CClientGame::BlendAnimationHierarchyHandler: Found pClientPed\n " );
4090- if ( pClientPed->isNextAnimationCustom () )
4085+ if ( pClientPed->IsNextAnimationCustom () )
40914086 {
4092- const SString & strBlockName = pClientPed->GetNextAnimationCustomBlockName ( );
4093- std::shared_ptr < CClientIFP > pIFP = GetIFPPointerFromMap ( strBlockName );
4087+ std::shared_ptr < CClientIFP > pIFP = pClientPed->GetCustomAnimationIFP ( );
40944088 if ( pIFP )
40954089 {
40964090 const SString & strAnimationName = pClientPed->GetNextAnimationCustomName ( );
40974091 auto pCustomAnimBlendHierarchy = pIFP->GetAnimationHierarchy ( strAnimationName );
40984092 if ( pCustomAnimBlendHierarchy != nullptr )
40994093 {
4100- std::shared_ptr < CIFPAnimations > pIFPAnimations = pIFP->GetIFPAnimationsPointer ();
4094+ std::shared_ptr < CIFPAnimations > pIFPAnimations = pIFP->GetIFPAnimationsPointer ( );
41014095 InsertAnimationAssociationToMap ( pAnimAssoc, pIFPAnimations );
41024096
4103- pClientPed->setCurrentAnimationCustom ( true );
4104- pClientPed->setNextAnimationNormal ( );
4105-
4097+ pClientPed->SetCurrentAnimationCustom ( true );
4098+ pClientPed->SetNextAnimationNormal ( );
4099+
4100+ if ( pIFP->IsUnloading ( ) )
4101+ {
4102+ pClientPed->DereferenceCustomAnimationBlock ();
4103+ }
41064104 *pOutAnimHierarchy = pCustomAnimBlendHierarchy;
41074105 isCustomAnimationToPlay = true ;
41084106 return isCustomAnimationToPlay;
41094107 }
4110- else
4111- {
4112- printf (" CClientGame::BlendAnimationHierarchyHandler: could not find IFP animation hierarchy '%s'\n " , strAnimationName.c_str ());
4113- }
4114- }
4115- else
4116- {
4117- printf (" CClientGame::BlendAnimationHierarchyHandler: could not find IFP block name '%s'\n " , strBlockName.c_str ());
41184108 }
41194109 }
41204110
4121- pClientPed->setCurrentAnimationCustom ( false );
4122- pClientPed->setNextAnimationNormal ( );
4111+ pClientPed->SetCurrentAnimationCustom ( false );
4112+ pClientPed->SetNextAnimationNormal ( );
41234113 }
41244114 return isCustomAnimationToPlay;
41254115}
@@ -6855,45 +6845,16 @@ void CClientGame::RestreamModel ( unsigned short usModel )
68556845
68566846}
68576847
6858- void CClientGame::InsertIFPPointerToMap ( const SString & strBlockName, const std::shared_ptr < CClientIFP > & pIFP )
6859- {
6860- const SString mapKey = strBlockName.ToLower ( );
6861- if ( m_mapOfIfpPointers.count ( mapKey ) == 0 )
6862- {
6863- m_mapOfIfpPointers [ mapKey ] = pIFP;
6864- }
6865- }
6866-
6867- void CClientGame::RemoveIFPPointerFromMap ( const SString & strBlockName )
6868- {
6869- m_mapOfIfpPointers.erase ( strBlockName.ToLower ( ) );
6870- }
6871-
6872- std::shared_ptr < CClientIFP > CClientGame::GetIFPPointerFromMap ( const SString & strBlockName )
6848+ std::shared_ptr < CClientIFP > CClientGame::GetIFPPointerFromMap ( const unsigned int u32BlockNameHash )
68736849{
6874- const SString mapKey = strBlockName.ToLower ( );
6875- auto it = m_mapOfIfpPointers.find ( mapKey );
6850+ auto it = m_mapOfIfpPointers.find ( u32BlockNameHash );
68766851 if ( it != m_mapOfIfpPointers.end ( ) )
68776852 {
68786853 return it->second ;
68796854 }
68806855 return nullptr ;
68816856}
68826857
6883-
6884- void CClientGame::InsertPedPointerToMap ( CClientPed * pPed )
6885- {
6886- if ( m_mapOfPedPointers.count ( pPed ) == 0 )
6887- {
6888- m_mapOfPedPointers [ pPed ] = true ;
6889- }
6890- }
6891-
6892- void CClientGame::RemovePedPointerFromMap ( CClientPed * pPed )
6893- {
6894- m_mapOfPedPointers.erase ( pPed );
6895- }
6896-
68976858CClientPed * CClientGame::GetClientPedByClump ( const RpClump & Clump )
68986859{
68996860 for ( auto it = m_mapOfPedPointers.begin (); it != m_mapOfPedPointers.end (); it++ )
@@ -6916,13 +6877,28 @@ CClientPed * CClientGame::GetClientPedByClump ( const RpClump & Clump )
69166877
69176878void CClientGame::OnClientIFPUnload ( const std::shared_ptr < CClientIFP > & IFP )
69186879{
6919- // remove IFP animations from replaced animations of peds/players
6880+ IFP-> MarkAsUnloading ( );
69206881 for ( auto it = m_mapOfPedPointers.begin (); it != m_mapOfPedPointers.end (); it++ )
69216882 {
6922- CEntity * pEntity = it->first ->GetGameEntity ();
6923- if ( pEntity != nullptr )
6924- {
6925- it->first ->RestoreAnimations ( IFP );
6883+ // Remove IFP animations from replaced animations of peds/players
6884+ it->first ->RestoreAnimations ( IFP );
6885+
6886+ // Make sure that streamed in pulses or changing model does not accidently
6887+ // play our custom animation. We can do that by making the custom animation
6888+ // untriggerable
6889+ if ( it->first ->GetCustomAnimationBlockNameHash ( ) == IFP->GetBlockNameHash ( ) )
6890+ {
6891+ if ( it->first ->IsCustomAnimationPlaying ( ) )
6892+ {
6893+ it->first ->SetCustomAnimationUntriggerable ( );
6894+ }
6895+
6896+ // Important! As we are using a shared_ptr, we need to decrement the reference counter
6897+ // by setting the shared_ptr to nullptr, this will avoid memory leak
6898+ if ( !it->first ->IsNextAnimationCustom ( ) && it->first ->IsCurrentAnimationCustom ( ) )
6899+ {
6900+ it->first ->DereferenceCustomAnimationBlock ();
6901+ }
69266902 }
69276903 }
69286904}
0 commit comments