From 618d689dff9a22d9385abf36f5e364b38273b7cf Mon Sep 17 00:00:00 2001 From: erorcun Date: Sat, 6 Mar 2021 19:28:59 +0300 Subject: Pool fixes + peds not forming circle fix --- src/objects/Object.cpp | 30 ++++++++++++++++++++++++++---- src/objects/Object.h | 8 ++++---- src/objects/Stinger.cpp | 30 ++++++++++++++++++++++++------ 3 files changed, 54 insertions(+), 14 deletions(-) (limited to 'src/objects') diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp index 0721725d..575c592c 100644 --- a/src/objects/Object.cpp +++ b/src/objects/Object.cpp @@ -25,10 +25,32 @@ int16 CObject::nNoTempObjects; //int16 CObject::nBodyCastHealth = 1000; float CObject::fDistToNearestTree; -void *CObject::operator new(size_t sz) { return CPools::GetObjectPool()->New(); } -void *CObject::operator new(size_t sz, int handle) { return CPools::GetObjectPool()->New(handle);}; -void CObject::operator delete(void *p, size_t sz) { CPools::GetObjectPool()->Delete((CObject*)p); } -void CObject::operator delete(void *p, int handle) { CPools::GetObjectPool()->Delete((CObject*)p); } +// Object pools tends to be full sometimes, let's free a temp. object in this case. +#ifdef FIX_BUGS +void *CObject::operator new(size_t sz) throw() { + CObject *obj = CPools::GetObjectPool()->New(); + if (!obj) { + CObjectPool *objectPool = CPools::GetObjectPool(); + for (int32 i = 0; i < objectPool->GetSize(); i++) { + CObject *existing = objectPool->GetSlot(i); + if (existing && existing->ObjectCreatedBy == TEMP_OBJECT) { + int32 handle = objectPool->GetIndex(existing); + CWorld::Remove(existing); + delete existing; + obj = objectPool->New(handle); + break; + } + } + } + return obj; +} +#else +void *CObject::operator new(size_t sz) throw() { return CPools::GetObjectPool()->New(); } +#endif +void *CObject::operator new(size_t sz, int handle) throw() { return CPools::GetObjectPool()->New(handle); }; + +void CObject::operator delete(void *p, size_t sz) throw() { CPools::GetObjectPool()->Delete((CObject*)p); } +void CObject::operator delete(void *p, int handle) throw() { CPools::GetObjectPool()->Delete((CObject*)p); } CObject::CObject(void) { diff --git a/src/objects/Object.h b/src/objects/Object.h index e34043a8..f59379bf 100644 --- a/src/objects/Object.h +++ b/src/objects/Object.h @@ -87,10 +87,10 @@ public: static int16 nNoTempObjects; static float fDistToNearestTree; - static void *operator new(size_t); - static void *operator new(size_t, int); - static void operator delete(void*, size_t); - static void operator delete(void*, int); + static void *operator new(size_t) throw(); + static void *operator new(size_t, int) throw(); + static void operator delete(void*, size_t) throw(); + static void operator delete(void*, int) throw(); CObject(void); CObject(int32, bool); diff --git a/src/objects/Stinger.cpp b/src/objects/Stinger.cpp index 41040d4a..29efea10 100644 --- a/src/objects/Stinger.cpp +++ b/src/objects/Stinger.cpp @@ -46,7 +46,14 @@ CStinger::Init(CPed *pPed) pOwner = pPed; for (i = 0; i < NUM_STINGER_SEGMENTS; i++) { - pSpikes[i] = new CStingerSegment; + pSpikes[i] = new CStingerSegment(); +#ifdef FIX_BUGS + if (!pSpikes[i]) { + // Abort!! Pool is full + Remove(); + return; + } +#endif pSpikes[i]->bUsesCollision = false; } bIsDeployed = true; @@ -77,8 +84,11 @@ CStinger::Remove() CStingerSegment *spikeSegment = pSpikes[i]; #ifdef FIX_BUGS - CWorld::Remove(spikeSegment); - delete spikeSegment; + if (spikeSegment) { + CWorld::Remove(spikeSegment); + delete spikeSegment; + pSpikes[i] = nil; + } #else if (spikeSegment->m_entryInfoList.first != nil) spikeSegment->bRemoveFromWorld = true; @@ -92,9 +102,15 @@ CStinger::Remove() void CStinger::Deploy(CPed *pPed) { + // So total number of stingers allowed at the same time is 2, each by different CCopPed. if (NumOfStingerSegments < NUM_STINGER_SEGMENTS*2 && !pPed->bInVehicle && pPed->IsPedInControl()) { if (!bIsDeployed && RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_STD_THROW_UNDER) == nil) { Init(pPed); +#ifdef FIX_BUGS + // Above call won't set it to true no more when object pool is full + if (!bIsDeployed) + return; +#endif pPed->SetPedState(PED_DEPLOY_STINGER); CAnimManager::AddAnimation(pPed->GetClump(), ASSOCGRP_STD, ANIM_STD_THROW_UNDER); } @@ -167,6 +183,7 @@ CStinger::CheckForBurstTyres() } } +// Only called when bIsDeployed void CStinger::Process() { @@ -232,10 +249,11 @@ CStinger::Process() break; case STINGERSTATE_REMOVE: Remove(); - break; - } #ifdef FIX_BUGS - if (bIsDeployed) + return; +#else + break; #endif + } CheckForBurstTyres(); } \ No newline at end of file -- cgit v1.2.3