From 3eee671438ac03922af585de5ba369299b9820a9 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sun, 13 Oct 2024 22:38:35 +0300 Subject: [PATCH] Add damageable objects support --- Client/game_sa/CModelInfoSA.cpp | 33 ++++++++++++++++++- Client/game_sa/CModelInfoSA.h | 8 +++++ Client/mods/deathmatch/logic/CClientModel.cpp | 13 ++++++++ Client/mods/deathmatch/logic/CClientModel.h | 1 + .../logic/lua/CLuaFunctionParseHelpers.cpp | 1 + .../logic/luadefs/CLuaEngineDefs.cpp | 3 ++ Client/sdk/game/CModelInfo.h | 2 ++ 7 files changed, 60 insertions(+), 1 deletion(-) diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index 2db97a5245e..08155a17071 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::MakeObjectDamagableModel(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 b261bcc04a1..92c5dcb1cc5 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 MakeObjectDamagableModel(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 795bc08579c..fb4fe1b5ad0 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->MakeObjectDamagableModel(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 903148192d4..759890e0e57 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 64708dea0ca..068e01e51a2 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 7ca02230d51..a6a688c366d 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 08cb032e4ce..0c289b2c2e9 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 MakeObjectDamagableModel(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; };