From e8e8a6b35a0182319fe5d83db448fa964ede1638 Mon Sep 17 00:00:00 2001 From: FileEX Date: Sun, 1 Mar 2026 16:46:24 +0100 Subject: [PATCH] Fix bug --- Client/game_sa/CBuildingsPoolSA.cpp | 20 ++++++++++++++++++++ Client/game_sa/CBuildingsPoolSA.h | 2 ++ Client/game_sa/CPlaceableSA.h | 1 + 3 files changed, 23 insertions(+) diff --git a/Client/game_sa/CBuildingsPoolSA.cpp b/Client/game_sa/CBuildingsPoolSA.cpp index 0521dcba6d1..3e33390f843 100644 --- a/Client/game_sa/CBuildingsPoolSA.cpp +++ b/Client/game_sa/CBuildingsPoolSA.cpp @@ -199,7 +199,12 @@ void CBuildingsPoolSA::RemoveAllWithBackup() RemoveBuildingFromWorld(building); if (building->HasMatrix()) + { + // Keep original matrix + m_buildingMatrix[building] = *building->matrix; + building->RemoveMatrix(); + } pBuildsingsPool->Release(i); @@ -231,6 +236,21 @@ void CBuildingsPoolSA::RestoreBackup() auto* pBuilding = pBuildsingsPool->AllocateAtNoInit(i); std::memcpy(pBuilding, &originalData[i].second, sizeof(CBuildingSAInterface)); + // Restore matrix if it was removed + auto it = m_buildingMatrix.find(pBuilding); + if (it != m_buildingMatrix.end()) + { + if (!pBuilding->HasMatrix()) + pBuilding->AllocateMatrix(); + + pBuilding->matrix->vRight = it->second.vRight; + pBuilding->matrix->vFront = it->second.vFront; + pBuilding->matrix->vUp = it->second.vUp; + pBuilding->matrix->vPos = it->second.vPos; + + m_buildingMatrix.erase(it); + } + worldSA->Add(pBuilding, CBuildingPool_Constructor); buildingRemovealSA->AddDataBuilding(pBuilding); } diff --git a/Client/game_sa/CBuildingsPoolSA.h b/Client/game_sa/CBuildingsPoolSA.h index e4b16021e81..06c6afa2bac 100644 --- a/Client/game_sa/CBuildingsPoolSA.h +++ b/Client/game_sa/CBuildingsPoolSA.h @@ -52,6 +52,8 @@ class CBuildingsPoolSA : public CBuildingsPool std::unique_ptr m_pOriginalBuildingsBackup; + std::unordered_map m_buildingMatrix{}; + // Set by RemoveAllWithBackup after sweeping stale entity links (vehicle damage, // ped contact, object entity refs). Cleared by Resize to skip a redundant pass // when SetBuildingPoolSize calls both in the same remove/resize cycle. diff --git a/Client/game_sa/CPlaceableSA.h b/Client/game_sa/CPlaceableSA.h index 858263e1de6..6898a49b520 100644 --- a/Client/game_sa/CPlaceableSA.h +++ b/Client/game_sa/CPlaceableSA.h @@ -27,6 +27,7 @@ class CPlaceableSAInterface bool IsPlaceableVTBL() const { return GetVTBL() == (void*)0x863C40; } bool HasMatrix() const noexcept { return matrix != nullptr; } + void AllocateMatrix() { ((void(__thiscall*)(void*))0x54F560)(this); } void RemoveMatrix() { ((void(__thiscall*)(void*))0x54F3B0)(this); } void SetOrientation(float x, float y, float z) { ((void(__thiscall*)(CPlaceableSAInterface * pEntity, float, float, float))0x439A80)(this, x, y, z); }