diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index 2db97a5245..0b1c634408 100644 --- a/Client/game_sa/CModelInfoSA.cpp +++ b/Client/game_sa/CModelInfoSA.cpp @@ -1744,6 +1744,24 @@ void CModelInfoSA::MakeObjectModel(ushort usBaseID) CopyStreamingInfoFromModel(usBaseID); } +void CModelInfoSA::MakeObjectDamageableModel(std::uint16_t baseModel) +{ + CDamageableModelInfoSAInterface* m_pInterface = new CDamageableModelInfoSAInterface(); + + CDamageableModelInfoSAInterface* pBaseObjectInfo = static_cast(ppModelInfo[baseModel]); + MemCpyFast(m_pInterface, pBaseObjectInfo, sizeof(CDamageableModelInfoSAInterface)); + m_pInterface->usNumberOfRefs = 0; + m_pInterface->pRwObject = nullptr; + m_pInterface->usUnknown = 65535; + m_pInterface->usDynamicIndex = 65535; + m_pInterface->m_damagedAtomic = nullptr; + + ppModelInfo[m_dwModelID] = m_pInterface; + + m_dwParentID = baseModel; + CopyStreamingInfoFromModel(baseModel); +} + void CModelInfoSA::MakeTimedObjectModel(ushort usBaseID) { CTimeModelInfoSAInterface* m_pInterface = new CTimeModelInfoSAInterface(); @@ -1809,7 +1827,14 @@ void CModelInfoSA::DeallocateModel(void) delete reinterpret_cast(ppModelInfo[m_dwModelID]); break; case eModelInfoType::ATOMIC: - delete reinterpret_cast(ppModelInfo[m_dwModelID]); + if (IsDamageableAtomic()) + { + delete reinterpret_cast(ppModelInfo[m_dwModelID]); + } + else + { + delete reinterpret_cast(ppModelInfo[m_dwModelID]); + } break; case eModelInfoType::CLUMP: delete reinterpret_cast(ppModelInfo[m_dwModelID]); @@ -2064,6 +2089,12 @@ bool CModelInfoSA::IsTowableBy(CModelInfo* towingModel) return isTowable; } +bool CModelInfoSA::IsDamageableAtomic() +{ + void* asDamagable = ((void* (*)())m_pInterface->VFTBL->AsDamageAtomicModelInfoPtr)(); + return asDamagable != nullptr; +} + ////////////////////////////////////////////////////////////////////////////////////////// // // CModelInfoSA::ForceUnload diff --git a/Client/game_sa/CModelInfoSA.h b/Client/game_sa/CModelInfoSA.h index b261bcc04a..dc80fc5f5d 100644 --- a/Client/game_sa/CModelInfoSA.h +++ b/Client/game_sa/CModelInfoSA.h @@ -259,6 +259,12 @@ class CTimeModelInfoSAInterface : public CBaseModelInfoSAInterface CTimeInfoSAInterface timeInfo; }; +class CDamageableModelInfoSAInterface : public CBaseModelInfoSAInterface +{ +public: + void* m_damagedAtomic; +}; + class CVehicleModelVisualInfoSAInterface // Not sure about this name. If somebody knows more, please change { public: @@ -447,6 +453,7 @@ class CModelInfoSA : public CModelInfo // CModelInfoSA methods void MakePedModel(char* szTexture); void MakeObjectModel(ushort usBaseModelID); + void MakeObjectDamageableModel(std::uint16_t usBaseModelID) override; void MakeVehicleAutomobile(ushort usBaseModelID); void MakeTimedObjectModel(ushort usBaseModelID); void MakeClumpModel(ushort usBaseModelID); @@ -467,6 +474,7 @@ class CModelInfoSA : public CModelInfo bool IsTowableBy(CModelInfo* towingModel) override; bool IsDynamic() { return m_pInterface ? m_pInterface->usDynamicIndex != 0xffff : false; }; + bool IsDamageableAtomic() override; private: void CopyStreamingInfoFromModel(ushort usCopyFromModelID); diff --git a/Client/mods/deathmatch/logic/CClientModel.cpp b/Client/mods/deathmatch/logic/CClientModel.cpp index 795bc08579..e197ce1bae 100644 --- a/Client/mods/deathmatch/logic/CClientModel.cpp +++ b/Client/mods/deathmatch/logic/CClientModel.cpp @@ -51,6 +51,17 @@ bool CClientModel::Allocate(ushort usParentID) return true; } break; + case eClientModelType::OBJECT_DAMAGEABLE: + { + bool isValidModel = g_pClientGame->GetObjectManager()->IsValidModel(usParentID); + bool isDamagable = pParentModelInfo->IsDamageableAtomic(); + if (isValidModel && isDamagable) + { + pModelInfo->MakeObjectDamageableModel(usParentID); + return true; + } + break; + } case eClientModelType::CLUMP: if (g_pClientGame->GetObjectManager()->IsValidModel(usParentID)) { @@ -109,6 +120,7 @@ void CClientModel::RestoreEntitiesUsingThisModel() { case eClientModelType::PED: case eClientModelType::OBJECT: + case eClientModelType::OBJECT_DAMAGEABLE: case eClientModelType::CLUMP: case eClientModelType::TIMED_OBJECT: case eClientModelType::VEHICLE: @@ -174,6 +186,7 @@ void CClientModel::RestoreDFF(CModelInfo* pModelInfo) } case eClientModelType::CLUMP: case eClientModelType::OBJECT: + case eClientModelType::OBJECT_DAMAGEABLE: case eClientModelType::TIMED_OBJECT: { const auto& objects = &g_pClientGame->GetManager()->GetObjectManager()->GetObjects(); diff --git a/Client/mods/deathmatch/logic/CClientModel.h b/Client/mods/deathmatch/logic/CClientModel.h index 903148192d..759890e0e5 100644 --- a/Client/mods/deathmatch/logic/CClientModel.h +++ b/Client/mods/deathmatch/logic/CClientModel.h @@ -18,6 +18,7 @@ enum class eClientModelType { PED, OBJECT, + OBJECT_DAMAGEABLE, VEHICLE, TIMED_OBJECT, CLUMP, diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp index 64708dea0c..068e01e51a 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.cpp @@ -675,6 +675,7 @@ IMPLEMENT_ENUM_END("surface-adhesion-group") IMPLEMENT_ENUM_CLASS_BEGIN(eClientModelType) ADD_ENUM(eClientModelType::PED, "ped") ADD_ENUM(eClientModelType::OBJECT, "object") +ADD_ENUM(eClientModelType::OBJECT_DAMAGEABLE, "object-damageable") ADD_ENUM(eClientModelType::VEHICLE, "vehicle") ADD_ENUM(eClientModelType::TIMED_OBJECT, "timed-object") ADD_ENUM(eClientModelType::CLUMP, "clump") diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 7ca02230d5..a6a688c366 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -892,6 +892,9 @@ int CLuaEngineDefs::EngineRequestModel(lua_State* luaVM) case eClientModelType::OBJECT: usParentID = 1337; // BinNt07_LA (trash can) break; + case eClientModelType::OBJECT_DAMAGEABLE: + usParentID = 994; // lhouse_barrier2 + break; case eClientModelType::VEHICLE: usParentID = VT_LANDSTAL; break; diff --git a/Client/sdk/game/CModelInfo.h b/Client/sdk/game/CModelInfo.h index 08cb032e4c..e696fd7caf 100644 --- a/Client/sdk/game/CModelInfo.h +++ b/Client/sdk/game/CModelInfo.h @@ -233,6 +233,7 @@ class CModelInfo virtual RwObject* GetRwObject() = 0; virtual void MakePedModel(char* szTexture) = 0; virtual void MakeObjectModel(unsigned short usBaseID) = 0; + virtual void MakeObjectDamageableModel(std::uint16_t baseID) = 0; virtual void MakeVehicleAutomobile(unsigned short usBaseID) = 0; virtual void MakeTimedObjectModel(unsigned short usBaseID) = 0; virtual void MakeClumpModel(unsigned short usBaseID) = 0; @@ -249,4 +250,5 @@ class CModelInfo virtual unsigned int GetParentID() = 0; virtual bool IsDynamic() = 0; + virtual bool IsDamageableAtomic() = 0; };