diff --git a/Client/game_sa/CBuildingsPoolSA.cpp b/Client/game_sa/CBuildingsPoolSA.cpp index 50ae14bb3c..ef30e81283 100644 --- a/Client/game_sa/CBuildingsPoolSA.cpp +++ b/Client/game_sa/CBuildingsPoolSA.cpp @@ -53,6 +53,13 @@ CBuilding* CBuildingsPoolSA::AddBuilding(CClientBuilding* pClientBuilding, uint1 if (!HasFreeBuildingSlot()) return nullptr; + auto modelInfo = pGame->GetModelInfo(modelId); + + // Change the properties group to force dynamic models to be created as buildings instead of dummies + auto prevGroup = modelInfo->GetObjectPropertiesGroup(); + if (prevGroup != MODEL_PROPERTIES_GROUP_STATIC) + modelInfo->SetObjectPropertiesGroup(MODEL_PROPERTIES_GROUP_STATIC); + // Load building SFileObjectInstance instance; instance.modelID = modelId; @@ -70,9 +77,12 @@ CBuilding* CBuildingsPoolSA::AddBuilding(CClientBuilding* pClientBuilding, uint1 pBuilding->m_pLod = nullptr; pBuilding->m_iplIndex = 0; + // Resore changes properties group + if (prevGroup != MODEL_PROPERTIES_GROUP_STATIC) + modelInfo->SetObjectPropertiesGroup(prevGroup); + // Always stream model collosion // TODO We can setup collison bounding box and use GTA streamer for it - auto modelInfo = pGame->GetModelInfo(modelId); modelInfo->AddColRef(); // Add building in world diff --git a/Client/game_sa/CModelInfoSA.h b/Client/game_sa/CModelInfoSA.h index b261bcc04a..889608404a 100644 --- a/Client/game_sa/CModelInfoSA.h +++ b/Client/game_sa/CModelInfoSA.h @@ -466,7 +466,7 @@ class CModelInfoSA : public CModelInfo // Vehicle towing functions bool IsTowableBy(CModelInfo* towingModel) override; - bool IsDynamic() { return m_pInterface ? m_pInterface->usDynamicIndex != 0xffff : false; }; + bool IsDynamic() { return m_pInterface ? m_pInterface->usDynamicIndex != MODEL_PROPERTIES_GROUP_STATIC : false; }; private: void CopyStreamingInfoFromModel(ushort usCopyFromModelID); diff --git a/Client/mods/deathmatch/logic/CClientBuildingManager.cpp b/Client/mods/deathmatch/logic/CClientBuildingManager.cpp index 243917b89f..a09df6a226 100644 --- a/Client/mods/deathmatch/logic/CClientBuildingManager.cpp +++ b/Client/mods/deathmatch/logic/CClientBuildingManager.cpp @@ -73,11 +73,6 @@ bool CClientBuildingManager::IsValidModel(uint16_t modelId) if (!pModelInfo->IsAllocatedInArchive()) return false; - if (pModelInfo->IsDynamic()) - { - return false; - } - eModelInfoType eType = pModelInfo->GetModelType(); return (eType == eModelInfoType::CLUMP || eType == eModelInfoType::ATOMIC || eType == eModelInfoType::WEAPON || eType == eModelInfoType::TIME); } @@ -106,29 +101,9 @@ void CClientBuildingManager::RestoreDestroyed() { const CClientBuilding* highLodBuilding = building->GetHighLodBuilding(); if (highLodBuilding && !highLodBuilding->IsValid()) - { hasInvalidLods = true; - } else - { - CModelInfo* modelInfo = building->GetModelInfo(); - const uint16_t physicalGroup = modelInfo->GetObjectPropertiesGroup(); - - if (physicalGroup == -1) - { - building->Create(); - } - else - { - // GTA creates dynamic models as dummies. - // It's possible that the physical group was changes after - // creating a new building. We can avoid crashes in this case. - modelInfo->SetObjectPropertiesGroup(-1); - building->Create(); - modelInfo->SetObjectPropertiesGroup(physicalGroup); - } - - } + building->Create(); } } } diff --git a/Client/sdk/game/CModelInfo.h b/Client/sdk/game/CModelInfo.h index 08cb032e4c..3541750038 100644 --- a/Client/sdk/game/CModelInfo.h +++ b/Client/sdk/game/CModelInfo.h @@ -15,6 +15,8 @@ #include "CAnimBlock.h" #include "Common.h" +constexpr std::uint16_t MODEL_PROPERTIES_GROUP_STATIC = 0xFFFF; + class CBaseModelInfoSAInterface; class CColModel; class CPedModelInfo; @@ -131,6 +133,7 @@ struct SVehicleSupportedUpgrades bool m_bMisc; bool m_bInitialised; }; + class CModelInfo { public: