Skip to content

Commit

Permalink
Add remove/restore functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
TheNormalnij committed Aug 2, 2024
1 parent a3f6d01 commit f4e90e4
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 53 deletions.
16 changes: 3 additions & 13 deletions Client/game_sa/CBuildingsPoolSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 +121,11 @@ void CBuildingsPoolSA::RemoveBuilding(CBuilding* pBuilding)
--m_buildingPool.count;
}

void CBuildingsPoolSA::RemoveAllBuildings()
void CBuildingsPoolSA::RemoveAllWithBackup()
{
if (m_pOriginalBuildingsBackup)
return;

pGame->GetCoverManager()->RemoveAllCovers();
pGame->GetPlantManager()->RemoveAllPlants();

// Remove all shadows
using CStencilShadowObjects_dtorAll = void* (*)();
((CStencilShadowObjects_dtorAll)0x711390)();

m_pOriginalBuildingsBackup = std::make_unique<std::array<std::pair<bool, CBuildingSAInterface>, MAX_BUILDINGS>>();

auto pBuildsingsPool = (*m_ppBuildingPoolInterface);
Expand All @@ -156,7 +149,7 @@ void CBuildingsPoolSA::RemoveAllBuildings()
}
}

void CBuildingsPoolSA::RestoreAllBuildings()
void CBuildingsPoolSA::RestoreBackup()
{
if (!m_pOriginalBuildingsBackup)
return;
Expand All @@ -182,10 +175,7 @@ void CBuildingsPoolSA::RemoveBuildingFromWorld(CBuildingSAInterface* pBuilding)
{
// Remove building from world
pGame->GetWorld()->Remove(pBuilding, CBuildingPool_Destructor);

pBuilding->DeleteRwObject();
pBuilding->ResolveReferences();
pBuilding->RemoveShadows();
pBuilding->RemoveRWObjectWithReferencesCleanup();
}

bool CBuildingsPoolSA::Resize(int size)
Expand Down
4 changes: 2 additions & 2 deletions Client/game_sa/CBuildingsPoolSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ class CBuildingsPoolSA : public CBuildingsPool
void RemoveBuilding(CBuilding* pBuilding);
bool HasFreeBuildingSlot();

void RemoveAllBuildings() override;
void RestoreAllBuildings() override;
void RemoveAllWithBackup() override;
void RestoreBackup() override;
bool Resize(int size) override;
int GetSize() const override { return (*m_ppBuildingPoolInterface)->m_nSize; };

Expand Down
72 changes: 51 additions & 21 deletions Client/game_sa/CDummyPoolSA.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
* FILE: game_sa/CDummyPoolSA.cpp
* PURPOSE: Dummy pool class
Expand All @@ -13,63 +13,93 @@

#include "StdInc.h"
#include "CDummyPoolSA.h"
#include "CGameSA.h"
#include <game/CWorld.h>

extern CGameSA* pGame;

CDummyPoolSA::CDummyPoolSA()
{
m_ppDummyPoolInterface = (CPoolSAInterface<CEntitySAInterface>**)0xB744A0;
}

void CDummyPoolSA::RemoveAllBuildingLods()
void CDummyPoolSA::RemoveAllWithBackup()
{
if (m_pLodBackup)
if (m_pOriginalElementsBackup)
return;

m_pLodBackup = std::make_unique<std::array<CEntitySAInterface*, MAX_DUMMIES>>();
m_pOriginalElementsBackup = std::make_unique<pool_backup_t>();

for (int i = 0; i < MAX_DUMMIES; i++)
auto pDummyPool = (*m_ppDummyPoolInterface);
for (size_t i = 0; i < MAX_DUMMIES_DEFAULT; i++)
{
CEntitySAInterface* object = (*m_ppDummyPoolInterface)->GetObject(i);
(*m_pLodBackup)[i] = object->m_pLod;
object->m_pLod = nullptr;
if (pDummyPool->IsContains(i))
{
CEntitySAInterface* building = pDummyPool->GetObject(i);

pGame->GetWorld()->Remove(building, CDummyPool_Destructor);
building->RemoveRWObjectWithReferencesCleanup();

pDummyPool->Release(i);

(*m_pOriginalElementsBackup)[i].first = true;
(*m_pOriginalElementsBackup)[i].second = *building;
}
else
{
(*m_pOriginalElementsBackup)[i].first = false;
}
}
}

void CDummyPoolSA::RestoreAllBuildingsLods()
void CDummyPoolSA::RestoreBackup()
{
if (!m_pLodBackup)
if (!m_pOriginalElementsBackup)
return;

for (int i = 0; i < MAX_DUMMIES; i++)
auto& originalData = *m_pOriginalElementsBackup;
auto pDummyPool = (*m_ppDummyPoolInterface);
for (size_t i = 0; i < MAX_DUMMIES_DEFAULT; i++)
{
CEntitySAInterface* object = (*m_ppDummyPoolInterface)->GetObject(i);
object->m_pLod = (*m_pLodBackup)[i];
if (originalData[i].first)
{
pDummyPool->AllocateAt(i);
auto pDummy = pDummyPool->GetObject(i);
*pDummy = originalData[i].second;

pGame->GetWorld()->Add(pDummy, CDummyPool_Constructor);
}
}

m_pLodBackup.release();
m_pOriginalElementsBackup = nullptr;
}

void CDummyPoolSA::UpdateBuildingLods(void* oldPool, void* newPool)
{
const uint32_t offset = (uint32_t)newPool - (uint32_t)oldPool;
const std::uint32_t offset = (std::uint32_t)newPool - (std::uint32_t)oldPool;

if (m_pLodBackup)
if (m_pOriginalElementsBackup)
{
for (int i = 0; i < MAX_DUMMIES; i++)
for (int i = 0; i < MAX_DUMMIES_DEFAULT; i++)
{
if ((*m_pLodBackup)[i] != nullptr)
if ((*m_pOriginalElementsBackup)[i].first)
{
(*m_pLodBackup)[i] = (CEntitySAInterface*)((uint32_t)(*m_pLodBackup)[i] + offset);
CEntitySAInterface* object = &(*m_pOriginalElementsBackup)[i].second;
if (object->m_pLod)
{
object->m_pLod = (CEntitySAInterface*)((std::uint32_t)(object->m_pLod) + offset);
}
}
}
}
else
{
for (int i = 0; i < MAX_DUMMIES; i++)
for (int i = 0; i < MAX_DUMMIES_DEFAULT; i++)
{
CEntitySAInterface* object = (*m_ppDummyPoolInterface)->GetObject(i);
if (object->m_pLod)
{
object->m_pLod = (CEntitySAInterface*)((uint32_t)object->m_pLod + offset);
object->m_pLod = (CEntitySAInterface*)((std::uint32_t)object->m_pLod + offset);
}
}
}
Expand Down
13 changes: 8 additions & 5 deletions Client/game_sa/CDummyPoolSA.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
* FILE: game_sa/CDummyPoolSA.h
* PURPOSE: Dummy pool class
Expand All @@ -16,18 +16,21 @@
#include "CPoolSAInterface.h"
#include <memory>

class CDummyPoolSA : public CDummyPool
constexpr std::size_t MAX_DUMMIES_DEFAULT = 2500;

class CDummyPoolSA final : public CDummyPool
{
public:
CDummyPoolSA();
~CDummyPoolSA() = default;

void RemoveAllBuildingLods();
void RestoreAllBuildingsLods();
void RemoveAllWithBackup() override;
void RestoreBackup() override;
void UpdateBuildingLods(void* oldPool, void* newPool);

private:
CPoolSAInterface<CEntitySAInterface>** m_ppDummyPoolInterface;

std::unique_ptr<std::array<CEntitySAInterface*, MAX_DUMMIES>> m_pLodBackup;
using pool_backup_t = std::array<std::pair<bool, CEntitySAInterface>, MAX_DUMMIES_DEFAULT>;
std::unique_ptr<pool_backup_t> m_pOriginalElementsBackup;
};
6 changes: 6 additions & 0 deletions Client/game_sa/CEntitySA.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,12 @@ class CEntitySAInterface
using vtbl_DeleteRwObject = void(__thiscall*)(CEntitySAInterface * pEntity);
((vtbl_DeleteRwObject)this->vtbl->DeleteRwObject)(this);
};

void RemoveRWObjectWithReferencesCleanup() {
DeleteRwObject();
ResolveReferences();
RemoveShadows();
}
};
static_assert(sizeof(CEntitySAInterface) == 0x38, "Invalid size for CEntitySAInterface");

