Skip to content

Commit 42582eb

Browse files
committed
Fix #371: engineReplaceAnimation does not apply the replaced animation-
if it is currently used
1 parent df10316 commit 42582eb

File tree

7 files changed

+68
-37
lines changed

7 files changed

+68
-37
lines changed

Client/game_sa/CAnimManagerSA.cpp

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -700,30 +700,6 @@ std::unique_ptr<CAnimBlendAssociation> CAnimManagerSA::RpAnimBlendClumpGetAssoci
700700
return nullptr;
701701
}
702702

703-
std::unique_ptr<CAnimBlendAssociation> CAnimManagerSA::RpAnimBlendClumpGetAssociationHashKey(RpClump* pClump, const unsigned int& uiAnimNameHashKey)
704-
{
705-
if (!pClump)
706-
{
707-
return nullptr;
708-
}
709-
710-
auto pAnimAssociation = RpAnimBlendClumpGetFirstAssociation(pClump);
711-
while (pAnimAssociation)
712-
{
713-
auto pAnimNextAssociation = RpAnimBlendGetNextAssociation(pAnimAssociation);
714-
auto pAnimHierarchy = pAnimAssociation->GetAnimHierarchy();
715-
if (pAnimHierarchy)
716-
{
717-
if (pAnimHierarchy->GetNameHashKey() == uiAnimNameHashKey)
718-
{
719-
return pAnimAssociation;
720-
}
721-
}
722-
pAnimAssociation = std::move(pAnimNextAssociation);
723-
}
724-
return nullptr;
725-
}
726-
727703
std::unique_ptr<CAnimBlendAssociation> CAnimManagerSA::RpAnimBlendGetNextAssociation(std::unique_ptr<CAnimBlendAssociation>& pAssociation)
728704
{
729705
CAnimBlendAssociationSAInterface* pInterface = nullptr;

Client/game_sa/CAnimManagerSA.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ class CAnimManagerSA : public CAnimManager
144144
std::unique_ptr<CAnimBlendAssociation> RpAnimBlendClumpGetFirstAssociation(RpClump* pClump);
145145
std::unique_ptr<CAnimBlendAssociation> RpAnimBlendClumpGetAssociation(RpClump* pClump, const char* szAnimName);
146146
std::unique_ptr<CAnimBlendAssociation> RpAnimBlendClumpGetAssociation(RpClump* pClump, AnimationId animID);
147-
std::unique_ptr<CAnimBlendAssociation> RpAnimBlendClumpGetAssociationHashKey(RpClump* pClump, const unsigned int& uiAnimNameHashKey);
148147
std::unique_ptr<CAnimBlendAssociation> RpAnimBlendGetNextAssociation(std::unique_ptr<CAnimBlendAssociation>& pAssociation);
149148
int RpAnimBlendClumpGetNumAssociations(RpClump* pClump);
150149
void RpAnimBlendClumpUpdateAnimations(RpClump* pClump, float f1, bool b1);

Client/mods/deathmatch/logic/CClientPed.cpp

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6079,8 +6079,9 @@ void CClientPed::ReplaceAnimation(std::unique_ptr<CAnimBlendHierarchy>& pInterna
60796079

60806080
void CClientPed::RestoreAnimation(std::unique_ptr<CAnimBlendHierarchy>& pInternalAnimHierarchy)
60816081
{
6082-
m_mapOfReplacedAnimations.erase(pInternalAnimHierarchy->GetInterface());
6083-
CIFPEngine::EngineApplyAnimation(*this, pInternalAnimHierarchy->GetInterface());
6082+
CAnimBlendHierarchySAInterface* pInterface = pInternalAnimHierarchy->GetInterface();
6083+
CIFPEngine::EngineApplyAnimation(*this, pInterface, pInterface);
6084+
m_mapOfReplacedAnimations.erase(pInterface);
60846085
}
60856086

60866087
void CClientPed::RestoreAnimations(const std::shared_ptr<CClientIFP>& IFP)
@@ -6089,7 +6090,8 @@ void CClientPed::RestoreAnimations(const std::shared_ptr<CClientIFP>& IFP)
60896090
{
60906091
if (std::addressof(*IFP.get()) == std::addressof(*iter->second.pIFP.get()))
60916092
{
6092-
CIFPEngine::EngineApplyAnimation(*this, iter->first);
6093+
auto pAnimHierarchy = g_pGame->GetAnimManager()->GetAnimBlendHierarchy(iter->first);
6094+
CIFPEngine::EngineApplyAnimation(*this, iter->first, iter->first);
60936095
iter = m_mapOfReplacedAnimations.erase(iter);
60946096
}
60956097
else
@@ -6106,14 +6108,13 @@ void CClientPed::RestoreAnimations(CAnimBlock& animationBlock)
61066108
for (size_t i = 0; i < cAnimations; i++)
61076109
{
61086110
auto pAnimHierarchyInterface = animationBlock.GetAnimationHierarchyInterface(i);
6111+
CIFPEngine::EngineApplyAnimation(*this, pAnimHierarchyInterface, pAnimHierarchyInterface);
61096112
m_mapOfReplacedAnimations.erase(pAnimHierarchyInterface);
6110-
CIFPEngine::EngineApplyAnimation(*this, pAnimHierarchyInterface);
61116113
}
61126114
}
61136115

61146116
void CClientPed::RestoreAllAnimations()
61156117
{
6116-
m_mapOfReplacedAnimations.clear();
61176118
CAnimManager* pAnimationManager = g_pGame->GetAnimManager();
61186119
RpClump* pClump = GetClump();
61196120
if (pClump)
@@ -6129,12 +6130,14 @@ void CClientPed::RestoreAllAnimations()
61296130
auto pAnimStaticAssociation = pAnimationManager->GetAnimStaticAssociation(iGroupID, iAnimID);
61306131
if (pAnimStaticAssociation && pAnimHierarchy->IsCustom())
61316132
{
6132-
CIFPEngine::EngineApplyAnimation(*this, pAnimStaticAssociation->GetAnimHierachyInterface());
6133+
auto pAnimHierarchyInterface = pAnimStaticAssociation->GetAnimHierachyInterface();
6134+
CIFPEngine::EngineApplyAnimation(*this, pAnimHierarchyInterface, pAnimHierarchyInterface);
61336135
}
61346136
}
61356137
pAnimAssociation = std::move(pAnimNextAssociation);
61366138
}
61376139
}
6140+
m_mapOfReplacedAnimations.clear();
61386141
}
61396142

