Skip to content

Commit

Permalink
Automatically resize building pool
Browse files Browse the repository at this point in the history
  • Loading branch information
TheNormalnij committed Jun 13, 2024
1 parent eb856da commit 21c7dd6
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 34 deletions.
74 changes: 68 additions & 6 deletions Client/mods/deathmatch/logic/CClientBuildingManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "StdInc.h"

constexpr float WORLD_DISTANCE_FROM_CENTER = 3000.0f;
constexpr size_t PRESERVED_POOL_SIZE = 1500;
constexpr size_t RESIZE_POOL_STEP = 5000;

CClientBuildingManager::CClientBuildingManager(CClientManager* pManager)
{
Expand Down Expand Up @@ -99,12 +101,72 @@ void CClientBuildingManager::RestoreDestroyed()
for (CClientBuilding* building : GetBuildings())
{
building->Create();
}
}

void CClientBuildingManager::ResizePoolIfNeeds()
{
const int currentUsed = g_pGame->GetPools()->GetNumberOfUsedSpaces(ePools::BUILDING_POOL);
const int currentCapacity = g_pGame->GetPools()->GetPoolCapacity(ePools::BUILDING_POOL);

if (currentCapacity - currentUsed < PRESERVED_POOL_SIZE)
{
DoPoolResize(currentCapacity + RESIZE_POOL_STEP);
}
}

bool CClientBuildingManager::SetPoolCapacity(size_t newCapacity)
{
const int currentUsed = g_pGame->GetPools()->GetNumberOfUsedSpaces(ePools::BUILDING_POOL);

if (newCapacity - currentUsed < PRESERVED_POOL_SIZE)
return false;

return DoPoolResize(newCapacity);
}

bool CClientBuildingManager::DoPoolResize(size_t newCapacity)
{
DestroyAllForABit();

if (!building->IsValid())
{
// User creates too much buildings
// We can't restore them all
delete building;
}
bool success = g_pGame->SetBuildingPoolSize(newCapacity);

RestoreDestroyed();

return success;
}


void CClientBuildingManager::RemoveAllGameBuildings()
{
// We do not want to remove scripted buildings
// But we need remove them from the buildings pool for a bit...
DestroyAllForABit();

// This function makes buildings backup without scripted buildings
g_pGame->RemoveAllBuildings();

// ... And restore here
RestoreDestroyed();
}

void CClientBuildingManager::RestoreAllGameBuildings()
{
// We want to restore the game buildings to the same positions as they were before the backup.
// Remove scripted buildings for a bit
DestroyAllForABit();

g_pGame->RestoreGameBuildings();

// Resize the building pool if we need
const int currentUsed = g_pGame->GetPools()->GetNumberOfUsedSpaces(ePools::BUILDING_POOL) + m_List.size();
const int currentCapacity = g_pGame->GetPools()->GetPoolCapacity(ePools::BUILDING_POOL);

if (currentCapacity - currentUsed < PRESERVED_POOL_SIZE)
{
DoPoolResize(currentUsed + PRESERVED_POOL_SIZE);
}

// Restore
RestoreDestroyed();
}
9 changes: 8 additions & 1 deletion Client/mods/deathmatch/logic/CClientBuildingManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,17 @@ class CClientBuildingManager
static bool IsValidModel(uint16_t modelId);
static bool IsValidPosition(const CVector& pos) noexcept;

void ResizePoolIfNeeds();
bool SetPoolCapacity(size_t newCapacity);

void RemoveAllGameBuildings();
void RestoreAllGameBuildings();

private:
void DestroyAllForABit();
void RestoreDestroyed();

private:
bool DoPoolResize(size_t newCapacity);
void AddToList(CClientBuilding* pBuilding) { m_List.push_back(pBuilding); }
void RemoveFromList(CClientBuilding* pBuilding);

Expand Down
24 changes: 4 additions & 20 deletions Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,13 @@ CClientBuilding* CLuaBuildingDefs::CreateBuilding(lua_State* const luaVM, uint16
if (!CClientBuildingManager::IsValidModel(modelId))
throw std::invalid_argument("Invalid building model id");

if (!g_pGame->GetPools()->GetBuildingsPool().HasFreeBuildingSlot())
throw std::invalid_argument("No free slot in buildings pool");

if (!CClientBuildingManager::IsValidPosition(pos))
throw std::invalid_argument("Position is outside of game world");

ConvertDegreesToRadians(rot);

m_pBuildingManager->ResizePoolIfNeeds();

CClientBuilding* pBuilding = new CClientBuilding(m_pManager, INVALID_ELEMENT_ID, modelId, pos, rot, interior.value_or(0));

CClientEntity* pRoot = pResource->GetResourceDynamicEntity();
Expand All @@ -63,25 +62,10 @@ CClientBuilding* CLuaBuildingDefs::CreateBuilding(lua_State* const luaVM, uint16

void CLuaBuildingDefs::RemoveAllGameBuildings()
{
// We do not want to remove scripted buildings
// But we need remove them from the buildings pool for a bit...
m_pBuildingManager->DestroyAllForABit();

// This function makes buildings backup without scripted buildings
g_pGame->RemoveAllBuildings();

// ... And restore here
m_pBuildingManager->RestoreDestroyed();
m_pBuildingManager->RemoveAllGameBuildings();
}

void CLuaBuildingDefs::RestoreGameBuildings()
{
// We want to restore the game buildings to the same positions as they were before the backup.
// Remove scripted buildings for a bit
m_pBuildingManager->DestroyAllForABit();

g_pGame->RestoreGameBuildings();

// Restore what we can
m_pBuildingManager->RestoreDestroyed();
m_pBuildingManager->RestoreAllGameBuildings();
}
8 changes: 1 addition & 7 deletions Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2497,13 +2497,7 @@ bool CLuaEngineDefs::EngineSetPoolCapacity(lua_State* luaVM, ePools pool, size_t
{
case ePools::BUILDING_POOL:
{
m_pBuildingManager->DestroyAllForABit();

bool success = g_pGame->SetBuildingPoolSize(newSize);

m_pBuildingManager->RestoreDestroyed();

return success;
return m_pBuildingManager->SetPoolCapacity(newSize);
}
default:
throw std::invalid_argument("Can not change this pool capacity");
Expand Down

0 comments on commit 21c7dd6

Please sign in to comment.