Skip to content

Commit 3f4e394

Browse files
committed
[FIX] Unloading IFP will allow gateway animation to play instead of custom
Custom animation was not playing if you unloaded IFP. I used a shared_ptr to fix this problem. Also, unloading IFP resulted in looped animations to play gateway animation instead of custom, so fixed that as well.
1 parent 679982d commit 3f4e394

File tree

3 files changed

+45
-67
lines changed

3 files changed

+45
-67
lines changed

Client/mods/deathmatch/logic/CClientGame.cpp

Lines changed: 38 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -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

37273727
void CClientGame::StaticPreWorldProcessHandler ( void )
@@ -4038,7 +4038,6 @@ typedef void (__thiscall* hCAnimBlendStaticAssociation_Init)
40384038
bool 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-
68976858
CClientPed * 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

69176878
void 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
}

Client/multiplayer_sa/CMultiplayerSA_CustomAnimations.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -312,13 +312,15 @@ void _declspec(naked) HOOK_CAnimManager_BlendAnimation_Hierarchy ()
312312

313313
// call our handler function
314314
mov edx, [ebp+28h+4+12]
315-
push edx // pClump
316-
lea edx, [ebp-4]
315+
lea ecx, [ebp+28h+4+20]
316+
push edx // pClump
317+
push ecx // pFlags
318+
lea edx, [ebp-4]
317319
push edx // CAnimBlendHierarchySAInterface ** pOutAnimHierarchy
318-
mov edx, [esp+24]
320+
mov edx, [esp+28]
319321
push edx // pAnimAssociation
320322
call m_pBlendAnimationHierarchyHandler //CAnimManager_BlendAnimation_Hierarchy
321-
add esp, 0Ch
323+
add esp, 10h
322324

323325
mov ecx, [ebp-4] // pCustomAnimHierarchy
324326

Client/sdk/multiplayer/CMultiplayer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ typedef CAnimBlendAssociationSAInterface * ( AddAnimationHandler ) ( RpClump *
7373
typedef CAnimBlendAssociationSAInterface * ( AddAnimationAndSyncHandler ) ( RpClump * pClump, CAnimBlendAssociationSAInterface * pAnimAssocToSyncWith, AssocGroupId animGroup, AnimationId animID );
7474
typedef void ( CAnimBlendAssocDestructorHandler ) ( CAnimBlendAssociationSAInterface * pThis );
7575
typedef bool ( AssocGroupCopyAnimationHandler ) ( CAnimBlendStaticAssociationSAInterface * pOutAnimStaticAssoc, CAnimBlendAssociationSAInterface * pAnimAssoc, RpClump * pClump, CAnimBlendAssocGroupSAInterface * pAnimAssocGroup, AnimationId animID );
76-
typedef bool ( BlendAnimationHierarchyHandler ) ( CAnimBlendAssociationSAInterface * pAnimAssoc, CAnimBlendHierarchySAInterface ** pOutAnimHierarchy, RpClump * pClump );
76+
typedef bool ( BlendAnimationHierarchyHandler ) ( CAnimBlendAssociationSAInterface * pAnimAssoc, CAnimBlendHierarchySAInterface ** pOutAnimHierarchy, int * pFlags, RpClump * pClump );
7777
typedef bool ( ProcessCollisionHandler ) ( class CEntitySAInterface* pThisInterface, class CEntitySAInterface* pOtherInterface );
7878
typedef bool ( VehicleCollisionHandler ) ( class CVehicleSAInterface* pCollidingVehicle, class CEntitySAInterface* pCollidedVehicle, int iModelIndex, float fDamageImpulseMag, float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity );
7979
typedef bool ( VehicleDamageHandler ) ( CEntitySAInterface* pVehicle, float fLoss, CEntitySAInterface* pAttacker, eWeaponType weaponType, const CVector& vecDamagePos, uchar ucTyre );

0 commit comments

Comments
 (0)