Skip to content

Commit

Permalink
Make engineRestoreAnimation apply animation
Browse files Browse the repository at this point in the history
- Default animation will be applied when engineRestoreAnimation is called.
- Default animation will be applied when ifp is unloaded.

Animations played via setPedAnimation are not affected by engineRestoreAnimation or engineReplaceAnimation.
  • Loading branch information
codenulls committed Sep 14, 2018
1 parent 7deb08a commit 80bb898
Show file tree
Hide file tree
Showing 16 changed files with 122 additions and 65 deletions.
24 changes: 10 additions & 14 deletions Client/game_sa/CAnimBlendAssociationSA.cpp
Expand Up @@ -53,25 +53,21 @@ CAnimBlendAssociationSAInterface* CAnimBlendAssociationSA::InitializeForCustomAn
m_pInterface->sAnimID = -1;
m_pInterface->listEntry.prev = 0;
m_pInterface->listEntry.next = 0;
InitializeWithHierarchy(pClump, pAnimHierarchy);
Init(pClump, pAnimHierarchy);
return m_pInterface;
}

void CAnimBlendAssociationSA::InitializeWithHierarchy(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy)
void CAnimBlendAssociationSA::Init(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy)
{
const unsigned short cBlendNodes = 32;
m_pInterface->cNumBlendNodes = cBlendNodes;
AllocateAnimBlendNodeArray(cBlendNodes);
m_pInterface->pAnimHierarchy = pAnimHierarchy;
for (size_t i = 0; i < cBlendNodes; i++)
DWORD DwFunc = 0x4CED50;
DWORD DwThisInterface = reinterpret_cast<DWORD>(m_pInterface);
_asm
{
m_pInterface->pAnimBlendNodeArray[i].pAnimBlendAssociation = m_pInterface;
CAnimBlendSequenceSAInterface& sequence = pAnimHierarchy->pSequences[i];
if (sequence.sNumKeyFrames > 0)
{
m_pInterface->pAnimBlendNodeArray[i].pAnimSequence = &sequence;
}
}
mov ecx, DwThisInterface
push pAnimHierarchy
push pClump
call DwFunc
};
}

void CAnimBlendAssociationSA::AllocateAnimBlendNodeArray(int iCount)
Expand Down
2 changes: 1 addition & 1 deletion Client/game_sa/CAnimBlendAssociationSA.h
Expand Up @@ -92,7 +92,7 @@ class CAnimBlendAssociationSA : public CAnimBlendAssociation
CAnimBlendAssociationSAInterface* Constructor(CAnimBlendStaticAssociationSAInterface& StaticAssociationByReference);
CAnimBlendAssociationSAInterface* Constructor(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy);
CAnimBlendAssociationSAInterface* InitializeForCustomAnimation(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy);
void InitializeWithHierarchy(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy);
void Init(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy);
void AllocateAnimBlendNodeArray(int count);
void FreeAnimBlendNodeArray();
CAnimBlendAssociationSAInterface* GetInterface() { return m_pInterface; }
Expand Down
26 changes: 14 additions & 12 deletions Client/game_sa/CAnimBlendHierarchySA.h
Expand Up @@ -10,7 +10,6 @@
*****************************************************************************/

/* CAnimBlendHierarchy: data tree on animation blending?*/

#pragma once

#include <game/CAnimBlendHierarchy.h>
Expand All @@ -32,7 +31,7 @@ class CAnimBlendHierarchySAInterface
// Careful, GetIndex will not work for custom animations
int GetIndex(void);

