From 2a6637af5eaf5733046fd3a22d2dab98976d54b5 Mon Sep 17 00:00:00 2001 From: Miran Date: Tue, 18 Nov 2025 19:45:23 +0100 Subject: [PATCH 1/4] Fixed crashing of plant manager methods --- plugin_sa/game_sa/CPlantMgr.cpp | 28 ++++++++++++++-------------- plugin_sa/game_sa/CPlantMgr.h | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/plugin_sa/game_sa/CPlantMgr.cpp b/plugin_sa/game_sa/CPlantMgr.cpp index 62995d99..9272f8f6 100644 --- a/plugin_sa/game_sa/CPlantMgr.cpp +++ b/plugin_sa/game_sa/CPlantMgr.cpp @@ -26,32 +26,32 @@ void CPlantMgr::Render() { plugin::CallDynGlobal(0x5DBAE0); } -void CPlantMgr::_ProcessEntryCollisionDataSections_RemoveLocTris(CPlantColEntEntry* col, CVector const& camPos, int triProcessSkipMask, int colStartIndex, int colEndIndex) { - plugin::CallDynGlobal(0x5DBF20, col, camPos, triProcessSkipMask, colStartIndex, colEndIndex); +void CPlantMgr::_ProcessEntryCollisionDataSections_RemoveLocTris(CPlantColEntEntry* col, const CVector& camPos, int triProcessSkipMask, int colStartIndex, int colEndIndex) { + plugin::CallDynGlobal(0x5DBF20, col, &camPos, triProcessSkipMask, colStartIndex, colEndIndex); } -void CPlantMgr::_ColEntityCache_Update(CVector const& camPos, uint8_t quickUpdate) { - plugin::CallDynGlobal(0x5DC510, camPos, quickUpdate); +void CPlantMgr::_ColEntityCache_Update(const CVector& camPos, uint8_t quickUpdate) { + plugin::CallDynGlobal(0x5DC510, &camPos, quickUpdate); } -void CPlantMgr::_ProcessEntryCollisionDataSections_AddLocTris(CPlantColEntEntry* col, CVector const& camPos, int processSkipMask, int colStartIndex, int colEndIndex) { - plugin::CallDynGlobal(0x5DC8B0, col, camPos, processSkipMask, colStartIndex, colEndIndex); +void CPlantMgr::_ProcessEntryCollisionDataSections_AddLocTris(CPlantColEntEntry* col, const CVector& camPos, int processSkipMask, int colStartIndex, int colEndIndex) { + plugin::CallDynGlobal(0x5DC8B0, col, &camPos, processSkipMask, colStartIndex, colEndIndex); } -void CPlantMgr::_ProcessEntryCollisionDataSections(CPlantColEntEntry* col, CVector const& camPos, int processSkipMask) { - plugin::CallDynGlobal(0x5DCD80, col, camPos, processSkipMask); +void CPlantMgr::_ProcessEntryCollisionDataSections(CPlantColEntEntry* col, const CVector& camPos, int processSkipMask) { + plugin::CallDynGlobal(0x5DCD80, col, &camPos, processSkipMask); } -void CPlantMgr::_UpdateLocTris(CVector const& camPos, int processSkipMask) { - plugin::CallDynGlobal(0x5DCF00, camPos, processSkipMask); +void CPlantMgr::_UpdateLocTris(const CVector& camPos, int processSkipMask) { + plugin::CallDynGlobal(0x5DCF00, &camPos, processSkipMask); } -bool CPlantMgr::PreUpdateOnceForNewCameraPos(CVector const& camPos) { - return plugin::CallAndReturnDynGlobal(0x5DCF30, camPos); +void CPlantMgr::PreUpdateOnceForNewCameraPos(const CVector& camPos) { + plugin::CallDynGlobal(0x5DCF30, &camPos); } -void CPlantMgr::Update(CVector const& camPos) { - plugin::CallDynGlobal(0x5DCFA0, camPos); +void CPlantMgr::Update(const CVector& camPos) { + plugin::CallDynGlobal(0x5DCFA0, &camPos); } bool CPlantMgr::ReloadConfig() { diff --git a/plugin_sa/game_sa/CPlantMgr.h b/plugin_sa/game_sa/CPlantMgr.h index 8eac8389..b2c4972b 100644 --- a/plugin_sa/game_sa/CPlantMgr.h +++ b/plugin_sa/game_sa/CPlantMgr.h @@ -63,13 +63,13 @@ class CPlantMgr { static void SetPlantFriendlyFlagInAtomicMI(CAtomicModelInfo*); static void Shutdown(); static void Render(); - static void _ProcessEntryCollisionDataSections_RemoveLocTris(CPlantColEntEntry*, CVector const&, int, int, int); - static void _ColEntityCache_Update(CVector const&, uint8_t); - static void _ProcessEntryCollisionDataSections_AddLocTris(CPlantColEntEntry*, CVector const&, int, int, int); - static void _ProcessEntryCollisionDataSections(CPlantColEntEntry*, CVector const&, int); - static void _UpdateLocTris(CVector const&, int); - static bool PreUpdateOnceForNewCameraPos(CVector const&); - static void Update(CVector const&); + static void _ProcessEntryCollisionDataSections_RemoveLocTris(CPlantColEntEntry*, const CVector&, int, int, int); + static void _ColEntityCache_Update(const CVector&, uint8_t); + static void _ProcessEntryCollisionDataSections_AddLocTris(CPlantColEntEntry*, const CVector&, int, int, int); + static void _ProcessEntryCollisionDataSections(CPlantColEntEntry*, const CVector&, int); + static void _UpdateLocTris(const CVector&, int); + static void PreUpdateOnceForNewCameraPos(const CVector&); + static void Update(const CVector&); static bool ReloadConfig(); static bool Initialise(); }; From 9a2775ee459dd9605fce07743fee35caee7e5d1b Mon Sep 17 00:00:00 2001 From: Miran Date: Tue, 18 Nov 2025 20:03:10 +0100 Subject: [PATCH 2/4] Added CColStore methods --- plugin_sa/game_sa/CColStore.cpp | 84 +++++++++++++++++++++++++++++++++ plugin_sa/game_sa/CColStore.h | 28 ++++++++--- 2 files changed, 106 insertions(+), 6 deletions(-) diff --git a/plugin_sa/game_sa/CColStore.cpp b/plugin_sa/game_sa/CColStore.cpp index fe06f014..200ce2cc 100644 --- a/plugin_sa/game_sa/CColStore.cpp +++ b/plugin_sa/game_sa/CColStore.cpp @@ -13,3 +13,87 @@ int CColStore::ms_nRequiredCollisionArea = *(int*)0x965554; CColPool*& CColStore::ms_pColPool = *(CColPool**)0x965560; CQuadTreeNode*& CColStore::ms_pQuadTree = *(CQuadTreeNode**)0x96555C; +void CColStore::Initialise() { + plugin::Call<0x4113F0>(); +} + +void CColStore::Shutdown() { + plugin::Call<0x4114D0>(); +} + +int CColStore::AddColSlot(const char* name) { + return plugin::CallAndReturn(name); +} + +void CColStore::AddCollisionNeededAtPosn(const CVector& pos) { + plugin::Call<0x4103A0, const CVector&>(pos); +} + +void CColStore::AddRef(int colNum) { + plugin::Call<0x4107A0, int>(colNum); +} + +void CColStore::BoundingBoxesPostProcess() { + plugin::Call<0x410EC0>(); +} + +void CColStore::EnsureCollisionIsInMemory(const CVector& pos) { + plugin::Call<0x410AD0, const CVector&>(pos); +} + +CRect* CColStore::GetBoundingBox(int colSlot) { + return plugin::CallAndReturn(colSlot); +} + +void CColStore::IncludeModelIndex(int colSlot, int modelId) { + plugin::Call<0x410820, int, int>(colSlot, modelId); +} + +bool CColStore::HasCollisionLoaded(const CVector& pos, int areaCode) { + return plugin::CallAndReturn(pos, areaCode); +} + +void CColStore::LoadAllBoundingBoxes() { + plugin::Call<0x4113D0>(); +} + +void CColStore::LoadAllCollision() { + plugin::Call<0x410E60>(); +} + +void CColStore::LoadCol(int colSlot, const char* filename) { + plugin::Call<0x410690, int, const char*>(colSlot, filename); +} + +bool CColStore::LoadCol(int colSlot, unsigned char* data, int dataSize) { + return plugin::CallAndReturn(colSlot, data, dataSize); +} + +void CColStore::LoadCollision(const CVector& pos, bool bIgnorePlayerVeh) { + plugin::Call<0x410860, const CVector&, bool>(pos, bIgnorePlayerVeh); +} + +void CColStore::RemoveAllCollision() { + plugin::Call<0x410E00>(); +} + +void CColStore::RemoveCol(int colSlot) { + plugin::Call<0x410730, int>(colSlot); +} + +void CColStore::RemoveColSlot(int colSlot) { + plugin::Call<0x411330, int>(colSlot); +} + +void CColStore::RemoveRef(int colNum) { + plugin::Call<0x4107D0, int>(colNum); +} + +void CColStore::RequestCollision(const CVector& pos, int areaCode) { + plugin::Call<0x410C00, const CVector&, int>(pos, areaCode); +} + +void CColStore::SetCollisionRequired(const CVector& pos, int areaCode) { + plugin::Call<0x4104E0, const CVector&, int>(pos, areaCode); +} + diff --git a/plugin_sa/game_sa/CColStore.h b/plugin_sa/game_sa/CColStore.h index d94ba1be..a05c726a 100644 --- a/plugin_sa/game_sa/CColStore.h +++ b/plugin_sa/game_sa/CColStore.h @@ -12,11 +12,7 @@ struct ColDef { CRect m_Area; - unsigned int field_10; - unsigned int field_14; - unsigned int field_18; - unsigned int field_1C; - unsigned short field_20; + char name[18]; short m_nModelIdStart; short m_nModelIdEnd; unsigned short m_nRefCount; @@ -25,7 +21,6 @@ struct ColDef { bool m_bProcedural; bool m_bInterior; }; - VALIDATE_SIZE(ColDef, 0x2C); typedef CPool CColPool; @@ -41,4 +36,25 @@ class CColStore { static bool& ms_bCollisionNeeded; static int ms_nRequiredCollisionArea; + static void Initialise(); + static void Shutdown(); + static int AddColSlot(const char* name); + static void AddCollisionNeededAtPosn(const CVector& pos); + static void AddRef(int colNum); + static void BoundingBoxesPostProcess(); + static void EnsureCollisionIsInMemory(const CVector& pos); + static CRect* GetBoundingBox(int colSlot); + static void IncludeModelIndex(int colSlot, int modelId); + static bool HasCollisionLoaded(const CVector& pos, int areaCode); + static void LoadAllBoundingBoxes(); + static void LoadAllCollision(); + static void LoadCol(int colSlot, const char* filename); + static bool LoadCol(int colSlot, unsigned char* data, int dataSize); + static void LoadCollision(const CVector& pos, bool bIgnorePlayerVeh); + static void RemoveAllCollision(); + static void RemoveCol(int colSlot); + static void RemoveColSlot(int colSlot); + static void RemoveRef(int colNum); + static void RequestCollision(const CVector& pos, int areaCode); + static void SetCollisionRequired(const CVector& pos, int areaCode); }; \ No newline at end of file From b478a528fe5959f2d493d391c26322e41afc90ee Mon Sep 17 00:00:00 2001 From: Miran Date: Wed, 19 Nov 2025 00:53:08 +0100 Subject: [PATCH 3/4] Added methods to CPathFind --- plugin_sa/game_sa/CPathFind.cpp | 8 ++++++++ plugin_sa/game_sa/CPathFind.h | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/plugin_sa/game_sa/CPathFind.cpp b/plugin_sa/game_sa/CPathFind.cpp index 03bcc00d..490ede96 100644 --- a/plugin_sa/game_sa/CPathFind.cpp +++ b/plugin_sa/game_sa/CPathFind.cpp @@ -20,6 +20,14 @@ void CPathFind::DoPathSearch(unsigned char pathType, CVector origin, CNodeAddres waterPath); } +void CPathFind::SetPathsNeededAtPosition(const CVector& pos) { + plugin::CallMethod<0x44DCD0, CPathFind*, const CVector&>(this, pos); +} + +void CPathFind::UpdateStreaming(bool bForceStreaming) { + plugin::CallMethod<0x450A60, CPathFind*, bool>(this, bForceStreaming); +} + CPathNode *CPathFind::GetPathNode(CNodeAddress address) { return ((CPathNode *(__thiscall *)(CPathFind *, CNodeAddress))0x420AC0)(this, address); diff --git a/plugin_sa/game_sa/CPathFind.h b/plugin_sa/game_sa/CPathFind.h index 3ee6edf7..c0edd172 100644 --- a/plugin_sa/game_sa/CPathFind.h +++ b/plugin_sa/game_sa/CPathFind.h @@ -55,9 +55,11 @@ class PLUGIN_API CPathFind float maxSearchDistance, CNodeAddress *targetAddr, float maxUnkLimit, bool oneSideOnly, CNodeAddress forbiddenNodeAddr, bool includeNodesWithoutLinks, bool waterPath); + void SetPathsNeededAtPosition(const CVector& pos); + void UpdateStreaming(bool bForceStreaming); + CPathNode *GetPathNode(CNodeAddress address); }; - VALIDATE_SIZE(CPathFind, 0x3C80); extern PLUGIN_API CPathFind& ThePaths; From 26ce08059fb9a7bebd92da0acd6b53ac93e6ecc0 Mon Sep 17 00:00:00 2001 From: Miran Date: Wed, 19 Nov 2025 00:54:07 +0100 Subject: [PATCH 4/4] Added methods to CCarCtrl --- plugin_sa/game_sa/CCarCtrl.cpp | 25 +++++++++++++++++++++++++ plugin_sa/game_sa/CCarCtrl.h | 25 ++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/plugin_sa/game_sa/CCarCtrl.cpp b/plugin_sa/game_sa/CCarCtrl.cpp index eb274cc9..7c3c6ffd 100644 --- a/plugin_sa/game_sa/CCarCtrl.cpp +++ b/plugin_sa/game_sa/CCarCtrl.cpp @@ -5,6 +5,31 @@ Do not delete this comment block. Respect others' work! */ #include "CCarCtrl.h" + +bool& CCarCtrl::bCarIsBeingCreated = *(bool*)0x9690CC; +unsigned int& CCarCtrl::NumLawEnforcerCars = *(unsigned int*)0x969098; +unsigned int& CCarCtrl::NumParkedCars = *(unsigned int*)0x9690A0; +unsigned int& CCarCtrl::NumAmbulancesOnDuty = *(unsigned int*)0x9690A8; +unsigned int& CCarCtrl::NumFireTrucksOnDuty = *(unsigned int*)0x9690AC; +unsigned int& CCarCtrl::MaxNumberOfCarsInUse = *(unsigned int*)0x8A5B24; +float& CCarCtrl::CarDensityMultiplier = *(float*)0x8A5B20; +int& CCarCtrl::NumRandomCars = *(int*)0x969094; +int& CCarCtrl::NumMissionCars = *(int*)0x96909C; +int& CCarCtrl::NumPermanentVehicles = *(int*)0x9690A4; +int& CCarCtrl::LastTimeAmbulanceCreated = *(int*)0x9690B0; +int& CCarCtrl::LastTimeFireTruckCreated = *(int*)0x9690B4; +bool& CCarCtrl::bAllowEmergencyServicesToBeCreated = *(bool*)0x8A5B28; +bool& CCarCtrl::bCarsGeneratedAroundCamera = *(bool*)0x9690C1; +char& CCarCtrl::CountDownToCarsAtStart = *(char*)0x9690C0; +float& CCarCtrl::TimeNextMadDriverChaseCreated = *(float*)0x9690BC; +int& CCarCtrl::SequenceElements = *(int*)0x969078; +int& CCarCtrl::SequenceRandomOffset = *(int*)0x969074; +bool& CCarCtrl::bSequenceOtherWay = *(bool*)0x969070; +int& CCarCtrl::LastTimeLawEnforcerCreated = *(int*)0x9690B8; + +CVehicle* (&CCarCtrl::apCarsToKeep)[2] = *(CVehicle*(*)[2])0x969084; +unsigned int (&CCarCtrl::aCarsToKeepTime)[2] = *(unsigned int(*)[2])0x96907C; + // Converted from cdecl int CCarCtrl::ChooseBoatModel(void) 0x421970 int CCarCtrl::ChooseBoatModel() { return plugin::CallAndReturn(); diff --git a/plugin_sa/game_sa/CCarCtrl.h b/plugin_sa/game_sa/CCarCtrl.h index 459218aa..d3bca183 100644 --- a/plugin_sa/game_sa/CCarCtrl.h +++ b/plugin_sa/game_sa/CCarCtrl.h @@ -15,6 +15,30 @@ class PLUGIN_API CCarCtrl { public: + static bool& bCarIsBeingCreated; + static unsigned int& NumLawEnforcerCars; + static unsigned int& NumParkedCars; + static unsigned int& NumAmbulancesOnDuty; + static unsigned int& NumFireTrucksOnDuty; + static unsigned int& MaxNumberOfCarsInUse; + static float& CarDensityMultiplier; + static int& NumRandomCars; + static int& NumMissionCars; + static int& NumPermanentVehicles; + static int& LastTimeAmbulanceCreated; + static int& LastTimeFireTruckCreated; + static bool& bAllowEmergencyServicesToBeCreated; + static bool& bCarsGeneratedAroundCamera; + static char& CountDownToCarsAtStart; + static float& TimeNextMadDriverChaseCreated; + static int& SequenceElements; + static int& SequenceRandomOffset; + static bool& bSequenceOtherWay; + static int& LastTimeLawEnforcerCreated; + + static CVehicle* (&apCarsToKeep)[2]; + static unsigned int (&aCarsToKeepTime)[2]; + static int ChooseBoatModel(); static int ChooseCarModelToLoad(int arg1); static int ChooseGangCarModel(int arg1); @@ -123,5 +147,4 @@ class PLUGIN_API CCarCtrl static void WeaveThroughCarsSectorList(CPtrList& PtrList, CVehicle* pVehicle, CPhysical* pPhysical, float arg4, float arg5, float arg6, float arg7, float* arg8, float* arg9); static void WeaveThroughObjectsSectorList(CPtrList& PtrList, CVehicle* pVehicle, float arg3, float arg4, float arg5, float arg6, float* arg7, float* arg8); static void WeaveThroughPedsSectorList(CPtrList& PtrList, CVehicle* pVehicle, CPhysical* pPhysical, float arg4, float arg5, float arg6, float arg7, float* arg8, float* arg9); - }; \ No newline at end of file