Skip to content

Commit 76f2d02

Browse files
committed
setPedAnimation finally works for playing custom animations. Both GTA VC and SA have been tested.
1 parent a467ae9 commit 76f2d02

File tree

3 files changed

+128
-25
lines changed

3 files changed

+128
-25
lines changed

Client/mods/deathmatch/logic/CClientGame.cpp

Lines changed: 121 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, CAnimBlendHierarchySAInterface * pAnimHierarchy, int flags, float fBlendDelta )
3700+
CAnimBlendHierarchySAInterface * CClientGame::StaticBlendAnimationHandler ( RpClump * pClump, CAnimBlendHierarchySAInterface * pAnimHierarchy, int flags, float fBlendDelta )
37013701
{
3702-
g_pClientGame->BlendAnimationHandler ( pClump, pAnimHierarchy, flags, fBlendDelta );
3702+
return g_pClientGame->BlendAnimationHandler ( pClump, pAnimHierarchy, flags, fBlendDelta );
37033703
}
37043704

37053705
void CClientGame::StaticPreWorldProcessHandler ( void )
@@ -3983,37 +3983,136 @@ 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 );
3991+
/*
3992+
hCAnimBlendAssocGroup_CopyAnimation CAnimBlendAssocGroup_CopyAnimation = (hCAnimBlendAssocGroup_CopyAnimation)0x004CE130;
3993+
hUncompressAnimation UncompressAnimation = (hUncompressAnimation)0x4d41c0;
3994+
hCAnimBlendAssoc_Constructor_staticAssocRef OLD_CAnimBlendAssoc_Constructor_staticAssocRef = (hCAnimBlendAssoc_Constructor_staticAssocRef)0x4CF080;
3995+
hCAnimBlendStaticAssoc_Constructor OLD_CAnimBlendStaticAssoc_Constructor = *(hCAnimBlendStaticAssoc_Constructor)0x4CE940;
3996+
hCAnimBlendStaticAssoc_Init OLD_CAnimBlendStaticAssoc_Init = (hCAnimBlendStaticAssoc_Init)0x004CEC20;
39893997
39903998
CAnimManager * pAnimationManager = g_pGame->GetAnimManager();
3991-
3999+
auto pOriginalAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation ( animGroup, animID );
4000+
39924001
CClientPed * pClientPed = pAnimationManager->GetPedPointerFromMap ( pClump );
39934002
if ( pClientPed != nullptr )
39944003
{
3995-
if ( pClientPed->isNextAnimationCustom () )
4004+
printf("AddAnimationHandler: found client ped pointer from map\n");
4005+
4006+
const SString & strBlockName = pClientPed->GetNextAnimationCustomBlockName ( );
4007+
CClientIFP * pIFP = GetIFPPointerFromMap ( strBlockName );
4008+
if ( pIFP )
39964009
{
3997-
auto pAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation ( animGroup, animID );
3998-
if ( pAnimationManager->isGateWayAnimationHierarchy ( pAnimStaticAssoc->pAnimHeirarchy ) )
3999-
{
4000-
printf("pAnimationManager->isGateWayAnimationHierarchy() is true\n");
4010+
printf("AddAnimationHandler: found IFP pointer from map\n");
4011+
4012+
const SString & strAnimationName = pClientPed->GetNextAnimationCustomName ( );
4013+
_CAnimBlendHierarchy * pCustomAnimBlendHierarchy = (_CAnimBlendHierarchy *)pIFP->GetAnimationHierarchy ( strAnimationName );
4014+
if ( pCustomAnimBlendHierarchy != nullptr )
4015+
{
4016+
printf("AddAnimationHandler:got custom animation hierarchy\n");
4017+
4018+
if ( animGroup == 0 && animID == 55 ) // if it's crouch animation
4019+
{
4020+
printf("AddAnimationHandler: Internal GTA Courch Animation Total Sequences: %d\n", pOriginalAnimStaticAssoc->pAnimHeirarchy->usNumSequences);
40014021
4002-
pClientPed->setNextAnimationNormal ( );
4022+
4023+
auto pCrouchAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation ( 0, 55 ); // 0, 55 for crouch animation
4024+
4025+
CAnimBlendStaticAssoc * pOriginalAnimStaticAssoc = (CAnimBlendStaticAssoc *)pCrouchAnimStaticAssoc;
4026+
4027+
// let's play the original crouch animation instead for testing ^^
4028+
pCustomAnimBlendHierarchy = pOriginalAnimStaticAssoc->m_pAnimBlendHier;
4029+
4030+
pCustomAnimBlendHierarchy->m_hashKey = pOriginalAnimStaticAssoc->m_pAnimBlendHier->m_hashKey;
4031+
pCustomAnimBlendHierarchy->m_nAnimBlockId = pOriginalAnimStaticAssoc->m_pAnimBlendHier->m_nAnimBlockId;
4032+
4033+
CAnimBlendStaticAssoc CustomAnimStaticAssoc;
4034+
OLD_CAnimBlendStaticAssoc_Constructor ( &CustomAnimStaticAssoc );
4035+
4036+
CustomAnimStaticAssoc.m_nFlags = pOriginalAnimStaticAssoc->m_nFlags;
4037+
4038+
OLD_CAnimBlendStaticAssoc_Init ( &CustomAnimStaticAssoc, pClump, pCustomAnimBlendHierarchy);
4039+
4040+
CustomAnimStaticAssoc.m_nAnimGroup = pOriginalAnimStaticAssoc->m_nAnimGroup;
4041+
CustomAnimStaticAssoc.m_nAnimID = pOriginalAnimStaticAssoc->m_nAnimID;
4042+
4043+
UncompressAnimation ( CustomAnimStaticAssoc.m_pAnimBlendHier );
4044+
CAnimBlendAssoc * pAnimAssoc = (CAnimBlendAssoc *)malloc(sizeof(CAnimBlendAssoc));
4045+
OLD_CAnimBlendAssoc_Constructor_staticAssocRef ( pAnimAssoc, CustomAnimStaticAssoc);
4046+
4047+
pAnimAssoc->m_nAnimGroup = pOriginalAnimStaticAssoc->m_nAnimGroup;
4048+
pAnimAssoc->m_nFlags = pOriginalAnimStaticAssoc->m_nFlags;
4049+
4050+
printf("AddAnimationHandler: returning pAnimAssoc\n");
4051+
return (CAnimBlendAssociationSAInterface * ) pAnimAssoc;
4052+
//auto pAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation ( 0, 55 ); // 0, 55 for crouch animation
4053+
//return pAnimStaticAssoc->pAnimHeirarchy;
4054+
}
4055+
}
4056+
else
4057+
{
4058+
printf ("AddAnimationHandler: could not find IFP animation hierarchy '%s'\n", strAnimationName.c_str());
40034059
}
40044060
}
4061+
else
4062+
{
4063+
printf("AddAnimationHandler: could not find IFP block name '%s'\n", strBlockName.c_str());
4064+
}
40054065
}
4006-
4066+
4067+
printf("AddAnimationHandler: executing normal flow instead of custom animation\n");
4068+
*/
4069+
// normal flow
40074070
std::unique_ptr < CAnimBlendAssocGroup > pAnimAssocGroup = g_pGame->CreateAnimBlendAssocGroup ( animGroup );
40084071
CAnimBlendAssociationSAInterface * pAnimAssociation = pAnimAssocGroup->CopyAnimation ( animID );
40094072

