Skip to content

Commit 64ba51c

Browse files
authored
Merge pull request #2 from saml1er/custom_ifp_animations
Working custom IFP animations
2 parents aa722ff + 7e4ad6c commit 64ba51c

19 files changed

+458
-182
lines changed

Client/game_sa/CAnimBlendHierarchySA.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ class CAnimBlendHierarchySAInterface
2828
public:
2929
int GetIndex ( void );
3030
unsigned int iHashKey;
31-
CAnimBlendSequence * pSequences;
31+
DWORD * pSequences;
3232
unsigned short usNumSequences;
33-
BYTE pad;
3433
bool bRunningCompressed;
34+
BYTE pad;
3535
int iAnimBlockID;
3636
float fTotalTime;
3737
//class CLink<class CAnimBlendHierarchy *> * pLinkPtr;

Client/game_sa/CAnimBlendStaticAssociationSA.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class CAnimBlendStaticAssociationSAInterface
3131
short sAnimID;
3232
short sAnimGroup;
3333
short sFlags;
34-
DWORD * pAnimBlendNodesSequenceArray;
34+
int * pAnimBlendNodesSequenceArray;
3535
CAnimBlendHierarchySAInterface * pAnimHeirarchy;
3636
};
3737

Client/game_sa/CAnimManagerSA.cpp

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ CAnimBlendAssociation * CAnimManagerSA::CreateAnimAssociation ( AssocGroupId ani
258258

259259
CAnimBlendStaticAssociationSAInterface * CAnimManagerSA::GetAnimStaticAssociation ( AssocGroupId animGroup, AnimationId animID )
260260
{
261-
CAnimBlendStaticAssociationSAInterface * pInterface;
261+
CAnimBlendStaticAssociationSAInterface * pInterface = nullptr;
262262
DWORD dwFunc = FUNC_CAnimManager_GetAnimAssociation;
263263
_asm
264264
{
@@ -776,25 +776,3 @@ const SString & CAnimManagerSA::GetGateWayAnimationName ( void )
776776
return m_kGateWayAnimationName;
777777
}
778778

779-
void CAnimManagerSA::InsertPedPointerToMap ( RpClump * pClump, CClientPed * pClientPed )
780-
{
781-
if ( m_mapOfPedPointers.count ( pClump ) == 0 )
782-
{
783-
m_mapOfPedPointers [ pClump ] = pClientPed;
784-
}
785-
}
786-
787-
void CAnimManagerSA::RemovePedPointerFromMap ( RpClump * pClump )
788-
{
789-
m_mapOfPedPointers.erase ( pClump );
790-
}
791-
792-
CClientPed * CAnimManagerSA::GetPedPointerFromMap ( RpClump * pClump )
793-
{
794-
ClumpMap_type::iterator it = m_mapOfPedPointers.find ( pClump );
795-
if ( it != m_mapOfPedPointers.end ( ) )
796-
{
797-
return it->second;
798-
}
799-
return nullptr;
800-
}

Client/game_sa/CAnimManagerSA.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ class CAnimManagerSAInterface
8080
class CAnimManagerSA : public CAnimManager
8181
{
8282
typedef CAnimBlendStaticAssociationSAInterface * StaticAssocIntface_type;
83-
typedef std::map < RpClump *, CClientPed * > ClumpMap_type;
8483

8584
public:
8685
CAnimManagerSA ( void );
@@ -155,18 +154,11 @@ class CAnimManagerSA : public CAnimManager
155154
const SString & GetGateWayBlockName ( void );
156155
const SString & GetGateWayAnimationName ( void );
157156

158-
// This is used in AddAnimationHandler and AddAnimationAndSyncHandler for playing
159-
// custom animations and to help in replacing and restoring animations
160-
void InsertPedPointerToMap ( RpClump * pClump, CClientPed * pClientPed );
161-
void RemovePedPointerFromMap ( RpClump * pClump );
162-
CClientPed * GetPedPointerFromMap ( RpClump * pClump );
163-
164157
private:
165158
CAnimBlendAssocGroup * m_pAnimAssocGroups [ MAX_ANIM_GROUPS ];
166159
CAnimBlendHierarchy * m_pAnimations [ MAX_ANIMATIONS ];
167160
CAnimBlock * m_pAnimBlocks [ MAX_ANIM_BLOCKS ];
168-
std::list < CAnimBlendAssociation * > m_Associations;
169-
ClumpMap_type m_mapOfPedPointers;
161+
std::list < CAnimBlendAssociation * > m_Associations;
170162

171163
// This "gateway" animation will allow us to play custom animations by simply playing this animation
172164
// and then in AddAnimation and AddAnimationAndSync hook, we can return our custom animation in the

Client/mods/deathmatch/logic/CClientEntity.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,6 +1490,42 @@ void CClientEntity::GetEntitiesFromRoot ( unsigned int uiTypeHash, lua_State* lu
14901490
}
14911491
}
14921492

1493+
CClientPed * CClientEntity::GetClientPedByClump ( const RpClump & Clump )
1494+
{
1495+
SString arrstrEntityTypes [2] = { "player", "ped" };
1496+
1497+
for ( size_t uiTypeIndex = 0;
1498+
uiTypeIndex < sizeof ( arrstrEntityTypes);
1499+
uiTypeIndex ++ )
1500+
{
1501+
unsigned int uiTypeHash = HashString ( arrstrEntityTypes [ uiTypeIndex ].c_str ( ) );
1502+
1503+
t_mapEntitiesFromRoot::iterator find = ms_mapEntitiesFromRoot.find ( uiTypeHash );
1504+
if ( find != ms_mapEntitiesFromRoot.end () )
1505+
{
1506+
CFromRootListType& listEntities = find->second;
1507+
CClientEntity* pEntity;
1508+
unsigned int uiIndex = 0;
1509+
1510+
for ( CFromRootListType::reverse_iterator i = listEntities.rbegin ();
1511+
i != listEntities.rend ();
1512+
++i )
1513+
{
1514+
pEntity = *i;
1515+
1516+
if ( !pEntity->IsBeingDeleted ( ) )
1517+
{
1518+
const RpClump & entityClump = *pEntity->GetClump ();
1519+
if ( std::addressof ( entityClump ) == std::addressof ( Clump ) )
1520+
{
1521+
return static_cast < CClientPed * > ( pEntity );
1522+
}
1523+
}
1524+
}
1525+
}
1526+
}
1527+
return nullptr;
1528+
}
14931529

14941530
#if CHECK_ENTITIES_FROM_ROOT
14951531

Client/mods/deathmatch/logic/CClientEntity.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,8 @@ class CClientEntity : public CClientEntityBase
325325
bool IsCallPropagationEnabled ( void ) { return m_bCallPropagationEnabled; }
326326
virtual void SetCallPropagationEnabled ( bool bEnabled ) { m_bCallPropagationEnabled = bEnabled; }
327327

328+
CClientPed * GetClientPedByClump ( const RpClump & Clump );
329+
328330
protected:
329331
CClientManager* m_pManager;
330332
CClientEntity* m_pParent;

Client/mods/deathmatch/logic/CClientGame.cpp

Lines changed: 168 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3697,9 +3697,9 @@ CAnimBlendAssociationSAInterface * CClientGame::StaticAddAnimationHandler ( RpCl
36973697
return g_pClientGame->AddAnimationHandler ( pClump, animGroup, animID );
36983698
}
36993699

3700-
void CClientGame::StaticBlendAnimationHandler ( RpClump * pClump, AssocGroupId animGroup, AnimationId animID, float fBlendDelta )
3700+
CAnimBlendHierarchySAInterface * CClientGame::StaticBlendAnimationHandler ( RpClump * pClump, CAnimBlendHierarchySAInterface * pAnimHierarchy, int flags, float fBlendDelta )
37013701
{
3702-
g_pClientGame->BlendAnimationHandler ( pClump, animGroup, animID, fBlendDelta );
3702+
return g_pClientGame->BlendAnimationHandler ( pClump, pAnimHierarchy, flags, fBlendDelta );
37033703
}
37043704

37053705
void CClientGame::StaticPreWorldProcessHandler ( void )
@@ -3983,38 +3983,151 @@ bool CClientGame::ChokingHandler ( unsigned char ucWeaponType )
39833983
return m_pLocalPlayer->CallEvent ( "onClientPlayerChoke", Arguments, true );
39843984
}
39853985

3986+
#include <../game_sa/CAnimBlendHierarchySA.h> // ---------------- REMOVE THIS LATER
3987+
39863988
CAnimBlendAssociationSAInterface * CClientGame::AddAnimationHandler ( RpClump * pClump, AssocGroupId animGroup, AnimationId animID )
39873989
{
39883990
printf ( "AddAnimationHandler called! pClump, GroupID, AnimID: %p, %d, %d\n", (void*)pClump, animGroup, animID );
39893991

3992+
CClientPed * pClientPed = GetClientPedByClump ( *pClump ); //pAnimationManager->GetPedPointerFromMap ( pClump ); //m_pRootEntity->GetClientPedByClump ( *pClump );
3993+
if ( pClientPed != nullptr )
3994+
{
3995+
//pClientPed->setCurrentAnimationCustom ( false );
3996+
}
3997+
/*
3998+
hCAnimBlendAssocGroup_CopyAnimation CAnimBlendAssocGroup_CopyAnimation = (hCAnimBlendAssocGroup_CopyAnimation)0x004CE130;
3999+
hUncompressAnimation UncompressAnimation = (hUncompressAnimation)0x4d41c0;
4000+
hCAnimBlendAssoc_Constructor_staticAssocRef OLD_CAnimBlendAssoc_Constructor_staticAssocRef = (hCAnimBlendAssoc_Constructor_staticAssocRef)0x4CF080;
4001+
hCAnimBlendStaticAssoc_Constructor OLD_CAnimBlendStaticAssoc_Constructor = *(hCAnimBlendStaticAssoc_Constructor)0x4CE940;
4002+
hCAnimBlendStaticAssoc_Init OLD_CAnimBlendStaticAssoc_Init = (hCAnimBlendStaticAssoc_Init)0x004CEC20;
4003+
39904004
CAnimManager * pAnimationManager = g_pGame->GetAnimManager();
3991-
4005+
auto pOriginalAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation ( animGroup, animID );
4006+
39924007
CClientPed * pClientPed = pAnimationManager->GetPedPointerFromMap ( pClump );
39934008
if ( pClientPed != nullptr )
39944009
{
3995-
if ( pClientPed->isNextAnimationCustom () )
4010+
printf("AddAnimationHandler: found client ped pointer from map\n");
4011+
4012+
const SString & strBlockName = pClientPed->GetNextAnimationCustomBlockName ( );
4013+
CClientIFP * pIFP = GetIFPPointerFromMap ( strBlockName );
4014+
if ( pIFP )
39964015
{
3997-
printf("pClientPed->isNextAnimationCustom () is true\n");
4016+
printf("AddAnimationHandler: found IFP pointer from map\n");
39984017
3999-
auto pAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation ( animGroup, animID );
4000-
if ( pAnimationManager->isGateWayAnimationHierarchy ( pAnimStaticAssoc->pAnimHeirarchy ) )
4001-
{
4002-
printf("pAnimationManager->isGateWayAnimationHierarchy() is true\n");
4018+
const SString & strAnimationName = pClientPed->GetNextAnimationCustomName ( );
4019+
_CAnimBlendHierarchy * pCustomAnimBlendHierarchy = (_CAnimBlendHierarchy *)pIFP->GetAnimationHierarchy ( strAnimationName );
4020+
if ( pCustomAnimBlendHierarchy != nullptr )
4021+
{
4022+
printf("AddAnimationHandler:got custom animation hierarchy\n");
4023+
4024+
if ( animGroup == 0 && animID == 55 ) // if it's crouch animation
4025+
{
4026+
printf("AddAnimationHandler: Internal GTA Courch Animation Total Sequences: %d\n", pOriginalAnimStaticAssoc->pAnimHeirarchy->usNumSequences);
4027+
4028+
4029+
auto pCrouchAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation ( 0, 55 ); // 0, 55 for crouch animation
4030+
4031+
CAnimBlendStaticAssoc * pOriginalAnimStaticAssoc = (CAnimBlendStaticAssoc *)pCrouchAnimStaticAssoc;
4032+
4033+
// let's play the original crouch animation instead for testing ^^
4034+
pCustomAnimBlendHierarchy = pOriginalAnimStaticAssoc->m_pAnimBlendHier;
40034035
4004-
pClientPed->setNextAnimationNormal ( );
4036+
pCustomAnimBlendHierarchy->m_hashKey = pOriginalAnimStaticAssoc->m_pAnimBlendHier->m_hashKey;
4037+
pCustomAnimBlendHierarchy->m_nAnimBlockId = pOriginalAnimStaticAssoc->m_pAnimBlendHier->m_nAnimBlockId;
4038+
4039+
CAnimBlendStaticAssoc CustomAnimStaticAssoc;
4040+
OLD_CAnimBlendStaticAssoc_Constructor ( &CustomAnimStaticAssoc );
4041+
4042+
CustomAnimStaticAssoc.m_nFlags = pOriginalAnimStaticAssoc->m_nFlags;
4043+
4044+
OLD_CAnimBlendStaticAssoc_Init ( &CustomAnimStaticAssoc, pClump, pCustomAnimBlendHierarchy);
4045+
4046+
CustomAnimStaticAssoc.m_nAnimGroup = pOriginalAnimStaticAssoc->m_nAnimGroup;
4047+
CustomAnimStaticAssoc.m_nAnimID = pOriginalAnimStaticAssoc->m_nAnimID;
4048+
4049+
UncompressAnimation ( CustomAnimStaticAssoc.m_pAnimBlendHier );
4050+
CAnimBlendAssoc * pAnimAssoc = (CAnimBlendAssoc *)malloc(sizeof(CAnimBlendAssoc));
4051+
OLD_CAnimBlendAssoc_Constructor_staticAssocRef ( pAnimAssoc, CustomAnimStaticAssoc);
4052+
4053+
pAnimAssoc->m_nAnimGroup = pOriginalAnimStaticAssoc->m_nAnimGroup;
4054+
pAnimAssoc->m_nFlags = pOriginalAnimStaticAssoc->m_nFlags;
4055+
4056+
printf("AddAnimationHandler: returning pAnimAssoc\n");
4057+
return (CAnimBlendAssociationSAInterface * ) pAnimAssoc;
4058+
//auto pAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation ( 0, 55 ); // 0, 55 for crouch animation
4059+
//return pAnimStaticAssoc->pAnimHeirarchy;
4060+
}
4061+
}
4062+
else
4063+
{
4064+
printf ("AddAnimationHandler: could not find IFP animation hierarchy '%s'\n", strAnimationName.c_str());
40054065
}
40064066
}
4067+
else
4068+
{
4069+
printf("AddAnimationHandler: could not find IFP block name '%s'\n", strBlockName.c_str());
4070+
}
40074071
}
4008-
4072+
4073+
printf("AddAnimationHandler: executing normal flow instead of custom animation\n");
4074+
*/
4075+
// normal flow
40094076
std::unique_ptr < CAnimBlendAssocGroup > pAnimAssocGroup = g_pGame->CreateAnimBlendAssocGroup ( animGroup );
40104077
CAnimBlendAssociationSAInterface * pAnimAssociation = pAnimAssocGroup->CopyAnimation ( animID );
40114078

4079+
printf("\n");
4080+
40124081
return pAnimAssociation;
40134082
}
40144083

4015-
void CClientGame::BlendAnimationHandler ( RpClump * pClump, AssocGroupId animGroup, AnimationId animID, float fBlendDelta )
4084+
CAnimBlendHierarchySAInterface * CClientGame::BlendAnimationHandler ( RpClump * pClump, CAnimBlendHierarchySAInterface * pAnimHierarchy, int flags, float fBlendDelta )
40164085
{
4017-
//CClientPed * pPed = m_pPedManager->Get ( pClump, true );
4086+
printf("CClientGame::BlendAnimationHandler called | pClump: %p\n", (void*)pClump);
4087+
4088+
CAnimManager * pAnimationManager = g_pGame->GetAnimManager();
4089+
CClientPed * pClientPed = GetClientPedByClump ( *pClump ); //pAnimationManager->GetPedPointerFromMap ( pClump ); //m_pRootEntity->GetClientPedByClump ( *pClump );
4090+
if ( pClientPed != nullptr )
4091+
{
4092+
printf ("BlendAnimationHandler: Found pClientPed\n");
4093+
if ( pClientPed->isNextAnimationCustom () )
4094+
{
4095+
const SString & strBlockName = pClientPed->GetNextAnimationCustomBlockName ( );
4096+
CClientIFP * pIFP = GetIFPPointerFromMap ( strBlockName );
4097+
if ( pIFP )
4098+
{
4099+
const SString & strAnimationName = pClientPed->GetNextAnimationCustomName ( );
4100+
auto pCustomAnimBlendHierarchy = pIFP->GetAnimationHierarchy ( strAnimationName );
4101+
if ( pCustomAnimBlendHierarchy != nullptr )
4102+
{
4103+
printf ("BlendAnimationHandler: Found Hierarchy, returning \n");
4104+
4105+
pClientPed->setCurrentAnimationCustom ( true );
4106+
4107+
// Modifying a hierarchy like this is just bad, it's much better to create a new CAnimBlendHierarchySAInterface for every animation
4108+
// and then delete it once animation is over
4109+
pCustomAnimBlendHierarchy->iHashKey = pAnimHierarchy->iHashKey;
4110+
pCustomAnimBlendHierarchy->iAnimBlockID = pAnimHierarchy->iAnimBlockID;
4111+
pClientPed->setNextAnimationNormal ( );
4112+
return pCustomAnimBlendHierarchy;
4113+
}
4114+
else
4115+
{
4116+
printf ("BlendAnimationHandler: could not find IFP animation hierarchy '%s'\n", strAnimationName.c_str());
4117+
}
4118+
}
4119+
else
4120+
{
4121+
printf("BlendAnimationHandler: could not find IFP block name '%s'\n", strBlockName.c_str());
4122+
}
4123+
}
4124+
else
4125+
{
4126+
pClientPed->setCurrentAnimationCustom ( false );
4127+
}
4128+
pClientPed->setNextAnimationNormal ( );
4129+
}
4130+
return pAnimHierarchy;
40184131
}
40194132

40204133
bool CClientGame::ProcessCollisionHandler ( CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface )
@@ -6747,25 +6860,60 @@ void CClientGame::RestreamModel ( unsigned short usModel )
67476860

67486861
}
67496862

6750-
void CClientGame::InsertIFPPointerToMap ( SString strBlockName, CClientIFP * pIFP )
6863+
void CClientGame::InsertIFPPointerToMap ( const SString & strBlockName, CClientIFP * pIFP )
67516864
{
6752-
if ( m_mapOfIfpPointers.count ( strBlockName ) == 0 )
6865+
const SString mapKey = strBlockName.ToLower ( );
6866+
if ( m_mapOfIfpPointers.count ( mapKey ) == 0 )
67536867
{
6754-
m_mapOfIfpPointers [ strBlockName ] = pIFP;
6868+
m_mapOfIfpPointers [ mapKey ] = pIFP;
67556869
}
67566870
}
67576871

6758-
void CClientGame::RemoveIFPPointerFromMap ( SString strBlockName )
6872+
void CClientGame::RemoveIFPPointerFromMap ( const SString & strBlockName )
67596873
{
6760-
m_mapOfIfpPointers.erase ( strBlockName );
6874+
m_mapOfIfpPointers.erase ( strBlockName.ToLower ( ) );
67616875
}
67626876

6763-
CClientIFP * CClientGame::GetIFPPointerFromMap ( SString strBlockName )
6877+
CClientIFP * CClientGame::GetIFPPointerFromMap ( const SString & strBlockName )
67646878
{
6765-
std::map < SString, CClientIFP * >::iterator it = m_mapOfIfpPointers.find ( strBlockName );
6879+
const SString mapKey = strBlockName.ToLower ( );
6880+
std::map < SString, CClientIFP * >::iterator it = m_mapOfIfpPointers.find ( mapKey );
67666881
if ( it != m_mapOfIfpPointers.end ( ) )
67676882
{
67686883
return it->second;
67696884
}
67706885
return nullptr;
67716886
}
6887+
6888+
void CClientGame::InsertPedPointerToMap ( CClientPed * pPed )
6889+
{
6890+
if ( m_mapOfPedPointers.count ( pPed ) == 0 )
6891+
{
6892+
m_mapOfPedPointers [ pPed ] = true;
6893+
}
6894+
}
6895+
6896+
void CClientGame::RemovePedPointerFromMap ( CClientPed * pPed )
6897+
{
6898+
m_mapOfPedPointers.erase ( pPed );
6899+
}
6900+
6901+
CClientPed * CClientGame::GetClientPedByClump ( const RpClump & Clump )
6902+
{
6903+
for ( auto it = m_mapOfPedPointers.begin(); it != m_mapOfPedPointers.end(); it++ )
6904+
{
6905+
CEntity * pEntity = it->first->GetGameEntity();
6906+
if ( pEntity != nullptr )
6907+
{
6908+
if ( pEntity->GetRpClump() != nullptr)
6909+
{
6910+
const RpClump & entityClump = *pEntity->GetRpClump();
6911+
if ( std::addressof ( entityClump ) == std::addressof ( Clump ) )
6912+
{
6913+
return it->first;
6914+
}
6915+
}
6916+
}
6917+
}
6918+
return nullptr;
6919+
}

0 commit comments

Comments
 (0)