Skip to content

Commit f4d1c55

Browse files
authored
Merge pull request #5 from saml1er/custom_ifp_animations
Custom ifp animations [Fixed unloading]
2 parents cc41b27 + cc5b9ed commit f4d1c55

File tree

14 files changed

+682
-402
lines changed

14 files changed

+682
-402
lines changed

Client/mods/deathmatch/logic/CClientGame.cpp

Lines changed: 108 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ CClientGame::CClientGame ( bool bLocalPlay )
270270
g_pMultiplayer->SetPostWorldProcessHandler ( CClientGame::StaticPostWorldProcessHandler );
271271
g_pMultiplayer->SetPreFxRenderHandler ( CClientGame::StaticPreFxRenderHandler );
272272
g_pMultiplayer->SetPreHudRenderHandler ( CClientGame::StaticPreHudRenderHandler );
273+
g_pMultiplayer->SetCAnimBlendAssocDestructorHandler ( CClientGame::StaticCAnimBlendAssocDestructorHandler );
273274
g_pMultiplayer->SetAddAnimationHandler ( CClientGame::StaticAddAnimationHandler );
274275
g_pMultiplayer->SetAddAnimationAndSyncHandler ( CClientGame::StaticAddAnimationAndSyncHandler );
275276
g_pMultiplayer->SetAssocGroupCopyAnimationHandler ( CClientGame::StaticAssocGroupCopyAnimationHandler );
@@ -430,6 +431,7 @@ CClientGame::~CClientGame ( void )
430431
g_pMultiplayer->SetPostWorldProcessHandler ( NULL );
431432
g_pMultiplayer->SetPreFxRenderHandler ( NULL );
432433
g_pMultiplayer->SetPreHudRenderHandler ( NULL );
434+
g_pMultiplayer->SetCAnimBlendAssocDestructorHandler ( NULL );
433435
g_pMultiplayer->SetAddAnimationHandler ( NULL );
434436
g_pMultiplayer->SetAddAnimationAndSyncHandler ( NULL );
435437
g_pMultiplayer->SetAssocGroupCopyAnimationHandler ( NULL );
@@ -3697,6 +3699,11 @@ bool CClientGame::StaticChokingHandler ( unsigned char ucWeaponType )
36973699
return g_pClientGame->ChokingHandler ( ucWeaponType );
36983700
}
36993701

3702+
void CClientGame::StaticCAnimBlendAssocDestructorHandler ( CAnimBlendAssociationSAInterface * pThis )
3703+
{
3704+
g_pClientGame->CAnimBlendAssocDestructorHandler ( pThis );
3705+
}
3706+
37003707
CAnimBlendAssociationSAInterface * CClientGame::StaticAddAnimationHandler ( RpClump * pClump, AssocGroupId animGroup, AnimationId animID )
37013708
{
37023709
return g_pClientGame->AddAnimationHandler ( pClump, animGroup, animID );
@@ -3707,14 +3714,14 @@ CAnimBlendAssociationSAInterface * CClientGame::StaticAddAnimationAndSyncHandler
37073714
return g_pClientGame->AddAnimationAndSyncHandler ( pClump, pAnimAssocToSyncWith, animGroup, animID );
37083715
}
37093716

3710-
void CClientGame::StaticAssocGroupCopyAnimationHandler ( CAnimBlendStaticAssociationSAInterface * pOutAnimStaticAssoc, RpClump * pClump, CAnimBlendAssocGroupSAInterface * pAnimAssocGroup, AnimationId animID )
3717+
bool CClientGame::StaticAssocGroupCopyAnimationHandler ( CAnimBlendStaticAssociationSAInterface * pOutAnimStaticAssoc, SIFPAnimations ** pOutIFPAnimations, RpClump * pClump, CAnimBlendAssocGroupSAInterface * pAnimAssocGroup, AnimationId animID )
37113718
{
3712-
g_pClientGame->AssocGroupCopyAnimationHandler ( pOutAnimStaticAssoc, pClump, pAnimAssocGroup, animID );
3719+
return g_pClientGame->AssocGroupCopyAnimationHandler ( pOutAnimStaticAssoc, pOutIFPAnimations, pClump, pAnimAssocGroup, animID );
37133720
}
37143721

3715-
CAnimBlendHierarchySAInterface * CClientGame::StaticBlendAnimationHierarchyHandler ( RpClump * pClump, CAnimBlendHierarchySAInterface * pAnimHierarchy, int flags, float fBlendDelta )
3722+
bool CClientGame::StaticBlendAnimationHierarchyHandler ( SIFPAnimations ** pOutIFPAnimations, CAnimBlendHierarchySAInterface ** pOutAnimHierarchy, RpClump * pClump )
37163723
{
3717-
return g_pClientGame->BlendAnimationHierarchyHandler ( pClump, pAnimHierarchy, flags, fBlendDelta );
3724+
return g_pClientGame->BlendAnimationHierarchyHandler ( pOutIFPAnimations, pOutAnimHierarchy, pClump );
37183725
}
37193726