4073+
printf("\n");
4074+
40104075
return pAnimAssociation;
40114076
}
40124077

4013-
void CClientGame::BlendAnimationHandler ( RpClump * pClump, CAnimBlendHierarchySAInterface * pAnimHierarchy, int flags, float fBlendDelta )
4078+
CAnimBlendHierarchySAInterface * CClientGame::BlendAnimationHandler ( RpClump * pClump, CAnimBlendHierarchySAInterface * pAnimHierarchy, int flags, float fBlendDelta )
40144079
{
4015-
//CClientPed * pPed = m_pPedManager->Get ( pClump, true );
4016-
printf ("CClientGame::BlendAnimationHandler called! pClump: %p\n", pClump);
4080+
printf("CClientGame::BlendAnimationHandler called\n");
4081+
4082+
CAnimManager * pAnimationManager = g_pGame->GetAnimManager();
4083+
CClientPed * pClientPed = pAnimationManager->GetPedPointerFromMap ( pClump );
4084+
if ( pClientPed != nullptr )
4085+
{
4086+
if ( pClientPed->isNextAnimationCustom () )
4087+
{
4088+
const SString & strBlockName = pClientPed->GetNextAnimationCustomBlockName ( );
4089+
CClientIFP * pIFP = GetIFPPointerFromMap ( strBlockName );
4090+
if ( pIFP )
4091+
{
4092+
const SString & strAnimationName = pClientPed->GetNextAnimationCustomName ( );
4093+
auto pCustomAnimBlendHierarchy = pIFP->GetAnimationHierarchy ( strAnimationName );
4094+
if ( pCustomAnimBlendHierarchy != nullptr )
4095+
{
4096+
// Modifying a hierarchy like this is just bad, it's much better to create a new CAnimBlendHierarchySAInterface for every animation
4097+
// and then delete it once animation is over
4098+
pCustomAnimBlendHierarchy->iHashKey = pAnimHierarchy->iHashKey;
4099+
pCustomAnimBlendHierarchy->iAnimBlockID = pAnimHierarchy->iAnimBlockID;
4100+
pClientPed->setNextAnimationNormal ( );
4101+
return pCustomAnimBlendHierarchy;
4102+
}
4103+
else
4104+
{
4105+
printf ("BlendAnimationHandler: could not find IFP animation hierarchy '%s'\n", strAnimationName.c_str());
4106+
}
4107+
}
4108+
else
4109+
{
4110+
printf("BlendAnimationHandler: could not find IFP block name '%s'\n", strBlockName.c_str());
4111+
}
4112+
}
4113+
pClientPed->setNextAnimationNormal ( );;
4114+
}
4115+
return pAnimHierarchy;
40174116
}
40184117

