diff --git a/Client/game_sa/CDynamicPool.h b/Client/game_sa/CDynamicPool.h new file mode 100644 index 0000000000..8a6d0a7433 --- /dev/null +++ b/Client/game_sa/CDynamicPool.h @@ -0,0 +1,178 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CDynamicPool.h + * PURPOSE: Custom implementation for SA pools + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include +#include +#include + +template +class CDynamicPoolPart +{ +public: + explicit CDynamicPoolPart(std::size_t size) : m_size{size} + { + m_items = std::make_unique(size); + m_unusedIndices.reserve(size); + for (std::size_t i = 0; i < size; i++) + m_unusedIndices.push_back(i); + } + + PoolObjT* AllocateItem() + { + std::size_t index = m_unusedIndices.back(); + m_unusedIndices.pop_back(); + return &m_items[index]; + } + + void RemoveItem(PoolObjT* item) + { + auto pos = item - m_items.get(); + m_unusedIndices.push_back(pos); + } + + bool OwnsItem(PoolObjT* item) const noexcept { return item >= m_items.get() && item < m_items.get() + m_size; } + bool HasFreeSize() const noexcept { return m_unusedIndices.size() != 0; } + std::size_t GetCapacity() const noexcept { return m_size; } + std::size_t GetUsedSize() const noexcept { return m_size - m_unusedIndices.size(); } + +private: + std::unique_ptr m_items; + std::vector m_unusedIndices; + const std::size_t m_size; +}; + +template +struct PoolGrowAddStrategy +{ + static constexpr std::size_t GetInitialSize() { return InitialSize; } + static constexpr std::size_t GetNextSize(std::size_t index) { return AddSize; } +}; + +template +class CDynamicPool +{ +public: + CDynamicPool() + { + constexpr size_t initialSize = GrowStrategy::GetInitialSize(); + m_poolParts.emplace_back(initialSize); + } + + PoolObjT* AllocateItem() + { + for (auto& pool : m_poolParts) + { + if (pool.HasFreeSize()) + return pool.AllocateItem(); + } + + try + { + return AllocateNewPart().AllocateItem(); + } + catch (const std::bad_alloc&) + { + assert(false && "Could not allocate a memory for CDynamicPoolPart"); + } + } + + void RemoveItem(PoolObjT* item) + { + for (auto& pool : m_poolParts) + { + if (pool.OwnsItem(item)) + { + pool.RemoveItem(item); + return; + } + } + + assert(false && "Invalid item for CDynamicPool::RemoveItem"); + } + + std::size_t GetCapacity() const noexcept + { + std::size_t size = 0; + for (auto& pool : m_poolParts) + size += pool.GetCapacity(); + + return size; + } + + std::size_t GetUsedSize() const noexcept + { + std::size_t size = 0; + for (auto& pool : m_poolParts) + size += pool.GetUsedSize(); + + return size; + } + + bool SetCapacity(std::size_t newSize) { + if (newSize == 0) + return false; + + std::size_t currentSize = GetCapacity(); + + if (currentSize == newSize) + return false; + else if (currentSize < newSize) + { + // Grow + while (currentSize < newSize) + { + try + { + auto& nextPart = AllocateNewPart(); + currentSize += nextPart.GetCapacity(); + } + catch (const std::bad_alloc&) + { + return false; + } + } + } + else + { + // Shrink + while (true) + { + auto& part = m_poolParts.back(); + if (part.GetUsedSize() != 0) + return false; + + currentSize -= part.GetCapacity(); + if (currentSize < newSize) + return false; + + m_poolParts.pop_back(); + + if (currentSize == newSize) + return true; + } + } + + return true; + } + +private: + CDynamicPoolPart& AllocateNewPart() + { + const std::size_t nextSize = GrowStrategy::GetNextSize(m_poolParts.size()); + m_poolParts.emplace_back(nextSize); + return m_poolParts.back(); + } + +private: + std::list> m_poolParts; +}; diff --git a/Client/game_sa/CGameSA.cpp b/Client/game_sa/CGameSA.cpp index 744993584e..49992830d9 100644 --- a/Client/game_sa/CGameSA.cpp +++ b/Client/game_sa/CGameSA.cpp @@ -59,6 +59,7 @@ #include "CIplStoreSA.h" #include "CBuildingRemovalSA.h" #include "CCheckpointSA.h" +#include "CPtrNodeSingleLinkPoolSA.h" extern CGameSA* pGame; @@ -245,6 +246,7 @@ CGameSA::CGameSA() CVehicleSA::StaticSetHooks(); CCheckpointSA::StaticSetHooks(); CHudSA::StaticSetHooks(); + CPtrNodeSingleLinkPoolSA::StaticSetHooks(); } catch (const std::bad_alloc& e) { diff --git a/Client/game_sa/CPoolsSA.cpp b/Client/game_sa/CPoolsSA.cpp index 6d926ecfc8..d5f86f6fea 100644 --- a/Client/game_sa/CPoolsSA.cpp +++ b/Client/game_sa/CPoolsSA.cpp @@ -900,8 +900,7 @@ int CPoolsSA::GetPoolCapacity(ePools pool) iPtr = 0x550F82; break; case POINTER_SINGLE_LINK_POOL: - iPtr = 0x550F46; - break; + return GetPtrNodeSingleLinkPool().GetCapacity(); case ENV_MAP_MATERIAL_POOL: iPtr = 0x5DA08E; break; @@ -1067,9 +1066,7 @@ int CPoolsSA::GetNumberOfUsedSpaces(ePools pool) dwThis = CLASS_CPtrNodeDoubleLinkPool; break; case POINTER_SINGLE_LINK_POOL: - dwFunc = FUNC_CPtrNodeSingleLinkPool_GetNoOfUsedSpaces; - dwThis = CLASS_CPtrNodeSingleLinkPool; - break; + return GetPtrNodeSingleLinkPool().GetUsedSize(); default: return -1; } diff --git a/Client/game_sa/CPoolsSA.h b/Client/game_sa/CPoolsSA.h index e190c2fbd6..072f893d30 100644 --- a/Client/game_sa/CPoolsSA.h +++ b/Client/game_sa/CPoolsSA.h @@ -18,6 +18,7 @@ #include "CBuildingsPoolSA.h" #include "CDummyPoolSA.h" #include "CTxdPoolSA.h" +#include "CPtrNodeSingleLinkPoolSA.h" #define INVALID_POOL_ARRAY_ID 0xFFFFFFFF @@ -97,6 +98,7 @@ class CPoolsSA : public CPools CBuildingsPool& GetBuildingsPool() noexcept override { return m_BuildingsPool; }; CDummyPool& GetDummyPool() noexcept { return m_DummyPool; }; CTxdPool& GetTxdPool() noexcept { return m_TxdPool; }; + CPtrNodeSingleLinkPool& GetPtrNodeSingleLinkPool() noexcept override { return m_PtrNodeSingleLinkPool; }; private: // Pools @@ -111,6 +113,7 @@ class CPoolsSA : public CPools CBuildingsPoolSA m_BuildingsPool; CDummyPoolSA m_DummyPool; CTxdPoolSA m_TxdPool; + CPtrNodeSingleLinkPoolSA m_PtrNodeSingleLinkPool; bool m_bGetVehicleEnabled; }; diff --git a/Client/game_sa/CPtrNodeSingleLinkPoolSA.cpp b/Client/game_sa/CPtrNodeSingleLinkPoolSA.cpp new file mode 100644 index 0000000000..6bed46f048 --- /dev/null +++ b/Client/game_sa/CPtrNodeSingleLinkPoolSA.cpp @@ -0,0 +1,68 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CPtrNodeSingleLinkPoolSA.cpp + * PURPOSE: Custom implementation for the CPtrNodeSingleLinkPool pool + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include "CPtrNodeSingleLinkPoolSA.h" + +CPtrNodeSingleLinkPoolSA::pool_t* CPtrNodeSingleLinkPoolSA::m_customPool = nullptr; + +CPtrNodeSingleLinkPoolSA::CPtrNodeSingleLinkPoolSA() +{ + if (!m_customPool) + m_customPool = new CPtrNodeSingleLinkPoolSA::pool_t(); +} + +constexpr std::uint32_t HOOKPOS_SingleLinkNodeConstructor = 0x552380; +constexpr std::size_t HOOKSIZE_SingleLinkNodeConstructor = 6; +static CPtrNodeSingleLinkPoolSA::pool_item_t* __cdecl HOOK_SingleLinkNodeConstructor() +{ + return CPtrNodeSingleLinkPoolSA::GetPoolInstance()->AllocateItem(); +} + +constexpr std::uint32_t HOOKPOS_SingleLinkNodeDestructor = 0x552390; +constexpr std::size_t HOOKSIZE_SingleLinkNodeDestructor = 6; +static CPtrNodeSingleLinkPoolSA::pool_item_t* __cdecl HOOK_SingleLinkNodeDestructor(CPtrNodeSingleLinkPoolSA::pool_item_t* item) +{ + CPtrNodeSingleLinkPoolSA::GetPoolInstance()->RemoveItem(item); + // The game doesen't use the return value + return item; +} + +// Replace pool->RemoveItem here +constexpr std::uint32_t HOOKPOS_CPtrListSingleLink_Flush = 0x55243B; +constexpr std::size_t HOOKSIZE_CPtrListSingleLink_Flush = 6; +constexpr std::uint32_t CONTINUE_CPtrListSingleLink_Flush = 0x55245B; +static void _declspec(naked) HOOK_CPtrListSingleLink_Flush() +{ + __asm { + mov edi, ecx ; save register + + ; CPtrNodeSingleLinkPoolSA::m_customPool->RemoveItem(eax) + + mov ecx, CPtrNodeSingleLinkPoolSA::m_customPool + push eax + call CPtrNodeSingleLinkPoolSA::pool_t::RemoveItem + + mov ecx, edi ; restore + jmp CONTINUE_CPtrListSingleLink_Flush + } +} + +void CPtrNodeSingleLinkPoolSA::StaticSetHooks() +{ + EZHookInstall(SingleLinkNodeConstructor); + EZHookInstall(SingleLinkNodeDestructor); + EZHookInstall(CPtrListSingleLink_Flush); + + // Skip the original pool initialization + MemCpy((void*)0x550F26, "\xEB\x2D", 2); +} + diff --git a/Client/game_sa/CPtrNodeSingleLinkPoolSA.h b/Client/game_sa/CPtrNodeSingleLinkPoolSA.h new file mode 100644 index 0000000000..afc760d0e1 --- /dev/null +++ b/Client/game_sa/CPtrNodeSingleLinkPoolSA.h @@ -0,0 +1,37 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CPtrNodeSingleLinkPoolSA.h + * PURPOSE: Custom implementation for the CPtrNodeSingleLinkPool pool + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include "CPoolSAInterface.h" +#include "CDynamicPool.h" +#include "CPtrNodeSingleListSA.h" +#include + +class CPtrNodeSingleLinkPoolSA final : public CPtrNodeSingleLinkPool +{ +public: + using pool_item_t = CPtrNodeSingleLink; + using pool_t = CDynamicPool>; + + CPtrNodeSingleLinkPoolSA(); + + std::size_t GetCapacity() const override { return m_customPool->GetCapacity(); } + std::size_t GetUsedSize() const override { return m_customPool->GetUsedSize(); } + + bool Resize(std::size_t newSize) override { return m_customPool->SetCapacity(newSize); }; + void ResetCapacity() override { m_customPool->SetCapacity(MAX_POINTER_SINGLE_LINKS); }; + + static auto* GetPoolInstance() { return m_customPool; } + static void StaticSetHooks(); +private: + static pool_t* m_customPool; +}; diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index b233e578ab..b8a89c1109 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -515,6 +515,7 @@ CClientGame::~CClientGame() g_pGame->SetPreWeaponFireHandler(NULL); g_pGame->SetPostWeaponFireHandler(NULL); g_pGame->SetTaskSimpleBeHitHandler(NULL); + g_pGame->GetPools()->GetPtrNodeSingleLinkPool().ResetCapacity(); g_pGame->GetAudioEngine()->SetWorldSoundHandler(NULL); g_pCore->SetMessageProcessor(NULL); g_pCore->GetKeyBinds()->SetKeyStrokeHandler(NULL); diff --git a/Client/mods/deathmatch/logic/CClientObjectManager.cpp b/Client/mods/deathmatch/logic/CClientObjectManager.cpp index 45cc2a0408..c59483b4db 100644 --- a/Client/mods/deathmatch/logic/CClientObjectManager.cpp +++ b/Client/mods/deathmatch/logic/CClientObjectManager.cpp @@ -230,22 +230,7 @@ void CClientObjectManager::OnDestruction(CClientObject* pObject) void CClientObjectManager::UpdateLimitInfo() { m_iEntryInfoNodeEntries = g_pMultiplayer->EntryInfoNodePool_NoOfUsedSpaces(); - m_iPointerNodeSingleLinkEntries = g_pMultiplayer->PtrNodeSingleLinkPool_NoOfUsedSpaces(); m_iPointerNodeDoubleLinkEntries = g_pMultiplayer->PtrNodeDoubleLinkPool_NoOfUsedSpaces(); - - /* - CPools* pPools = g_pGame->GetPools(); - unsigned int nEntryInfoNodeEntries = pPools->GetEntryInfoNodePool()->GetNumberOfUsedSpaces(); - unsigned int nPointerNodeSingleLinkEntries = pPools->GetPointerNodeSingleLinkPool()->GetNumberOfUsedSpaces(); - unsigned int nPointerNodeDoubleLinkEntries = pPools->GetPointerNodeDoubleLinkPool()->GetNumberOfUsedSpaces(); - - g_pCore->ChatPrintf("%d = %d ### %d = %d ### %d = %d", false, nEntryInfoNodeEntries, m_iEntryInfoNodeEntries, nPointerNodeSingleLinkEntries, - m_iPointerNodeSingleLinkEntries, nPointerNodeDoubleLinkEntries, m_iPointerNodeDoubleLinkEntries); - - assert(nEntryInfoNodeEntries == m_iEntryInfoNodeEntries); - assert(nPointerNodeSingleLinkEntries == m_iPointerNodeSingleLinkEntries); - assert(nPointerNodeDoubleLinkEntries == m_iPointerNodeDoubleLinkEntries); - */ } bool CClientObjectManager::StaticIsObjectLimitReached() @@ -278,8 +263,7 @@ bool CClientObjectManager::IsHardObjectLimitReached() return true; // If we've run out of either of these limit, don't allow more objects - if (m_iEntryInfoNodeEntries >= MAX_ENTRY_INFO_NODES_MTA || m_iPointerNodeSingleLinkEntries >= MAX_POINTER_SINGLE_LINKS_MTA || - m_iPointerNodeDoubleLinkEntries >= MAX_POINTER_DOUBLE_LINKS_MTA) + if (m_iEntryInfoNodeEntries >= MAX_ENTRY_INFO_NODES_MTA || m_iPointerNodeDoubleLinkEntries >= MAX_POINTER_DOUBLE_LINKS_MTA) { if (!m_bDoneLimitWarning) { @@ -287,9 +271,8 @@ bool CClientObjectManager::IsHardObjectLimitReached() SString strMessage( "CClientObjectManager reached limit -" " ENTRY_INFO_NODES:%d/%d" - " POINTER_SINGLE_LINKS:%d/%d" " POINTER_DOUBLE_LINKS:%d/%d", - m_iEntryInfoNodeEntries, MAX_ENTRY_INFO_NODES_MTA, m_iPointerNodeSingleLinkEntries, MAX_POINTER_SINGLE_LINKS_MTA, + m_iEntryInfoNodeEntries, MAX_ENTRY_INFO_NODES_MTA, m_iPointerNodeDoubleLinkEntries, MAX_POINTER_DOUBLE_LINKS_MTA); g_pCore->GetConsole()->Echo(strMessage); AddReportLog(7430, strMessage); diff --git a/Client/mods/deathmatch/logic/CClientObjectManager.h b/Client/mods/deathmatch/logic/CClientObjectManager.h index 113e33db9b..7be7aa70ab 100644 --- a/Client/mods/deathmatch/logic/CClientObjectManager.h +++ b/Client/mods/deathmatch/logic/CClientObjectManager.h @@ -56,7 +56,6 @@ class CClientObjectManager void UpdateLimitInfo(); int m_iEntryInfoNodeEntries; - int m_iPointerNodeSingleLinkEntries; int m_iPointerNodeDoubleLinkEntries; uint m_uiMaxStreamedInCount; uint m_uiMaxLowLodStreamedInCount; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index a6a688c366..0ad88113b1 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "CLuaEngineDefs.h" @@ -2505,6 +2506,10 @@ bool CLuaEngineDefs::EngineSetPoolCapacity(lua_State* luaVM, ePools pool, size_t { return m_pBuildingManager->SetPoolCapacity(newSize); } + case ePools::POINTER_SINGLE_LINK_POOL: + { + return g_pGame->GetPools()->GetPtrNodeSingleLinkPool().Resize(newSize); + } default: throw std::invalid_argument("Can not change this pool capacity"); } diff --git a/Client/multiplayer_sa/CMultiplayerSA.h b/Client/multiplayer_sa/CMultiplayerSA.h index 0dd642cb4b..b4339fae47 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.h +++ b/Client/multiplayer_sa/CMultiplayerSA.h @@ -354,7 +354,6 @@ class CMultiplayerSA : public CMultiplayer DWORD GetLastAnimArrayAddress() { return m_dwLastAnimArrayAddress; } unsigned int EntryInfoNodePool_NoOfUsedSpaces() const noexcept override; - unsigned int PtrNodeSingleLinkPool_NoOfUsedSpaces() const noexcept override; unsigned int PtrNodeDoubleLinkPool_NoOfUsedSpaces() const noexcept override; CVector m_vecAkimboTarget; diff --git a/Client/multiplayer_sa/CMultiplayerSA_ObjectStreamerOptimization.cpp b/Client/multiplayer_sa/CMultiplayerSA_ObjectStreamerOptimization.cpp index 2fb73247c3..976eefb98b 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_ObjectStreamerOptimization.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_ObjectStreamerOptimization.cpp @@ -11,7 +11,6 @@ #include "StdInc.h" static unsigned int CEntryInfoNodePool_UsedSpaces = 0; -static unsigned int CPtrNodeSingleLinkPool_UsedSpaces = 0; static unsigned int CPtrNodeDoubleLinkPool_UsedSpaces = 0; #define HOOKPOS_CEntryInfoNodePool__New 0x536D6E @@ -55,46 +54,6 @@ static void _declspec(naked) HOOK_CEntryInfoList__Flush() } } -#define HOOKPOS_CPtrNodeSingleLinkPool__New 0x55229B -#define HOOKSIZE_CPtrNodeSingleLinkPool__New 0x5 -static void _declspec(naked) HOOK_CPtrNodeSingleLinkPool__New() -{ - _asm { - inc CPtrNodeSingleLinkPool_UsedSpaces - - lea eax, [ecx+eax*8] - pop esi - ret - } -} -#define HOOKPOS_CPtrNodeSingleLink__operator_delete 0x5523AA -#define HOOKSIZE_CPtrNodeSingleLink__operator_delete 0x5 -static const unsigned int RETURN_CPtrNodeSingleLink__operator_delete = 0x5523AF; -static void _declspec(naked) HOOK_CPtrNodeSingleLink__operator_delete() -{ - _asm { - dec CPtrNodeSingleLinkPool_UsedSpaces - - or bl, 0x80 - mov [ecx], bl - jmp RETURN_CPtrNodeSingleLink__operator_delete - } -} - -#define HOOKPOS_CPtrListSingleLink__Flush 0x55244D -#define HOOKSIZE_CPtrListSingleLink__Flush 0x6 -static const unsigned int RETURN_CPtrListSingleLink__Flush = 0x552453; -static void _declspec(naked) HOOK_CPtrListSingleLink__Flush() -{ - _asm { - dec CPtrNodeSingleLinkPool_UsedSpaces - - or byte ptr [edx+eax], 0x80 - add edx, eax - jmp RETURN_CPtrListSingleLink__Flush - } -} - #define HOOKPOS_CPtrNodeDoubleLinkPool__New 0x55233E #define HOOKSIZE_CPtrNodeDoubleLinkPool__New 0x6 static void _declspec(naked) HOOK_CPtrNodeDoubleLinkPool__New() @@ -142,10 +101,6 @@ void CMultiplayerSA::InitHooks_ObjectStreamerOptimization() EZHookInstall(CEntryInfoNode__operator_delete); EZHookInstall(CEntryInfoList__Flush); - EZHookInstall(CPtrNodeSingleLinkPool__New); - EZHookInstall(CPtrNodeSingleLink__operator_delete); - EZHookInstall(CPtrListSingleLink__Flush); - EZHookInstall(CPtrNodeDoubleLinkPool__New); EZHookInstall(CPtrNodeDoubleLink__operator_delete); EZHookInstall(CPtrListDoubleLink__Flush); @@ -156,11 +111,6 @@ unsigned int CMultiplayerSA::EntryInfoNodePool_NoOfUsedSpaces() const noexcept return CEntryInfoNodePool_UsedSpaces; } -unsigned int CMultiplayerSA::PtrNodeSingleLinkPool_NoOfUsedSpaces() const noexcept -{ - return CPtrNodeSingleLinkPool_UsedSpaces; -} - unsigned int CMultiplayerSA::PtrNodeDoubleLinkPool_NoOfUsedSpaces() const noexcept { return CPtrNodeDoubleLinkPool_UsedSpaces; diff --git a/Client/sdk/game/CPools.h b/Client/sdk/game/CPools.h index 46359a02a6..0fc8555134 100644 --- a/Client/sdk/game/CPools.h +++ b/Client/sdk/game/CPools.h @@ -15,6 +15,7 @@ #include "CBuildingsPool.h" #include "CDummyPool.h" #include "CTxdPool.h" +#include "CPtrNodeSingleLinkPool.h" class CClientEntity; class CEntity; @@ -111,4 +112,5 @@ class CPools virtual CBuildingsPool& GetBuildingsPool() noexcept = 0; virtual CDummyPool& GetDummyPool() noexcept = 0; virtual CTxdPool& GetTxdPool() noexcept = 0; + virtual CPtrNodeSingleLinkPool& GetPtrNodeSingleLinkPool() noexcept = 0; }; diff --git a/Client/sdk/game/CPtrNodeSingleLinkPool.h b/Client/sdk/game/CPtrNodeSingleLinkPool.h new file mode 100644 index 0000000000..125820edf8 --- /dev/null +++ b/Client/sdk/game/CPtrNodeSingleLinkPool.h @@ -0,0 +1,20 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: sdk/game/CPtrNodeSingleLinkPool.h + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +class CPtrNodeSingleLinkPool +{ +public: + virtual bool Resize(std::size_t size) = 0; + virtual void ResetCapacity() = 0; + virtual std::size_t GetCapacity() const = 0; + virtual std::size_t GetUsedSize() const = 0; +}; diff --git a/Client/sdk/game/Common.h b/Client/sdk/game/Common.h index 11e5a31554..be4d18a643 100644 --- a/Client/sdk/game/Common.h +++ b/Client/sdk/game/Common.h @@ -29,7 +29,7 @@ #define MAX_BUILDINGS 13000 #define MAX_DUMMIES 2500 #define MAX_ENTRY_INFO_NODES ( MAX_ENTRY_INFO_NODES_MTA + 600 ) // 72600 -#define MAX_POINTER_SINGLE_LINKS ( MAX_POINTER_SINGLE_LINKS_MTA + 5000 ) // 90000 +#define MAX_POINTER_SINGLE_LINKS ( MAX_POINTER_SINGLE_LINKS_MTA + 5000 ) // 90000 May be changed in runtime #define MAX_POINTER_DOUBLE_LINKS ( MAX_POINTER_DOUBLE_LINKS_MTA + 800 ) // 74800 #define MAX_RWOBJECT_INSTANCES 2500 diff --git a/Client/sdk/multiplayer/CMultiplayer.h b/Client/sdk/multiplayer/CMultiplayer.h index 33e349ea71..d9dd4ab571 100644 --- a/Client/sdk/multiplayer/CMultiplayer.h +++ b/Client/sdk/multiplayer/CMultiplayer.h @@ -460,6 +460,5 @@ class CMultiplayer virtual DWORD GetLastAnimArrayAddress() = 0; virtual unsigned int EntryInfoNodePool_NoOfUsedSpaces() const noexcept = 0; - virtual unsigned int PtrNodeSingleLinkPool_NoOfUsedSpaces() const noexcept = 0; virtual unsigned int PtrNodeDoubleLinkPool_NoOfUsedSpaces() const noexcept = 0; };