Skip to content

Commit c7ed932

Browse files
committed
Fix CAnimBlendStaticAssociation::Init crash
CAnimBlendStaticAssociation::Init was being called by CClientGame::AssocGroupCopyAnimationHandler whenever an animation was being played, for some reason, it crashed due to faulty animation(animation sequences not initialized properly). I removed the call to CAnimBlendStaticAssociation::Init, and used two different constructors of CAnimBlendAssociation, one when there is no animation replaced, the other constructor is called for replaced animations.
1 parent a2d27e4 commit c7ed932

13 files changed

+87
-65
lines changed

Client/game_sa/CAnimBlendAssociationSA.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,31 @@
1313

1414
extern CGameSA* pGame;
1515

16+
CAnimBlendAssociationSAInterface* CAnimBlendAssociationSA::Constructor(CAnimBlendStaticAssociationSAInterface& staticAssociationByReference)
17+
{
18+
DWORD DwFunc = 0x4CF080;
19+
DWORD DwThisInterface = reinterpret_cast<DWORD>(m_pInterface);
20+
_asm
21+
{
22+
mov ecx, DwThisInterface
23+
push staticAssociationByReference
24+
call DwFunc
25+
};
26+
}
27+
28+
CAnimBlendAssociationSAInterface* CAnimBlendAssociationSA::Constructor(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy)
29+
{
30+
DWORD DwFunc = 0x4CEFC0;
31+
DWORD DwThisInterface = reinterpret_cast<DWORD>(m_pInterface);
32+
_asm
33+
{
34+
mov ecx, DwThisInterface
35+
push pAnimHierarchy
36+
push pClump
37+
call DwFunc
38+
};
39+
}
40+
1641
CAnimBlendHierarchy* CAnimBlendAssociationSA::GetAnimHierarchy(void)
1742
{
1843
return pGame->GetAnimManager()->GetAnimBlendHierarchy(m_pInterface->pAnimHierarchy);
@@ -30,4 +55,4 @@ void CAnimBlendAssociationSA::SetCurrentProgress(float fProgress)
3055
push fTime
3156
call DwFunc
3257
};
33-
}
58+
}

Client/game_sa/CAnimBlendAssociationSA.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,19 @@ class CAnimBlendAssociationSA : public CAnimBlendAssociation
4545
public:
4646
CAnimBlendAssociationSA(CAnimBlendAssociationSAInterface* pInterface) { m_pInterface = pInterface; }
4747

48+
CAnimBlendAssociationSAInterface* Constructor(CAnimBlendStaticAssociationSAInterface& StaticAssociationByReference);
49+
CAnimBlendAssociationSAInterface* Constructor(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy);
4850
CAnimBlendAssociationSAInterface* GetInterface(void) { return m_pInterface; }
4951
AssocGroupId GetAnimGroup(void) { return (AssocGroupId)m_pInterface->sAnimGroup; }
5052
AnimationId GetAnimID(void) { return (AnimationId)m_pInterface->sAnimID; }
5153
CAnimBlendHierarchy* GetAnimHierarchy(void);
5254

5355
float GetBlendAmount(void) { return m_pInterface->fBlendAmount; }
5456
void SetBlendAmount(float fAmount) { m_pInterface->fBlendAmount = fAmount; }
55-
56-
void SetCurrentProgress(float fProgress);
57+
void SetCurrentProgress(float fProgress);
58+
void SetAnimID(short sAnimID) { m_pInterface->sAnimID = sAnimID; }
59+
void SetAnimGroup(short sAnimGroup) { m_pInterface->sAnimGroup = sAnimGroup; }
60+
void SetFlags(short sFlags) { m_pInterface->sFlags = sFlags; }
5761

5862
protected:
5963
CAnimBlendAssociationSAInterface* m_pInterface;

Client/game_sa/CAnimBlendStaticAssociationSA.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,12 @@ class CAnimBlendStaticAssociationSA : public CAnimBlendStaticAssociation
4747
void SetAnimGroup(short sAnimGroup) { m_pInterface->sAnimGroup = sAnimGroup; }
4848
void SetFlags(short sFlags) { m_pInterface->sFlags = sFlags; }
4949

