Skip to content

Commit 1d37c73

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. (reverted from commit c7ed932)
1 parent f6ce95a commit 1d37c73

13 files changed

+65
-87
lines changed

Client/game_sa/CAnimBlendAssociationSA.cpp

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,6 @@
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-
4116
CAnimBlendHierarchy* CAnimBlendAssociationSA::GetAnimHierarchy(void)
4217
{
4318
return pGame->GetAnimManager()->GetAnimBlendHierarchy(m_pInterface->pAnimHierarchy);
@@ -55,4 +30,4 @@ void CAnimBlendAssociationSA::SetCurrentProgress(float fProgress)
5530
push fTime
5631
call DwFunc
5732
};
58-
}
33+
}

Client/game_sa/CAnimBlendAssociationSA.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,15 @@ 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);
5048
CAnimBlendAssociationSAInterface* GetInterface(void) { return m_pInterface; }
5149
AssocGroupId GetAnimGroup(void) { return (AssocGroupId)m_pInterface->sAnimGroup; }
5250
AnimationId GetAnimID(void) { return (AnimationId)m_pInterface->sAnimID; }
5351
CAnimBlendHierarchy* GetAnimHierarchy(void);
5452

5553
float GetBlendAmount(void) { return m_pInterface->fBlendAmount; }
5654
void SetBlendAmount(float fAmount) { m_pInterface->fBlendAmount = fAmount; }
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; }
55+
56+
void SetCurrentProgress(float fProgress);
6157

6258
protected:
6359
CAnimBlendAssociationSAInterface* m_pInterface;

Client/game_sa/CAnimBlendStaticAssociationSA.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,11 @@ 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; }
55-
CAnimBlendStaticAssociationSAInterface* GetInterface(void) { return m_pInterface; }
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; }
5655

5756
protected:
5857
CAnimBlendStaticAssociationSAInterface* m_pInterface;

Client/game_sa/CAnimManagerSA.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -749,11 +749,6 @@ 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-
757752
CAnimManagerSA::StaticAssocIntface_type CAnimManagerSA::GetAnimStaticAssociation(CAnimBlendStaticAssociationSAInterface* pInterface)
758753
{
759754
return std::make_unique<CAnimBlendStaticAssociationSA>(pInterface);

Client/game_sa/CAnimManagerSA.h

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

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

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

Client/mods/deathmatch/logic/CClientGame.cpp

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

3650-
bool CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump,
3650+
bool CClientGame::StaticAssocGroupCopyAnimationHandler(CAnimBlendStaticAssociationSAInterface* pOutAnimStaticAssoc,
3651+
CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump,
36513652
CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID)
36523653
{
3653-
return g_pClientGame->AssocGroupCopyAnimationHandler(pAnimAssoc, pClump, pAnimAssocGroup, animID);
3654+
return g_pClientGame->AssocGroupCopyAnimationHandler(pOutAnimStaticAssoc, pAnimAssoc, pClump, pAnimAssocGroup, animID);
36543655
}
36553656

36563657
bool CClientGame::StaticBlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy,
@@ -3958,44 +3959,38 @@ CAnimBlendAssociationSAInterface* CClientGame::AddAnimationAndSyncHandler(RpClum
39583959
return nullptr;
39593960
}
39603961

3961-
bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendAssociationSAInterface* pAnimAssocInterface, RpClump* pClump,
3962+
bool CClientGame::AssocGroupCopyAnimationHandler(CAnimBlendStaticAssociationSAInterface* pOutAnimStaticAssocInterface,
3963+
CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump,
39623964
CAnimBlendAssocGroupSAInterface* pAnimAssocGroupInterface, AnimationId animID)
39633965
{
39643966
bool isCustomAnimationToPlay = false;
39653967
CAnimManager* pAnimationManager = g_pGame->GetAnimManager();
39663968
auto pAnimAssocGroup = pAnimationManager->GetAnimBlendAssocGroup(pAnimAssocGroupInterface);
39673969
auto pOriginalAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation(pAnimAssocGroup->GetGroupID(), animID);
39683970
auto pOriginalAnimHierarchyInterface = pOriginalAnimStaticAssoc->GetAnimHierachyInterface();
3969-
auto pAnimAssociation = pAnimationManager->GetAnimBlendAssociation2(pAnimAssocInterface);
3970-
3971-
CClientPed* pClientPed = GetClientPedByClump(*pClump);
3971+
auto pOutAnimStaticAssoc = pAnimationManager->GetAnimStaticAssociation(pOutAnimStaticAssocInterface);
3972+
CClientPed* pClientPed = GetClientPedByClump(*pClump);
39723973
if (pClientPed != nullptr)
39733974
{
39743975
auto pReplacedAnimation = pClientPed->GetReplacedAnimation(pOriginalAnimHierarchyInterface);
39753976
if (pReplacedAnimation != nullptr)
39763977
{
39773978
std::shared_ptr<CIFPAnimations> pIFPAnimations = pReplacedAnimation->pIFP->GetIFPAnimationsPointer();
3978-
InsertAnimationAssociationToMap(pAnimAssocInterface, pIFPAnimations);
3979+
InsertAnimationAssociationToMap(pAnimAssoc, pIFPAnimations);
39793980

39803981
// Play our custom animation instead of default
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());
3982+
pOutAnimStaticAssoc->Initialize(pClump, pReplacedAnimation->pAnimationHierarchy);
39873983
isCustomAnimationToPlay = true;
39883984
}
39893985
}
39903986

39913987
if (!isCustomAnimationToPlay)
39923988
{
3993-
auto pAnimHierarchy = pAnimationManager->GetAnimBlendHierarchy(pOriginalAnimHierarchyInterface);
3994-
39953989
// Play default internal animation
3996-
pAnimationManager->UncompressAnimation(pAnimHierarchy);
3997-
pAnimAssociation->Constructor(*pOriginalAnimStaticAssoc->GetInterface());
3990+
pOutAnimStaticAssoc->Initialize(pClump, pOriginalAnimHierarchyInterface);
39983991
}
3992+
3993+
CopyStaticAssociationProperties(pOutAnimStaticAssoc, pOriginalAnimStaticAssoc);
39993994
return isCustomAnimationToPlay;
40003995
}
40013996