unsigned int iHashKey;
unsigned int uiHashKey;
CAnimBlendSequenceSAInterface* pSequences;
unsigned short usNumSequences;
bool bRunningCompressed;
Expand All @@ -47,23 +46,26 @@ class CAnimBlendHierarchySA : public CAnimBlendHierarchy
{
public:
CAnimBlendHierarchySA(CAnimBlendHierarchySAInterface* pInterface) { m_pInterface = pInterface; }
void Initialize(void);
void Initialize();
void SetName(const char* szName);
void SetSequences(CAnimBlendSequenceSAInterface* pSequences) { m_pInterface->pSequences = pSequences; }
void SetNumSequences(unsigned short uNumSequences) { m_pInterface->usNumSequences = uNumSequences; }
void SetRunningCompressed(bool bCompressed) { m_pInterface->bRunningCompressed = bCompressed; }
void SetAnimationBlockID(int iBlockID) { m_pInterface->iAnimBlockID = iBlockID; }
void RemoveAnimSequences(void);
void RemoveFromUncompressedCache(void);
void RemoveQuaternionFlips(void);
void CalculateTotalTime(void);
void RemoveAnimSequences();
void RemoveFromUncompressedCache();
void RemoveQuaternionFlips();
void CalculateTotalTime();
CAnimBlendSequenceSAInterface* GetSequence(DWORD dwIndex);
CAnimBlendSequenceSAInterface* GetSequences(void) { return m_pInterface->pSequences; }
unsigned short GetNumSequences(void) { return m_pInterface->usNumSequences; }
bool isRunningCompressed(void) { return m_pInterface->bRunningCompressed; }
int GetAnimBlockID(void) { return m_pInterface->iAnimBlockID; }
CAnimBlendHierarchySAInterface* GetInterface(void) { return m_pInterface; }
CAnimBlendSequenceSAInterface* GetSequences() { return m_pInterface->pSequences; }
unsigned short GetNumSequences() { return m_pInterface->usNumSequences; }
bool IsRunningCompressed() { return m_pInterface->bRunningCompressed; }
bool IsCustom() { return m_pInterface->iAnimBlockID == -1; }
int GetAnimBlockID() { return m_pInterface->iAnimBlockID; }
CAnimBlendHierarchySAInterface* GetInterface() { return m_pInterface; }
unsigned int GetNameHashKey() { return m_pInterface->uiHashKey; }

protected:
CAnimBlendHierarchySAInterface* m_pInterface;
};

2 changes: 0 additions & 2 deletions Client/game_sa/CAnimBlendStaticAssociationSA.h
Expand Up @@ -9,8 +9,6 @@
*
*****************************************************************************/

/* CAnimBlendStaticAssociation: 1 per uncompressed animation?*/

#pragma once

#include <game/CAnimBlendStaticAssociation.h>
Expand Down
26 changes: 25 additions & 1 deletion Client/game_sa/CAnimManagerSA.cpp
Expand Up @@ -688,6 +688,30 @@ std::unique_ptr<CAnimBlendAssociation> CAnimManagerSA::RpAnimBlendClumpGetAssoci
return nullptr;
}

std::unique_ptr<CAnimBlendAssociation> CAnimManagerSA::RpAnimBlendClumpGetAssociationHashKey(RpClump* pClump, const unsigned int& uiAnimNameHashKey)
{
if (!pClump)
{
return nullptr;
}

auto pAnimAssociation = RpAnimBlendClumpGetFirstAssociation(pClump);
while (pAnimAssociation)
{
auto pAnimNextAssociation = RpAnimBlendGetNextAssociation(pAnimAssociation);
auto pAnimHierarchy = pAnimAssociation->GetAnimHierarchy();
if (pAnimHierarchy)
{
if (pAnimHierarchy->GetNameHashKey() == uiAnimNameHashKey)
{
return pAnimAssociation;
}
}
pAnimAssociation = std::move(pAnimNextAssociation);
}
return nullptr;
}