50-
unsigned short GetNumBlendNodes(void) { return m_pInterface->nNumBlendNodes; };
51-
short GetAnimID(void) { return m_pInterface->sAnimID; }
52-
short GetAnimGroup(void) { return m_pInterface->sAnimGroup; }
53-
short GetFlags(void) { return m_pInterface->sFlags; }
54-
CAnimBlendHierarchySAInterface* GetAnimHierachyInterface(void) { return m_pInterface->pAnimHeirarchy; }
50+
unsigned short GetNumBlendNodes(void) { return m_pInterface->nNumBlendNodes; };
51+
short GetAnimID(void) { return m_pInterface->sAnimID; }
52+
short GetAnimGroup(void) { return m_pInterface->sAnimGroup; }
53+
short GetFlags(void) { return m_pInterface->sFlags; }
54+
CAnimBlendHierarchySAInterface* GetAnimHierachyInterface(void) { return m_pInterface->pAnimHeirarchy; }
55+
CAnimBlendStaticAssociationSAInterface* GetInterface(void) { return m_pInterface; }
5556

5657
protected:
5758
CAnimBlendStaticAssociationSAInterface* m_pInterface;

Client/game_sa/CAnimManagerSA.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,11 @@ CAnimBlendHierarchy* CAnimManagerSA::GetAnimBlendHierarchy(CAnimBlendHierarchySA
749749
return NULL;
750750
}
751751

752+
std::unique_ptr<CAnimBlendAssociation> CAnimManagerSA::GetAnimBlendAssociation2(CAnimBlendAssociationSAInterface* pInterface)
753+
{
754+
return std::make_unique<CAnimBlendAssociationSA>(pInterface);
755+
}
756+
752757
CAnimManagerSA::StaticAssocIntface_type CAnimManagerSA::GetAnimStaticAssociation(CAnimBlendStaticAssociationSAInterface* pInterface)
753758
{
754759
return std::make_unique<CAnimBlendStaticAssociationSA>(pInterface);

Client/game_sa/CAnimManagerSA.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ class CAnimManagerSA : public CAnimManager
153153
CAnimBlock* GetAnimBlock(CAnimBlockSAInterface* pInterface);
154154
CAnimBlendHierarchy* GetAnimBlendHierarchy(CAnimBlendHierarchySAInterface* pInterface);
155155

156-
StaticAssocIntface_type GetAnimStaticAssociation(CAnimBlendStaticAssociationSAInterface* pInterface);
156+
std::unique_ptr<CAnimBlendAssociation> GetAnimBlendAssociation2(CAnimBlendAssociationSAInterface* pInterface);
157+
StaticAssocIntface_type GetAnimStaticAssociation(CAnimBlendStaticAssociationSAInterface* pInterface);
157158

158159
// MTA members, but use this strictly for custom animations only
159160
std::unique_ptr<CAnimBlendHierarchy> GetCustomAnimBlendHierarchy(CAnimBlendHierarchySAInterface* pInterface);

Client/mods/deathmatch/logic/CClientGame.cpp

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3647,11 +3647,10 @@ CAnimBlendAssociationSAInterface* CClientGame::StaticAddAnimationAndSyncHandler(
36473647
return g_pClientGame->AddAnimationAndSyncHandler(pClump, pAnimAssocToSyncWith, animGroup, animID);
36483648
}
36493649

3650-
bool CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendStaticAssociationSAInterface* pOutAnimStaticAssoc,
3651-
CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump,
3650+
bool CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump,
36523651
CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID)
36533652
{
3654-
return g_pClientGame->AssocGroupCopyAnimationHandler(pOutAnimStaticAssoc, pAnimAssoc, pClump, pAnimAssocGroup, animID);
3653+
return g_pClientGame->AssocGroupCopyAnimationHandler(pAnimAssoc, pClump, pAnimAssocGroup, animID);
36553654
}
36563655

36573656
bool CClientGame::StaticBlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy,
@@ -3959,38 +3958,44 @@ CAnimBlendAssociationSAInterface* CClientGame::AddAnimationAndSyncHandler(RpClum
39593958
return nullptr;
39603959
}
39613960