40194118
bool CClientGame::ProcessCollisionHandler ( CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface )
@@ -6746,22 +6845,24 @@ void CClientGame::RestreamModel ( unsigned short usModel )
67466845

67476846
}
67486847

6749-
void CClientGame::InsertIFPPointerToMap ( SString strBlockName, CClientIFP * pIFP )
6848+
void CClientGame::InsertIFPPointerToMap ( const SString & strBlockName, CClientIFP * pIFP )
67506849
{
6751-
if ( m_mapOfIfpPointers.count ( strBlockName ) == 0 )
6850+
const SString mapKey = strBlockName.ToLower ( );
6851+
if ( m_mapOfIfpPointers.count ( mapKey ) == 0 )
67526852
{
6753-
m_mapOfIfpPointers [ strBlockName ] = pIFP;
6853+
m_mapOfIfpPointers [ mapKey ] = pIFP;
67546854
}
67556855
}
67566856

6757-
void CClientGame::RemoveIFPPointerFromMap ( SString strBlockName )
6857+
void CClientGame::RemoveIFPPointerFromMap ( const SString & strBlockName )
67586858
{
6759-
m_mapOfIfpPointers.erase ( strBlockName );
6859+
m_mapOfIfpPointers.erase ( strBlockName.ToLower ( ) );
67606860
}
67616861