Expand Down
14 changes: 10 additions & 4 deletions Client/game_sa/CGameSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1009,8 +1009,14 @@ void CGameSA::RemoveAllBuildings(bool clearBuildingRemoval)
{
m_pIplStore->SetDynamicIplStreamingEnabled(false);

m_pPools->GetDummyPool().RemoveAllBuildingLods();
m_pPools->GetBuildingsPool().RemoveAllBuildings();
m_pCoverManager->RemoveAllCovers();
m_pPlantManager->RemoveAllPlants();

// Remove all shadows in CStencilShadowObjects::dtorAll
((void* (*)())0x711390)();

m_pPools->GetDummyPool().RemoveAllWithBackup();
m_pPools->GetBuildingsPool().RemoveAllWithBackup();

auto pBuildingRemoval = static_cast<CBuildingRemovalSA*>(m_pBuildingRemoval);
if (clearBuildingRemoval)
Expand All @@ -1024,8 +1030,8 @@ void CGameSA::RemoveAllBuildings(bool clearBuildingRemoval)

void CGameSA::RestoreGameBuildings()
{
m_pPools->GetBuildingsPool().RestoreAllBuildings();
m_pPools->GetDummyPool().RestoreAllBuildingsLods();
m_pPools->GetBuildingsPool().RestoreBackup();
m_pPools->GetDummyPool().RestoreBackup();

m_pIplStore->SetDynamicIplStreamingEnabled(true, [](CIplSAInterface* ipl) { return memcmp("barriers", ipl->name, 8) != 0; });
m_isBuildingsRemoved = false;
Expand Down
8 changes: 4 additions & 4 deletions Client/sdk/game/CBuildingsPool.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
* FILE: sdk/game/CBuildingsPool.h
* PURPOSE: Buildings pool interface
Expand All @@ -22,12 +22,12 @@ class CBuildingsPool
public:

// Buildings pool
virtual CBuilding* AddBuilding(class CClientBuilding*, uint16_t modelId, CVector* vPos, CVector4D* vRot, uint8_t interior) = 0;
virtual CBuilding* AddBuilding(class CClientBuilding*, std::uint16_t modelId, CVector* vPos, CVector4D* vRot, std::uint8_t interior) = 0;
virtual void RemoveBuilding(CBuilding* pObject) = 0;
virtual bool HasFreeBuildingSlot() = 0;
virtual bool Resize(int size) = 0;
virtual int GetSize() const = 0;

virtual void RemoveAllBuildings() = 0;
virtual void RestoreAllBuildings() = 0;
virtual void RemoveAllWithBackup() = 0;
virtual void RestoreBackup() = 0;
};
6 changes: 3 additions & 3 deletions Client/sdk/game/CDummyPool.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
* FILE: sdk/game/CDummyPool.h
* PURPOSE: Dummy pool interface
Expand All @@ -16,7 +16,7 @@
class CDummyPool
{
public:
virtual void RemoveAllBuildingLods() = 0;
virtual void RestoreAllBuildingsLods() = 0;
virtual void RemoveAllWithBackup() = 0;
virtual void RestoreBackup() = 0;
virtual void UpdateBuildingLods(void* oldPool, void* newPool) = 0;
};
2 changes: 2 additions & 0 deletions Client/sdk/game/CWorld.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ enum eDebugCaller
CBuildingPool_Constructor,
CBuildingPool_Destructor,
CBuilding_SetLod,
CDummyPool_Constructor,
CDummyPool_Destructor,
};

enum eSurfaceProperties
Expand Down
1 change: 0 additions & 1 deletion Client/sdk/game/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#define MAX_PEDS ( MAX_PEDS_MTA + 30 ) // 140
#define MAX_OBJECTS ( MAX_OBJECTS_MTA + 200 ) // 1200
#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_DOUBLE_LINKS ( MAX_POINTER_DOUBLE_LINKS_MTA + 800 ) // 74800
Expand Down

0 comments on commit f4e90e4

Please sign in to comment.