diff --git a/source/InjectHooksMain.cpp b/source/InjectHooksMain.cpp index 93ec19c274..a56db7b281 100644 --- a/source/InjectHooksMain.cpp +++ b/source/InjectHooksMain.cpp @@ -441,7 +441,6 @@ void InjectHooksMain() { CPedAttractorPedPlacer::InjectHooks(); BoneNode_c::InjectHooks(); BoneNodeManager_c::InjectHooks(); - CAnimBlendClumpData::InjectHooks(); IKChainManager_c::InjectHooks(); IKChain_c::InjectHooks(); CCheckpoint::InjectHooks(); @@ -1222,6 +1221,7 @@ void InjectHooksMain() { CAnimManager::InjectHooks(); }; + Animation(); App(); Audio(); Tasks(); diff --git a/source/game_sa/Animation/AnimAssocDefinitions.cpp b/source/game_sa/Animation/AnimAssocDefinitions.cpp index 33a89aa3c5..fd3c0bc14a 100644 --- a/source/game_sa/Animation/AnimAssocDefinitions.cpp +++ b/source/game_sa/Animation/AnimAssocDefinitions.cpp @@ -6,7 +6,7 @@ // animsCount, anims #define awc(a) std::size(a), a -std::array CAnimManager::ms_aAnimAssocDefinitionsX = std::to_array({ // 0x8AA5A8 +std::array CAnimManager::ms_aAnimAssocDefinitionsX{{ // 0x8AA5A8 { "default", "ped", MODEL_MALE01, awc(aStdAnimations), aStdAnimDescs }, { "door", "ped", MODEL_INVALID, awc(aDoorAnimations), aDoorDescs }, { "bikes", "bikes", MODEL_MALE01, awc(aBikesAnimations), aBikesDescs }, @@ -125,5 +125,5 @@ std::array CAnimManager::ms_aAnimAss { "harrplaneanims", "rustler", MODEL_MALE01, awc(aHarrPlaneAnimations), aCarAnimDescs1 }, { "stdcarupright", "ped", MODEL_MALE01, awc(aStdCarAnimations), aCarAnimDescs2 }, { "nvadaplaneanims", "nevada", MODEL_MALE01, awc(aNevadaPlaneAnimations), aCarAnimDescs1 } -}); +}}; #undef awc diff --git a/source/game_sa/Animation/AnimBlendHierarchy.cpp b/source/game_sa/Animation/AnimBlendHierarchy.cpp index 0ecd035b35..6e084f35c4 100644 --- a/source/game_sa/Animation/AnimBlendHierarchy.cpp +++ b/source/game_sa/Animation/AnimBlendHierarchy.cpp @@ -28,7 +28,7 @@ void CAnimBlendHierarchy::InjectHooks() { CAnimBlendHierarchy::CAnimBlendHierarchy() { m_pSequences = nullptr; m_nSeqCount = 0; - m_bRunningCompressed = false; + m_bIsCompressed = false; m_bKeepCompressed = false; m_nAnimBlockId = -1; m_fTotalTime = 0.0f; @@ -44,7 +44,7 @@ CAnimBlendHierarchy::~CAnimBlendHierarchy() { // 0x4CF980 void CAnimBlendHierarchy::Shutdown() { RemoveAnimSequences(); - m_bRunningCompressed = false; + m_bIsCompressed = false; } // 0x4CF8E0 @@ -156,7 +156,7 @@ void CAnimBlendHierarchy::Uncompress() { CMemoryMgr::Free(oldFrameData); } - m_bRunningCompressed = false; + m_bIsCompressed = false; if (m_fTotalTime == 0.0f) { RemoveQuaternionFlips(); CalcTotalTime(); @@ -194,7 +194,7 @@ void CAnimBlendHierarchy::RemoveUncompressedData() { CMemoryMgr::Free(oldFrameData); } - m_bRunningCompressed = true; + m_bIsCompressed = true; } // 0x4CF800 diff --git a/source/game_sa/Animation/AnimBlendHierarchy.h b/source/game_sa/Animation/AnimBlendHierarchy.h index 7d3700218a..60af27cf02 100644 --- a/source/game_sa/Animation/AnimBlendHierarchy.h +++ b/source/game_sa/Animation/AnimBlendHierarchy.h @@ -13,7 +13,7 @@ class CAnimBlendHierarchy { uint32 m_hashKey; CAnimBlendSequence* m_pSequences; uint16 m_nSeqCount; - bool m_bRunningCompressed; + bool m_bIsCompressed; bool m_bKeepCompressed; int32 m_nAnimBlockId; float m_fTotalTime; diff --git a/source/game_sa/Animation/AnimManager.cpp b/source/game_sa/Animation/AnimManager.cpp index 1ac74757a6..3aec64318f 100644 --- a/source/game_sa/Animation/AnimManager.cpp +++ b/source/game_sa/Animation/AnimManager.cpp @@ -7,6 +7,8 @@ #include "StdInc.h" +#include + #include "AnimManager.h" #include "AnimAssocDescriptions.h" @@ -14,37 +16,37 @@ void CAnimManager::InjectHooks() { RH_ScopedClass(CAnimManager); RH_ScopedCategory("Animation"); - RH_ScopedInstall(Initialise, 0x5BF6B0, { .reversed = false }); - RH_ScopedInstall(ReadAnimAssociationDefinitions, 0x5BC910, { .reversed = false }); + RH_ScopedInstall(Initialise, 0x5BF6B0); + RH_ScopedInstall(ReadAnimAssociationDefinitions, 0x5BC910); RH_ScopedInstall(Shutdown, 0x4D4130); RH_ScopedOverloadedInstall(GetAnimationBlock, "", 0x4D3940, CAnimBlock*(*)(const char*)); - RH_ScopedOverloadedInstall(GetAnimationBlockIndex, "by-name", 0x4D3990, int32(*)(const char*), { .reversed = false }); - RH_ScopedInstall(GetFirstAssocGroup, 0x4D39B0, { .reversed = false }); + RH_ScopedOverloadedInstall(GetAnimationBlockIndex, "by-name", 0x4D3990, int32(*)(const char*)); + RH_ScopedInstall(GetFirstAssocGroup, 0x4D39B0); RH_ScopedOverloadedInstall(GetAnimation, "0", 0x4D39F0, CAnimBlendHierarchy*(*)(uint32, const CAnimBlock*)); RH_ScopedOverloadedInstall(GetAnimation, "1", 0x4D42F0, CAnimBlendHierarchy*(*)(const char*, const CAnimBlock*)); RH_ScopedInstall(GetAnimGroupName, 0x4D3A20); RH_ScopedInstall(GetAnimBlockName, 0x4D3A30); RH_ScopedInstall(CreateAnimAssociation, 0x4D3A40); - RH_ScopedOverloadedInstall(GetAnimAssociation, "", 0x4D3A60, CAnimBlendStaticAssociation*(*)(AssocGroupId, AnimationId)); - RH_ScopedOverloadedInstall(GetAnimAssociation, "", 0x4D3A80, CAnimBlendStaticAssociation*(*)(AssocGroupId, const char*)); - RH_ScopedOverloadedInstall(AddAnimation, "id", 0x4D3AA0, CAnimBlendAssociation*(*)(RpClump*, AssocGroupId, AnimationId), { .reversed = false }); - RH_ScopedOverloadedInstall(AddAnimation, "hier", 0x4D4330, CAnimBlendAssociation*(*)(RpClump*, CAnimBlendHierarchy*, int32), { .reversed = false }); - RH_ScopedInstall(AddAnimationAndSync, 0x4D3B30, { .reversed = false }); - RH_ScopedInstall(AddAnimAssocDefinition, 0x4D3BA0, { .reversed = false }); - RH_ScopedInstall(AddAnimToAssocDefinition, 0x4D3C80, { .reversed = false }); - RH_ScopedInstall(CreateAnimAssocGroups, 0x4D3CC0, { .reversed = false }); - RH_ScopedInstall(RegisterAnimBlock, 0x4D3E50, { .reversed = false }); - RH_ScopedInstall(RemoveLastAnimFile, 0x4D3ED0, { .reversed = false }); - RH_ScopedInstall(RemoveAnimBlock, 0x4D3F40, { .reversed = false }); - RH_ScopedInstall(AddAnimBlockRef, 0x4D3FB0, { .reversed = false }); - RH_ScopedInstall(RemoveAnimBlockRefWithoutDelete, 0x4D3FF0, { .reversed = false }); - RH_ScopedInstall(GetNumRefsToAnimBlock, 0x4D4010, { .reversed = false }); - RH_ScopedInstall(UncompressAnimation, 0x4D41C0, { .reversed = false }); - RH_ScopedInstall(RemoveFromUncompressedCache, 0x4D42A0, { .reversed = false }); + RH_ScopedOverloadedInstall(GetAnimAssociation, "by-id", 0x4D3A60, CAnimBlendStaticAssociation*(*)(AssocGroupId, AnimationId)); + RH_ScopedOverloadedInstall(GetAnimAssociation, "by-name", 0x4D3A80, CAnimBlendStaticAssociation*(*)(AssocGroupId, const char*)); + RH_ScopedOverloadedInstall(AddAnimation, "id", 0x4D3AA0, CAnimBlendAssociation*(*)(RpClump*, AssocGroupId, AnimationId)); + RH_ScopedOverloadedInstall(AddAnimation, "hier", 0x4D4330, CAnimBlendAssociation*(*)(RpClump*, CAnimBlendHierarchy*, int32)); + RH_ScopedInstall(AddAnimationAndSync, 0x4D3B30); + RH_ScopedInstall(AddAnimAssocDefinition, 0x4D3BA0); + RH_ScopedInstall(AddAnimToAssocDefinition, 0x4D3C80); + RH_ScopedInstall(CreateAnimAssocGroups, 0x4D3CC0); + RH_ScopedInstall(RegisterAnimBlock, 0x4D3E50); + RH_ScopedInstall(RemoveLastAnimFile, 0x4D3ED0); + RH_ScopedInstall(RemoveAnimBlock, 0x4D3F40); + RH_ScopedInstall(AddAnimBlockRef, 0x4D3FB0); + RH_ScopedInstall(RemoveAnimBlockRefWithoutDelete, 0x4D3FF0); + RH_ScopedInstall(GetNumRefsToAnimBlock, 0x4D4010); + RH_ScopedInstall(UncompressAnimation, 0x4D41C0); + RH_ScopedInstall(RemoveFromUncompressedCache, 0x4D42A0); RH_ScopedOverloadedInstall(BlendAnimation, "id", 0x4D4610, CAnimBlendAssociation*(*)(RpClump*, AssocGroupId, AnimationId, float), { .reversed = false }); RH_ScopedOverloadedInstall(BlendAnimation, "hier", 0x4D4410, CAnimBlendAssociation*(*)(RpClump*, CAnimBlendHierarchy*, int32, float), { .reversed = false }); RH_ScopedInstall(LoadAnimFiles, 0x4D5620); - RH_ScopedInstall(LoadAnimFile, 0x4D47F0, { .reversed = false }); + RH_ScopedInstall(LoadAnimFile, 0x4D47F0, {.reversed = false}); } struct IfpHeader { @@ -56,8 +58,6 @@ struct IfpHeader { void CAnimManager::Initialise() { ZoneScoped; - return plugin::Call<0x5BF6B0>(); - ms_numAnimations = 0; ms_numAnimBlocks = 0; ms_numAnimAssocDefinitions = 118; // ANIM_TOTAL_GROUPS aka NUM_ANIM_ASSOC_GROUPS @@ -68,36 +68,36 @@ void CAnimManager::Initialise() { // 0x5BC910 void CAnimManager::ReadAnimAssociationDefinitions() { - // return plugin::Call<0x5BC910>(); - char name[32], block[32], type[32]; - bool isAnimSection = false; + bool isAnimSection = false; AnimAssocDefinition* animStyle; - int animCount; + uint32 animCount; CFileMgr::SetDir(""); - auto* file = CFileMgr::OpenFile("DATA\\ANIMGRP.DAT", "rb"); - for (auto line = CFileLoader::LoadLine(file); line; line = CFileLoader::LoadLine(file)) { - if (!*line || *line == '#') + const auto f = CFileMgr::OpenFile("DATA\\ANIMGRP.DAT", "rb"); + for (;;) { + const auto l = CFileLoader::LoadLine(f); + if (!l) { + break; + } + if (!*l || *l == '#') { continue; - + } if (isAnimSection) { - if (sscanf_s(line, "%s", SCANF_S_STR(name)) == 1) { + if (sscanf_s(l, "%s", SCANF_S_STR(name)) == 1) { if (!memcmp(name, "end", 4)) { isAnimSection = false; } else { AddAnimToAssocDefinition(animStyle, name); } } - } - else - { - VERIFY(sscanf_s(line, "%s %s %s %d", SCANF_S_STR(name), SCANF_S_STR(block), SCANF_S_STR(type), &animCount) == 4); + } else { + VERIFY(sscanf_s(l, "%s %s %s %d", SCANF_S_STR(name), SCANF_S_STR(block), SCANF_S_STR(type), &animCount) == 4); animStyle = AddAnimAssocDefinition(name, block, MODEL_MALE01, animCount, aStdAnimDescs); isAnimSection = true; } } - CFileMgr::CloseFile(file); + CFileMgr::CloseFile(f); } // 0x4D4130 @@ -120,9 +120,10 @@ CAnimBlock* CAnimManager::GetAnimationBlock(AssocGroupId animGroup) { // 0x4D3940 CAnimBlock* CAnimManager::GetAnimationBlock(const char* name) { - for (auto& block : std::span{ ms_aAnimBlocks.data(), (size_t)ms_numAnimBlocks }) { - if (_stricmp(block.szName, name) == 0) { - return █ + const auto namesv = notsa::ci_string_view{ name }; + for (auto& ab : GetAnimBlocks()) { + if (namesv == ab.szName) { + return &ab; } } return nullptr; @@ -138,32 +139,30 @@ int32 CAnimManager::GetAnimationBlockIndex(CAnimBlock* animBlock) { // 0x4D3990 int32 CAnimManager::GetAnimationBlockIndex(const char* name) { - return plugin::CallAndReturn(name); + const auto b = GetAnimationBlock(name); + return b + ? (int32)(std::distance(ms_aAnimBlocks.data(), b)) + : -1; } // 0x4D39B0 AssocGroupId CAnimManager::GetFirstAssocGroup(const char* name) { - return plugin::CallAndReturn(name); - - // ANIM_TOTAL_GROUPS + const auto namesv = notsa::ci_string_view{ name }; for (auto i = 0; i < ANIM_GROUP_MAN; i++) { - if (!_stricmp(ms_aAnimAssocDefinitions[i].blockName, name)) { + if (ms_aAnimAssocDefinitions[i].blockName == namesv) { return static_cast(i); } } - return ANIM_GROUP_MAN; } // 0x4D39F0 CAnimBlendHierarchy* CAnimManager::GetAnimation(uint32 hash, const CAnimBlock* animBlock) { - CAnimBlendHierarchy* hier = &ms_aAnimations[animBlock->startAnimation]; - - for (auto i = 0; i < animBlock->animationCount; i++) { - if (hier->m_hashKey == hash) { - return hier; + auto h = &ms_aAnimations[animBlock->startAnimation]; + for (auto i = animBlock->animationCount; i-- > 0; h++) { + if (h->m_hashKey == hash) { + return h; } - hier++; } return nullptr; } @@ -184,9 +183,9 @@ const char* CAnimManager::GetAnimBlockName(AssocGroupId groupId) { } // NOTSA -AssocGroupId CAnimManager::GetAnimationGroupId(const char* name) { - for (auto i = 0; i < ms_numAnimAssocDefinitions; i++) { - if (std::string_view{ name } == GetAnimGroupName((AssocGroupId)i)) { +AssocGroupId CAnimManager::GetAnimationGroupIdByName(notsa::ci_string_view name) { + for (const auto& [i, gd] : notsa::enumerate(GetAssocGroupDefs())) { + if (gd.groupName == name) { return (AssocGroupId)i; } } @@ -208,126 +207,103 @@ CAnimBlendStaticAssociation* CAnimManager::GetAnimAssociation(AssocGroupId group return ms_aAnimAssocGroups[groupId].GetAnimation(animName); } -// 0x4D3AA0 -CAnimBlendAssociation* CAnimManager::AddAnimation(RpClump* clump, AssocGroupId groupId, AnimationId animId) { - return plugin::CallAndReturn(clump, groupId, animId); - - CAnimBlendAssociation* anim = CreateAnimAssociation(groupId, animId); - CAnimBlendClumpData* clumpData = RpClumpGetAnimBlendClumpData(clump); - if (anim->IsMoving()) { - CAnimBlendAssociation* syncAnim; - CAnimBlendLink* link; - for (link = clumpData->m_Associations.next; link; link = link->next) { - syncAnim = CAnimBlendAssociation::FromLink(link); - if (syncAnim->IsMoving()) - break; +CAnimBlendAssociation* CAnimManager::AddAnimationToClump(RpClump* clump, CAnimBlendAssociation* anim) { + const auto clumpAnims = &RpClumpGetAnimBlendClumpData(clump)->m_Associations; + const auto syncWith = [&]() -> CAnimBlendAssociation* { + if (anim->IsMoving()) { + for (auto l = clumpAnims->next; l; l = l->next) { + const auto a = CAnimBlendAssociation::FromLink(l); + if (a->IsMoving()) { + return a; + } + } } - if (link) { - anim->SyncAnimation(syncAnim); - anim->m_nFlags |= ANIMATION_STARTED; - } else - anim->Start(0.0f); - } else + return nullptr; + }(); + if (syncWith) { + anim->SyncAnimation(syncWith); + anim->m_nFlags |= ANIMATION_STARTED; + } else { anim->Start(0.0f); - - clumpData->m_Associations.Prepend(&anim->m_Link); + } + clumpAnims->Prepend(&anim->m_Link); return anim; } +// 0x4D3AA0 +CAnimBlendAssociation* CAnimManager::AddAnimation(RpClump* clump, AssocGroupId groupId, AnimationId animId) { + return AddAnimationToClump(clump, CreateAnimAssociation(groupId, animId)); +} + // 0x4D4330 CAnimBlendAssociation* CAnimManager::AddAnimation(RpClump* clump, CAnimBlendHierarchy* hier, int32 clumpAssocFlag) { - return plugin::CallAndReturn(clump, hier, clumpAssocFlag); - - CAnimBlendAssociation* anim = new CAnimBlendAssociation(clump, hier); + const auto anim = new CAnimBlendAssociation(clump, hier); anim->m_nFlags |= clumpAssocFlag; anim->ReferenceAnimBlock(); UncompressAnimation(hier); - CAnimBlendClumpData* clumpData = RpClumpGetAnimBlendClumpData(clump); - if (anim->IsMoving()) { - CAnimBlendAssociation* syncAnim; - CAnimBlendLink* link; - for (link = clumpData->m_Associations.next; link; link = link->next) { - syncAnim = CAnimBlendAssociation::FromLink(link); - if (syncAnim->IsMoving()) - break; - } - if (link) { - anim->SyncAnimation(syncAnim); - anim->m_nFlags |= ANIMATION_STARTED; - } else - anim->Start(0.0f); - } else - anim->Start(0.0f); - - clumpData->m_Associations.Prepend(&anim->m_Link); - return anim; + return AddAnimationToClump(clump, anim); } // 0x4D3B30 CAnimBlendAssociation* CAnimManager::AddAnimationAndSync(RpClump* clump, CAnimBlendAssociation* animBlendAssoc, AssocGroupId groupId, AnimationId animId) { - return plugin::CallAndReturn(clump, animBlendAssoc, groupId, animId); - - CAnimBlendAssociation* anim = CreateAnimAssociation(groupId, animId); - CAnimBlendClumpData* clumpData = RpClumpGetAnimBlendClumpData(clump); - if (anim->IsMoving() && animBlendAssoc) { - anim->SyncAnimation(animBlendAssoc); - anim->m_nFlags |= ANIMATION_STARTED; - } else - anim->Start(0.0f); - - clumpData->m_Associations.Prepend(&anim->m_Link); - return anim; + const auto a = CreateAnimAssociation(groupId, animId); + const auto clumpAnims = RpClumpGetAnimBlendClumpData(clump); + if (a->IsMoving() && animBlendAssoc) { + a->SyncAnimation(animBlendAssoc); + a->m_nFlags |= ANIMATION_STARTED; + } else { + a->Start(0.0f); + } + clumpAnims->m_Associations.Prepend(&a->m_Link); + return a; } // 0x4D3BA0 AnimAssocDefinition* CAnimManager::AddAnimAssocDefinition(const char* groupName, const char* blockName, uint32 modelIndex, uint32 animsCount, AnimDescriptor* descriptor) { - return plugin::CallAndReturn(groupName, blockName, modelIndex, animsCount, descriptor); + const auto d = &ms_aAnimAssocDefinitions[ms_numAnimAssocDefinitions++]; - /* - auto* def = &ms_aAnimAssocDefinitions[ms_numAnimAssocDefinitions++]; - strcpy_s(def->groupName, groupName); - strcpy_s(def->blockName, blockName); - def->modelIndex = modelIndex; - def->animsCount = animsCount; - def->animDesc = descriptor; - def->animNames = new char*[animsCount]; - for (auto i = 0; i < animsCount; i++) { - def->animNames[i] = new char[24]; - *def->animNames[i] = '\0'; + strcpy_s(d->groupName, groupName); + strcpy_s(d->blockName, blockName); + + d->modelIndex = modelIndex; + d->animsCount = animsCount; + d->animDesc = descriptor; + + d->animNames = new const char*[animsCount]; + const auto bufsz = AnimAssocDefinition::ANIM_NAME_BUF_SZ * animsCount; + const auto buf = new char[bufsz]; + memset(buf, 0, bufsz); + for (auto i = animsCount; i-->0;) { + d->animNames[i] = buf + i * 24; } - return def; - */ + + return d; } // 0x4D3C80 -void CAnimManager::AddAnimToAssocDefinition(AnimAssocDefinition* definition, const char* animName) { - return plugin::Call<0x4D3C80, AnimAssocDefinition*, const char*>(definition, animName); - - /* - int i = 0; - while (*definition->animNames[i]) { - i++; +void CAnimManager::AddAnimToAssocDefinition(AnimAssocDefinition* def, const char* animName) { + int32 i = 0; + for (; *def->animNames[i]; i++) { + assert(i < def->animsCount); } - strcpy_s(definition->animNames[i], animName); - */ + // `const_cast` is fine here, because it's heap allocated [presumeably] + strcpy_s(const_cast(def->animNames[i]), AnimAssocDefinition::ANIM_NAME_BUF_SZ, animName); } // 0x4C4DC0 bool IsClumpSkinned(RpClump *clump) { - auto* atomic = GetFirstAtomic(clump); - return atomic && RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic)); + const auto a = GetFirstAtomic(clump); + return a && RpSkinGeometryGetSkin(RpAtomicGetGeometry(a)); } // 0x4D3CC0 void CAnimManager::CreateAnimAssocGroups() { - return plugin::Call<0x4D3CC0>(); - - for (auto i = 0; i < ms_numAnimAssocDefinitions; i++) { - CAnimBlendAssocGroup* group = &ms_aAnimAssocGroups[i]; - AnimAssocDefinition* def = &ms_aAnimAssocDefinitions[i]; - CAnimBlock* block = GetAnimationBlock(def->blockName); - if (block == nullptr || !block->bLoaded || group->m_pAssociations) + for (auto&& [i, group] : notsa::enumerate(GetAssocGroups())) { + const auto def = &ms_aAnimAssocDefinitions[i]; + const auto block = GetAnimationBlock(def->blockName); + if (block == nullptr || !block->bLoaded || group.m_pAssociations) { continue; + } RpClump* clump = nullptr; if (def->modelIndex != MODEL_INVALID) { @@ -335,11 +311,11 @@ void CAnimManager::CreateAnimAssocGroups() { RpAnimBlendClumpInit(clump); } - group->m_nGroupID = i; - group->m_nIdOffset = def->animDesc->animId; - group->CreateAssociations(def->blockName, clump, const_cast(def->animNames), def->animsCount); // todo: remove const_cast - for (auto j = 0u; j < group->m_nNumAnimations; j++) { - group->GetAnimation(def->animDesc[j].animId)->m_nFlags |= def->animDesc[j].flags; + group.m_nGroupID = i; + group.m_nIdOffset = def->animDesc->animId; + group.CreateAssociations(def->blockName, clump, const_cast(def->animNames), def->animsCount); // todo: remove const_cast + for (auto j = 0u; j < group.m_nNumAnimations; j++) { + group.GetAnimation(def->animDesc[j].animId)->m_nFlags |= def->animDesc[j].flags; } if (clump) { @@ -353,59 +329,54 @@ void CAnimManager::CreateAnimAssocGroups() { // 0x4D3E50 int32 CAnimManager::RegisterAnimBlock(const char* name) { - return plugin::CallAndReturn(name); - - CAnimBlock* animBlock = GetAnimationBlock(name); - if (animBlock == nullptr) { - animBlock = &ms_aAnimBlocks[ms_numAnimBlocks++]; - strncpy_s(animBlock->szName, name, MAX_ANIM_BLOCK_NAME); - animBlock->animationCount = 0; - animBlock->animationStyle = GetFirstAssocGroup(name); - assert(animBlock->usRefs == 0); + CAnimBlock* ab = GetAnimationBlock(name); + if (ab == nullptr) { // Initialize a new anim block + ab = &ms_aAnimBlocks[ms_numAnimBlocks++]; + strncpy_s(ab->szName, name, MAX_ANIM_BLOCK_NAME); + ab->animationCount = 0; + ab->animationStyle = GetFirstAssocGroup(name); + assert(ab->usRefs == 0); } - return GetAnimationBlockIndex(animBlock); + + return GetAnimationBlockIndex(ab); } // 0x4D3ED0 void CAnimManager::RemoveLastAnimFile() { - return plugin::Call<0x4D3ED0>(); - - ms_numAnimBlocks--; - ms_numAnimations = ms_aAnimBlocks[ms_numAnimBlocks].startAnimation; - for (auto i = 0; i < ms_aAnimBlocks[ms_numAnimBlocks].animationCount; i++) { - ms_aAnimations[ms_aAnimBlocks[ms_numAnimBlocks].startAnimation + i].Shutdown(); + const auto ab = &GetAnimBlocks()[--ms_numAnimBlocks]; + ms_numAnimations = ab->startAnimation; + for (auto i = 0; i < ab->animationCount; i++) { // Remove related animations too + ms_aAnimations[ab->startAnimation + i].Shutdown(); } - - ms_aAnimBlocks[ms_numAnimBlocks].bLoaded = false; + ab->bLoaded = false; } // 0x4D3F40 void CAnimManager::RemoveAnimBlock(int32 index) { - return plugin::Call<0x4D3F40, int32>(index); + const auto ab = &GetAnimBlocks()[index]; - CAnimBlock* block = &ms_aAnimBlocks[index]; - for (auto i = 0; i < ms_numAnimAssocDefinitions; i++) { - if (ms_aAnimAssocGroups[i].m_pAnimBlock == block) { - ms_aAnimAssocGroups[i].DestroyAssociations(); + for (auto& g : GetAssocGroups()) { + if (g.m_pAnimBlock == ab) { + g.DestroyAssociations(); } } - - for (auto i = 0; i < block->animationCount; i++) { - ms_aAnimations[block->startAnimation + i].Shutdown(); + + for (auto i = 0; i < ab->animationCount; i++) { // Remove related animations too + ms_aAnimations[ab->startAnimation + i].Shutdown(); } - block->bLoaded = false; - block->usRefs = 0; + ab->bLoaded = false; + ab->usRefs = 0; } // 0x4D3FB0 void CAnimManager::AddAnimBlockRef(int32 index) { - ms_aAnimBlocks[index].usRefs++; + GetAnimBlocks()[index].usRefs++; } // 0x4D3FD0 void CAnimManager::RemoveAnimBlockRef(int32 index) { - ms_aAnimBlocks[index].usRefs--; + GetAnimBlocks()[index].usRefs--; /* see RemoveAnimBlockRefWithoutDelete, logically here should be called RemoveModel or something if (--ms_aAnimBlocks[index].usRefs == 0) { CStreaming::RemoveModel(IFPToModelId(index)); @@ -424,13 +395,35 @@ int32 CAnimManager::GetNumRefsToAnimBlock(int32 index) { } // 0x4D41C0 -void CAnimManager::UncompressAnimation(CAnimBlendHierarchy* hier) { - return plugin::Call<0x4D41C0, CAnimBlendHierarchy*>(hier); +void CAnimManager::UncompressAnimation(CAnimBlendHierarchy* h) { + if (h->m_bKeepCompressed) { + if (h->m_fTotalTime == 0.f) { + h->CalcTotalTimeCompressed(); + } + } else if (h->m_bIsCompressed) { + auto l = ms_animCache.Insert(h); + if (!l) { // Not more free links? + // Remove least recently added item + const auto llr = ms_animCache.GetTail(); + llr->data->RemoveUncompressedData(); + RemoveFromUncompressedCache(llr->data); + + // Now try again, this time it should succeed + VERIFY(l = ms_animCache.Insert(h)); + } + h->m_Link = l; + h->Uncompress(); + } else if (h->m_Link) { // Already uncompressed, add to cache + h->m_Link->Insert(ms_animCache.GetHead()); + } } // 0x4D42A0 -void CAnimManager::RemoveFromUncompressedCache(CAnimBlendHierarchy* hier) { - return plugin::Call<0x4D42A0, CAnimBlendHierarchy*>(hier); +void CAnimManager::RemoveFromUncompressedCache(CAnimBlendHierarchy* h) { + if (const auto l = h->m_Link) { + l->data->m_Link = nullptr; + ms_animCache.Remove(l); + } } // 0x4D4410 @@ -557,8 +550,6 @@ void CAnimManager::LoadAnimFiles() { // 0x4D47F0 void CAnimManager::LoadAnimFile(RwStream* stream, bool loadCompressed, char const(*uncompressedAnimations)[32]) { - return plugin::Call<0x4D47F0, RwStream*, bool, char const(*)[32]>(stream, loadCompressed, uncompressedAnimations); - RwStreamRead(stream, &header, sizeof(IfpHeader)); if (header.ident == '3PNA' || header.ident == '2PNA') { LoadAnimFile_ANP23(stream, loadCompressed, header.ident == '3PNA'); @@ -572,7 +563,6 @@ inline void CAnimManager::LoadAnimFile_ANPK(RwStream* stream, bool compress, con if ((x)&3) \ (x) += 4 - ((x)&3) - /* IfpHeader info, name, dgan, cpan, anim; char buf[256]; float* fbuf = (float*)buf; @@ -595,7 +585,7 @@ inline void CAnimManager::LoadAnimFile_ANPK(RwStream* stream, bool compress, con } } else { animBlock = &ms_aAnimBlocks[ms_numAnimBlocks++]; - strncpy_s(animBlock->szName, buf + 4, MAX_ANIMBLOCK_NAME); + strncpy_s(animBlock->szName, buf + 4, MAX_ANIM_BLOCK_NAME); animBlock->animationCount = *(int*)buf; animBlock->startAnimation = ms_numAnimations; animBlock->animationStyle = GetFirstAssocGroup(animBlock->szName); @@ -606,7 +596,7 @@ inline void CAnimManager::LoadAnimFile_ANPK(RwStream* stream, bool compress, con int animIndex = animBlock->startAnimation; for (auto j = 0; j < animBlock->animationCount; j++) { - assert(animIndex < ARRAY_SIZE(ms_aAnimations)); + assert(animIndex < (int32)std::size(ms_aAnimations)); CAnimBlendHierarchy* hier = &ms_aAnimations[animIndex++]; // animation name @@ -617,7 +607,7 @@ inline void CAnimManager::LoadAnimFile_ANPK(RwStream* stream, bool compress, con hier->SetName(buf); //#ifdef ANIM_COMPRESSION - bool compressHier = compress; + bool isCompressed = compress; //#else // bool compressHier = false; //#endif @@ -626,32 +616,36 @@ inline void CAnimManager::LoadAnimFile_ANPK(RwStream* stream, bool compress, con //if (!stricmp(uncompressedAnims[i], buf)) if (CKeyGen::GetUppercaseKey(uncompressedAnims[i]) == hier->m_hashKey)// { //debug("Loading %s uncompressed\n", hier->name); - compressHier = false; + isCompressed = false; //} } } - hier->m_bRunningCompressed = compressHier; + hier->m_bIsCompressed = isCompressed; hier->m_bKeepCompressed = false; // DG info has number of nodes/sequences RwStreamRead(stream, (char*)&dgan, sizeof(IfpHeader)); ROUND_SIZE(dgan.size); + RwStreamRead(stream, (char*)&info, sizeof(IfpHeader)); ROUND_SIZE(info.size); + RwStreamRead(stream, buf, info.size); int nSeq = *(int*)buf; - hier->numSequences = nSeq; - //hier->sequences = (CAnimBlendSequence*)CMemoryMgr::Malloc(nSeq * sizeof(CAnimBlendSequence)); - hier->sequences = new CAnimBlendSequence[nSeq]; + hier->m_nSeqCount = nSeq; + hier->m_pSequences = new CAnimBlendSequence[nSeq]; //= (CAnimBlendSequence*)CMemoryMgr::Malloc(nSeq * sizeof(CAnimBlendSequence)); + + for (auto s = 0; s < nSeq; s++) { // or seq++ ? + CAnimBlendSequence* seq = &hier->m_pSequences[s]; - for (auto k = 0; k < nSeq; k++) { // or seq++ ? - CAnimBlendSequence* seq = &hier->sequences[k]; // Each node has a name and key frames RwStreamRead(stream, &cpan, sizeof(IfpHeader)); ROUND_SIZE(cpan.size); + RwStreamRead(stream, &anim, sizeof(IfpHeader)); ROUND_SIZE(anim.size); + RwStreamRead(stream, buf, anim.size); int numFrames = *(int*)(buf + 28); seq->SetName(buf); @@ -666,15 +660,17 @@ inline void CAnimManager::LoadAnimFile_ANPK(RwStream* stream, bool compress, con RwStreamRead(stream, &info, sizeof(info)); //if (numFrames == 0) // continue; - if (strncmp(info.ident, "KRTS", 4) == 0) { + + if (memcmp(&info.ident, "KRTS", 4) == 0) { hasScale = true; - seq->SetNumFrames(numFrames, true, compressHier, NULL); - } else if (strncmp(info.ident, "KRT0", 4) == 0) { + seq->SetNumFrames(numFrames, true, isCompressed, NULL); + } else if (memcmp(&info.ident, "KRT0", 4) == 0) { hasTranslation = true; - seq->SetNumFrames(numFrames, true, compressHier, NULL); - } else if (strncmp(info.ident, "KR00", 4) == 0) { - seq->SetNumFrames(numFrames, false, compressHier, NULL); + seq->SetNumFrames(numFrames, true, isCompressed, NULL); + } else if (memcmp(&info.ident, "KR00", 4) == 0) { + seq->SetNumFrames(numFrames, false, isCompressed, NULL); } + //if (seq->numFrames) // if(strstr(seq->name, "L Toe")) // debug("anim %s has toe keyframes\n", hier->name); // BUG: seq->name @@ -686,14 +682,14 @@ inline void CAnimManager::LoadAnimFile_ANPK(RwStream* stream, bool compress, con rot.Conjugate(); CVector trans(fbuf[4], fbuf[5], fbuf[6]); - if (compressHier) { - KeyFrameTransCompressed* kf = (KeyFrameTransCompressed*)seq->GetKeyFrameCompressed(l); + if (isCompressed) { + KeyFrameTransCompressed* kf = (KeyFrameTransCompressed*)seq->GetCompressedFrame(l); kf->SetRotation(rot); kf->SetTranslation(trans); // scaling ignored kf->SetTime(fbuf[10]); // absolute time here } else { - KeyFrameTrans* kf = (KeyFrameTrans*)seq->GetKeyFrame(l); + KeyFrameTrans* kf = (KeyFrameTrans*)seq->GetUncompressedFrame(l); kf->rotation = rot; kf->translation = trans; // scaling ignored @@ -705,13 +701,13 @@ inline void CAnimManager::LoadAnimFile_ANPK(RwStream* stream, bool compress, con rot.Conjugate(); CVector trans(fbuf[4], fbuf[5], fbuf[6]); - if (compressHier) { - KeyFrameTransCompressed* kf = (KeyFrameTransCompressed*)seq->GetKeyFrameCompressed(l); + if (isCompressed) { + KeyFrameTransCompressed* kf = (KeyFrameTransCompressed*)seq->GetCompressedFrame(l); kf->SetRotation(rot); kf->SetTranslation(trans); kf->SetTime(fbuf[7]); // absolute time here } else { - KeyFrameTrans* kf = (KeyFrameTrans*)seq->GetKeyFrame(l); + KeyFrameTrans* kf = (KeyFrameTrans*)seq->GetUncompressedFrame(l); kf->rotation = rot; kf->translation = trans; kf->deltaTime = fbuf[7]; // absolute time here @@ -721,12 +717,12 @@ inline void CAnimManager::LoadAnimFile_ANPK(RwStream* stream, bool compress, con CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]); rot.Conjugate(); - if (compressHier) { - KeyFrameCompressed* kf = (KeyFrameCompressed*)seq->GetKeyFrameCompressed(l); + if (isCompressed) { + KeyFrameCompressed* kf = (KeyFrameCompressed*)seq->GetCompressedFrame(l); kf->SetRotation(rot); kf->SetTime(fbuf[4]); // absolute time here } else { - KeyFrame* kf = (KeyFrame*)seq->GetKeyFrame(l); + KeyFrame* kf = (KeyFrame*)seq->GetUncompressedFrame(l); kf->rotation = rot; kf->deltaTime = fbuf[4]; // absolute time here } @@ -734,7 +730,7 @@ inline void CAnimManager::LoadAnimFile_ANPK(RwStream* stream, bool compress, con } } - if (!compressHier) { + if (!isCompressed) { hier->RemoveQuaternionFlips(); hier->CalcTotalTime(); } @@ -743,26 +739,26 @@ inline void CAnimManager::LoadAnimFile_ANPK(RwStream* stream, bool compress, con if (animIndex > ms_numAnimations) { ms_numAnimations = animIndex; } - */ + #undef ROUND_SIZE } // NOTSA inline void CAnimManager::LoadAnimFile_ANP23(RwStream* stream, bool compress, bool isANP3) { char buf[256]; - // char name[24]; + char blockName[24]; int nAnims, nSeq; - RwStreamRead(stream, &buf, 24); // animation name - RwStreamRead(stream, &nAnims, 4); + RwStreamRead(stream, &blockName, sizeof(blockName)); + RwStreamRead(stream, &nAnims, sizeof(nAnims)); - CAnimBlock* animBlock = GetAnimationBlock(buf); + CAnimBlock* animBlock = GetAnimationBlock(blockName); if (animBlock) { if (animBlock->animationCount == 0) { animBlock->animationCount = nAnims; animBlock->startAnimation = ms_numAnimations; } - } else { + } else { // Register a new block animBlock = &ms_aAnimBlocks[ms_numAnimBlocks++]; strncpy_s(animBlock->szName, buf, MAX_ANIM_BLOCK_NAME); animBlock->animationCount = nAnims; @@ -836,7 +832,7 @@ inline void CAnimManager::LoadAnimFile_ANP23(RwStream* stream, bool compress, bo } if (!bInvalidType) { if (k == 0) { - hier->m_bRunningCompressed = bIsCompressed; + hier->m_bIsCompressed = bIsCompressed; } seq->SetNumFrames(sdata.frames_count, bIsRoot, bIsCompressed, st); @@ -849,7 +845,7 @@ inline void CAnimManager::LoadAnimFile_ANP23(RwStream* stream, bool compress, bo } } } - if (!hier->m_bRunningCompressed) { + if (!hier->m_bIsCompressed) { hier->RemoveQuaternionFlips(); hier->CalcTotalTime(); } diff --git a/source/game_sa/Animation/AnimManager.h b/source/game_sa/Animation/AnimManager.h index 9bf8e2c85d..e522bb72b4 100644 --- a/source/game_sa/Animation/AnimManager.h +++ b/source/game_sa/Animation/AnimManager.h @@ -11,6 +11,8 @@ #include "AnimBlendAssociation.h" #include "AnimBlock.h" +#include + constexpr auto MAX_ANIM_BLOCK_NAME = 16; constexpr auto NUM_ANIM_ASSOC_GROUPS = 118; constexpr auto NUM_ANIM_BLOCKS = 180; @@ -19,10 +21,10 @@ class CAnimManager { public: static std::array ms_aAnimAssocDefinitionsX; // replacement static inline AnimAssocDefinition (&ms_aAnimAssocDefinitions)[NUM_ANIM_ASSOC_GROUPS] = *(AnimAssocDefinition(*)[NUM_ANIM_ASSOC_GROUPS])0x8AA5A8; // std::array - see SurfaceInfos_c - static inline int32& ms_numAnimAssocDefinitions = *(int32*)0xB4EA28; + static inline uint32& ms_numAnimAssocDefinitions = *(uint32*)0xB4EA28; static inline CAnimBlendAssocGroup*& ms_aAnimAssocGroups = *(CAnimBlendAssocGroup**)0xB4EA34; - static inline int32& ms_numAnimBlocks = *(int32*)0xB4EA30; + static inline uint32& ms_numAnimBlocks = *(uint32*)0xB4EA30; static inline std::array& ms_aAnimations = *(std::array*)0xB4EA40; static inline int32& ms_numAnimations = *(int32*)0xB4EA2C; @@ -52,9 +54,10 @@ class CAnimManager { static CAnimBlendHierarchy* GetAnimation(const char* animName, const CAnimBlock* animBlock); static const char* GetAnimGroupName(AssocGroupId groupId); static const char* GetAnimBlockName(AssocGroupId groupId); - static AssocGroupId GetAnimationGroupId(const char* name); + static AssocGroupId GetAnimationGroupIdByName(notsa::ci_string_view name); static CAnimBlendStaticAssociation* GetAnimAssociation(AssocGroupId groupId, AnimationId animId); static CAnimBlendStaticAssociation* GetAnimAssociation(AssocGroupId groupId, const char* animName); + static CAnimBlendAssociation* AddAnimationToClump(RpClump* clump, CAnimBlendAssociation* anim); // NOTSA - Internal static int32 GetNumRefsToAnimBlock(int32 index); static CAnimBlendAssociation* CreateAnimAssociation(AssocGroupId groupId, AnimationId animId); @@ -79,7 +82,11 @@ class CAnimManager { /// NOTSA. Get random gangtalk anim static AnimationId GetRandomGangTalkAnim(); + + static auto GetAnimBlocks() { return ms_aAnimBlocks | rng::views::take(ms_numAnimBlocks); } + static auto GetAssocGroups() { return std::span{ms_aAnimAssocGroups, ms_numAnimAssocDefinitions}; } + static auto GetAssocGroupDefs() { return std::span{ms_aAnimAssocDefinitions, ms_numAnimAssocDefinitions}; } private: - static inline void LoadAnimFile_ANPK(RwStream* stream, bool compress, const char (*uncompressedAnims)[32]); - static inline void LoadAnimFile_ANP23(RwStream* stream, bool compress, bool isANP3); + static void LoadAnimFile_ANPK(RwStream* stream, bool compress, const char (*uncompressedAnims)[32]); + static void LoadAnimFile_ANP23(RwStream* stream, bool compress, bool isANP3); }; diff --git a/source/game_sa/Animation/AnimationStyleDescriptor.h b/source/game_sa/Animation/AnimationStyleDescriptor.h index b2d770e78d..3af164dd50 100644 --- a/source/game_sa/Animation/AnimationStyleDescriptor.h +++ b/source/game_sa/Animation/AnimationStyleDescriptor.h @@ -6,12 +6,14 @@ struct AnimDescriptor { }; struct AnimAssocDefinition { + constexpr static size_t ANIM_NAME_BUF_SZ = 24; + char groupName[16]{}; char blockName[16]{}; int32 modelIndex{}; int32 animsCount{}; - const char** animNames{}; + const char** animNames{}; //< Pointers to heap allocated char arrays (size 24 each) - The array of pointers itself is heap allocated as well - Size == animsCount AnimDescriptor* animDesc{}; }; VALIDATE_SIZE(AnimAssocDefinition, 0x30); diff --git a/source/game_sa/Core/LinkList.h b/source/game_sa/Core/LinkList.h index 263e160049..0f432a13e2 100644 --- a/source/game_sa/Core/LinkList.h +++ b/source/game_sa/Core/LinkList.h @@ -75,6 +75,9 @@ template class CLinkList { link->Remove(); freeListHead.Insert(link); } + + auto GetTail() { return usedListTail.prev; } + auto GetHead() { return usedListHead.next; } }; VALIDATE_SIZE(CLinkList, 0x34); diff --git a/source/game_sa/CutsceneMgr.cpp b/source/game_sa/CutsceneMgr.cpp index 972a765d97..e73379a528 100644 --- a/source/game_sa/CutsceneMgr.cpp +++ b/source/game_sa/CutsceneMgr.cpp @@ -866,7 +866,7 @@ void CCutsceneMgr::SetCutsceneAnim(const char* animName, CObject* object) { return; } - if (theAnim->m_pHierarchy->m_bRunningCompressed) { + if (theAnim->m_pHierarchy->m_bIsCompressed) { theAnim->m_pHierarchy->m_bKeepCompressed = true; } @@ -914,7 +914,7 @@ void CCutsceneMgr::SetupCutsceneToStart() { anim->SetFlag(ANIMATION_STARTED, true); } else { // Get anim translation and offset the object's position by it - const auto animTrans = anim->m_pHierarchy->m_bRunningCompressed + const auto animTrans = anim->m_pHierarchy->m_bIsCompressed ? anim->m_pHierarchy->m_pSequences->GetCompressedFrame(1)->GetTranslation() : anim->m_pHierarchy->m_pSequences->GetUncompressedFrame(1)->translation; SetObjPos(ms_cutsceneOffset + animTrans); diff --git a/source/game_sa/FileLoader.cpp b/source/game_sa/FileLoader.cpp index 66014c24a7..99b3e80966 100644 --- a/source/game_sa/FileLoader.cpp +++ b/source/game_sa/FileLoader.cpp @@ -1476,33 +1476,24 @@ int32 CFileLoader::LoadPedObject(const char* line) { SCANF_S_STR(voiceMax) ) == 14); - const auto FindAnimGroup = [animGroup, nAssocGroups = CAnimManager::ms_numAnimAssocDefinitions] { - for (auto i = 0; i < nAssocGroups; i++) { - if (CAnimManager::GetAnimGroupName((AssocGroupId)i) == std::string_view{animGroup}) { - return (AssocGroupId)i; - } - } - return (AssocGroupId)nAssocGroups; - }; - const auto mi = CModelInfo::AddPedModel(modelId); mi->m_nKey = CKeyGen::GetUppercaseKey(modelName); mi->SetTexDictionary(texName); mi->SetAnimFile(animFile); mi->SetColModel(&colModelPeds, false); - mi->m_nPedType = CPedType::FindPedType(pedType); - mi->m_nStatType = CPedStats::GetPedStatType(statName); - mi->m_nAnimType = FindAnimGroup(); + mi->m_nPedType = CPedType::FindPedType(pedType); + mi->m_nStatType = CPedStats::GetPedStatType(statName); + mi->m_nAnimType = CAnimManager::GetAnimationGroupIdByName(animGroup); mi->m_nCarsCanDriveMask = carsCanDriveMask; - mi->m_nPedFlags = flags; - mi->m_nRadio2 = (eRadioID)(radio2 + 1); - mi->m_nRadio1 = (eRadioID)(radio1 + 1); - mi->m_nRace = CPopulation::FindPedRaceFromName(modelName); - mi->m_nPedAudioType = CAEPedSpeechAudioEntity::GetAudioPedType(pedVoiceType); - mi->m_nVoiceMin = CAEPedSpeechAudioEntity::GetVoice(voiceMin, mi->m_nPedAudioType); - mi->m_nVoiceMax = CAEPedSpeechAudioEntity::GetVoice(voiceMax, mi->m_nPedAudioType); - mi->m_nVoiceId = mi->m_nVoiceMin; + mi->m_nPedFlags = flags; + mi->m_nRadio2 = (eRadioID)(radio2 + 1); + mi->m_nRadio1 = (eRadioID)(radio1 + 1); + mi->m_nRace = CPopulation::FindPedRaceFromName(modelName); + mi->m_nPedAudioType = CAEPedSpeechAudioEntity::GetAudioPedType(pedVoiceType); + mi->m_nVoiceMin = CAEPedSpeechAudioEntity::GetVoice(voiceMin, mi->m_nPedAudioType); + mi->m_nVoiceMax = CAEPedSpeechAudioEntity::GetVoice(voiceMax, mi->m_nPedAudioType); + mi->m_nVoiceId = mi->m_nVoiceMin; return modelId; } @@ -1671,7 +1662,7 @@ void CFileLoader::LoadPickup(const char* line) { } }; - if (const auto model = GetModel(); model != -1) { + if (const auto model = GetModel(); model != MODEL_INVALID) { CPickups::GenerateNewOne(pos, model, PICKUP_ON_STREET, 0, 0, false, nullptr); } } diff --git a/source/game_sa/Population.cpp b/source/game_sa/Population.cpp index 7e3aed3846..f2658e2b1b 100644 --- a/source/game_sa/Population.cpp +++ b/source/game_sa/Population.cpp @@ -1867,8 +1867,8 @@ void CPopulation::PopulateInterior(int32 numPedsToCreate, CVector pos) { ped->GetIntelligence()->SetPedDecisionMakerType(7); - if (ped->m_nAnimGroup == CAnimManager::GetAnimationGroupId("jogger")) { // TODO: Move `GetAnimationGroupId` out the loop? - ped->m_nAnimGroup = CAnimManager::GetAnimationGroupId("man"); + if (ped->m_nAnimGroup == CAnimManager::GetAnimationGroupIdByName("jogger")) { // TODO: Move `GetAnimationGroupId` out the loop? + ped->m_nAnimGroup = CAnimManager::GetAnimationGroupIdByName("man"); } } } diff --git a/source/game_sa/WeaponInfo.cpp b/source/game_sa/WeaponInfo.cpp index a557641f07..4897d38342 100644 --- a/source/game_sa/WeaponInfo.cpp +++ b/source/game_sa/WeaponInfo.cpp @@ -232,7 +232,7 @@ void CWeaponInfo::LoadWeaponData() { if (!std::string_view{ animGrpName }.starts_with("null")) { - wi.m_eAnimGroup = CAnimManager::GetAnimationGroupId(animGrpName); + wi.m_eAnimGroup = CAnimManager::GetAnimationGroupIdByName(animGrpName); } if (wi.m_eAnimGroup >= ANIM_GROUP_PYTHON && wi.m_eAnimGroup <= ANIM_GROUP_SPRAYCAN) { @@ -255,7 +255,7 @@ void CWeaponInfo::LoadWeaponData() { VERIFY(sscanf_s(line, "%*s %s %f %f %f %f %d %d %d %d", SCANF_S_STR(stealthAnimGrp), &aimX, &aimZ, &duckX, &duckZ, &RLoadA, &RLoadB, &crouchRLoadA, &crouchRLoadB) == 9); - g_GunAimingOffsets[CAnimManager::GetAnimationGroupId(stealthAnimGrp) - ANIM_GROUP_PYTHON] = { + g_GunAimingOffsets[CAnimManager::GetAnimationGroupIdByName(stealthAnimGrp) - ANIM_GROUP_PYTHON] = { .AimX = aimX, .AimZ = aimZ, @@ -310,7 +310,7 @@ void CWeaponInfo::LoadWeaponData() { wi.m_nFlags = flags; if (!std::string_view{stealthAnimGrpName}.starts_with("null")) - wi.m_eAnimGroup = CAnimManager::GetAnimationGroupId(stealthAnimGrpName); + wi.m_eAnimGroup = CAnimManager::GetAnimationGroupIdByName(stealthAnimGrpName); if (modelId1 > 0) CModelInfo::GetModelInfo(modelId1)->AsWeaponModelInfoPtr()->m_weaponInfo = wType;