Skip to content

Commit

Permalink
Merge branch 'master' into Buildings/fix-removeWorldModel
Browse files Browse the repository at this point in the history
  • Loading branch information
Dutchman101 authored Jun 16, 2024
2 parents e821f4c + bf9b97d commit 5f57491
Show file tree
Hide file tree
Showing 24 changed files with 311 additions and 56 deletions.
19 changes: 11 additions & 8 deletions Client/game_sa/CBuildingsPoolSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ inline bool CBuildingsPoolSA::AddBuildingToPool(CClientBuilding* pClientBuilding
if (dwElementIndexInPool == UINT_MAX)
return false;

m_buildingPool.arrayOfClientEntities[dwElementIndexInPool] = {pBuilding, (CClientEntity*)pClientBuilding};
m_buildingPool.entities[dwElementIndexInPool] = {pBuilding, (CClientEntity*)pClientBuilding};

// Increase the count of objects
++m_buildingPool.ulCount;
++m_buildingPool.count;

return true;
}
Expand Down Expand Up @@ -108,8 +108,8 @@ void CBuildingsPoolSA::RemoveBuilding(CBuilding* pBuilding)
modelInfo->RemoveColRef();

// Remove from BuildingSA pool
auto* pBuildingSA = m_buildingPool.arrayOfClientEntities[dwElementIndexInPool].pEntity;
m_buildingPool.arrayOfClientEntities[dwElementIndexInPool] = {nullptr, nullptr};
auto* pBuildingSA = m_buildingPool.entities[dwElementIndexInPool].pEntity;
m_buildingPool.entities[dwElementIndexInPool] = {nullptr, nullptr};

// Delete it from memory
delete pBuildingSA;
Expand All @@ -118,7 +118,7 @@ void CBuildingsPoolSA::RemoveBuilding(CBuilding* pBuilding)
(*m_ppBuildingPoolInterface)->Release(dwElementIndexInPool);

// Decrease the count of elements in the pool
--m_buildingPool.ulCount;
--m_buildingPool.count;
}

void CBuildingsPoolSA::RemoveAllBuildings()
Expand Down Expand Up @@ -191,7 +191,9 @@ void CBuildingsPoolSA::RemoveBuildingFromWorld(CBuildingSAInterface* pBuilding)
bool CBuildingsPoolSA::Resize(int size)
{
auto* pool = (*m_ppBuildingPoolInterface);
const int curretnSize = pool->m_nSize;
const int currentSize = pool->m_nSize;

m_buildingPool.entities.resize(size);

void* oldPool = pool->m_pObjects;

Expand All @@ -210,15 +212,15 @@ bool CBuildingsPoolSA::Resize(int size)
CBuildingSAInterface* newObjects = MemSA::malloc_struct<CBuildingSAInterface>(size);
if (newObjects == nullptr)
{
Resize(curretnSize);
Resize(currentSize);
return false;
}

tPoolObjectFlags* newBytemap = MemSA::malloc_struct<tPoolObjectFlags>(size);
if (newBytemap == nullptr)
{
MemSA::free(newObjects);
Resize(curretnSize);
Resize(currentSize);
return false;
}

Expand Down Expand Up @@ -322,6 +324,7 @@ void CBuildingsPoolSA::RemovePedsContactEnityLinks()
CPedSAInterface* ped = pedLinks->pEntity->GetPedInterface();
ped->m_pCollidedEntity = nullptr;
ped->pContactEntity = nullptr;
ped->pLastContactEntity = nullptr;
ped->pLastContactedEntity[0] = nullptr;
ped->pLastContactedEntity[1] = nullptr;
ped->pLastContactedEntity[2] = nullptr;
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 @@ -40,8 +40,8 @@ class CBuildingsPoolSA : public CBuildingsPool
void RemovePedsContactEnityLinks();

private:
SPoolData<CBuildingSA, CBuildingSAInterface, MAX_BUILDINGS> m_buildingPool;
CPoolSAInterface<CBuildingSAInterface>** m_ppBuildingPoolInterface;
SVectorPoolData<CBuildingSA> m_buildingPool{MAX_BUILDINGS};
CPoolSAInterface<CBuildingSAInterface>** m_ppBuildingPoolInterface;

std::unique_ptr<std::array<std::pair<bool, CBuildingSAInterface>, MAX_BUILDINGS>> m_pOriginalBuildingsBackup;
};
90 changes: 90 additions & 0 deletions Client/game_sa/CFxSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,3 +239,93 @@ void CFxSA::TriggerFootSplash(CVector& vecPosition)
call dwFunc
}
}