@@ -6777,6 +6772,17 @@ void CClientGame::RestreamModel(unsigned short usModel)
67776772
m_pManager->GetVehicleManager()->RestreamVehicleUpgrades(usModel);
67786773
}
67796774

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+
67806786
void CClientGame::InsertIFPPointerToMap(const unsigned int u32BlockNameHash, const std::shared_ptr<CClientIFP>& pIFP)
67816787
{
67826788
m_mapOfIfpPointers[u32BlockNameHash] = pIFP;

Client/mods/deathmatch/logic/CClientGame.h

Lines changed: 6 additions & 4 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(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump,
507-
CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID);
506+
static bool StaticAssocGroupCopyAnimationHandler(CAnimBlendStaticAssociationSAInterface* pOutAnimStaticAssoc, CAnimBlendAssociationSAInterface* pAnimAssoc,
507+
RpClump* pClump, 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(CAnimBlendAssociationSAInterface* pAnimAssoc, RpClump* pClump, CAnimBlendAssocGroupSAInterface* pAnimAssocGroup,
547-
AnimationId animID);
546+
bool AssocGroupCopyAnimationHandler(CAnimBlendStaticAssociationSAInterface* pOutAnimStaticAssoc, CAnimBlendAssociationSAInterface* pAnimAssoc,
547+
RpClump* pClump, CAnimBlendAssocGroupSAInterface* pAnimAssocGroup, AnimationId animID);
548548
bool BlendAnimationHierarchyHandler(CAnimBlendAssociationSAInterface* pAnimAssoc, CAnimBlendHierarchySAInterface** pOutAnimHierarchy, int* pFlags,
549549
RpClump* pClump);
550550
bool ProcessCollisionHandler(CEntitySAInterface* pThisInterface, CEntitySAInterface* pOtherInterface);
@@ -601,6 +601,8 @@ 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);
604606
void InsertIFPPointerToMap(const unsigned int u32BlockNameHash, const std::shared_ptr<CClientIFP>& pIFP);
605607
void RemoveIFPPointerFromMap(const unsigned int u32BlockNameHash);
606608
std::shared_ptr<CClientIFP> GetIFPPointerFromMap(const unsigned int u32BlockNameHash);

Client/multiplayer_sa/CMultiplayerSA.h

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

43+
typedef void(__thiscall* hCAnimBlendStaticAssociation_FreeSequenceArray)(CAnimBlendStaticAssociationSAInterface* pThis);
44+
typedef void(__cdecl* hUncompressAnimation)(CAnimBlendHierarchySAInterface* pAnimBlendHierarchyInterface);
4345
typedef void*(__cdecl* hCAnimBlendAssociation_NewOperator)(size_t iSizeInBytes);
4446

47+
typedef CAnimBlendAssociationSAInterface*(__thiscall* hCAnimBlendAssociation_Constructor_staticAssocByReference)(
48+
CAnimBlendAssociationSAInterface* pThis, CAnimBlendStaticAssociationSAInterface& StaticAssociationByReference);
49+
4550
class CMultiplayerSA : public CMultiplayer
4651
{
4752
friend class COffsetsMP;

Client/multiplayer_sa/CMultiplayerSA_CustomAnimations.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ 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+
2933
auto CAnimBlendAssociation_NewOperator_US = (hCAnimBlendAssociation_NewOperator)0x82119A;
3034
auto CAnimBlendAssociation_NewOperator_EU = (hCAnimBlendAssociation_NewOperator)0x8211DA;
3135

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

6771
if (pAnimAssociationInterface)
6872
{
69-
m_pAssocGroupCopyAnimationHandler(pAnimAssociationInterface, pClump, pAnimAssocGroupInterface, animID);
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);
7082
}
7183
return pAnimAssociationInterface;
7284
}

Client/sdk/game/CAnimBlendAssociation.h

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

1515
class CAnimBlendAssociationSAInterface;
16-
class CAnimBlendStaticAssociationSAInterface;
1716
typedef unsigned long AssocGroupId;
1817
typedef unsigned long AnimationId;
1918
class CAnimBlendHierarchy;
20-
class CAnimBlendHierarchySAInterface;
21-
struct RpClump;
2219

2320
class CAnimBlendAssociation
2421
{
2522
public:
26-
virtual CAnimBlendAssociationSAInterface* Constructor(CAnimBlendStaticAssociationSAInterface& StaticAssociationByReference) = 0;
27-
virtual CAnimBlendAssociationSAInterface* Constructor(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy) = 0;
2823
virtual CAnimBlendAssociationSAInterface* GetInterface(void) = 0;
2924
virtual AssocGroupId GetAnimGroup(void) = 0;
3025
virtual AnimationId GetAnimID(void) = 0;
3126
virtual CAnimBlendHierarchy* GetAnimHierarchy(void) = 0;
3227

3328
virtual float GetBlendAmount(void) = 0;
3429
virtual void SetBlendAmount(float fAmount) = 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;
30+
31+
virtual void SetCurrentProgress(float fProgress) = 0;
3932
};
4033

4134
#endif

0 commit comments

Comments
 (0)