3962-
bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendStaticAssociationSAInterface* pOutAnimStaticAssocInterface,
3963-
CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump,
3961+
bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssocInterface, RpClump* pClump,
39643962
CAnimBlendAssocGroupSAInterface* pAnimAssocGroupInterface, AnimationId animID)
39653963
{
39663964
bool isCustomAnimationToPlay = false;
39673965
CAnimManager* pAnimationManager = g_pGame->GetAnimManager();
39683966
auto pAnimAssocGroup = pAnimationManager->GetAnimBlendAssocGroup(pAnimAssocGroupInterface);
39693967
auto pOriginalAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation(pAnimAssocGroup->GetGroupID(), animID);
39703968
auto pOriginalAnimHierarchyInterface = pOriginalAnimStaticAssoc->GetAnimHierachyInterface();
3971-
auto pOutAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation(pOutAnimStaticAssocInterface);
3972-
CClientPed* pClientPed = GetClientPedByClump(*pClump);
3969+
auto pAnimAssociation = pAnimationManager->GetAnimBlendAssociation2(pAnimAssocInterface);
3970+
3971+
CClientPed* pClientPed = GetClientPedByClump(*pClump);
39733972
if (pClientPed != nullptr)
39743973
{
39753974
auto pReplacedAnimation = pClientPed->GetReplacedAnimation(pOriginalAnimHierarchyInterface);
39763975
if (pReplacedAnimation != nullptr)
39773976
{
39783977
std::shared_ptr<CIFPAnimations> pIFPAnimations = pReplacedAnimation->pIFP->GetIFPAnimationsPointer();
3979-
InsertAnimationAssociationToMap(pAnimAssoc, pIFPAnimations);
3978+
InsertAnimationAssociationToMap(pAnimAssocInterface, pIFPAnimations);
39803979

39813980
// Play our custom animation instead of default
3982-
pOutAnimStaticAssoc->Initialize(pClump, pReplacedAnimation->pAnimationHierarchy);
3981+
auto pAnimHierarchy = pAnimationManager->GetCustomAnimBlendHierarchy(pReplacedAnimation->pAnimationHierarchy);
3982+
pAnimationManager->UncompressAnimation(pAnimHierarchy.get());
3983+
pAnimAssociation->Constructor(pClump, pAnimHierarchy->GetInterface());
3984+
pAnimAssociation->SetFlags(pOriginalAnimStaticAssoc->GetFlags());
3985+
pAnimAssociation->SetAnimID(pOriginalAnimStaticAssoc->GetAnimID());
3986+
pAnimAssociation->SetAnimGroup(pOriginalAnimStaticAssoc->GetAnimGroup());
39833987
isCustomAnimationToPlay = true;
39843988
}
39853989
}
39863990

39873991
if (!isCustomAnimationToPlay)
39883992
{
3993+
auto pAnimHierarchy = pAnimationManager->GetAnimBlendHierarchy(pOriginalAnimHierarchyInterface);
3994+
39893995
// Play default internal animation
3990-
pOutAnimStaticAssoc->Initialize(pClump, pOriginalAnimHierarchyInterface);
3996+
pAnimationManager->UncompressAnimation(pAnimHierarchy);
3997+
pAnimAssociation->Constructor(*pOriginalAnimStaticAssoc->GetInterface());
39913998
}
3992-
3993-
CopyStaticAssociationProperties(pOutAnimStaticAssoc, pOriginalAnimStaticAssoc);
39943999
return isCustomAnimationToPlay;
39954000
}
39964001

@@ -6772,17 +6777,6 @@ void CClientGame::RestreamModel(unsigned short usModel)
67726777
m_pManager->GetVehicleManager()->RestreamVehicleUpgrades(usModel);
67736778
}
67746779