std::unique_ptr<CAnimBlendAssociation> CAnimManagerSA::RpAnimBlendGetNextAssociation(std::unique_ptr<CAnimBlendAssociation>& pAssociation)
{
CAnimBlendAssociationSAInterface* pInterface = nullptr;
Expand Down Expand Up @@ -840,5 +864,5 @@ void CAnimManagerSA::DeleteCustomAnimSequenceInterface(CAnimBlendSequenceSAInter

bool CAnimManagerSA::isGateWayAnimationHierarchy(CAnimBlendHierarchySAInterface* pInterface)
{
return pGame->GetKeyGen()->GetUppercaseKey(m_kGateWayAnimationName.c_str()) == pInterface->iHashKey;
return pGame->GetKeyGen()->GetUppercaseKey(m_kGateWayAnimationName.c_str()) == pInterface->uiHashKey;
}
1 change: 1 addition & 0 deletions Client/game_sa/CAnimManagerSA.h
Expand Up @@ -143,6 +143,7 @@ class CAnimManagerSA : public CAnimManager
std::unique_ptr<CAnimBlendAssociation> RpAnimBlendClumpGetFirstAssociation(RpClump* pClump);
std::unique_ptr<CAnimBlendAssociation> RpAnimBlendClumpGetAssociation(RpClump* pClump, const char* szAnimName);
std::unique_ptr<CAnimBlendAssociation> RpAnimBlendClumpGetAssociation(RpClump* pClump, AnimationId animID);
std::unique_ptr<CAnimBlendAssociation> RpAnimBlendClumpGetAssociationHashKey(RpClump* pClump, const unsigned int& uiAnimNameHashKey);
std::unique_ptr<CAnimBlendAssociation> RpAnimBlendGetNextAssociation(std::unique_ptr<CAnimBlendAssociation>& pAssociation);
int RpAnimBlendClumpGetNumAssociations(RpClump* pClump);
void RpAnimBlendClumpUpdateAnimations(RpClump* pClump, float f1, bool b1);
Expand Down
2 changes: 1 addition & 1 deletion Client/mods/deathmatch/logic/CClientGame.cpp
Expand Up @@ -3940,7 +3940,7 @@ bool CClientGame::ChokingHandler(unsigned char ucWeaponType)

void CClientGame::CAnimBlendAssocDestructorHandler(CAnimBlendAssociationSAInterface* pThis)
{
// printf("CClientGame::CAnimBlendAssocDestructorHandler called! sAnimID: %d\n", pThis->sAnimID);
// printf("CClientGame::CAnimBlendAssocDestructorHandler called! sAnimGroupID: %d | sAnimID: %d\n", pThis->sAnimGroup, pThis->sAnimID);
RemoveAnimationAssociationFromMap(pThis);
}

Expand Down
6 changes: 3 additions & 3 deletions Client/mods/deathmatch/logic/CClientIFP.cpp
Expand Up @@ -236,7 +236,7 @@ std::int32_t CClientIFP::ReadSequenceVersion1(SAnim& Anim)
RoundSize(Anim.Base.Size);
ReadBytes(&Anim.Name, Anim.Base.Size);

SString strBoneName = ConvertStringToKey(Anim.Name);
SString strBoneName = ConvertStringToKey(Anim.Name);
std::int32_t iBoneID = GetBoneIDFromName(strBoneName);

SString strCorrectBoneName = GetCorrectBoneNameFromName(strBoneName);
Expand Down Expand Up @@ -447,7 +447,7 @@ void CClientIFP::InitializeAnimationHierarchy(std::unique_ptr<CAnimBlendHierarch
pAnimationHierarchy->Initialize();
pAnimationHierarchy->SetName(strAnimationName);
pAnimationHierarchy->SetNumSequences(iSequences);
pAnimationHierarchy->SetAnimationBlockID(0);
pAnimationHierarchy->SetAnimationBlockID(-1);
pAnimationHierarchy->SetRunningCompressed(m_kbAllKeyFramesCompressed);
}

Expand All @@ -460,7 +460,7 @@ void CClientIFP::InitializeAnimationSequence(std::unique_ptr<CAnimBlendSequence>

void CClientIFP::PreProcessAnimationHierarchy(std::unique_ptr<CAnimBlendHierarchy>& pAnimationHierarchy)
{
if (!pAnimationHierarchy->isRunningCompressed())
if (!pAnimationHierarchy->IsRunningCompressed())
{
pAnimationHierarchy->RemoveQuaternionFlips();
pAnimationHierarchy->CalculateTotalTime();
Expand Down
27 changes: 26 additions & 1 deletion Client/mods/deathmatch/logic/CClientPed.cpp
Expand Up @@ -6089,6 +6089,7 @@ void CClientPed::ReplaceAnimation(std::unique_ptr<CAnimBlendHierarchy>& pInterna
void CClientPed::RestoreAnimation(std::unique_ptr<CAnimBlendHierarchy>& pInternalAnimHierarchy)
{
m_mapOfReplacedAnimations.erase(pInternalAnimHierarchy->GetInterface());
CIFPEngine::EngineApplyAnimation(*this, pInternalAnimHierarchy->GetInterface());
}

void CClientPed::RestoreAnimations(const std::shared_ptr<CClientIFP>& IFP)
Expand All @@ -6098,23 +6099,47 @@ void CClientPed::RestoreAnimations(const std::shared_ptr<CClientIFP>& IFP)
if (std::addressof(*IFP.get()) == std::addressof(*x.second.pIFP.get()))
{
m_mapOfReplacedAnimations.erase(x.first);
CIFPEngine::EngineApplyAnimation(*this, x.first);
}
}
}

void CClientPed::RestoreAnimations(CAnimBlock& animationBlock)
{
const size_t cAnimations = animationBlock.GetAnimationCount();
CAnimManager* pAnimationManager = g_pGame->GetAnimManager();
const size_t cAnimations = animationBlock.GetAnimationCount();
for (size_t i = 0; i < cAnimations; i++)
{
auto pAnimHierarchyInterface = animationBlock.GetAnimationHierarchyInterface(i);
m_mapOfReplacedAnimations.erase(pAnimHierarchyInterface);
CIFPEngine::EngineApplyAnimation(*this, pAnimHierarchyInterface);
}
}

void CClientPed::RestoreAllAnimations(void)
{
m_mapOfReplacedAnimations.clear();
CAnimManager* pAnimationManager = g_pGame->GetAnimManager();
RpClump* pClump = GetClump();
if (pClump)
{
auto pAnimAssociation = pAnimationManager->RpAnimBlendClumpGetFirstAssociation(pClump);
while (pAnimAssociation)
{
auto pAnimNextAssociation = pAnimationManager->RpAnimBlendGetNextAssociation(pAnimAssociation);
auto pAnimHierarchy = pAnimAssociation->GetAnimHierarchy();
int iGroupID = pAnimAssociation->GetAnimGroup(), iAnimID = pAnimAssociation->GetAnimID();
if (pAnimHierarchy && iGroupID >= 0 && iAnimID >= 0)
{
auto pAnimStaticAssociation = pAnimationManager->GetAnimStaticAssociation(iGroupID, iAnimID);
if (pAnimStaticAssociation && pAnimHierarchy->IsCustom())
{
CIFPEngine::EngineApplyAnimation(*this, pAnimStaticAssociation->GetAnimHierachyInterface());
}
}
pAnimAssociation = std::move(pAnimNextAssociation);
}
}
}

SReplacedAnimation* CClientPed::GetReplacedAnimation(CAnimBlendHierarchySAInterface* pInternalHierarchyInterface)
Expand Down
40 changes: 23 additions & 17 deletions Client/mods/deathmatch/logic/CIFPEngine.cpp
Expand Up @@ -10,7 +10,8 @@

#include <StdInc.h>

std::shared_ptr<CClientIFP> CIFPEngine::EngineLoadIFP(CResource* pResource, CClientManager* pManager, const SString& strFile, bool bIsRawData, const SString& strBlockName)
std::shared_ptr<CClientIFP> CIFPEngine::EngineLoadIFP(CResource* pResource, CClientManager* pManager, const SString& strFile, bool bIsRawData,
const SString& strBlockName)
{
// Grab the resource root entity
CClientEntity* pRoot = pResource->GetResourceIFPRoot();
Expand Down Expand Up @@ -56,21 +57,7 @@ bool CIFPEngine::EngineReplaceAnimation(CClientEntity* pEntity, const SString& s
if (pInternalAnimHierarchy && pCustomAnimHierarchyInterface)
{
Ped.ReplaceAnimation(pInternalAnimHierarchy, pCustomIFP, pCustomAnimHierarchyInterface);

CAnimManager* pAnimationManager = g_pGame->GetAnimManager();
RpClump* pClump = Ped.GetClump();
if (pClump)
{
auto pCurrentAnimAssociation = pAnimationManager->RpAnimBlendClumpGetAssociation(pClump, strInternalAnimName);
if (pCurrentAnimAssociation)
{
auto pAnimHierarchy = pAnimationManager->GetCustomAnimBlendHierarchy(pCustomAnimHierarchyInterface);
pAnimationManager->UncompressAnimation(pAnimHierarchy.get());
pCurrentAnimAssociation->FreeAnimBlendNodeArray();
pCurrentAnimAssociation->InitializeWithHierarchy(pClump, pCustomAnimHierarchyInterface);
pCurrentAnimAssociation->SetCurrentProgress(0.0);
}
}
EngineApplyAnimation(Ped, pCustomAnimHierarchyInterface);
return true;
}
}
Expand All @@ -84,7 +71,6 @@ bool CIFPEngine::EngineRestoreAnimation(CClientEntity* pEntity, const SString& s
if (IS_PED(pEntity))
{
CClientPed& Ped = static_cast<CClientPed&>(*pEntity);

if (eRestoreType == eRestoreAnimation::ALL)
{
Ped.RestoreAllAnimations();
Expand Down Expand Up @@ -115,6 +101,26 @@ bool CIFPEngine::EngineRestoreAnimation(CClientEntity* pEntity, const SString& s
return false;
}

bool CIFPEngine::EngineApplyAnimation(CClientPed& Ped, CAnimBlendHierarchySAInterface* pAnimHierarchyInterface)
{
CAnimManager* pAnimationManager = g_pGame->GetAnimManager();
RpClump* pClump = Ped.GetClump();
if (pClump)
{
auto pAnimHierarchy = pAnimationManager->GetAnimBlendHierarchy(pAnimHierarchyInterface);
auto pCurrentAnimAssociation = pAnimationManager->RpAnimBlendClumpGetAssociationHashKey(pClump, pAnimHierarchy->GetNameHashKey());
if (pCurrentAnimAssociation)
{
pAnimationManager->UncompressAnimation(pAnimHierarchy.get());
pCurrentAnimAssociation->FreeAnimBlendNodeArray();
pCurrentAnimAssociation->Init(pClump, pAnimHierarchyInterface);
pCurrentAnimAssociation->SetCurrentProgress(0.0);
return true;
}
}
return false;
}

// IsIFPData returns true if the provided data looks like an IFP file
bool CIFPEngine::IsIFPData(const SString& strData)
{
Expand Down
6 changes: 4 additions & 2 deletions Client/mods/deathmatch/logic/CIFPEngine.h
Expand Up @@ -18,15 +18,17 @@ class CIFPEngine
public:
enum eRestoreAnimation
{
SINGLE,
SINGLE = 0,
BLOCK,
ALL
};

static std::shared_ptr<CClientIFP> EngineLoadIFP(CResource* pResource, CClientManager* pManager, const SString& strFile, bool bIsRawData, const SString& strBlockName);
static std::shared_ptr<CClientIFP> EngineLoadIFP(CResource* pResource, CClientManager* pManager, const SString& strFile, bool bIsRawData,
const SString& strBlockName);
static bool EngineReplaceAnimation(CClientEntity* pEntity, const SString& strInternalBlockName, const SString& strInternalAnimName,
const SString& strCustomBlockName, const SString& strCustomAnimName);
static bool EngineRestoreAnimation(CClientEntity* pEntity, const SString& strInternalBlockName, const SString& strInternalAnimName,
const eRestoreAnimation& eRestoreType);
static bool EngineApplyAnimation(CClientPed& Ped, CAnimBlendHierarchySAInterface* pAnimHierarchyInterface);
static bool IsIFPData(const SString& strData);
};
2 changes: 1 addition & 1 deletion Client/sdk/game/CAnimBlendAssociation.h
Expand Up @@ -26,7 +26,7 @@ class CAnimBlendAssociation
public:
virtual CAnimBlendAssociationSAInterface* Constructor(CAnimBlendStaticAssociationSAInterface& StaticAssociationByReference) = 0;
virtual CAnimBlendAssociationSAInterface* Constructor(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy) = 0;
virtual void InitializeWithHierarchy(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy) = 0;
virtual void Init(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy) = 0;
virtual CAnimBlendAssociationSAInterface* InitializeForCustomAnimation(RpClump* pClump, CAnimBlendHierarchySAInterface* pAnimHierarchy) = 0;
virtual void FreeAnimBlendNodeArray() = 0;
virtual CAnimBlendAssociationSAInterface* GetInterface() = 0;
Expand Down

0 comments on commit 80bb898

Please sign in to comment.