diff --git a/Client/game_sa/CAnimBlendHierarchySA.cpp b/Client/game_sa/CAnimBlendHierarchySA.cpp index ad418673d66..f5bc943cc57 100644 --- a/Client/game_sa/CAnimBlendHierarchySA.cpp +++ b/Client/game_sa/CAnimBlendHierarchySA.cpp @@ -25,7 +25,7 @@ void CAnimBlendHierarchySA::Initialize() m_pInterface->pSequences = 0; m_pInterface->usNumSequences = 0; m_pInterface->bRunningCompressed = 0; - m_pInterface->pad = 0; + m_pInterface->keepCompressed = 0; m_pInterface->iAnimBlockID = -1; m_pInterface->fTotalTime = 0; m_pInterface->pLinkPtr = 0; diff --git a/Client/game_sa/CAnimBlendHierarchySA.h b/Client/game_sa/CAnimBlendHierarchySA.h index 5c87ac7c6ff..f96800c7a68 100644 --- a/Client/game_sa/CAnimBlendHierarchySA.h +++ b/Client/game_sa/CAnimBlendHierarchySA.h @@ -32,7 +32,7 @@ class CAnimBlendHierarchySAInterface CAnimBlendSequenceSAInterface* pSequences; unsigned short usNumSequences; bool bRunningCompressed; - BYTE pad; + bool keepCompressed; int iAnimBlockID; float fTotalTime; DWORD* pLinkPtr; @@ -43,11 +43,16 @@ class CAnimBlendHierarchySA : public CAnimBlendHierarchy { public: CAnimBlendHierarchySA(CAnimBlendHierarchySAInterface* pInterface) { m_pInterface = pInterface; } - 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 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, bool isANPK) + { + m_pInterface->bRunningCompressed = bCompressed; + if (isANPK && !bCompressed) + m_pInterface->keepCompressed = false; + } void SetAnimationBlockID(int iBlockID) { m_pInterface->iAnimBlockID = iBlockID; } void RemoveAnimSequences(); void RemoveFromUncompressedCache(); diff --git a/Client/mods/deathmatch/logic/CClientIFP.cpp b/Client/mods/deathmatch/logic/CClientIFP.cpp index 9b36b5a97fc..38b1c6fe41e 100644 --- a/Client/mods/deathmatch/logic/CClientIFP.cpp +++ b/Client/mods/deathmatch/logic/CClientIFP.cpp @@ -39,10 +39,11 @@ void CClientIFP::Unlink() } } -bool CClientIFP::Load(SString blockName, bool isRawData, SString input) +bool CClientIFP::Load(SString blockName, bool isRawData, SString input, std::vector&& uncompressedAnims) { m_strBlockName = std::move(blockName); m_pVecAnimations = &m_pIFPAnimations->vecAnimations; + m_uncompressedAnimations = std::move(uncompressedAnims); if (isRawData) { @@ -110,11 +111,14 @@ void CClientIFP::ReadIFPVersion1() ReadDgan(Dgan); Animation.pHierarchy = m_pAnimManager->GetCustomAnimBlendHierarchy(); - InitializeAnimationHierarchy(Animation.pHierarchy, Animation.Name, Dgan.Info.Entries); + + bool isUncompressed = std::find(m_uncompressedAnimations.begin(), m_uncompressedAnimations.end(), Animation.Name) != m_uncompressedAnimations.end(); + InitializeAnimationHierarchy(Animation.pHierarchy, Animation.Name, Dgan.Info.Entries, isUncompressed); + Animation.pSequencesMemory = AllocateSequencesMemory(Animation.pHierarchy); Animation.pHierarchy->SetSequences(reinterpret_cast(Animation.pSequencesMemory + 4)); - *(DWORD*)Animation.pSequencesMemory = ReadSequencesWithDummies(Animation.pHierarchy); + *(DWORD*)Animation.pSequencesMemory = ReadSequencesWithDummies(Animation.pHierarchy, isUncompressed); PreProcessAnimationHierarchy(Animation.pHierarchy); } } @@ -143,12 +147,12 @@ void CClientIFP::ReadIFPVersion2(bool bAnp3) } } -WORD CClientIFP::ReadSequencesWithDummies(std::unique_ptr& pAnimationHierarchy) +WORD CClientIFP::ReadSequencesWithDummies(std::unique_ptr& pAnimationHierarchy, bool isUncompressed) { SequenceMapType MapOfSequences; - WORD wUnknownSequences = ReadSequences(pAnimationHierarchy, MapOfSequences); + WORD wUnknownSequences = ReadSequences(pAnimationHierarchy, MapOfSequences, isUncompressed); - MoveSequencesWithDummies(pAnimationHierarchy, MapOfSequences); + MoveSequencesWithDummies(pAnimationHierarchy, MapOfSequences, isUncompressed); WORD cSequences = m_kcIFPSequences + wUnknownSequences; // As we need support for all 32 bones, we must change the total sequences count @@ -156,16 +160,16 @@ WORD CClientIFP::ReadSequencesWithDummies(std::unique_ptr& return cSequences; } -WORD CClientIFP::ReadSequences(std::unique_ptr& pAnimationHierarchy, SequenceMapType& MapOfSequences) +WORD CClientIFP::ReadSequences(std::unique_ptr& pAnimationHierarchy, SequenceMapType& MapOfSequences, bool isUncompressed) { if (m_bVersion1) { - return ReadSequencesVersion1(pAnimationHierarchy, MapOfSequences); + return ReadSequencesVersion1(pAnimationHierarchy, MapOfSequences, isUncompressed); } return ReadSequencesVersion2(pAnimationHierarchy, MapOfSequences); } -WORD CClientIFP::ReadSequencesVersion1(std::unique_ptr& pAnimationHierarchy, SequenceMapType& MapOfSequences) +WORD CClientIFP::ReadSequencesVersion1(std::unique_ptr& pAnimationHierarchy, SequenceMapType& MapOfSequences, bool isUncompressed) { WORD wUnknownSequences = 0; for (size_t SequenceIndex = 0; SequenceIndex < pAnimationHierarchy->GetNumSequences(); SequenceIndex++) @@ -193,7 +197,7 @@ WORD CClientIFP::ReadSequencesVersion1(std::unique_ptr& pAn InitializeAnimationSequence(pAnimationSequence, Anim.Name, iBoneID); eFrameType iFrameType = ReadKfrm(); - if ((ReadSequenceKeyFrames(pAnimationSequence, iFrameType, Anim.Frames)) && (!bUnknownSequence)) + if ((ReadSequenceKeyFrames(pAnimationSequence, iFrameType, Anim.Frames, isUncompressed)) && (!bUnknownSequence)) { MapOfSequences[iBoneID] = std::move(pAnimationSequence); } @@ -273,14 +277,16 @@ void CClientIFP::ReadSequenceVersion2(SSequenceHeaderV2& ObjectNode) strncpy(ObjectNode.Name, strCorrectBoneName, strCorrectBoneName.size() + 1); } -bool CClientIFP::ReadSequenceKeyFrames(std::unique_ptr& pAnimationSequence, eFrameType iFrameType, const std::int32_t& cFrames) +bool CClientIFP::ReadSequenceKeyFrames(std::unique_ptr& pAnimationSequence, eFrameType iFrameType, const std::int32_t& cFrames, + bool isUncompressed) { - size_t iCompressedFrameSize = GetSizeOfCompressedFrame(iFrameType); + size_t iCompressedFrameSize = GetSizeOfCompressedFrame(iFrameType, isUncompressed); if (iCompressedFrameSize) { BYTE* pKeyFrames = m_pAnimManager->AllocateKeyFramesMemory(iCompressedFrameSize * cFrames); - pAnimationSequence->SetKeyFrames(cFrames, IsKeyFramesTypeRoot(iFrameType), m_kbAllKeyFramesCompressed, pKeyFrames); - ReadKeyFramesAsCompressed(pAnimationSequence, iFrameType, cFrames); + pAnimationSequence->SetKeyFrames(cFrames, IsKeyFramesTypeRoot(iFrameType), m_kbAllKeyFramesCompressed && !isUncompressed, pKeyFrames); + ReadKeyFrames(pAnimationSequence, iFrameType, cFrames, isUncompressed); + return true; } return false; @@ -334,23 +340,35 @@ void CClientIFP::ReadAnimationHeaderVersion2(SAnimationHeaderV2& AnimationNode, } } -void CClientIFP::ReadKeyFramesAsCompressed(std::unique_ptr& pAnimationSequence, eFrameType iFrameType, const std::int32_t& cFrames) +void CClientIFP::ReadKeyFrames(std::unique_ptr& pAnimationSequence, eFrameType iFrameType, const std::int32_t& cFrames, bool isUncompressed) { switch (iFrameType) { case eFrameType::KRTS: { - ReadKrtsFramesAsCompressed(pAnimationSequence, cFrames); + if (isUncompressed) + ReadKrtsFramesUncompressed(pAnimationSequence, cFrames); + else + ReadKrtsFramesAsCompressed(pAnimationSequence, cFrames); + break; } case eFrameType::KRT0: { - ReadKrt0FramesAsCompressed(pAnimationSequence, cFrames); + if (isUncompressed) + ReadKrt0FramesUncompressed(pAnimationSequence, cFrames); + else + ReadKrt0FramesAsCompressed(pAnimationSequence, cFrames); + break; } case eFrameType::KR00: { - ReadKr00FramesAsCompressed(pAnimationSequence, cFrames); + if (isUncompressed) + ReadKr00FramesUncompressed(pAnimationSequence, cFrames); + else + ReadKr00FramesAsCompressed(pAnimationSequence, cFrames); + break; } case eFrameType::KR00_COMPRESSED: @@ -366,6 +384,23 @@ void CClientIFP::ReadKeyFramesAsCompressed(std::unique_ptr& } } +void CClientIFP::ReadKrtsFramesUncompressed(std::unique_ptr& pAnimationSequence, const std::int32_t& cFrames) +{ + for (std::int32_t FrameIndex = 0; FrameIndex < cFrames; FrameIndex++) + { + SKrts_Memory* krt0 = static_cast(pAnimationSequence->GetKeyFrame(FrameIndex, sizeof(SKrts_Memory))); + SKrts Krts; + ReadBuffer(&Krts); + + krt0->Rotation.X = -Krts.Rotation.X; + krt0->Rotation.Y = -Krts.Rotation.Y; + krt0->Rotation.Z = -Krts.Rotation.Z; + krt0->Rotation.W = Krts.Rotation.W; + krt0->Time = Krts.Time; + krt0->Translation = Krts.Translation; + } +} + void CClientIFP::ReadKrtsFramesAsCompressed(std::unique_ptr& pAnimationSequence, const std::int32_t& cFrames) { for (std::int32_t FrameIndex = 0; FrameIndex < cFrames; FrameIndex++) @@ -385,6 +420,23 @@ void CClientIFP::ReadKrtsFramesAsCompressed(std::unique_ptr& } } +void CClientIFP::ReadKrt0FramesUncompressed(std::unique_ptr& pAnimationSequence, const std::int32_t& cFrames) +{ + for (std::int32_t FrameIndex = 0; FrameIndex < cFrames; FrameIndex++) + { + SKrt0_Memory* frameKrt0 = static_cast(pAnimationSequence->GetKeyFrame(FrameIndex, sizeof(SKrt0_Memory))); + SKrt0 Krt0; + ReadBuffer(&Krt0); + + frameKrt0->Rotation.X = -Krt0.Rotation.X; + frameKrt0->Rotation.Y = -Krt0.Rotation.Y; + frameKrt0->Rotation.Z = -Krt0.Rotation.Z; + frameKrt0->Rotation.W = Krt0.Rotation.W; + frameKrt0->Time = Krt0.Time; + frameKrt0->Translation = Krt0.Translation; + } +} + void CClientIFP::ReadKrt0FramesAsCompressed(std::unique_ptr& pAnimationSequence, const std::int32_t& cFrames) { for (std::int32_t FrameIndex = 0; FrameIndex < cFrames; FrameIndex++) @@ -404,6 +456,22 @@ void CClientIFP::ReadKrt0FramesAsCompressed(std::unique_ptr& } } +void CClientIFP::ReadKr00FramesUncompressed(std::unique_ptr& pAnimationSequence, const std::int32_t& cFrames) +{ + for (std::int32_t FrameIndex = 0; FrameIndex < cFrames; FrameIndex++) + { + SKr00* frameKr00 = static_cast(pAnimationSequence->GetKeyFrame(FrameIndex, sizeof(SKr00))); + SKr00 Kr00; + ReadBuffer(&Kr00); + + frameKr00->Rotation.X = -Kr00.Rotation.X; + frameKr00->Rotation.Y = -Kr00.Rotation.Y; + frameKr00->Rotation.Z = -Kr00.Rotation.Z; + frameKr00->Rotation.W = Kr00.Rotation.W; + frameKr00->Time = Kr00.Time; + } +} + void CClientIFP::ReadKr00FramesAsCompressed(std::unique_ptr& pAnimationSequence, const std::int32_t& cFrames) { for (std::int32_t FrameIndex = 0; FrameIndex < cFrames; FrameIndex++) @@ -420,21 +488,21 @@ void CClientIFP::ReadKr00FramesAsCompressed(std::unique_ptr& } } -size_t CClientIFP::GetSizeOfCompressedFrame(eFrameType iFrameType) +size_t CClientIFP::GetSizeOfCompressedFrame(eFrameType iFrameType, bool isUncompressed) { switch (iFrameType) { case eFrameType::KRTS: { - return sizeof(SCompressed_KRT0); + return isUncompressed ? sizeof(SKrts) : sizeof(SCompressed_KRT0); } case eFrameType::KRT0: { - return sizeof(SCompressed_KRT0); + return isUncompressed ? sizeof(SKrt0) : sizeof(SCompressed_KRT0); } case eFrameType::KR00: { - return sizeof(SCompressed_KR00); + return isUncompressed ? sizeof(SKr00) : sizeof(SCompressed_KR00); } case eFrameType::KR00_COMPRESSED: { @@ -449,13 +517,13 @@ size_t CClientIFP::GetSizeOfCompressedFrame(eFrameType iFrameType) } void CClientIFP::InitializeAnimationHierarchy(std::unique_ptr& pAnimationHierarchy, const SString& strAnimationName, - const std::int32_t& iSequences) + const std::int32_t& iSequences, bool isUncompressed) { pAnimationHierarchy->Initialize(); pAnimationHierarchy->SetName(strAnimationName); pAnimationHierarchy->SetNumSequences(static_cast(iSequences)); pAnimationHierarchy->SetAnimationBlockID(-1); - pAnimationHierarchy->SetRunningCompressed(m_kbAllKeyFramesCompressed); + pAnimationHierarchy->SetRunningCompressed(m_kbAllKeyFramesCompressed && !isUncompressed, isUncompressed); } void CClientIFP::InitializeAnimationSequence(std::unique_ptr& pAnimationSequence, const SString& strName, const std::int32_t& iBoneID) @@ -474,7 +542,7 @@ void CClientIFP::PreProcessAnimationHierarchy(std::unique_ptr& pAnimationHierarchy, SequenceMapType& mapOfSequences) +void CClientIFP::MoveSequencesWithDummies(std::unique_ptr& pAnimationHierarchy, SequenceMapType& mapOfSequences, bool isUncompressed) { for (size_t SequenceIndex = 0; SequenceIndex < m_kcIFPSequences; SequenceIndex++) { @@ -493,7 +561,7 @@ void CClientIFP::MoveSequencesWithDummies(std::unique_ptr& } else { - InsertAnimationDummySequence(pAnimationSequence, BoneName, BoneID); + InsertAnimationDummySequence(pAnimationSequence, BoneName, BoneID, isUncompressed); } } } @@ -522,7 +590,8 @@ CClientIFP::eFrameType CClientIFP::GetFrameTypeFromFourCC(const char* szFourCC) return eFrameType::UNKNOWN_FRAME; } -void CClientIFP::InsertAnimationDummySequence(std::unique_ptr& pAnimationSequence, const SString& BoneName, const DWORD& dwBoneID) +void CClientIFP::InsertAnimationDummySequence(std::unique_ptr& pAnimationSequence, const SString& BoneName, const DWORD& dwBoneID, + bool isUncompressed) { InitializeAnimationSequence(pAnimationSequence, BoneName, dwBoneID); @@ -532,18 +601,18 @@ void CClientIFP::InsertAnimationDummySequence(std::unique_ptrAllocateKeyFramesMemory(FramesDataSizeInBytes); - pAnimationSequence->SetKeyFrames(cKeyFrames, bHasTranslationValues, m_kbAllKeyFramesCompressed, pKeyFrames); + pAnimationSequence->SetKeyFrames(cKeyFrames, bHasTranslationValues, m_kbAllKeyFramesCompressed && !isUncompressed, pKeyFrames); CopyDummyKeyFrameByBoneID(pKeyFrames, dwBoneID); } diff --git a/Client/mods/deathmatch/logic/CClientIFP.h b/Client/mods/deathmatch/logic/CClientIFP.h index 6218ff5182b..60ba04ec6b3 100644 --- a/Client/mods/deathmatch/logic/CClientIFP.h +++ b/Client/mods/deathmatch/logic/CClientIFP.h @@ -87,12 +87,13 @@ class CClientIFP final : public CClientEntity, CFileReader float X, Y, Z; }; - struct SKr00 + struct SKr00 // CAnimBlendKeyFrameNoTrans { SQuaternion Rotation; float Time; }; + // Structues used for reading IFP files struct SKrt0 { SQuaternion Rotation; @@ -104,10 +105,26 @@ class CClientIFP final : public CClientEntity, CFileReader { SQuaternion Rotation; SVector Translation; - SVector Scale; + SVector Scale; // unused float Time; }; + // Structures used by GTA SA (time is always at 0x10 offset for uncompressed anims) + struct SKrt0_Memory // CAnimBlendKeyFrame + { + SQuaternion Rotation; + float Time; + SVector Translation; + }; + + struct SKrts_Memory + { + SQuaternion Rotation; + float Time; + SVector Translation; + SVector Scale; // unused + }; + struct SCompressedQuaternion { std::int16_t X, Y, Z, W; @@ -205,7 +222,7 @@ class CClientIFP final : public CClientEntity, CFileReader void MarkAsUnloading() { m_bUnloading = true; } bool IsUnloading() { return m_bUnloading; } - bool Load(SString blockName, bool isRawData, SString input); + bool Load(SString blockName, bool isRawData, SString input, std::vector&& uncompressedAnims); const SString& GetBlockName() { return m_strBlockName; } const unsigned int& GetBlockNameHash() { return m_u32Hashkey; } @@ -223,9 +240,9 @@ class CClientIFP final : public CClientEntity, CFileReader void ReadIFPVersion1(); void ReadIFPVersion2(bool bAnp3); - WORD ReadSequencesWithDummies(std::unique_ptr& pAnimationHierarchy); - WORD ReadSequences(std::unique_ptr& pAnimationHierarchy, SequenceMapType& MapOfSequences); - WORD ReadSequencesVersion1(std::unique_ptr& pAnimationHierarchy, SequenceMapType& MapOfSequences); + WORD ReadSequencesWithDummies(std::unique_ptr& pAnimationHierarchy, bool isUncompressed = false); + WORD ReadSequences(std::unique_ptr& pAnimationHierarchy, SequenceMapType& MapOfSequences, bool isUncompressed = false); + WORD ReadSequencesVersion1(std::unique_ptr& pAnimationHierarchy, SequenceMapType& MapOfSequences, bool isUncompressed = false); WORD ReadSequencesVersion2(std::unique_ptr& pAnimationHierarchy, SequenceMapType& MapOfSequences); std::int32_t ReadSequenceVersion1(SAnim& Anim); void ReadSequenceVersion2(SSequenceHeaderV2& ObjectNode); @@ -236,8 +253,15 @@ class CClientIFP final : public CClientEntity, CFileReader CClientIFP::eFrameType ReadKfrm(); void ReadAnimationHeaderVersion2(SAnimationHeaderV2& AnimationNode, bool bAnp3); - bool ReadSequenceKeyFrames(std::unique_ptr& pAnimationSequence, eFrameType iFrameType, const std::int32_t& cFrames); - void ReadKeyFramesAsCompressed(std::unique_ptr& pAnimationSequence, eFrameType iFrameType, const std::int32_t& cFrames); + bool ReadSequenceKeyFrames(std::unique_ptr& pAnimationSequence, eFrameType iFrameType, const std::int32_t& cFrames, + bool isUncompressed = false); + void ReadKeyFrames(std::unique_ptr& pAnimationSequence, eFrameType iFrameType, const std::int32_t& cFrames, + bool isUncompressed = false); + + void ReadKrtsFramesUncompressed(std::unique_ptr& pAnimationSequence, const std::int32_t& cFrames); + void ReadKrt0FramesUncompressed(std::unique_ptr& pAnimationSequence, const std::int32_t& cFrames); + void ReadKr00FramesUncompressed(std::unique_ptr& pAnimationSequence, const std::int32_t& cFrames); + void ReadKrtsFramesAsCompressed(std::unique_ptr& pAnimationSequence, const std::int32_t& cFrames); void ReadKrt0FramesAsCompressed(std::unique_ptr& pAnimationSequence, const std::int32_t& cFrames); void ReadKr00FramesAsCompressed(std::unique_ptr& pAnimationSequence, const std::int32_t& cFrames); @@ -251,14 +275,15 @@ class CClientIFP final : public CClientEntity, CFileReader } void InitializeAnimationHierarchy(std::unique_ptr& pAnimationHierarchy, const SString& strAnimationName, - const std::int32_t& iSequences); + const std::int32_t& iSequences, bool isUncompressed = false); void InitializeAnimationSequence(std::unique_ptr& pAnimationSequence, const SString& strName, const std::int32_t& iBoneID); void PreProcessAnimationHierarchy(std::unique_ptr& pAnimationHierarchy); void MoveSequencesWithDummies(std::unique_ptr& pAnimationHierarchy, - std::map>& mapOfSequences); + std::map>& mapOfSequences, bool isUncompressed = false); BYTE* AllocateSequencesMemory(std::unique_ptr& pAnimationHierarchy); - void InsertAnimationDummySequence(std::unique_ptr& pAnimationSequence, const SString& BoneName, const DWORD& dwBoneID); + void InsertAnimationDummySequence(std::unique_ptr& pAnimationSequence, const SString& BoneName, const DWORD& dwBoneID, + bool isUncompressed = false); void CopyDummyKeyFrameByBoneID(BYTE* pKeyFrames, DWORD dwBoneID); SString ConvertStringToKey(const SString& strBoneName); @@ -266,7 +291,7 @@ class CClientIFP final : public CClientEntity, CFileReader constexpr bool IsKeyFramesTypeRoot(eFrameType iFrameType); eFrameType GetFrameTypeFromFourCC(const char* szFourCC); - size_t GetSizeOfCompressedFrame(eFrameType FrameType); + size_t GetSizeOfCompressedFrame(eFrameType FrameType, bool isUncompressed = false); std::int32_t GetBoneIDFromName(const SString& strBoneName); SString GetCorrectBoneNameFromName(const SString& strBoneName); SString GetCorrectBoneNameFromID(const std::int32_t& iBoneID); @@ -278,6 +303,7 @@ class CClientIFP final : public CClientEntity, CFileReader bool m_bVersion1; bool m_bUnloading; CAnimManager* m_pAnimManager; + std::vector m_uncompressedAnimations; // 32 because there are 32 bones in a ped model const unsigned short m_kcIFPSequences = 32; diff --git a/Client/mods/deathmatch/logic/CIFPEngine.cpp b/Client/mods/deathmatch/logic/CIFPEngine.cpp index 44cfbdd4107..e706dc6eeb2 100644 --- a/Client/mods/deathmatch/logic/CIFPEngine.cpp +++ b/Client/mods/deathmatch/logic/CIFPEngine.cpp @@ -12,7 +12,8 @@ #include #include -std::shared_ptr CIFPEngine::LoadIFP(CResource* resource, CClientManager* clientManager, const SString& blockName, bool isRawInput, SString input) +std::shared_ptr CIFPEngine::LoadIFP(CResource* resource, CClientManager* clientManager, const SString& blockName, bool isRawInput, SString input, + std::vector&& uncompressedAnims) { // Grab the resource root entity const unsigned int u32BlockNameHash = HashString(blockName.ToLower()); @@ -24,7 +25,7 @@ std::shared_ptr CIFPEngine::LoadIFP(CResource* resource, CClientMana std::shared_ptr pIFP(new CClientIFP(clientManager, INVALID_ELEMENT_ID)); // Try to load the IFP file - if (pIFP->Load(blockName, isRawInput, std::move(input))) + if (pIFP->Load(blockName, isRawInput, std::move(input), std::move(uncompressedAnims))) { // We can use the map to retrieve correct IFP by block name later g_pClientGame->InsertIFPPointerToMap(u32BlockNameHash, pIFP); diff --git a/Client/mods/deathmatch/logic/CIFPEngine.h b/Client/mods/deathmatch/logic/CIFPEngine.h index 9b2f5af57ed..84b11437b9f 100644 --- a/Client/mods/deathmatch/logic/CIFPEngine.h +++ b/Client/mods/deathmatch/logic/CIFPEngine.h @@ -23,7 +23,8 @@ class CIFPEngine ALL }; - static std::shared_ptr LoadIFP(CResource* resource, CClientManager* clientManager, const SString& blockName, bool isRawInput, SString input); + static std::shared_ptr LoadIFP(CResource* resource, CClientManager* clientManager, const SString& blockName, bool isRawInput, SString input, + std::vector&& uncompressedAnims); 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, diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 8d9bc6ece59..550ec94f63e 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -524,14 +524,18 @@ int CLuaEngineDefs::EngineLoadTXD(lua_State* luaVM) int CLuaEngineDefs::EngineLoadIFP(lua_State* luaVM) { - SString input; - SString blockName; + SString input; + SString blockName; + std::vector uncompressedAnims{}; CScriptArgReader argStream(luaVM); // Grab the IFP filename or data argStream.ReadString(input); argStream.ReadString(blockName); + if (argStream.NextIsTable()) + argStream.ReadStringTable(uncompressedAnims); + if (!argStream.HasErrors()) { // Grab our virtual machine and grab our resource from that. @@ -558,8 +562,8 @@ int CLuaEngineDefs::EngineLoadIFP(lua_State* luaVM) // Is this a legal filepath? if (bIsRawData || CResourceManager::ParseResourcePathInput(input, pResource, &filePath)) { - std::shared_ptr pIFP = - CIFPEngine::LoadIFP(pResource, m_pManager, std::move(blockName), bIsRawData, bIsRawData ? std::move(input) : std::move(filePath)); + std::shared_ptr pIFP = CIFPEngine::LoadIFP(pResource, m_pManager, std::move(blockName), bIsRawData, + bIsRawData ? std::move(input) : std::move(filePath), std::move(uncompressedAnims)); if (pIFP) { diff --git a/Client/sdk/game/CAnimBlendHierarchy.h b/Client/sdk/game/CAnimBlendHierarchy.h index 72c7d3abecf..45a478b2725 100644 --- a/Client/sdk/game/CAnimBlendHierarchy.h +++ b/Client/sdk/game/CAnimBlendHierarchy.h @@ -21,7 +21,7 @@ class CAnimBlendHierarchy virtual void SetName(const char* szName) = 0; virtual void SetSequences(CAnimBlendSequenceSAInterface* pSequences) = 0; virtual void SetNumSequences(unsigned short uNumSequences) = 0; - virtual void SetRunningCompressed(bool bCompressed) = 0; + virtual void SetRunningCompressed(bool bCompressed, bool isANPK) = 0; virtual void SetAnimationBlockID(int iBlockID) = 0; virtual void RemoveAnimSequences() = 0; virtual void RemoveFromUncompressedCache() = 0;