Skip to content

Commit

Permalink
HOOK_CStreaming__DeleteRwObjectsAfterDeath
Browse files Browse the repository at this point in the history
  • Loading branch information
TheNormalnij committed Oct 20, 2024
1 parent b5e51ff commit d741984
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 24 deletions.
2 changes: 1 addition & 1 deletion Client/game_sa/CCoverManagerSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ CCoverManagerSA::CCoverManagerSA()

void CCoverManagerSA::RemoveAllCovers()
{
CPtrNodeDoubleLink<CEntitySAInterface>* pNode = m_pCoverList->m_pNode;
CPtrNodeDoubleLink<CEntitySAInterface>* pNode = m_pCoverList->GetNode();
while (pNode)
{
RemoveCoverFromArray(pNode->pItem);
Expand Down
93 changes: 78 additions & 15 deletions Client/game_sa/CEntityScanExtender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@

struct tScanLists
{
CPtrNodeDoubleListSAInterface<CEntitySAInterface*>* buildingsList;
CPtrNodeDoubleListSAInterface<CEntitySAInterface*>* objectsList;
CPtrNodeDoubleListSAInterface<CEntitySAInterface*>* vehiclesList;
CPtrNodeDoubleListSAInterface<CEntitySAInterface*>* pedsList;
CPtrNodeDoubleListSAInterface<CEntitySAInterface*>* dummiesList;
CPtrNodeDoubleListSAInterface<CEntitySAInterface>* buildingsList;
CPtrNodeDoubleListSAInterface<CEntitySAInterface>* objectsList;
CPtrNodeDoubleListSAInterface<CEntitySAInterface>* vehiclesList;
CPtrNodeDoubleListSAInterface<CEntitySAInterface>* pedsList;
CPtrNodeDoubleListSAInterface<CEntitySAInterface>* dummiesList;
};

static CRepeatSector (&DEFAULT_REPEAT_SECTORS)[16][16] = *(CRepeatSector(*)[16][16])0xB992B8;
const auto MAX_REPEAT_SECTORS_X = 16;
const auto MAX_REPEAT_SECTORS_Y = 16;

static CRepeatSector (&DEFAULT_REPEAT_SECTORS)[MAX_REPEAT_SECTORS_Y][MAX_REPEAT_SECTORS_X] = *(CRepeatSector(*)[16][16])0xB992B8;
static CSector (&DEFAULT_SECTORS)[MAX_SECTORS_Y][MAX_SECTORS_X] = *(CSector(*)[MAX_SECTORS_Y][MAX_SECTORS_X])0xB7D0B8;
static auto* SCAN_LIST = (tScanLists*)0xC8E0C8;

Expand Down Expand Up @@ -71,6 +74,17 @@ void CEntityScanExtenter::Resize(std::size_t count)
PatchDynamic();
}

std::int32_t CEntityScanExtenter::GetSectorX(float x) const noexcept
{
x = x / static_cast<float>(m_SectorsW / CURRENT_SECTORS_X) + static_cast<float>(CURRENT_SECTORS_X / 2);
return std::floor(x);
}

std::int32_t CEntityScanExtenter::GetSectorY(float y) const noexcept
{
y = y / static_cast<float>(m_SectorsH / CURRENT_SECTORS_Y) + static_cast<float>(CURRENT_SECTORS_Y / 2);
return std::floor(y);
}

void CEntityScanExtenter::PatchOnce()
{
Expand Down Expand Up @@ -182,7 +196,7 @@ static void __cdecl HOOK_CRenderer__SetupScanLists(std::int32_t sectorX, std::in

#define HOOKPOS_CStreaming__AddModelsToRequestLiså1 0x40D66B
#define HOOKSIZE_CStreaming__AddModelsToRequestLiså1 0x5
static std::size_t CStreaming__AddModelsToRequestList1_CONTINUE = 0x40D578;
static std::uint32_t CStreaming__AddModelsToRequestList1_CONTINUE = 0x40D578;
void __declspec(naked) HOOK_CStreaming__AddModelsToRequestLiså1()
{
_asm {
Expand All @@ -195,7 +209,7 @@ static std::size_t CStreaming__AddModelsToRequestList1_CONTINUE = 0x40D578;

#define HOOKPOS_CStreaming__AddModelsToRequestLiså2 0x40D66B
#define HOOKSIZE_CStreaming__AddModelsToRequestLiså2 0x5
static std::size_t CStreaming__AddModelsToRequestList2_CONTINUE = 0x40D686;
static std::uint32_t CStreaming__AddModelsToRequestList2_CONTINUE = 0x40D686;
void __declspec(naked) HOOK_CStreaming__AddModelsToRequestLiså2()
{
_asm {
Expand All @@ -218,7 +232,7 @@ static std::size_t CStreaming__AddModelsToRequestList2_CONTINUE = 0x40D686;

#define HOOKPOS_CStreaming__DeleteAllRwObjects1 0x409125
#define HOOKSIZE_CStreaming__DeleteAllRwObjects1 0x5
static std::size_t CStreaming__CStreaming__DeleteAllRwObjects1_CONTINUE = 0x409133;
static std::uint32_t CStreaming__CStreaming__DeleteAllRwObjects1_CONTINUE = 0x409133;
void __declspec(naked) HOOK_CStreaming__DeleteAllRwObjects1()
{
_asm {
Expand All @@ -234,7 +248,7 @@ void __declspec(naked) HOOK_CStreaming__DeleteAllRwObjects1()

#define HOOKPOS_CStreaming__DeleteAllRwObjects2 0x40913F
#define HOOKSIZE_CStreaming__DeleteAllRwObjects2 0x5
static std::size_t CStreaming__CStreaming__DeleteAllRwObjects2_CONTINUE = 0x40914C;
static std::uint32_t CStreaming__CStreaming__DeleteAllRwObjects2_CONTINUE = 0x40914C;
void __declspec(naked) HOOK_CStreaming__DeleteAllRwObjects2()
{
_asm {
Expand All @@ -251,7 +265,7 @@ void __declspec(naked) HOOK_CStreaming__DeleteAllRwObjects2()

#define HOOKPOS_CStreaming__DeleteAllRwObjects3 0x4091AA
#define HOOKSIZE_CStreaming__DeleteAllRwObjects3 0x5
static std::size_t CStreaming__CStreaming__DeleteAllRwObjects3_CONTINUE = 0x4091C3;
static std::uint32_t CStreaming__CStreaming__DeleteAllRwObjects3_CONTINUE = 0x4091C3;
void __declspec(naked) HOOK_CStreaming__DeleteAllRwObjects3()
{
_asm {
Expand All @@ -274,9 +288,9 @@ void __declspec(naked) HOOK_CStreaming__DeleteAllRwObjects3()

#define HOOKPOS_CStreaming__DeleteAllRwObjects4 0x4091E7
#define HOOKSIZE_CStreaming__DeleteAllRwObjects4 0x5
static std::size_t CStreaming__CStreaming__DeleteAllRwObjects4_LOOP_Y = 0x409125;
static std::size_t CStreaming__CStreaming__DeleteAllRwObjects4_LOOP_X = 0x409110;
static std::size_t CStreaming__CStreaming__DeleteAllRwObjects4_CONTINUE = 0x4091F8;
static std::uint32_t CStreaming__CStreaming__DeleteAllRwObjects4_LOOP_Y = 0x409125;
static std::uint32_t CStreaming__CStreaming__DeleteAllRwObjects4_LOOP_X = 0x409110;
static std::uint32_t CStreaming__CStreaming__DeleteAllRwObjects4_CONTINUE = 0x4091F8;
void __declspec(naked) HOOK_CStreaming__DeleteAllRwObjects4()
{
_asm {
Expand All @@ -294,16 +308,65 @@ void __declspec(naked) HOOK_CStreaming__DeleteAllRwObjects4()
}
}

void CEntityScanExtenter::StaticSetHooks()
static void DeleteRwObjectsInSectorList(CPtrNodeDoubleListSAInterface<CEntitySAInterface> &list)
{
auto nextNode = list.GetNode();
while (nextNode)
{
if (!nextNode->pItem->bImBeingRendered && !nextNode->pItem->bStreamingDontDelete)
nextNode->pItem->DeleteRwObject();
nextNode = nextNode->pNext;
}
}

static CRepeatSector* GetRepeatSector(int32 x, int32 y)
{
return &DEFAULT_REPEAT_SECTORS[y % MAX_REPEAT_SECTORS_Y][x % MAX_REPEAT_SECTORS_X];
}

// Is this code ever used?
#define HOOKPOS_CStreaming__DeleteRwObjectsAfterDeath 0x409210
#define HOOKSIZE_CStreaming__DeleteRwObjectsAfterDeath 0x5

// Deletes all RW objects more than 3 sectors (on each axis) away from the given point's sector
static void HOOK_CStreaming__DeleteRwObjectsAfterDeath(const CVector2D& point)
{
const std::int32_t pointSecX = instance->GetSectorX(point.fX);
const std::int32_t pointSecY = instance->GetSectorY(point.fY);
for (int32 sx = 0; sx < instance->GetSectorsX(); ++sx)
{
if (std::abs(pointSecX - sx) > 3)
{
for (int32 sy = 0; sy < instance->GetSectorsY(); ++sy)
{
if (std::abs(pointSecY - sy) > 3)
{
CRepeatSector* repeatSector = GetRepeatSector(sx, sy);
CSector* sector = instance->GetSector(sx, sy);
DeleteRwObjectsInSectorList(sector->m_buildings);
DeleteRwObjectsInSectorList(repeatSector->GetList(REPEATSECTOR_OBJECTS));
DeleteRwObjectsInSectorList(sector->m_dummies);
}
}
}
}
}

void CEntityScanExtenter::Initialize()
{
instance = std::make_unique<CEntityScanExtenter>();
StaticSetHooks();
}

void CEntityScanExtenter::StaticSetHooks()
{
EZHookInstall(CRenderer__SetupScanLists);
EZHookInstall(CStreaming__AddModelsToRequestLiså1);
EZHookInstall(CStreaming__AddModelsToRequestLiså2);
EZHookInstall(CStreaming__DeleteAllRwObjects1);
EZHookInstall(CStreaming__DeleteAllRwObjects2);
EZHookInstall(CStreaming__DeleteAllRwObjects3);
EZHookInstall(CStreaming__DeleteAllRwObjects4);
EZHookInstall(CStreaming__DeleteRwObjectsAfterDeath);
EZHookInstall(GetSector);
}
13 changes: 10 additions & 3 deletions Client/game_sa/CEntityScanExtender.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ constexpr auto MAX_SECTORS_X = 120;

struct CSector
{
CPtrNodeDoubleListSAInterface<CEntitySAInterface*> m_buildings;
CPtrNodeDoubleListSAInterface<CEntitySAInterface*> m_dummies;
CPtrNodeDoubleListSAInterface<CEntitySAInterface> m_buildings;
CPtrNodeDoubleListSAInterface<CEntitySAInterface> m_dummies;
};

class CEntityScanExtenter
Expand All @@ -32,7 +32,10 @@ class CEntityScanExtenter
CSector* GetSectorResize(std::uint32_t x, std::uint32_t y);
void Resize(std::size_t count);

static void StaticSetHooks();
static void Initialize();

std::int32_t GetSectorX(float x) const noexcept;
std::int32_t GetSectorY(float x) const noexcept;

std::uint32_t GetSectorsX() const noexcept;
std::uint32_t GetSectorsY() const noexcept;
Expand All @@ -41,7 +44,11 @@ class CEntityScanExtenter
void PatchOnce();
void PatchDynamic();

static void StaticSetHooks();

private:
std::size_t m_SectorsW{6000};
std::size_t m_SectorsH{6000};
std::size_t m_SectorsHalfW{3000};
std::size_t m_SectorsHalfH{3000};

Expand Down
2 changes: 1 addition & 1 deletion Client/game_sa/CGameSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ CGameSA::CGameSA()
D3DResourceSystemSA::StaticSetHooks();
CVehicleSA::StaticSetHooks();
CCheckpointSA::StaticSetHooks();
CEntityScanExtenter::StaticSetHooks();
CEntityScanExtenter::Initialize();
}

CGameSA::~CGameSA()
Expand Down
6 changes: 5 additions & 1 deletion Client/game_sa/CPtrNodeDoubleListSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ template <class T>
class CPtrNodeDoubleListSAInterface
{
public:
CPtrNodeDoubleLink<T>* m_pNode;

void RemoveItem(T* pItem)
{
Expand All @@ -38,4 +37,9 @@ class CPtrNodeDoubleListSAInterface
RemoveItem(m_pNode->pItem);
}
};

CPtrNodeDoubleLink<T>* GetNode() const noexcept { return m_pNode; }

private:
CPtrNodeDoubleLink<T>* m_pNode;
};
6 changes: 3 additions & 3 deletions Client/game_sa/CRepeatSectorSAInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ enum eRepeatSectorList : std::int32_t
class CRepeatSector
{
public:
CPtrNodeDoubleListSAInterface<CEntitySAInterface*>& GetList(eRepeatSectorList type) noexcept { return m_lists[type]; }
CPtrNodeDoubleListSAInterface<CEntitySAInterface>& GetList(eRepeatSectorList type) noexcept { return m_lists[type]; }

const CPtrNodeDoubleListSAInterface<CEntitySAInterface*>& GetList(eRepeatSectorList type) const noexcept { return m_lists[type]; }
const CPtrNodeDoubleListSAInterface<CEntitySAInterface>& GetList(eRepeatSectorList type) const noexcept { return m_lists[type]; }
// private: Preferrably use the accessor method
CPtrNodeDoubleListSAInterface<CEntitySAInterface*> m_lists[3];
CPtrNodeDoubleListSAInterface<CEntitySAInterface> m_lists[3];
};

0 comments on commit d741984

Please sign in to comment.