6775-
void CClientGame::CopyStaticAssociationProperties(std::unique_ptr<CAnimBlendStaticAssociation>& pOutAnimStaticAssoc,
6776-
std::unique_ptr<CAnimBlendStaticAssociation>& pOriginalAnimStaticAssoc)
6777-
{
6778-
pOutAnimStaticAssoc->SetAnimGroup(pOriginalAnimStaticAssoc->GetAnimGroup());
6779-
pOutAnimStaticAssoc->SetAnimID(pOriginalAnimStaticAssoc->GetAnimID());
6780-
6781-
// Total bones in clump. GTA SA is using 32 bones for peds/players
6782-
pOutAnimStaticAssoc->SetNumBlendNodes(pOriginalAnimStaticAssoc->GetNumBlendNodes());
6783-
pOutAnimStaticAssoc->SetFlags(pOriginalAnimStaticAssoc->GetFlags());
6784-
}
6785-
67866780
void CClientGame::InsertIFPPointerToMap(const unsigned int u32BlockNameHash, const std::shared_ptr<CClientIFP>& pIFP)
67876781
{
67886782
m_mapOfIfpPointers[u32BlockNameHash] = pIFP;

Client/mods/deathmatch/logic/CClientGame.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -503,8 +503,8 @@ class CClientGame
503503
static CAnimBlendAssociationSAInterface* StaticAddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID);
504504
static CAnimBlendAssociationSAInterface* StaticAddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith,
505505
AssocGroupId animGroup, AnimationId animID);
506-
static bool StaticAssocGroupCopyAnimationHandler(CAnimBlendStaticAssociationSAInterface* pOutAnimStaticAssoc, CAnimBlendAssociationSAInterface* pAnimAssoc,
507-
RpClump* pClump, CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID);
506+
static bool StaticAssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump,
507+
CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID);
508508
static bool StaticBlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy,
509509
int* pFlags, RpClump* pClump);
510510
static bool StaticProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface);
@@ -543,8 +543,8 @@ class CClientGame
543543
CAnimBlendAssociationSAInterface* AddAnimationHandler(RpClump* pClump, AssocGroupId animGroup, AnimationId animID);
544544
CAnimBlendAssociationSAInterface* AddAnimationAndSyncHandler(RpClump* pClump, CAnimBlendAssociationSAInterface* pAnimAssocToSyncWith,
545545
AssocGroupId animGroup, AnimationId animID);
546-
bool AssocGroupCopyAnimationHandler(CAnimBlendStaticAssociationSAInterface* pOutAnimStaticAssoc, CAnimBlendAssociationSAInterface* pAnimAssoc,
547-
RpClump* pClump, CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID);
546+
bool AssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, CAnimBlendAssocGroupSAInterface* pAnimAssocGroup,
547+
AnimationId animID);
548548
bool BlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, int* pFlags,
549549
RpClump* pClump);
550550
bool ProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface);
@@ -601,8 +601,6 @@ class CClientGame
601601
void SetFileCacheRoot(void);
602602
const char* GetFileCacheRoot(void) { return m_strFileCacheRoot; }
603603

604-
void CopyStaticAssociationProperties(std::unique_ptr<CAnimBlendStaticAssociation>& pOutAnimStaticAssoc,
605-
std::unique_ptr<CAnimBlendStaticAssociation>& pOriginalAnimStaticAssoc);
606604
void InsertIFPPointerToMap(const unsigned int u32BlockNameHash, const std::shared_ptr<CClientIFP>& pIFP);
607605
void RemoveIFPPointerFromMap(const unsigned int u32BlockNameHash);
608606
std::shared_ptr<CClientIFP> GetIFPPointerFromMap(const unsigned int u32BlockNameHash);

Client/multiplayer_sa/CMultiplayerSA.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,8 @@ enum eRadioStationID
4040
WCTR,
4141
};
4242

43-
typedef void(__thiscall* hCAnimBlendStaticAssociation_FreeSequenceArray)(CAnimBlendStaticAssociationSAInterface* pThis);
44-
typedef void(__cdecl* hUncompressAnimation)(CAnimBlendHierarchySAInterface* pAnimBlendHierarchyInterface);
4543
typedef void*(__cdecl* hCAnimBlendAssociation_NewOperator)(size_t iSizeInBytes);
4644