61406143
SReplacedAnimation* CClientPed::GetReplacedAnimation(CAnimBlendHierarchySAInterface* pInternalHierarchyInterface)
@@ -6148,6 +6151,45 @@ SReplacedAnimation* CClientPed::GetReplacedAnimation(CAnimBlendHierarchySAInterf
61486151
return nullptr;
61496152
}
61506153

6154+
std::unique_ptr<CAnimBlendAssociation> CClientPed::GetAnimAssociation(CAnimBlendHierarchySAInterface* pOriginalHierarchyInterface)
6155+
{
6156+
RpClump* pClump = GetClump();
6157+
if (!pClump)
6158+
{
6159+
return nullptr;
6160+
}
6161+
6162+
auto pReplacedAnimation = GetReplacedAnimation(pOriginalHierarchyInterface);
6163+
CAnimBlendHierarchySAInterface* pReplacedInterface = nullptr;
6164+
if (pReplacedAnimation != nullptr)
6165+
{
6166+
pReplacedInterface = pReplacedAnimation->pAnimationHierarchy;
6167+
}
6168+
6169+
CAnimManager* pAnimationManager = g_pGame->GetAnimManager();
6170+
auto pAnimAssociation = pAnimationManager->RpAnimBlendClumpGetFirstAssociation(pClump);
6171+
while (pAnimAssociation)
6172+
{
6173+
auto pAnimNextAssociation = pAnimationManager->RpAnimBlendGetNextAssociation(pAnimAssociation);
6174+
auto pAnimHierarchy = pAnimAssociation->GetAnimHierarchy();
6175+
if (pAnimHierarchy)
6176+
{
6177+
CAnimBlendHierarchySAInterface* pInterface = pAnimHierarchy->GetInterface();
6178+
if (pInterface == pOriginalHierarchyInterface)
6179+
{
6180+
return pAnimAssociation;
6181+
}
6182+
if (pReplacedInterface && pInterface == pReplacedInterface)
6183+
{
6184+
return pAnimAssociation;
6185+
}
6186+
}
6187+
pAnimAssociation = std::move(pAnimNextAssociation);
6188+
}
6189+
return nullptr;
6190+
6191+
}
6192+
61516193
CSphere CClientPed::GetWorldBoundingSphere()
61526194
{
61536195
CSphere sphere;

Client/mods/deathmatch/logic/CClientPed.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,8 @@ class CClientPed : public CClientStreamElement, public CAntiCheatModule
500500
void RestoreAllAnimations();
501501
SReplacedAnimation* GetReplacedAnimation(CAnimBlendHierarchySAInterface* pInternalHierarchyInterface);
502502

503+
std::unique_ptr<CAnimBlendAssociation> GetAnimAssociation(CAnimBlendHierarchySAInterface* pHierarchyInterface);
504+
503505
protected:
504506
// This constructor is for peds managed by a player. These are unknown to the ped manager.
505507
CClientPed(CClientManager* pManager, unsigned long ulModelID, ElementID ID, bool bIsLocalPlayer);

Client/mods/deathmatch/logic/CIFPEngine.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ bool CIFPEngine::EngineReplaceAnimation(CClientEntity* pEntity, const SString& s
5656
CAnimBlendHierarchySAInterface* pCustomAnimHierarchyInterface = pCustomIFP->GetAnimationHierarchy(strCustomAnimName);
5757
if (pInternalAnimHierarchy && pCustomAnimHierarchyInterface)
5858
{
59+
EngineApplyAnimation(Ped, pInternalAnimHierarchy->GetInterface(), pCustomAnimHierarchyInterface);
5960
Ped.ReplaceAnimation(pInternalAnimHierarchy, pCustomIFP, pCustomAnimHierarchyInterface);
60-
EngineApplyAnimation(Ped, pCustomAnimHierarchyInterface);
6161
return true;
6262
}
6363
}
@@ -101,16 +101,29 @@ bool CIFPEngine::EngineRestoreAnimation(CClientEntity* pEntity, const SString& s
101101
return false;
102102
}
103103

104-
bool CIFPEngine::EngineApplyAnimation(CClientPed& Ped, CAnimBlendHierarchySAInterface* pAnimHierarchyInterface)
104+
bool CIFPEngine::EngineApplyAnimation(CClientPed& Ped, CAnimBlendHierarchySAInterface* pOriginalHierarchyInterface, CAnimBlendHierarchySAInterface* pAnimHierarchyInterface)
105105
{
106106
CAnimManager* pAnimationManager = g_pGame->GetAnimManager();
107107
RpClump* pClump = Ped.GetClump();
108108
if (pClump)
109109
{
110-
auto pAnimHierarchy = pAnimationManager->GetAnimBlendHierarchy(pAnimHierarchyInterface);
111-
auto pCurrentAnimAssociation = pAnimationManager->RpAnimBlendClumpGetAssociationHashKey(pClump, pAnimHierarchy->GetNameHashKey());
110+
auto pCurrentAnimAssociation = Ped.GetAnimAssociation(pOriginalHierarchyInterface);
112111
if (pCurrentAnimAssociation)
113112
{
113+
auto pCurrentAnimHierarchy = pCurrentAnimAssociation->GetAnimHierarchy();
114+
auto pAssocHierachyInterface = pCurrentAnimHierarchy->GetInterface();
115+
if (pAssocHierachyInterface == pAnimHierarchyInterface)
116+
{
117+
return true;
118+
}
119+
120+
int iGroupID = pCurrentAnimAssociation->GetAnimGroup();
121+
int iAnimID = pCurrentAnimAssociation->GetAnimID();
122+
if (iGroupID < 0 && iAnimID < 0)
123+
{
124+
return true;
125+
}
126+
auto pAnimHierarchy = pAnimationManager->GetAnimBlendHierarchy(pAnimHierarchyInterface);
114127
pAnimationManager->UncompressAnimation(pAnimHierarchy.get());
115128
pCurrentAnimAssociation->FreeAnimBlendNodeArray();
116129
pCurrentAnimAssociation->Init(pClump, pAnimHierarchyInterface);

Client/mods/deathmatch/logic/CIFPEngine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ class CIFPEngine
2929
const SString& strCustomBlockName, const SString& strCustomAnimName);
3030
static bool EngineRestoreAnimation(CClientEntity* pEntity, const SString& strInternalBlockName, const SString& strInternalAnimName,
3131
const eRestoreAnimation& eRestoreType);
32-
static bool EngineApplyAnimation(CClientPed& Ped, CAnimBlendHierarchySAInterface* pAnimHierarchyInterface);
32+
static bool EngineApplyAnimation(CClientPed& Ped, CAnimBlendHierarchySAInterface* pOriginalHierarchyInterface, CAnimBlendHierarchySAInterface* pAnimHierarchyInterface);
3333
static bool IsIFPData(const SString& strData);
3434
};

Client/sdk/game/CAnimManager.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ class CAnimManager
107107
virtual AnimBlendAssoc_type RpAnimBlendClumpGetFirstAssociation(RpClump* pClump) = 0;
108108
virtual AnimBlendAssoc_type RpAnimBlendClumpGetAssociation(RpClump* pClump, const char* szAnimName) = 0;
109109
virtual AnimBlendAssoc_type RpAnimBlendClumpGetAssociation(RpClump* pClump, AnimationId animID) = 0;
110-
virtual AnimBlendAssoc_type RpAnimBlendClumpGetAssociationHashKey(RpClump* pClump, const unsigned int& uiAnimNameHashKey) = 0;
111110
virtual AnimBlendAssoc_type RpAnimBlendGetNextAssociation(std::unique_ptr<CAnimBlendAssociation>& pAssociation) = 0;
112111
virtual int RpAnimBlendClumpGetNumAssociations(RpClump* pClump) = 0;
113112
virtual void RpAnimBlendClumpUpdateAnimations(RpClump* pClump, float f1, bool b1) = 0;

0 commit comments

Comments
 (0)