From f8e7139e9e8c3bacdf71b7ec4bf0f01163e85bfe Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Mon, 18 Dec 2023 03:10:15 +0300 Subject: [PATCH] createBuilding --- Client/game_sa/CBuildingSA.cpp | 18 ++++ Client/game_sa/CBuildingSA.h | 28 ++++++ Client/game_sa/CEntitySA.cpp | 6 ++ Client/game_sa/CEntitySA.h | 1 + Client/game_sa/CFileLoaderSA.cpp | 9 +- Client/game_sa/CFileLoaderSA.h | 6 +- Client/game_sa/CPoolsSA.cpp | 94 ++++++++++++++++++- Client/game_sa/CPoolsSA.h | 30 ++++-- Client/mods/deathmatch/StdInc.h | 2 + .../mods/deathmatch/logic/CClientBuilding.cpp | 53 +++++++++++ .../mods/deathmatch/logic/CClientBuilding.h | 44 +++++++++ .../logic/CClientBuildingManager.cpp | 66 +++++++++++++ .../deathmatch/logic/CClientBuildingManager.h | 41 ++++++++ Client/mods/deathmatch/logic/CClientEntity.h | 2 + .../mods/deathmatch/logic/CClientManager.cpp | 4 + Client/mods/deathmatch/logic/CClientManager.h | 3 + .../deathmatch/logic/lua/CLuaFunctionDefs.cpp | 2 + .../deathmatch/logic/lua/CLuaFunctionDefs.h | 1 + .../logic/lua/CLuaFunctionParseHelpers.h | 4 + .../mods/deathmatch/logic/lua/CLuaManager.cpp | 1 + Client/mods/deathmatch/logic/lua/LuaCommon.h | 1 + .../logic/luadefs/CLuaBuildingDefs.cpp | 51 ++++++++++ .../logic/luadefs/CLuaBuildingDefs.h | 23 +++++ .../deathmatch/logic/luadefs/CLuaDefs.cpp | 2 + .../mods/deathmatch/logic/luadefs/CLuaDefs.h | 1 + Client/sdk/game/CBuilding.h | 24 +++++ Client/sdk/game/CPools.h | 6 ++ .../deathmatch/logic/lua/CLuaFunctionParser.h | 2 - 28 files changed, 508 insertions(+), 17 deletions(-) create mode 100644 Client/game_sa/CBuildingSA.cpp create mode 100644 Client/game_sa/CBuildingSA.h create mode 100644 Client/mods/deathmatch/logic/CClientBuilding.cpp create mode 100644 Client/mods/deathmatch/logic/CClientBuilding.h create mode 100644 Client/mods/deathmatch/logic/CClientBuildingManager.cpp create mode 100644 Client/mods/deathmatch/logic/CClientBuildingManager.h create mode 100644 Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp create mode 100644 Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.h create mode 100644 Client/sdk/game/CBuilding.h diff --git a/Client/game_sa/CBuildingSA.cpp b/Client/game_sa/CBuildingSA.cpp new file mode 100644 index 0000000000..964506dd02 --- /dev/null +++ b/Client/game_sa/CBuildingSA.cpp @@ -0,0 +1,18 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CBuildingSA.cpp + * PURPOSE: Building entity + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include "CBuildingSA.h" + +CBuildingSA::CBuildingSA(CBuildingSAInterface* pInterface) +{ + SetInterface(pInterface); +} diff --git a/Client/game_sa/CBuildingSA.h b/Client/game_sa/CBuildingSA.h new file mode 100644 index 0000000000..6d6794ceb7 --- /dev/null +++ b/Client/game_sa/CBuildingSA.h @@ -0,0 +1,28 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CBuildingSA.h + * PURPOSE: Header file for game building class + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include +#include "CEntitySA.h" + +class CBuildingSAInterface : public CEntitySAInterface +{ +}; +static_assert(sizeof(CBuildingSAInterface) == 0x38, "Invalid size CBuildingSAInterface"); + +class CBuildingSA final : public virtual CBuilding, public virtual CEntitySA +{ +public: + CBuildingSA(CBuildingSAInterface* pInterface); + + CBuildingSAInterface* GetBuildingInterface() { return reinterpret_cast(GetInterface()); }; +}; diff --git a/Client/game_sa/CEntitySA.cpp b/Client/game_sa/CEntitySA.cpp index 4466a53fe4..ad1506abc9 100644 --- a/Client/game_sa/CEntitySA.cpp +++ b/Client/game_sa/CEntitySA.cpp @@ -43,6 +43,12 @@ void CEntitySAInterface::UpdateRpHAnim() ((void(__thiscall*)(CEntitySAInterface*))0x532B20)(this); } +void CEntitySAInterface::AddRect() +{ + typedef void(__thiscall * add_rect_t)(CEntitySAInterface*); + ((add_rect_t)(this->vtbl->Add))(this); +} + CRect* CEntitySAInterface::GetBoundRect_(CRect* pRect) { CColModelSAInterface* colModel = CModelInfoSAInterface::GetModelInfo(m_nModelIndex)->pColModel; diff --git a/Client/game_sa/CEntitySA.h b/Client/game_sa/CEntitySA.h index 101b88a46a..708f0e0aab 100644 --- a/Client/game_sa/CEntitySA.h +++ b/Client/game_sa/CEntitySA.h @@ -191,6 +191,7 @@ class CEntitySAInterface uint8 m_pad0; // 55 + void AddRect(); CRect* GetBoundRect_(CRect* pRect); void TransformFromObjectSpace(CVector& outPosn, CVector const& offset); CVector* GetBoundCentre(CVector* pOutCentre); diff --git a/Client/game_sa/CFileLoaderSA.cpp b/Client/game_sa/CFileLoaderSA.cpp index 5bb8dd1fe0..01372c29bb 100644 --- a/Client/game_sa/CFileLoaderSA.cpp +++ b/Client/game_sa/CFileLoaderSA.cpp @@ -28,6 +28,11 @@ void CFileLoaderSA::StaticSetHooks() HookInstall(0x538690, (DWORD)CFileLoader_LoadObjectInstance, 5); } +CBuildingSAInterface* CFileLoaderSA::LoadFileObjectInstance(SFileObjectInstance* obj) +{ + return ((CBuildingSAInterface * (__cdecl*)(SFileObjectInstance*))0x538090)(obj); +} + class CAtomicModelInfo { public: @@ -201,7 +206,7 @@ RpAtomic* CFileLoader_SetRelatedModelInfoCB(RpAtomic* atomic, SRelatedModelInfo* return atomic; } -CEntitySAInterface* CFileLoader_LoadObjectInstance(const char* szLine) +CBuildingSAInterface* CFileLoader_LoadObjectInstance(const char* szLine) { char szModelName[24]; SFileObjectInstance inst; @@ -217,5 +222,5 @@ CEntitySAInterface* CFileLoader_LoadObjectInstance(const char* szLine) if (fLenSq > 0.0f && std::fabs(fLenSq - 1.0f) > std::numeric_limits::epsilon()) inst.rotation /= std::sqrt(fLenSq); - return ((CEntitySAInterface * (__cdecl*)(SFileObjectInstance*))0x538090)(&inst); + return ((CBuildingSAInterface * (__cdecl*)(SFileObjectInstance*))0x538090)(&inst); } diff --git a/Client/game_sa/CFileLoaderSA.h b/Client/game_sa/CFileLoaderSA.h index f18c7e4633..ad5103c75c 100644 --- a/Client/game_sa/CFileLoaderSA.h +++ b/Client/game_sa/CFileLoaderSA.h @@ -3,7 +3,7 @@ #include "CVector.h" #include "CVector4D.h" -class CEntitySAInterface; +class CBuildingSAInterface; struct RpAtomic; struct RpClump; struct RwStream; @@ -29,9 +29,11 @@ class CFileLoaderSA CFileLoaderSA(); ~CFileLoaderSA(); + CBuildingSAInterface* LoadFileObjectInstance(SFileObjectInstance*); + static void StaticSetHooks(); }; bool CFileLoader_LoadAtomicFile(RwStream* stream, unsigned int modelId); RpAtomic* CFileLoader_SetRelatedModelInfoCB(RpAtomic* atomic, SRelatedModelInfo* pRelatedModelInfo); -CEntitySAInterface* CFileLoader_LoadObjectInstance(const char* szLine); +CBuildingSAInterface* CFileLoader_LoadObjectInstance(const char* szLine); diff --git a/Client/game_sa/CPoolsSA.cpp b/Client/game_sa/CPoolsSA.cpp index 9f3260029d..1c81754862 100644 --- a/Client/game_sa/CPoolsSA.cpp +++ b/Client/game_sa/CPoolsSA.cpp @@ -13,6 +13,7 @@ #include "CBikeSA.h" #include "CBmxSA.h" #include "CBoatSA.h" +#include "CBuildingSA.h" #include "CGameSA.h" #include "CHeliSA.h" #include "CMonsterTruckSA.h" @@ -24,6 +25,7 @@ #include "CTrainSA.h" #include "CWorldSA.h" #include "CKeyGenSA.h" +#include "CFileLoaderSA.h" extern CGameSA* pGame; @@ -33,6 +35,7 @@ CPoolsSA::CPoolsSA() m_ppObjectPoolInterface = (CPoolSAInterface**)0xB7449C; m_ppVehiclePoolInterface = (CPoolSAInterface**)0xB74494; m_ppTxdPoolInterface = (CPoolSAInterface**)0xC8800C; + m_ppBuildingPoolInterface = (CPoolSAInterface**)0xB74498; m_bGetVehicleEnabled = true; } @@ -329,6 +332,83 @@ void CPoolsSA::DeleteAllObjects() } } +////////////////////////////////////////////////////////////////////////////////////////// +// BUILDINGS POOL // +////////////////////////////////////////////////////////////////////////////////////////// + +inline bool CPoolsSA::AddBuildingToPool(CClientBuilding* pClientBuilding, CBuildingSA* pBuilding) +{ + // Grab the new object interface + CBuildingSAInterface* pInterface = pBuilding->GetBuildingInterface(); + + if (!pInterface) + { + return false; + } + else + { + DWORD dwElementIndexInPool = GetBuildingPoolIndex((std::uint8_t*)pInterface); + if (dwElementIndexInPool >= MAX_BUILDINGS) + { + return false; + } + + m_buildingPool.arrayOfClientEntities[dwElementIndexInPool] = {pBuilding, (CClientEntity*)pClientBuilding}; + + // Increase the count of objects + ++m_buildingPool.ulCount; + } + + return true; +} + +CBuilding* CPoolsSA::AddBuilding(class CClientBuilding* pClientBuilding, uint16_t modelId, CVector vPos, CVector4D vRot, uint8_t interior) +{ + CFileLoaderSA loader{}; + + SFileObjectInstance instance; + instance.modelID = modelId; + instance.lod = -1; + instance.interiorID = interior; + instance.position = vPos; + instance.rotation = vRot; + + auto pBuilding = loader.LoadFileObjectInstance(&instance); + + pBuilding->m_pLod = nullptr; + pBuilding->m_iplIndex = 0; + + pBuilding->AddRect(); + + auto pBuildingSA = new CBuildingSA(pBuilding); + + AddBuildingToPool(pClientBuilding, pBuildingSA); + + return pBuildingSA; +} + +void CPoolsSA::RemoveBuilding(CBuilding* pBuilding) +{ + assert(NULL != pBuilding); + + CBuildingSAInterface* pInterface = pBuilding->GetBuildingInterface(); + + DWORD dwElementIndexInPool = GetBuildingPoolIndex((std::uint8_t*)pInterface); + if (dwElementIndexInPool >= MAX_BUILDINGS) + { + return; + } + + auto* pBuildingSA = m_buildingPool.arrayOfClientEntities[dwElementIndexInPool].pEntity; + m_buildingPool.arrayOfClientEntities[dwElementIndexInPool] = {nullptr, nullptr}; + + // Delete it from memory + delete pBuildingSA; + + // Decrease the count of elements in the pool + --m_buildingPool.ulCount; +} + ////////////////////////////////////////////////////////////////////////////////////////// // PEDS POOL // ////////////////////////////////////////////////////////////////////////////////////////// @@ -676,7 +756,7 @@ DWORD CPoolsSA::GetPedPoolIndex(std::uint8_t* pInterface) { return MAX_PEDS; } - return ((pInterface - pTheObjects) / dwAlignedSize); + return ((pInterface - pTheObjects) / dwAlignedSize); } DWORD CPoolsSA::GetVehiclePoolIndex(std::uint8_t* pInterface) @@ -703,6 +783,18 @@ DWORD CPoolsSA::GetObjectPoolIndex(std::uint8_t* pInterface) return ((pInterface - pTheObjects) / dwAlignedSize); } +DWORD CPoolsSA::GetBuildingPoolIndex(std::uint8_t* pInterface) +{ + DWORD dwAlignedSize = 412; + std::uint8_t* pTheObjects = (std::uint8_t*)(*m_ppBuildingPoolInterface)->m_pObjects; + DWORD dwMaxIndex = MAX_BUILDINGS - 1; + if (pInterface < pTheObjects || pInterface > pTheObjects + (dwMaxIndex * dwAlignedSize)) + { + return MAX_BUILDINGS; + } + return ((pInterface - pTheObjects) / dwAlignedSize); +} + uint CPoolsSA::GetModelIdFromClump(RpClump* pRpClump) { // Search our pools for a match diff --git a/Client/game_sa/CPoolsSA.h b/Client/game_sa/CPoolsSA.h index 60f5d549e8..edc404a7bb 100644 --- a/Client/game_sa/CPoolsSA.h +++ b/Client/game_sa/CPoolsSA.h @@ -14,6 +14,7 @@ #include "CPedSA.h" #include "CVehicleSA.h" #include "CObjectSA.h" +#include "CBuildingSA.h" #include "CTextureDictonarySA.h" #define INVALID_POOL_ARRAY_ID 0xFFFFFFFF @@ -170,6 +171,14 @@ class CPoolsSA : public CPools unsigned long GetObjectCount() { return m_objectPool.ulCount; } void DeleteAllObjects(); + // Buildings pool +private: + bool AddBuildingToPool(CClientBuilding* pClientBuilding, CBuildingSA* pBuilding); + +public: + CBuilding* AddBuilding(class CClientBuilding*, uint16_t modelId, CVector vPos, CVector4D vRot, uint8_t interior); + void RemoveBuilding(CBuilding* pBuilding); + // Peds pool CPed* AddPed(CClientPed* pClientPed, unsigned int nModelIndex); CPed* AddPed(CClientPed* pClientPed, DWORD* pGameInterface); @@ -195,6 +204,7 @@ class CPoolsSA : public CPools DWORD GetPedPoolIndex(std::uint8_t* pInterface); DWORD GetVehiclePoolIndex(std::uint8_t* pInterfacee); DWORD GetObjectPoolIndex(std::uint8_t* pInterface); + DWORD GetBuildingPoolIndex(std::uint8_t* pInterface); int GetNumberOfUsedSpaces(ePools pools); int GetPoolDefaultCapacity(ePools pool); @@ -231,16 +241,16 @@ class CPoolsSA : public CPools }; // Pools - typedef SPoolData vehiclePool_t; - typedef SPoolData pedPool_t; - typedef SPoolData objectPool_t; - vehiclePool_t m_vehiclePool; - pedPool_t m_pedPool; - objectPool_t m_objectPool; - CPoolSAInterface** m_ppPedPoolInterface; - CPoolSAInterface** m_ppObjectPoolInterface; - CPoolSAInterface** m_ppVehiclePoolInterface; - CPoolSAInterface** m_ppTxdPoolInterface; + SPoolData m_vehiclePool; + SPoolData m_pedPool; + SPoolData m_objectPool; + SPoolData m_buildingPool; + + CPoolSAInterface** m_ppPedPoolInterface; + CPoolSAInterface** m_ppObjectPoolInterface; + CPoolSAInterface** m_ppVehiclePoolInterface; + CPoolSAInterface** m_ppTxdPoolInterface; + CPoolSAInterface** m_ppBuildingPoolInterface; bool m_bGetVehicleEnabled; }; diff --git a/Client/mods/deathmatch/StdInc.h b/Client/mods/deathmatch/StdInc.h index 0d7cc5168c..68b18a6ab5 100644 --- a/Client/mods/deathmatch/StdInc.h +++ b/Client/mods/deathmatch/StdInc.h @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -143,6 +144,7 @@ #include #include #include +#include #include // Shared includes diff --git a/Client/mods/deathmatch/logic/CClientBuilding.cpp b/Client/mods/deathmatch/logic/CClientBuilding.cpp new file mode 100644 index 0000000000..17621730d6 --- /dev/null +++ b/Client/mods/deathmatch/logic/CClientBuilding.cpp @@ -0,0 +1,53 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * (Shared logic for modifications) + * LICENSE: See LICENSE in the top level directory + * FILE: mods/shared_logic/CClientBuilding.cpp + * PURPOSE: Buildings handling class + * + *****************************************************************************/ + +#include "StdInc.h" + +CClientBuilding::CClientBuilding(class CClientManager* pManager, ElementID ID, uint16_t usModelId, CVector pos, CVector4D rot, uint8_t interior) + : ClassInit(this), + CClientEntity(ID), + m_pBuildingManager(pManager->GetBuildingManager()), + m_usModelId(usModelId), + m_vPos(pos), + m_vRot(rot), + m_interior(interior) +{ + m_pBuilding = nullptr; + m_pManager = pManager; + SetTypeName("building"); + m_pBuildingManager->AddToList(this); + Create(); +} + +CClientBuilding::~CClientBuilding() +{ + m_pBuildingManager->RemoveFromList(this); + if (m_pBuilding) + { + Destroy(); + } +} + +void CClientBuilding::Create() +{ + if (m_pBuilding) + return; + + m_pBuilding = g_pGame->GetPools()->AddBuilding(this, m_usModelId, m_vPos, m_vRot, m_interior); +} + +void CClientBuilding::Destroy() +{ + if (m_pBuilding) + { + g_pGame->GetPools()->RemoveBuilding(m_pBuilding); + m_pBuilding = nullptr; + } +} diff --git a/Client/mods/deathmatch/logic/CClientBuilding.h b/Client/mods/deathmatch/logic/CClientBuilding.h new file mode 100644 index 0000000000..7ff5e76885 --- /dev/null +++ b/Client/mods/deathmatch/logic/CClientBuilding.h @@ -0,0 +1,44 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * (Shared logic for modifications) + * LICENSE: See LICENSE in the top level directory + * FILE: mods/shared_logic/CClientBuilding.h + * PURPOSE: Physical object entity class + * + *****************************************************************************/ + +class CClientBuilding; + +#pragma once + +#include + +class CClientBuilding : public CClientEntity +{ + DECLARE_CLASS(CClientBuilding, CClientEntity) + friend class CClientBuildingManager; + +public: + CClientBuilding(class CClientManager* pManager, ElementID ID, uint16_t usModelId, CVector pos, CVector4D rot, uint8_t interior); + ~CClientBuilding(); + + void Unlink(){}; + void GetPosition(CVector& vecPosition) const { vecPosition = m_vPos; }; + void SetPosition(const CVector& vecPosition) { m_vPos = vecPosition; }; + + eClientEntityType GetType() const { return CCLIENTBUILDING; } + +private: + void Create(); + void Destroy(); + +private: + CClientBuildingManager* m_pBuildingManager; + + CBuilding* m_pBuilding; + uint16_t m_usModelId; + CVector m_vPos; + CVector4D m_vRot; + uint8_t m_interior; +}; diff --git a/Client/mods/deathmatch/logic/CClientBuildingManager.cpp b/Client/mods/deathmatch/logic/CClientBuildingManager.cpp new file mode 100644 index 0000000000..fb9a512ff2 --- /dev/null +++ b/Client/mods/deathmatch/logic/CClientBuildingManager.cpp @@ -0,0 +1,66 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * (Shared logic for modifications) + * LICENSE: See LICENSE in the top level directory + * FILE: mods/shared_logic/CClientBuildingManager.cpp + * PURPOSE: Building manager class + * + *****************************************************************************/ + +#include "StdInc.h" + +CClientBuildingManager::CClientBuildingManager(CClientManager* pManager) +{ + // Init + m_bRemoveFromList = true; +} + +CClientBuildingManager::~CClientBuildingManager() +{ + // Delete all our buildings + RemoveAll(); +} + +void CClientBuildingManager::RemoveAll() +{ + // Make sure they don't remove themselves from our list + m_bRemoveFromList = false; + + // Run through our list deleting the buildings + auto iter = m_List.begin(); + for (; iter != m_List.end(); iter++) + { + delete *iter; + } + + // Allow list removal again + m_bRemoveFromList = true; +} + +bool CClientBuildingManager::Exists(CClientBuilding* pBuilding) +{ + // Matches given DFF? + auto iter = m_List.begin(); + for (; iter != m_List.end(); iter++) + { + // Match? + if (pBuilding == *iter) + { + // It exists + return true; + } + } + + // It doesn't + return false; +} + +void CClientBuildingManager::RemoveFromList(CClientBuilding* pBuilding) +{ + // Can we remove anything from the list? + if (m_bRemoveFromList) + { + m_List.remove(pBuilding); + } +} diff --git a/Client/mods/deathmatch/logic/CClientBuildingManager.h b/Client/mods/deathmatch/logic/CClientBuildingManager.h new file mode 100644 index 0000000000..dd595d3cb3 --- /dev/null +++ b/Client/mods/deathmatch/logic/CClientBuildingManager.h @@ -0,0 +1,41 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * (Shared logic for modifications) + * LICENSE: See LICENSE in the top level directory + * FILE: mods/shared_logic/CClientBuildingManager.h + * PURPOSE: Building manager class + * + *****************************************************************************/ + +class CClientBuildingManager; + +#pragma once + +#include +#include "CClientBuilding.h" + +class CClientBuildingManager +{ + friend class CClientBuilding; + +public: + CClientBuildingManager(class CClientManager* pManager); + ~CClientBuildingManager(); + + void RemoveAll(); + bool Exists(CClientBuilding* pBuilding); + + std::list::const_iterator IterBegin() { return m_List.begin(); } + std::list::const_iterator IterEnd() { return m_List.end(); } + +private: + void AddToList(CClientBuilding* pBuilding) { m_List.push_back(pBuilding); } + void RemoveFromList(CClientBuilding* pBuilding); + + class CClientObjectManager* m_pObjectManager; + class CClientVehicleManager* m_pVehicleManager; + + std::list m_List; + bool m_bRemoveFromList; +}; diff --git a/Client/mods/deathmatch/logic/CClientEntity.h b/Client/mods/deathmatch/logic/CClientEntity.h index bd60dab3ba..0d84526d8b 100644 --- a/Client/mods/deathmatch/logic/CClientEntity.h +++ b/Client/mods/deathmatch/logic/CClientEntity.h @@ -79,6 +79,7 @@ enum eClientEntityType CCLIENTVECTORGRAPHIC, CCLIENTUNKNOWN, CCLIENTIMG, + CCLIENTBUILDING, }; class CEntity; @@ -143,6 +144,7 @@ enum eCClientEntityClassTypes CLASS_CClientPointLights, CLASS_CClientSearchLight, CLASS_CClientIMG, + CLASS_CClientBuilding, }; class CClientEntity : public CClientEntityBase diff --git a/Client/mods/deathmatch/logic/CClientManager.cpp b/Client/mods/deathmatch/logic/CClientManager.cpp index 21962cc8f3..e3a808555b 100644 --- a/Client/mods/deathmatch/logic/CClientManager.cpp +++ b/Client/mods/deathmatch/logic/CClientManager.cpp @@ -54,6 +54,7 @@ CClientManager::CClientManager() m_pModelManager = new CClientModelManager(); m_pPacketRecorder = new CClientPacketRecorder(this); m_pImgManager = new CClientIMGManager(this); + m_pBuildingManager = new CClientBuildingManager(this); m_bBeingDeleted = false; m_bGameUnloadedFlag = false; @@ -177,6 +178,9 @@ CClientManager::~CClientManager() delete m_pImgManager; m_pImgManager = nullptr; + + delete m_pBuildingManager; + m_pBuildingManager = nullptr; } // diff --git a/Client/mods/deathmatch/logic/CClientManager.h b/Client/mods/deathmatch/logic/CClientManager.h index e916c8eb73..92f8481db8 100644 --- a/Client/mods/deathmatch/logic/CClientManager.h +++ b/Client/mods/deathmatch/logic/CClientManager.h @@ -43,6 +43,7 @@ class CClientManager; #include "CClientPointLightsManager.h" #include "CClientModelManager.h" #include "CClientIMGManager.h" +#include "CClientBuildingManager.h" class CClientProjectileManager; class CClientExplosionManager; @@ -96,6 +97,7 @@ class CClientManager CClientEffectManager* GetEffectManager() { return m_pEffectManager; } CClientPointLightsManager* GetPointLightsManager() { return m_pPointLightsManager; } CClientIMGManager* GetIMGManager() { return m_pImgManager; } + CClientBuildingManager* GetBuildingManager() { return m_pBuildingManager; } bool IsGameLoaded() { return g_pGame->GetSystemState() == 9 && !m_bGameUnloadedFlag && g_pCore->GetNetwork()->GetServerBitStreamVersion(); } bool IsBeingDeleted() { return m_bBeingDeleted; } @@ -148,6 +150,7 @@ class CClientManager CClientModelManager* m_pModelManager; CClientIMGManager* m_pImgManager; CClientPacketRecorder* m_pPacketRecorder; + CClientBuildingManager* m_pBuildingManager; bool m_bBeingDeleted; bool m_bGameUnloadedFlag; int m_iNumLowLODElements; diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.cpp index 912fd99f66..feb2bdf058 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.cpp @@ -31,6 +31,7 @@ CClientDFFManager* CLuaFunctionDefs::m_pDFFManager; CClientColModelManager* CLuaFunctionDefs::m_pColModelManager; CRegisteredCommands* CLuaFunctionDefs::m_pRegisteredCommands; CClientIMGManager* CLuaFunctionDefs::m_pImgManager; +CClientBuildingManager* CLuaFunctionDefs::m_pBuildingManager; void CLuaFunctionDefs::Initialize(CLuaManager* pLuaManager, CScriptDebugging* pScriptDebugging, CClientGame* pClientGame) { @@ -55,4 +56,5 @@ void CLuaFunctionDefs::Initialize(CLuaManager* pLuaManager, CScriptDebugging* pS m_pColModelManager = m_pManager->GetColModelManager(); m_pRegisteredCommands = m_pClientGame->GetRegisteredCommands(); m_pImgManager = m_pManager->GetIMGManager(); + m_pBuildingManager = m_pManager->GetBuildingManager(); } diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.h b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.h index 1681110616..105754152f 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.h +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.h @@ -139,4 +139,5 @@ class CLuaFunctionDefs static CClientColModelManager* m_pColModelManager; static CRegisteredCommands* m_pRegisteredCommands; static CClientIMGManager* m_pImgManager; + static CClientBuildingManager* m_pBuildingManager; }; diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h index 5688c78d34..7f0b98c679 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h @@ -272,6 +272,10 @@ inline SString GetClassTypeName(CClientIMG*) { return "img"; } +inline SString GetClassTypeName(CClientBuilding*) +{ + return "building"; +} inline SString GetClassTypeName(CClientSound*) { return "sound"; diff --git a/Client/mods/deathmatch/logic/lua/CLuaManager.cpp b/Client/mods/deathmatch/logic/lua/CLuaManager.cpp index 33388a5edc..c2a28809af 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaManager.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaManager.cpp @@ -280,4 +280,5 @@ void CLuaManager::LoadCFunctions() CLuaXMLDefs::LoadFunctions(); CLuaClientDefs::LoadFunctions(); CLuaDiscordDefs::LoadFunctions(); + CLuaBuildingDefs::LoadFunctions(); } diff --git a/Client/mods/deathmatch/logic/lua/LuaCommon.h b/Client/mods/deathmatch/logic/lua/LuaCommon.h index 238cfeeed5..20dda7ff11 100644 --- a/Client/mods/deathmatch/logic/lua/LuaCommon.h +++ b/Client/mods/deathmatch/logic/lua/LuaCommon.h @@ -38,6 +38,7 @@ class CClientRadarMarker; class CClientTeam; class CClientTXD; class CClientIMG; +class CClientBuilding; class CClientVehicle; class CClientWater; class CClientWeapon; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp new file mode 100644 index 0000000000..1015fc453c --- /dev/null +++ b/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp @@ -0,0 +1,51 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include + +void CLuaBuildingDefs::LoadFunctions() +{ + // Backwards compatibility functions + constexpr static const std::pair functions[]{ + {"createBuilding", ArgumentParser}, + }; + + // Add functions + for (const auto& [name, func] : functions) + CLuaCFunctions::AddFunction(name, func); +} + +void CLuaBuildingDefs::AddClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "createBuilding"); + + lua_registerclass(luaVM, "Building"); +} + +CClientBuilding* CLuaBuildingDefs::CreateBuilding(lua_State* const luaVM, uint16_t modelId, CVector pos, CVector4D rot, uint8_t interior) +{ + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + + // Get the resource we belong to + CResource* pResource = pLuaMain->GetResource(); + if (!pResource) + return false; + + // Grab the resource root entity + CClientEntity* pRoot = pResource->GetResourceDynamicEntity(); + // Create the img handle + CClientBuilding* pBuilding = new CClientBuilding(m_pManager, INVALID_ELEMENT_ID, modelId, pos, rot, interior); + + pBuilding->SetParent(pRoot); + + return pBuilding; +} diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.h new file mode 100644 index 0000000000..f158f22587 --- /dev/null +++ b/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.h @@ -0,0 +1,23 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.x + * LICENSE: See LICENSE in the top level directory + * FILE: mods/shared_logic/luadefs/CLuaBuildingDefs.h + * PURPOSE: Lua building definitions class header + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once +#include "CLuaDefs.h" + +class CLuaBuildingDefs : public CLuaDefs +{ +public: + static void LoadFunctions(); + static void AddClass(lua_State* luaVM); + + // Buiding create funcs + static CClientBuilding* CreateBuilding(lua_State* const luaVM, uint16_t modelId, CVector pos, CVector4D rot, uint8_t interior = 0); +}; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaDefs.cpp index de07ea84a4..457f72998f 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDefs.cpp @@ -31,6 +31,7 @@ CClientDFFManager* CLuaDefs::m_pDFFManager = NULL; CClientColModelManager* CLuaDefs::m_pColModelManager = NULL; CRegisteredCommands* CLuaDefs::m_pRegisteredCommands = NULL; CClientIMGManager* CLuaDefs::m_pImgManager = NULL; +CClientBuildingManager* CLuaDefs::m_pBuildingManager = nullptr; bool ms_bRegisterdPostCallHook = false; void CLuaDefs::Initialize(CClientGame* pClientGame, CLuaManager* pLuaManager, CScriptDebugging* pScriptDebugging) @@ -56,6 +57,7 @@ void CLuaDefs::Initialize(CClientGame* pClientGame, CLuaManager* pLuaManager, CS m_pColModelManager = m_pManager->GetColModelManager(); m_pRegisteredCommands = pClientGame->GetRegisteredCommands(); m_pImgManager = m_pManager->GetIMGManager(); + m_pBuildingManager = m_pManager->GetBuildingManager(); } int CLuaDefs::CanUseFunction(lua_CFunction f, lua_State* luaVM) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaDefs.h index cf043b4572..3f3c18386f 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDefs.h @@ -65,6 +65,7 @@ class CLuaDefs static CClientColModelManager* m_pColModelManager; static CRegisteredCommands* m_pRegisteredCommands; static CClientIMGManager* m_pImgManager; + static CClientBuildingManager* m_pBuildingManager; protected: // Old style: Only warn on failure. This should diff --git a/Client/sdk/game/CBuilding.h b/Client/sdk/game/CBuilding.h new file mode 100644 index 0000000000..8cbaf6abb4 --- /dev/null +++ b/Client/sdk/game/CBuilding.h @@ -0,0 +1,24 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: sdk/game/CBuilding.h + * PURPOSE: Physical entity interface + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include "CEntity.h" + +class CBuildingSAInterface; + +class CBuilding : public virtual CEntity +{ +public: + virtual ~CBuilding(){}; + + virtual CBuildingSAInterface* GetBuildingInterface() = 0; +}; diff --git a/Client/sdk/game/CPools.h b/Client/sdk/game/CPools.h index 76a39d9989..44cf5bf8fd 100644 --- a/Client/sdk/game/CPools.h +++ b/Client/sdk/game/CPools.h @@ -18,6 +18,8 @@ class CObject; class CObjectSA; class CPed; class CPedSA; +class CBuilding; +class CBuildingSA; class CVector; class CVehicle; class CVehicleSA; @@ -82,6 +84,10 @@ class CPools virtual CPed* GetPedFromRef(DWORD dwGameRef) = 0; virtual unsigned long GetPedCount() = 0; + // Buildings pool + virtual CBuilding* AddBuilding(class CClientBuilding*, uint16_t modelId, CVector vPos, CVector4D vRot, uint8_t interior) = 0; + virtual void RemoveBuilding(CBuilding* pObject) = 0; + // Others virtual CVehicle* AddTrain(class CClientVehicle* pClientVehicle, CVector* vecPosition, DWORD dwModels[], int iSize, bool iDirection, uchar ucTrackId = 0xFF) = 0; diff --git a/Shared/mods/deathmatch/logic/lua/CLuaFunctionParser.h b/Shared/mods/deathmatch/logic/lua/CLuaFunctionParser.h index db8056763d..686a855deb 100644 --- a/Shared/mods/deathmatch/logic/lua/CLuaFunctionParser.h +++ b/Shared/mods/deathmatch/logic/lua/CLuaFunctionParser.h @@ -588,8 +588,6 @@ struct CLuaFunctionParserBase // A vector3 may also be filled from a vector4 if (CLuaVector4D* pVec4D = cast((CLuaVector4D*)0); pVec4D != nullptr) return *pVec4D; - if (CLuaMatrix* pMatrix = cast((CLuaMatrix*)0); pMatrix != nullptr) - return *pMatrix; // Subtract one from the index, as the call to lua::PopPrimitive above increments the index, even if the // underlying element is of a wrong type