47-
typedef CAnimBlendAssociationSAInterface*(__thiscall* hCAnimBlendAssociation_Constructor_staticAssocByReference)(
48-
CAnimBlendAssociationSAInterface* pThis, CAnimBlendStaticAssociationSAInterface& StaticAssociationByReference);
49-
5045
class CMultiplayerSA : public CMultiplayer
5146
{
5247
friend class COffsetsMP;

Client/multiplayer_sa/CMultiplayerSA_CustomAnimations.cpp

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ DWORD RETURN_CAnimManager_AddAnimation = 0x4D3AB1;
2626
DWORD RETURN_CAnimManager_AddAnimationAndSync = 0x4D3B41;
2727
DWORD RETURN_CAnimManager_BlendAnimation_Hierarchy = 0x4D4577;
2828

29-
auto CAnimBlendStaticAssociation_FreeSequenceArray = (hCAnimBlendStaticAssociation_FreeSequenceArray)0x4ce9a0;
30-
auto UncompressAnimation = (hUncompressAnimation)0x4d41c0;
31-
auto CAnimBlendAssociation_Constructor_staticAssocByReference = (hCAnimBlendAssociation_Constructor_staticAssocByReference)0x4CF080;
32-
3329
auto CAnimBlendAssociation_NewOperator_US = (hCAnimBlendAssociation_NewOperator)0x82119A;
3430
auto CAnimBlendAssociation_NewOperator_EU = (hCAnimBlendAssociation_NewOperator)0x8211DA;
3531

@@ -70,15 +66,7 @@ CAnimBlendAssociationSAInterface* __cdecl CAnimBlendAssocGroup_CopyAnimation(RpC
7066

7167
if (pAnimAssociationInterface)
7268
{
73-
CAnimBlendStaticAssociationSAInterface staticAnimAssociationInterface;
74-
75-
m_pAssocGroupCopyAnimationHandler(&staticAnimAssociationInterface, pAnimAssociationInterface, pClump, pAnimAssocGroupInterface, animID);
76-
77-
UncompressAnimation(staticAnimAssociationInterface.pAnimHeirarchy);
78-
79-
CAnimBlendAssociation_Constructor_staticAssocByReference(pAnimAssociationInterface, staticAnimAssociationInterface);
80-
81-
CAnimBlendStaticAssociation_FreeSequenceArray(&staticAnimAssociationInterface);
69+
m_pAssocGroupCopyAnimationHandler(pAnimAssociationInterface, pClump, pAnimAssocGroupInterface, animID);
8270
}
8371
return pAnimAssociationInterface;
8472
}

Client/sdk/game/CAnimBlendAssociation.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,29 @@
1313
#define __CAnimBlendAssociation_H
1414

1515
class CAnimBlendAssociationSAInterface;
16+
class CAnimBlendStaticAssociationSAInterface;
1617
typedef unsigned long AssocGroupId;
1718
typedef unsigned long AnimationId;
1819
class CAnimBlendHierarchy;
20+
class CAnimBlendHierarchySAInterface;
21+
struct RpClump;
1922

2023
class CAnimBlendAssociation
2124
{
2225
public:
26+
virtual CAnimBlendAssociationSAInterface* Constructor(CAnimBlendStaticAssociationSAInterface& StaticAssociationByReference) = 0;
27+
virtual CAnimBlendAssociationSAInterface* Constructor(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy) = 0;
2328
virtual CAnimBlendAssociationSAInterface* GetInterface(void) = 0;
2429
virtual AssocGroupId GetAnimGroup(void) = 0;
2530
virtual AnimationId GetAnimID(void) = 0;
2631
virtual CAnimBlendHierarchy* GetAnimHierarchy(void) = 0;
2732

2833
virtual float GetBlendAmount(void) = 0;
2934
virtual void SetBlendAmount(float fAmount) = 0;
30-
31-
virtual void SetCurrentProgress(float fProgress) = 0;
35+
virtual void SetCurrentProgress(float fProgress) = 0;
36+
virtual void SetAnimID(short sAnimID) = 0;
37+
virtual void SetAnimGroup(short sAnimGroup) = 0;
38+
virtual void SetFlags(short sFlags) = 0;
3239
};
3340

3441
#endif

0 commit comments

Comments
 (0)