37203727
void CClientGame::StaticPreWorldProcessHandler ( void )
@@ -3999,51 +4006,63 @@ bool CClientGame::ChokingHandler ( unsigned char ucWeaponType )
39994006
}
40004007

40014008

4009+
void CClientGame::CAnimBlendAssocDestructorHandler ( CAnimBlendAssociationSAInterface * pThis )
4010+
{
4011+
//printf("CClientGame::CAnimBlendAssocDestructorHandler called! sAnimID: %d\n", pThis->sAnimID);
4012+
}
40024013

40034014

40044015
CAnimBlendAssociationSAInterface * CClientGame::AddAnimationHandler ( RpClump * pClump, AssocGroupId animGroup, AnimationId animID )
40054016
{
4006-
printf ( "AddAnimationHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID );
4017+
//printf ( "AddAnimationHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID );
40074018
return nullptr;
40084019
}
40094020

4021+
40104022
CAnimBlendAssociationSAInterface * CClientGame::AddAnimationAndSyncHandler ( RpClump * pClump, CAnimBlendAssociationSAInterface * pAnimAssocToSyncWith, AssocGroupId animGroup, AnimationId animID )
40114023
{
4012-
printf ( "AddAnimationAndSyncHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID );
4024+
//printf ( "AddAnimationAndSyncHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID );
40134025
return nullptr;
40144026
}
40154027

4028+
40164029
typedef void (__thiscall* hCAnimBlendStaticAssociation_Init)
40174030
(
40184031
CAnimBlendStaticAssociationSAInterface * pThis,
40194032
RpClump * Clump,
40204033
CAnimBlendHierarchySAInterface * pAnimBlendHierarchy
40214034
);
40224035

4023-
void CClientGame::AssocGroupCopyAnimationHandler ( CAnimBlendStaticAssociationSAInterface * pOutAnimStaticAssoc, RpClump * pClump, CAnimBlendAssocGroupSAInterface * pAnimAssocGroup, AnimationId animID )
4024-
{
4025-
printf ("AssocGroupCopyAnimationHandler called!\n");
40264036

4037+
bool CClientGame::AssocGroupCopyAnimationHandler ( CAnimBlendStaticAssociationSAInterface * pOutAnimStaticAssoc, SIFPAnimations ** pOutIFPAnimations, RpClump * pClump, CAnimBlendAssocGroupSAInterface * pAnimAssocGroup, AnimationId animID )
4038+
{
40274039
auto CAnimBlendStaticAssociation_Init = (hCAnimBlendStaticAssociation_Init)0x4CEC20;
40284040

4041+
bool isCustomAnimationToPlay = false;
40294042
CAnimManager * pAnimationManager = g_pGame->GetAnimManager();
40304043
auto pOriginalAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation ( pAnimAssocGroup->groupID, animID );
40314044

40324045
CClientPed * pClientPed = GetClientPedByClump ( *pClump );
40334046
if ( pClientPed != nullptr )
40344047
{
4035-
auto pReplacedAnimHeirarchyInterface = pClientPed->getReplacedAnimation ( pOriginalAnimStaticAssoc->pAnimHeirarchy );
4036-
if ( pReplacedAnimHeirarchyInterface != nullptr )
4037-
{ // Play our custom animation instead of default
4038-
CAnimBlendStaticAssociation_Init ( pOutAnimStaticAssoc, pClump, pReplacedAnimHeirarchyInterface );
4039-
}
4040-
else
4041-
{ // Play default internal animation
4042-
CAnimBlendStaticAssociation_Init ( pOutAnimStaticAssoc, pClump, pOriginalAnimStaticAssoc->pAnimHeirarchy );
4048+
auto pReplacedAnimation = pClientPed->getReplacedAnimation ( pOriginalAnimStaticAssoc->pAnimHeirarchy );
4049+
if ( pReplacedAnimation != nullptr )
4050+
{
4051+
if ( pReplacedAnimation->pIFP->isIFPLoaded ( ) )
4052+
{
4053+
SIFPAnimations * pIFPAnimations = pReplacedAnimation->pIFP->GetIFPAnimationsPointer ();
4054+
pIFPAnimations->iReferences ++;
4055+
// Play our custom animation instead of default
4056+
*pOutIFPAnimations = pIFPAnimations;
4057+
CAnimBlendStaticAssociation_Init ( pOutAnimStaticAssoc, pClump, pReplacedAnimation->pAnimationHierarchy );
4058+
isCustomAnimationToPlay = true;
4059+
}
40434060
}
40444061
}
4045-
else
4046-
{ // Play default internal animation
4062+
4063+
if ( !isCustomAnimationToPlay )
4064+
{
4065+
// Play default internal animation
40474066
CAnimBlendStaticAssociation_Init ( pOutAnimStaticAssoc, pClump, pOriginalAnimStaticAssoc->pAnimHeirarchy );
40484067
}
40494068

@@ -4053,17 +4072,21 @@ void CClientGame::AssocGroupCopyAnimationHandler ( CAnimBlendStaticAssociationSA
40534072
// Total bones in clump. GTA SA is using 32 bones for peds/players
40544073
pOutAnimStaticAssoc->nNumBlendNodes = pOriginalAnimStaticAssoc->nNumBlendNodes;
40554074
pOutAnimStaticAssoc->sFlags = pOriginalAnimStaticAssoc->sFlags;
4075+
4076+
printf(" CClientGame::AssocGroupCopyAnimationHandler: About to return sAnimGroup: %d | sAnimID: %d !\n", pOutAnimStaticAssoc->sAnimGroup, pOutAnimStaticAssoc->sAnimID);
4077+
return isCustomAnimationToPlay;
40564078
}
40574079

4058-
CAnimBlendHierarchySAInterface * CClientGame::BlendAnimationHierarchyHandler ( RpClump * pClump, CAnimBlendHierarchySAInterface * pAnimHierarchy, int flags, float fBlendDelta )
4080+
4081+
bool CClientGame::BlendAnimationHierarchyHandler ( SIFPAnimations ** pOutIFPAnimations, CAnimBlendHierarchySAInterface ** pOutAnimHierarchy, RpClump * pClump )
40594082
{
4060-
printf("CClientGame::BlendAnimationHierarchyHandler called | pClump: %p\n", (void*)pClump);
4083+
bool isCustomAnimationToPlay = false;
40614084

40624085
CAnimManager * pAnimationManager = g_pGame->GetAnimManager();
4063-
CClientPed * pClientPed = GetClientPedByClump ( *pClump ); //pAnimationManager->GetPedPointerFromMap ( pClump ); //m_pRootEntity->GetClientPedByClump ( *pClump );
4086+
CClientPed * pClientPed = GetClientPedByClump ( *pClump );
40644087
if ( pClientPed != nullptr )
40654088
{
4066-
printf ("BlendAnimationHierarchyHandler: Found pClientPed\n");
4089+
printf ("CClientGame::BlendAnimationHierarchyHandler: Found pClientPed\n");
40674090
if ( pClientPed->isNextAnimationCustom () )
40684091
{
40694092
const SString & strBlockName = pClientPed->GetNextAnimationCustomBlockName ( );
@@ -4074,36 +4097,38 @@ CAnimBlendHierarchySAInterface * CClientGame::BlendAnimationHierarchyHandler ( R
40744097
auto pCustomAnimBlendHierarchy = pIFP->GetAnimationHierarchy ( strAnimationName );
40754098
if ( pCustomAnimBlendHierarchy != nullptr )
40764099
{
4077-
printf ("BlendAnimationHierarchyHandler: Found Hierarchy, returning \n");
4078-
4079-
pClientPed->setCurrentAnimationCustom ( true );
4080-
4081-
// Modifying a hierarchy like this is just bad, it's much better to create a new CAnimBlendHierarchySAInterface for every animation
4082-
// and then delete it once animation is over
4083-
pCustomAnimBlendHierarchy->iHashKey = pAnimHierarchy->iHashKey;
4084-
pCustomAnimBlendHierarchy->iAnimBlockID = pAnimHierarchy->iAnimBlockID;
4085-
pClientPed->setNextAnimationNormal ( );
4086-
return pCustomAnimBlendHierarchy;
4100+
if ( pIFP->isIFPLoaded ( ) )
4101+
{
4102+
SIFPAnimations * pIFPAnimations = pIFP->GetIFPAnimationsPointer ();
4103+
pIFPAnimations->iReferences ++;
4104+
4105+
pClientPed->setCurrentAnimationCustom ( true );
4106+
pClientPed->setNextAnimationNormal ( );
4107+
4108+
*pOutIFPAnimations = pIFPAnimations;
4109+
*pOutAnimHierarchy = pCustomAnimBlendHierarchy;
4110+
isCustomAnimationToPlay = true;
4111+
return isCustomAnimationToPlay;
4112+
}
40874113
}
40884114
else
40894115
{
4090-
printf ("BlendAnimationHierarchyHandler: could not find IFP animation hierarchy '%s'\n", strAnimationName.c_str());
4116+
printf ("CClientGame::BlendAnimationHierarchyHandler: could not find IFP animation hierarchy '%s'\n", strAnimationName.c_str());
40914117
}
40924118
}
40934119
else
40944120
{
4095-
printf("BlendAnimationHierarchyHandler: could not find IFP block name '%s'\n", strBlockName.c_str());
4121+
printf("CClientGame::BlendAnimationHierarchyHandler: could not find IFP block name '%s'\n", strBlockName.c_str());
40964122
}
40974123
}
4098-
else
4099-
{
4100-
pClientPed->setCurrentAnimationCustom ( false );
4101-
}
4124+
4125+
pClientPed->setCurrentAnimationCustom ( false );
41024126
pClientPed->setNextAnimationNormal ( );
41034127
}
4104-
return pAnimHierarchy;
4128+
return isCustomAnimationToPlay;
41054129
}
41064130

4131+
41074132
bool CClientGame::ProcessCollisionHandler ( CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface )
41084133
{
41094134
if ( pThisInterface == pOtherInterface )
@@ -6892,7 +6917,7 @@ CClientPed * CClientGame::GetClientPedByClump ( const RpClump & Clump )
68926917
return nullptr;
68936918
}
68946919

6895-
void CClientGame::onClientIFPUnload ( const CClientIFP & IFP )
6920+
void CClientGame::OnClientIFPUnload ( const CClientIFP & IFP )
68966921
{
68976922
// remove IFP animations from replaced animations of peds/players
68986923
for ( auto it = m_mapOfPedPointers.begin(); it != m_mapOfPedPointers.end(); it++ )
@@ -6904,3 +6929,45 @@ void CClientGame::onClientIFPUnload ( const CClientIFP & IFP )
69046929
}
69056930
}
69066931
}
6932+
6933+
void CClientGame::DeleteIFPAnimations ( SIFPAnimations * pIFPAnimations )
6934+
{
6935+
if ( pIFPAnimations->iReferences == 0 )
6936+
{
6937+
printf("CClientGame::UnloadIFPAnimations (): iReferences are Zero\n");
6938+
6939+
hCMemoryMgr_Free OLD_CMemoryMgr_Free = (hCMemoryMgr_Free)0x0072F430;
6940+
auto OLD_CAnimBlendHierarchy_RemoveFromUncompressedCache = (hCAnimBlendHierarchy_RemoveFromUncompressedCache)0x004D42A0;
6941+
6942+
for ( size_t i = 0; i < pIFPAnimations->vecAnimations.size(); i++ )
6943+
{
6944+
IFP_Animation * ifpAnimation = &pIFPAnimations->vecAnimations[i];
6945+
6946+
OLD_CAnimBlendHierarchy_RemoveFromUncompressedCache ( (int)&ifpAnimation->Hierarchy );
6947+
6948+
for (unsigned short SequenceIndex = 0; SequenceIndex < ifpAnimation->Hierarchy.m_nSeqCount; SequenceIndex++)
6949+
{
6950+
_CAnimBlendSequence * pSequence = (_CAnimBlendSequence*)((BYTE*)ifpAnimation->Hierarchy.m_pSequences + (sizeof(_CAnimBlendSequence) * SequenceIndex));
6951+
6952+
if ( !( (pSequence->m_nFlags >> 3) & 1 ) ) // If ( !OneBigChunkForAllSequences )
6953+
{
6954+
OLD_CMemoryMgr_Free ( pSequence->m_pFrames ); //*(void **)(pThis + 8)); //pSequence->m_pFrames );
6955+
}
6956+
else
6957+
{
6958+
if ( SequenceIndex == 0 )
6959+
{
6960+
// All frames of all sequences are allocated on one memory block, so free that one
6961+
// and break the loop
6962+
OLD_CMemoryMgr_Free ( pSequence->m_pFrames );
6963+
break;
6964+
}
6965+
}
6966+
6967+
}
6968+
delete ifpAnimation->pSequencesMemory;
6969+
}
6970+
delete pIFPAnimations;
6971+
printf("CClientGame::UnloadIFPAnimations (): IFP Animations have been unloaded successfully!\n");
6972+
}
6973+
}

Client/mods/deathmatch/logic/CClientGame.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -503,10 +503,11 @@ class CClientGame
503503
static void StaticPostWorldProcessHandler ( void );
504504
static void StaticPreFxRenderHandler ( void );
505505
static void StaticPreHudRenderHandler ( void );
506+
static void StaticCAnimBlendAssocDestructorHandler ( CAnimBlendAssociationSAInterface * pThis );
506507
static CAnimBlendAssociationSAInterface * StaticAddAnimationHandler ( RpClump * pClump, AssocGroupId animGroup, AnimationId animID );
507508
static CAnimBlendAssociationSAInterface * StaticAddAnimationAndSyncHandler( RpClump * pClump, CAnimBlendAssociationSAInterface * pAnimAssocToSyncWith, AssocGroupId animGroup, AnimationId animID );
508-
static void StaticAssocGroupCopyAnimationHandler ( CAnimBlendStaticAssociationSAInterface * pOutAnimStaticAssoc, RpClump * pClump, CAnimBlendAssocGroupSAInterface * pAnimAssocGroup, AnimationId animID );
509-
static CAnimBlendHierarchySAInterface * StaticBlendAnimationHierarchyHandler ( RpClump * pClump, CAnimBlendHierarchySAInterface * pAnimHierarchy, int flags, float fBlendDelta );
509+
static bool StaticAssocGroupCopyAnimationHandler ( CAnimBlendStaticAssociationSAInterface * pOutAnimStaticAssoc, SIFPAnimations ** pOutIFPAnimations, RpClump * pClump, CAnimBlendAssocGroupSAInterface * pAnimAssocGroup, AnimationId animID );
510+
static bool StaticBlendAnimationHierarchyHandler ( SIFPAnimations ** pOutIFPAnimations, CAnimBlendHierarchySAInterface ** pOutAnimHierarchy, RpClump * pClump );
510511
static bool StaticProcessCollisionHandler ( CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface );
511512
static bool StaticVehicleCollisionHandler ( CVehicleSAInterface* pThisInterface, CEntitySAInterface* pOtherInterface, int iModelIndex, float fDamageImpulseMag, float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity );
512513
static bool StaticVehicleDamageHandler ( CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, const CVector& vecDamagePos, uchar ucTyre );
@@ -536,10 +537,11 @@ class CClientGame
536537
bool ChokingHandler ( unsigned char ucWeaponType );
537538
void PreWorldProcessHandler ( void );
538539
void PostWorldProcessHandler ( void );
540+
void CAnimBlendAssocDestructorHandler ( CAnimBlendAssociationSAInterface * pThis );
539541
CAnimBlendAssociationSAInterface * AddAnimationHandler ( RpClump * pClump, AssocGroupId animGroup, AnimationId animID );
540542
CAnimBlendAssociationSAInterface * AddAnimationAndSyncHandler ( RpClump * pClump, CAnimBlendAssociationSAInterface * pAnimAssocToSyncWith, AssocGroupId animGroup, AnimationId animID );
541-
void AssocGroupCopyAnimationHandler ( CAnimBlendStaticAssociationSAInterface * pOutAnimStaticAssoc, RpClump * pClump, CAnimBlendAssocGroupSAInterface * pAnimAssocGroup, AnimationId animID );
542-
CAnimBlendHierarchySAInterface * BlendAnimationHierarchyHandler ( RpClump * pClump, CAnimBlendHierarchySAInterface * pAnimHierarchy, int flags, float fBlendDelta );
543+
bool AssocGroupCopyAnimationHandler ( CAnimBlendStaticAssociationSAInterface * pOutAnimStaticAssoc, SIFPAnimations ** pOutIFPAnimations, RpClump * pClump, CAnimBlendAssocGroupSAInterface * pAnimAssocGroup, AnimationId animID );
544+
bool BlendAnimationHierarchyHandler ( SIFPAnimations ** pOutIFPAnimations, CAnimBlendHierarchySAInterface ** pOutAnimHierarchy, RpClump * pClump );
543545
bool ProcessCollisionHandler ( CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface );
544546
bool VehicleCollisionHandler ( CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedVehicle, int iModelIndex, float fDamageImpulseMag, float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity );
545547
bool VehicleDamageHandler ( CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, const CVector& vecDamagePos, uchar ucTyre );
@@ -598,8 +600,9 @@ class CClientGame
598600
void RemovePedPointerFromMap ( CClientPed * pPed );
599601
CClientPed * GetClientPedByClump ( const RpClump & Clump );
600602

601-
void onClientIFPUnload ( const CClientIFP & IFP );
602-
603+
void OnClientIFPUnload ( const CClientIFP & IFP );
604+
void DeleteIFPAnimations ( SIFPAnimations * pIFPAnimations );
605+
603606
private:
604607
eStatus m_Status;
605608
eServerType m_ServerType;

0 commit comments

Comments
 (0)