6762-
CClientIFP * CClientGame::GetIFPPointerFromMap ( SString strBlockName )
6862+
CClientIFP * CClientGame::GetIFPPointerFromMap ( const SString & strBlockName )
67636863
{
6764-
std::map < SString, CClientIFP * >::iterator it = m_mapOfIfpPointers.find ( strBlockName );
6864+
const SString mapKey = strBlockName.ToLower ( );
6865+
std::map < SString, CClientIFP * >::iterator it = m_mapOfIfpPointers.find ( mapKey );
67656866
if ( it != m_mapOfIfpPointers.end ( ) )
67666867
{
67676868
return it->second;

Client/mods/deathmatch/logic/CClientGame.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ class CClientGame
504504
static void StaticPreFxRenderHandler ( void );
505505
static void StaticPreHudRenderHandler ( void );
506506
static CAnimBlendAssociationSAInterface * StaticAddAnimationHandler ( RpClump * pClump, AssocGroupId animGroup, AnimationId animID );
507-
static void StaticBlendAnimationHandler ( RpClump * pClump, CAnimBlendHierarchySAInterface * pAnimHierarchy, int flags, float fBlendDelta );
507+
static CAnimBlendHierarchySAInterface * StaticBlendAnimationHandler ( RpClump * pClump, CAnimBlendHierarchySAInterface * pAnimHierarchy, int flags, float fBlendDelta );
508508
static bool StaticProcessCollisionHandler ( CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface );
509509
static bool StaticVehicleCollisionHandler ( CVehicleSAInterface* pThisInterface, CEntitySAInterface* pOtherInterface, int iModelIndex, float fDamageImpulseMag, float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity );
510510
static bool StaticVehicleDamageHandler ( CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, const CVector& vecDamagePos, uchar ucTyre );
@@ -535,7 +535,7 @@ class CClientGame
535535
void PreWorldProcessHandler ( void );
536536
void PostWorldProcessHandler ( void );
537537
CAnimBlendAssociationSAInterface * AddAnimationHandler ( RpClump * pClump, AssocGroupId animGroup, AnimationId animID );
538-
void BlendAnimationHandler ( RpClump * pClump, CAnimBlendHierarchySAInterface * pAnimHierarchy, int flags, float fBlendDelta );
538+
CAnimBlendHierarchySAInterface * BlendAnimationHandler ( RpClump * pClump, CAnimBlendHierarchySAInterface * pAnimHierarchy, int flags, float fBlendDelta );
539539
bool ProcessCollisionHandler ( CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface );
540540
bool VehicleCollisionHandler ( CVehicleSAInterface* pCollidingVehicle, CEntitySAInterface* pCollidedVehicle, int iModelIndex, float fDamageImpulseMag, float fCollidingDamageImpulseMag, uint16 usPieceType, CVector vecCollisionPos, CVector vecCollisionVelocity );
541541
bool VehicleDamageHandler ( CEntitySAInterface* pVehicleInterface, float fLoss, CEntitySAInterface* pAttackerInterface, eWeaponType weaponType, const CVector& vecDamagePos, uchar ucTyre );
@@ -586,9 +586,9 @@ class CClientGame
586586
void SetFileCacheRoot ( void );
587587
const char* GetFileCacheRoot ( void ) { return m_strFileCacheRoot; }
588588

589-
void InsertIFPPointerToMap ( SString strBlockName, CClientIFP * pIFP );
590-
void RemoveIFPPointerFromMap ( SString strBlockName );
591-
CClientIFP * GetIFPPointerFromMap ( SString strBlockName );
589+
void InsertIFPPointerToMap ( const SString & strBlockName, CClientIFP * pIFP );
590+
void RemoveIFPPointerFromMap ( const SString & strBlockName );
591+
CClientIFP * GetIFPPointerFromMap ( const SString & strBlockName );
592592

593593
private:
594594
eStatus m_Status;

Client/mods/deathmatch/logic/CClientPed.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,8 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule
460460
// This will indicate that we have played custom animation, so next animation can be internal GTA animation
461461
// You must call this function after playing a custom animation
462462
void setNextAnimationNormal ( void ) { m_bisNextAnimationCustom = false; }
463+
const SString & GetNextAnimationCustomBlockName ( void ) { return m_strCustomIFPBlockName; }
464+
const SString & GetNextAnimationCustomName ( void ) { return m_strCustomIFPAnimationName; }
463465

464466
protected:
465467
// This constructor is for peds managed by a player. These are unknown to the ped manager.

0 commit comments

Comments
 (0)