void CFxSA::AddParticle(eFxParticleSystems eFxParticle, const CVector& vecPosition, const CVector& vecDirection, float fR, float fG, float fB, float fA, bool bRandomizeColors, std::uint32_t iCount, float fBrightness, float fSize, bool bRandomizeSizes, float fLife)
{
// Init our own FxPrtMult struct
FxPrtMult_c fxPrt{{fR,fG,fB,fA}, fSize, 0, fLife};
CVector newDirection;

FxSystem_c* fxParticleSystem;

switch (eFxParticle)
{
case eFxParticleSystems::PRT_BLOOD:
fxParticleSystem = m_pInterface->m_fxSysBlood;
break;
case eFxParticleSystems::PRT_BOATSPLASH:
fxParticleSystem = m_pInterface->m_fxSysBoatSplash;
break;
case eFxParticleSystems::PRT_BUBBLE:
fxParticleSystem = m_pInterface->m_fxSysBubble;
break;
case eFxParticleSystems::PRT_DEBRIS:
fxParticleSystem = m_pInterface->m_fxSysDebris;
break;
case eFxParticleSystems::PRT_GUNSHELL:
fxParticleSystem = m_pInterface->m_fxSysGunshell;
break;
case eFxParticleSystems::PRT_SAND:
fxParticleSystem = m_pInterface->m_fxSysSand;
break;
case eFxParticleSystems::PRT_SAND2:
fxParticleSystem = m_pInterface->m_fxSysSand2;
break;
case eFxParticleSystems::PRT_SMOKE:
fxParticleSystem = m_pInterface->m_fxSysSmoke;
break;
case eFxParticleSystems::PRT_SMOKEHUGE:
fxParticleSystem = m_pInterface->m_fxSysSmokeHuge;
break;
case eFxParticleSystems::PRT_SMOKE2:
fxParticleSystem = m_pInterface->m_fxSysSmoke2;
break;
case eFxParticleSystems::PRT_SPARK:
fxParticleSystem = m_pInterface->m_fxSysSpark;
break;
case eFxParticleSystems::PRT_SPARK2:
fxParticleSystem = m_pInterface->m_fxSysSpark2;
break;
case eFxParticleSystems::PRT_SPLASH:
fxParticleSystem = m_pInterface->m_fxSysSplash;
break;
case eFxParticleSystems::PRT_WAKE:
fxParticleSystem = m_pInterface->m_fxSysWake;
break;
case eFxParticleSystems::PRT_WATERSPLASH:
fxParticleSystem = m_pInterface->m_fxSysWaterSplash;
break;
case eFxParticleSystems::PRT_WHEELDIRT:
fxParticleSystem = m_pInterface->m_fxSysWheelDirt;
break;
case eFxParticleSystems::PRT_GLASS:
fxParticleSystem = m_pInterface->m_fxSysGlass;
break;
default:
fxParticleSystem = m_pInterface->m_fxSysBlood;
}

for (size_t i = 0; i < iCount; i++)
{
if (bRandomizeColors)
{
// 0x49EECB
fxPrt.m_color.red = (rand() % 10000) * 0.0001f * fR + 0.13f;
fxPrt.m_color.green = (rand() % 10000) * 0.0001f * fG + 0.12f;
fxPrt.m_color.blue = (rand() % 10000) * 0.0001f * fB + 0.04f;
}

if (bRandomizeSizes)
// 0x49EF21 - Calculate random size for each particle
fxPrt.m_fSize = (rand() % 10000) * 0.0001f * fSize + 0.3f;

// 0x49EF4C - Calculate random direction for each particle
newDirection = CVector(vecDirection.fX * 4, vecDirection.fY * 4, vecDirection.fZ * 4);
newDirection.fX = (rand() % 10000) * 0.0001f * 4 - 2 + newDirection.fX;
newDirection.fY = (rand() % 10000) * 0.0001f * 4 - 2 + newDirection.fY;
newDirection.fZ = (rand() % 10000) * 0.0001f * 4 - 2 + newDirection.fZ;

// Call FxSystem_c::AddParticle
((int(__thiscall*)(FxSystem_c*, const CVector*, const CVector*, float, FxPrtMult_c*, float, float, float, int))FUNC_FXSystem_c_AddParticle)(fxParticleSystem, &vecPosition, &newDirection, 0, &fxPrt, -1.0f, fBrightness, 0, 0);
}
}
37 changes: 37 additions & 0 deletions Client/game_sa/CFxSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <game/CFx.h>

struct RwColor;
class FxSystem_c;

#define FUNC_CFx_AddBlood 0x49eb00
#define FUNC_CFx_AddWood 0x49ee10
Expand All @@ -29,10 +30,30 @@ struct RwColor;
#define FUNC_CFx_TriggerWaterSplash 0x4a1070
#define FUNC_CFx_TriggerBulletSplash 0x4a10e0
#define FUNC_CFx_TriggerFootSplash 0x4a1150
#define FUNC_FXSystem_c_AddParticle 0x4AA440

class CFxSAInterface
{
public:
FxSystem_c* m_fxSysBlood;
FxSystem_c* m_fxSysBoatSplash;
FxSystem_c* m_fxSysBubble;
FxSystem_c* m_fxSysDebris;
FxSystem_c* m_fxSysSmoke;
FxSystem_c* m_fxSysGunshell;
FxSystem_c* m_fxSysSand;
FxSystem_c* m_fxSysSand2;
FxSystem_c* m_fxSysSmokeHuge;
FxSystem_c* m_fxSysSmoke2;
FxSystem_c* m_fxSysSpark;
FxSystem_c* m_fxSysSpark2;
FxSystem_c* m_fxSysSplash;
FxSystem_c* m_fxSysWake;
FxSystem_c* m_fxSysWaterSplash;
FxSystem_c* m_fxSysWheelDirt;
FxSystem_c* m_fxSysGlass;

private:
};

class CFxSA : public CFx
Expand All @@ -55,7 +76,23 @@ class CFxSA : public CFx
void TriggerWaterSplash(CVector& vecPosition);
void TriggerBulletSplash(CVector& vecPosition);
void TriggerFootSplash(CVector& vecPosition);
void AddParticle(eFxParticleSystems eFxParticle, const CVector& vecPosition, const CVector& vecDirection, float fR, float fG, float fB, float fA, bool bRandomizeColors, std::uint32_t iCount, float fBrightness, float fSize, bool bRandomizeSizes, float fLife);

private:
CFxSAInterface* m_pInterface;

struct FxPrtMult_c
{
struct
{
float red;
float green;
float blue;
float alpha;
} m_color;

float m_fSize;
float unk;
float m_fLife;
};
};
6 changes: 1 addition & 5 deletions Client/game_sa/CModelInfoSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1992,11 +1992,7 @@ void CModelInfoSA::SetObjectPropertiesGroup(unsigned short usNewGroup)

unsigned short CModelInfoSA::GetObjectPropertiesGroup()
{
unsigned short usGroup = GetInterface()->usDynamicIndex;
if (usGroup == 0xFFFF)
usGroup = 0;

return usGroup;
return GetInterface()->usDynamicIndex;
}

void CModelInfoSA::RestoreObjectPropertiesGroup()
Expand Down
4 changes: 2 additions & 2 deletions Client/game_sa/CPedSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,11 @@ class CPedSAInterface : public CPhysicalSAInterface // +1420 = curre
float fTargetRotation;
float fRotationSpeed;
float fMoveAnim;
CPedSAInterface* unkPed;
CEntitySAInterface* pContactEntity;
CVector unk_56C;
CVector unk_578;

CEntitySAInterface* pContactEntity;
CEntitySAInterface* pLastContactEntity;
CVehicleSAInterface* pLastVehicle;
CVehicleSAInterface* pVehicle;

Expand Down
13 changes: 13 additions & 0 deletions Client/game_sa/CPoolSAInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,16 @@ struct SPoolData
}
}
};

template <class T>
struct SVectorPoolData
{
std::vector<SClientEntity<T>> entities;
size_t count;

public:
SVectorPoolData(size_t defaultSize) : count(0)
{
entities.resize(defaultSize, {nullptr, nullptr});
}
};
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 = 2000;
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
4 changes: 4 additions & 0 deletions Client/mods/deathmatch/logic/CClientSound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ bool CClientSound::Create()
m_pAudio->SetPanEnabled(m_bPan);
m_pAudio->SetPan(m_fPan);

// Also check and transfer if paused
if (m_bPaused)
m_pAudio->SetPaused(m_bPaused);

// Transfer play position if it was being simulated
EndSimulationOfPlayPositionAndApply();

Expand Down
Loading

0 comments on commit 5f57491

Please sign in to comment.