summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/animation/CutsceneMgr.h1
-rw-r--r--src/control/Replay.cpp2
-rw-r--r--src/core/World.cpp982
-rw-r--r--src/core/World.h36
-rw-r--r--src/core/re3.cpp6
-rw-r--r--src/entities/Entity.cpp12
-rw-r--r--src/entities/Entity.h3
-rw-r--r--src/modelinfo/ModelIndices.h7
-rw-r--r--src/objects/Object.cpp4
-rw-r--r--src/objects/Object.h2
-rw-r--r--src/peds/Ped.cpp94
-rw-r--r--src/render/Coronas.cpp2
12 files changed, 1079 insertions, 72 deletions
diff --git a/src/animation/CutsceneMgr.h b/src/animation/CutsceneMgr.h
index b025816b..bfdcdb57 100644
--- a/src/animation/CutsceneMgr.h
+++ b/src/animation/CutsceneMgr.h
@@ -28,6 +28,7 @@ public:
static void StartCutsceneProcessing() { ms_cutsceneProcessing = true; }
static bool IsRunning(void) { return ms_running; }
+ static bool HasLoaded(void) { return ms_loaded; }
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
static bool UseLodMultiplier(void) { return ms_useLodMultiplier; }
static CCutsceneObject* GetCutsceneObject(int id) { return ms_pCutsceneObjects[id]; }
diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp
index 92d1736d..0570f9a8 100644
--- a/src/control/Replay.cpp
+++ b/src/control/Replay.cpp
@@ -1083,7 +1083,7 @@ void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float ca
Playback.m_bSlot = first;
Playback.m_nOffset = 0;
Playback.m_pBase = Buffers[first];
- CObject::DeleteAllTempObjectInArea(CVector(0.0f, 0.0f, 0.0f), 1000000.0f);
+ CObject::DeleteAllTempObjectsInArea(CVector(0.0f, 0.0f, 0.0f), 1000000.0f);
StoreStuffInMem();
EmptyPedsAndVehiclePools();
SlowMotion = 1;
diff --git a/src/core/World.cpp b/src/core/World.cpp
index 313b958a..02c0e2f6 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -20,6 +20,17 @@
#include "Replay.h"
#include "Population.h"
#include "Fire.h"
+#include "ProjectileInfo.h"
+#include "WaterLevel.h"
+#include "CopPed.h"
+#include "Object.h"
+#include "Shadows.h"
+#include "Explosion.h"
+#include "Glass.h"
+#include "ParticleObject.h"
+#include "EventList.h"
+
+#define OBJECT_REPOSITION_OFFSET_Z 2.0f
CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS];
@@ -40,26 +51,6 @@ bool &CWorld::bProcessCutsceneOnly = *(bool*)0x95CD8B;
bool &CWorld::bDoingCarCollisions = *(bool*)0x95CD8C;
bool &CWorld::bIncludeCarTyres = *(bool*)0x95CDAA;
-WRAPPER void CWorld::ClearForRestart(void) { EAXJMP(0x4AE850); }
-WRAPPER void CWorld::AddParticles(void) { EAXJMP(0x4B4010); }
-WRAPPER void CWorld::ShutDown(void) { EAXJMP(0x4AE450); }
-WRAPPER void CWorld::RepositionCertainDynamicObjects() { EAXJMP(0x4B42B0); }
-WRAPPER void CWorld::RemoveStaticObjects() { EAXJMP(0x4B4D50); }
-WRAPPER void CWorld::RemoveReferencesToDeletedObject(CEntity*) { EAXJMP(0x4B3BF0); }
-WRAPPER void CWorld::FindObjectsKindaColliding(const CVector &, float, bool, int16*, int16, CEntity **, bool, bool, bool, bool, bool){ EAXJMP(0x4B2A30); }
-WRAPPER void CWorld::ClearExcitingStuffFromArea(const CVector &pos, float radius, uint8) { EAXJMP(0x4B4E70) };
-WRAPPER void CWorld::FindObjectsIntersectingCube(const CVector &, const CVector &, int16*, int16, CEntity **, bool, bool, bool, bool, bool) { EAXJMP(0x4B2E70); }
-WRAPPER void CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox &, const CMatrix &, const CVector &, float, float, float, float, int16*, int16, CEntity **, bool, bool, bool, bool, bool) { EAXJMP(0x4B3280); }
-WRAPPER void CWorld::FindObjectsOfTypeInRange(uint32, CVector&, float, bool, short*, short, CEntity**, bool, bool, bool, bool, bool) { EAXJMP(0x4B2600); }
-WRAPPER void CWorld::FindObjectsOfTypeInRangeSectorList(uint32, CPtrList&, CVector&, float, bool, short*, short, CEntity**) { EAXJMP(0x4B2960); }
-WRAPPER void CWorld::FindMissionEntitiesIntersectingCube(const CVector&, const CVector&, int16*, int16, CEntity**, bool, bool, bool) { EAXJMP(0x4B3680); }
-WRAPPER void CWorld::ClearCarsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B50E0); }
-WRAPPER void CWorld::ClearPedsFromArea(float, float, float, float, float, float) { EAXJMP(0x4B52B0); }
-WRAPPER void CWorld::CallOffChaseForArea(float, float, float, float) { EAXJMP(0x4B5530); }
-WRAPPER void CWorld::TriggerExplosion(const CVector& a1, float a2, float a3, CEntity *a4, bool a5) { EAXJMP(0x4B1140); }
-WRAPPER void CWorld::SetPedsOnFire(float, float, float, float, CEntity*) { EAXJMP(0x4B3D30); }
-WRAPPER void CWorld::UseDetonator(CEntity *) { EAXJMP(0x4B4650); }
-
void
CWorld::Initialise()
{
@@ -129,6 +120,48 @@ CWorld::ClearScanCodes(void)
}
}
+void
+CWorld::ClearExcitingStuffFromArea(const CVector& pos, float radius, bool bRemoveProjectilesAndTidyUpShadows)
+{
+ CPedPool* pedPool = CPools::GetPedPool();
+ for (int32 i = 0; i < pedPool->GetSize(); i++) {
+ CPed* pPed = pedPool->GetSlot(i);
+ if (pPed && !pPed->IsPlayer() && pPed->CanBeDeleted() &&
+ CVector2D(pPed->GetPosition() - pos).MagnitudeSqr() < radius) {
+ CPopulation::RemovePed(pPed);
+ }
+ }
+ CVehiclePool* VehiclePool = CPools::GetVehiclePool();
+ for (int32 i = 0; i < VehiclePool->GetSize(); i++) {
+ CVehicle* pVehicle = VehiclePool->GetSlot(i);
+ if (pVehicle && CVector2D(pVehicle->GetPosition() - pos).MagnitudeSqr() < radius &&
+ !pVehicle->bIsLocked && pVehicle->CanBeDeleted()) {
+ if (pVehicle->pDriver) {
+ CPopulation::RemovePed(pVehicle->pDriver);
+ pVehicle->pDriver = nil;
+ }
+ for (int32 j = 0; j < pVehicle->m_nNumMaxPassengers; ++j) {
+ if (pVehicle->pPassengers[j]) {
+ CPopulation::RemovePed(pVehicle->pPassengers[j]);
+ pVehicle->pPassengers[j] = nil;
+ --pVehicle->m_nNumPassengers;
+ }
+ }
+ CCarCtrl::RemoveFromInterestingVehicleList(pVehicle);
+ CWorld::Remove(pVehicle);
+ delete pVehicle;
+ }
+ }
+ CObject::DeleteAllTempObjectsInArea(pos, radius);
+ gFireManager.ExtinguishPoint(pos, radius);
+ CWorld::ExtinguishAllCarFiresInArea(pos, radius);
+ CExplosion::RemoveAllExplosionsInArea(pos, radius);
+ if (bRemoveProjectilesAndTidyUpShadows) {
+ CProjectileInfo::RemoveAllProjectiles();
+ CShadows::TidyUpShadows();
+ }
+}
+
bool
CWorld::CameraToIgnoreThisObject(CEntity *ent)
{
@@ -695,6 +728,67 @@ CWorld::FindObjectsInRange(CVector &centre, float radius, bool ignoreZ, short *n
}
}
+void
+CWorld::FindObjectsOfTypeInRangeSectorList(uint32 modelId, CPtrList& list, const CVector& position, float radius, bool bCheck2DOnly, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities)
+{
+ CPtrNode* pNode = list.first;
+ while (pNode) {
+ CEntity* pEntity = (CEntity*)pNode->item;
+ if (pEntity->m_scanCode != ms_nCurrentScanCode) {
+ pEntity->m_scanCode = ms_nCurrentScanCode;
+ float fMagnitude = 0.0f;
+ if (bCheck2DOnly)
+ fMagnitude = (position - pEntity->GetPosition()).MagnitudeSqr2D();
+ else
+ fMagnitude = (position - pEntity->GetPosition()).MagnitudeSqr();
+ if (fMagnitude < radius * radius && *nEntitiesFound < maxEntitiesToFind) {
+ if (aEntities)
+ aEntities[*nEntitiesFound] = pEntity;
+ ++*nEntitiesFound;
+ }
+ }
+ pNode = pNode->next;
+ }
+}
+
+void
+CWorld::FindObjectsOfTypeInRange(uint32 modelId, const CVector& position, float radius, bool bCheck2DOnly, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies)
+{
+ CWorld::AdvanceCurrentScanCode();
+ *nEntitiesFound = 0;
+ const CVector2D vecSectorStartPos(position.x - radius, position.y - radius);
+ const CVector2D vecSectorEndPos(position.x + radius, position.y + radius);
+ const int32 nStartX = max(CWorld::GetSectorIndexX(vecSectorStartPos.x), 0);
+ const int32 nStartY = max(CWorld::GetSectorIndexY(vecSectorStartPos.y), 0);
+ const int32 nEndX = min(CWorld::GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1);
+ const int32 nEndY = min(CWorld::GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1);
+ for (int32 y = nStartY; y <= nEndY; y++) {
+ for (int32 x = nStartX; x <= nEndX; x++) {
+ CSector* pSector = CWorld::GetSector(x, y);
+ if (bBuildings) {
+ CWorld::FindObjectsOfTypeInRangeSectorList(modelId, pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsOfTypeInRangeSectorList(modelId, pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ if (bVehicles) {
+ CWorld::FindObjectsOfTypeInRangeSectorList(modelId, pSector->m_lists[ENTITYLIST_VEHICLES], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsOfTypeInRangeSectorList(modelId, pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ if (bPeds) {
+ CWorld::FindObjectsOfTypeInRangeSectorList(modelId, pSector->m_lists[ENTITYLIST_PEDS], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsOfTypeInRangeSectorList(modelId, pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ if (bObjects) {
+ CWorld::FindObjectsOfTypeInRangeSectorList(modelId, pSector->m_lists[ENTITYLIST_OBJECTS], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsOfTypeInRangeSectorList(modelId, pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ if (bDummies) {
+ CWorld::FindObjectsOfTypeInRangeSectorList(modelId, pSector->m_lists[ENTITYLIST_DUMMIES], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsOfTypeInRangeSectorList(modelId, pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], position, radius, bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ }
+ }
+}
+
CEntity*
CWorld::TestSphereAgainstWorld(CVector centre, float radius, CEntity *entityToIgnore, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSomeObjects)
{
@@ -873,6 +967,273 @@ CWorld::FindRoofZFor3DCoord(float x, float y, float z, bool *found)
}
}
+void
+CWorld::RemoveReferencesToDeletedObject(CEntity* pDeletedObject)
+{
+ int32 i = CPools::GetPedPool()->GetSize();
+ while (--i >= 0) {
+ CPed* pPed = CPools::GetPedPool()->GetSlot(i);
+ if (pPed && pPed != pDeletedObject) {
+ pPed->RemoveRefsToEntity(pDeletedObject);
+ if (pPed->m_pCurrentPhysSurface == pDeletedObject)
+ pPed->m_pCurrentPhysSurface = nil;
+ }
+ }
+ i = CPools::GetVehiclePool()->GetSize();
+ while (--i >= 0) {
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
+ if (pVehicle && pVehicle != pDeletedObject) {
+ pVehicle->RemoveRefsToEntity(pDeletedObject);
+ pVehicle->RemoveRefsToVehicle(pDeletedObject);
+ }
+ }
+ i = CPools::GetObjectPool()->GetSize();
+ while (--i >= 0) {
+ CObject* pObject = CPools::GetObjectPool()->GetSlot(i);
+ if (pObject && pObject != pDeletedObject) {
+ pObject->RemoveRefsToEntity(pDeletedObject);
+ }
+ }
+}
+
+void
+CWorld::FindObjectsKindaColliding(const CVector& position, float radius, bool bCheck2DOnly, int16* nCollidingEntities, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies)
+{
+ CWorld::AdvanceCurrentScanCode();
+ *nCollidingEntities = 0;
+ const CVector2D vecSectorStartPos(position.x - radius, position.y - radius);
+ const CVector2D vecSectorEndPos(position.x + radius, position.y + radius);
+ const int32 nStartX = max(CWorld::GetSectorIndexX(vecSectorStartPos.x), 0);
+ const int32 nStartY = max(CWorld::GetSectorIndexY(vecSectorStartPos.y), 0);
+ const int32 nEndX = min(CWorld::GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1);
+ const int32 nEndY = min(CWorld::GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1);
+ for (int32 y = nStartY; y <= nEndY; y++) {
+ for (int32 x = nStartX; x <= nEndX; x++) {
+ CSector* pSector = CWorld::GetSector(x, y);
+ if (bBuildings) {
+ CWorld::FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities);
+ }
+ if (bVehicles) {
+ CWorld::FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities);
+ }
+ if (bPeds) {
+ CWorld::FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities);
+ }
+ if (bObjects) {
+ CWorld::FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities);
+ }
+ if (bDummies) {
+ CWorld::FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_DUMMIES], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], position, radius, bCheck2DOnly, nCollidingEntities, maxEntitiesToFind, aEntities);
+ }
+ }
+ }
+}
+
+void
+CWorld::FindObjectsKindaCollidingSectorList(CPtrList& list, const CVector& position, float radius, bool bCheck2DOnly, int16* nCollidingEntities, int16 maxEntitiesToFind, CEntity** aEntities)
+{
+ CPtrNode* pNode = list.first;
+ while (pNode) {
+ CEntity* pEntity = (CEntity*)pNode->item;
+ if (pEntity->m_scanCode != ms_nCurrentScanCode) {
+ pEntity->m_scanCode = ms_nCurrentScanCode;
+ float fMagnitude = 0.0f;
+ if (bCheck2DOnly)
+ fMagnitude = (position - pEntity->GetPosition()).Magnitude2D();
+ else
+ fMagnitude = (position - pEntity->GetPosition()).Magnitude();
+ if (pEntity->GetBoundRadius() + radius > fMagnitude && *nCollidingEntities < maxEntitiesToFind) {
+ if (aEntities)
+ aEntities[*nCollidingEntities] = pEntity;
+ ++*nCollidingEntities;
+ }
+ }
+ pNode = pNode->next;
+ }
+}
+
+void
+CWorld::FindObjectsIntersectingCube(const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies)
+{
+ CWorld::AdvanceCurrentScanCode();
+ *nIntersecting = 0;
+ const int32 nStartX = max(CWorld::GetSectorIndexX(vecStartPos.x), 0);
+ const int32 nStartY = max(CWorld::GetSectorIndexY(vecStartPos.y), 0);
+ const int32 nEndX = min(CWorld::GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1);
+ const int32 nEndY = min(CWorld::GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1);
+ for (int32 y = nStartY; y <= nEndY; y++) {
+ for (int32 x = nStartX; x <= nEndX; x++) {
+ CSector* pSector = CWorld::GetSector(x, y);
+ if (bBuildings) {
+ CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities);
+ }
+ if (bVehicles) {
+ CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities);
+ }
+ if (bPeds) {
+ CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities);
+ }
+ if (bObjects) {
+ CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities);
+ }
+ if (bDummies) {
+ CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_DUMMIES], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities);
+ }
+ }
+ }
+
+}
+
+void
+CWorld::FindObjectsIntersectingCubeSectorList(CPtrList& list, const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities)
+{
+ CPtrNode* pNode = list.first;
+ while (pNode) {
+ CEntity* pEntity = (CEntity*)pNode->item;
+ if (pEntity->m_scanCode != CWorld::ms_nCurrentScanCode) {
+ pEntity->m_scanCode = CWorld::ms_nCurrentScanCode;
+ float fRadius = pEntity->GetBoundRadius();
+ const CVector& entityPos = pEntity->GetPosition();
+ if (fRadius + entityPos.x >= vecStartPos.x && entityPos.x - fRadius <= vecEndPos.x &&
+ fRadius + entityPos.y >= vecStartPos.y && entityPos.y - fRadius <= vecEndPos.y &&
+ fRadius + entityPos.z >= vecStartPos.z && entityPos.z - fRadius <= vecEndPos.z &&
+ *nIntersecting < maxEntitiesToFind) {
+ if (aEntities)
+ aEntities[*nIntersecting] = pEntity;
+ ++*nIntersecting;
+ }
+ }
+ pNode = pNode->next;
+ }
+}
+
+void
+CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox& boundingBox, const CMatrix& matrix, const CVector& position, float fStartX, float fStartY, float fEndX, float fEndY, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies)
+{
+ CWorld::AdvanceCurrentScanCode();
+ *nEntitiesFound = 0;
+ const int32 nStartX = max(CWorld::GetSectorIndexX(fStartX), 0);
+ const int32 nStartY = max(CWorld::GetSectorIndexY(fStartY), 0);
+ const int32 nEndX = min(CWorld::GetSectorIndexX(fEndX), NUMSECTORS_X - 1);
+ const int32 nEndY = min(CWorld::GetSectorIndexY(fEndY), NUMSECTORS_Y - 1);
+ for (int32 y = nStartY; y <= nEndY; y++) {
+ for (int32 x = nStartX; x <= nEndX; x++) {
+ CSector* pSector = CWorld::GetSector(x, y);
+ if (bBuildings) {
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ if (bVehicles) {
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ if (bPeds) {
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(pSector->m_lists[ENTITYLIST_PEDS], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ if (bObjects) {
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ if (bDummies) {
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(pSector->m_lists[ENTITYLIST_DUMMIES], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities);
+ CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], boundingBox, matrix, position, nEntitiesFound, maxEntitiesToFind, aEntities);
+ }
+ }
+ }
+}
+
+void
+CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList& list, const CColBox& boundingBox, const CMatrix& matrix, const CVector& position, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities)
+{
+ CPtrNode* pNode = list.first;
+ while (pNode) {
+ CEntity* pEntity = (CEntity*)pNode->item;
+ if (pEntity->m_scanCode != CWorld::ms_nCurrentScanCode) {
+ pEntity->m_scanCode = CWorld::ms_nCurrentScanCode;
+ CColSphere sphere;
+ CVector vecDistance = pEntity->GetPosition() - position;
+ sphere.radius = pEntity->GetBoundRadius();
+ sphere.center = Multiply3x3(vecDistance, matrix);
+ if (CCollision::TestSphereBox(sphere, boundingBox) && *nEntitiesFound < maxEntitiesToFind) {
+ if (aEntities)
+ aEntities[*nEntitiesFound] = pEntity;
+ ++*nEntitiesFound;
+ }
+ }
+ pNode = pNode->next;
+ }
+}
+
+void
+CWorld::FindMissionEntitiesIntersectingCube(const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bVehicles, bool bPeds, bool bObjects)
+{
+ CWorld::AdvanceCurrentScanCode();
+ *nIntersecting = 0;
+ const int32 nStartX = max(CWorld::GetSectorIndexX(vecStartPos.x), 0);
+ const int32 nStartY = max(CWorld::GetSectorIndexY(vecStartPos.y), 0);
+ const int32 nEndX = min(CWorld::GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1);
+ const int32 nEndY = min(CWorld::GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1);
+ for (int32 y = nStartY; y <= nEndY; y++) {
+ for (int32 x = nStartX; x <= nEndX; x++) {
+ CSector* pSector = CWorld::GetSector(x, y);
+ if (bVehicles) {
+ CWorld::FindMissionEntitiesIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, true, false);
+ CWorld::FindMissionEntitiesIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, true, false);
+ }
+ if (bPeds) {
+ CWorld::FindMissionEntitiesIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, false, true);
+ CWorld::FindMissionEntitiesIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, false, true);
+ }
+ if (bObjects) {
+ CWorld::FindMissionEntitiesIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, false, false);
+ CWorld::FindMissionEntitiesIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], vecStartPos, vecEndPos, nIntersecting, maxEntitiesToFind, aEntities, false, false);
+ }
+ }
+ }
+}
+
+void
+CWorld::FindMissionEntitiesIntersectingCubeSectorList(CPtrList& list, const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bIsVehicleList, bool bIsPedList)
+{
+ CPtrNode* pNode = list.first;
+ while (pNode) {
+ CEntity* pEntity = (CEntity*)pNode->item;
+ if (pEntity->m_scanCode != CWorld::ms_nCurrentScanCode) {
+ pEntity->m_scanCode = CWorld::ms_nCurrentScanCode;
+ bool bIsMissionEntity = false;
+ if (bIsVehicleList)
+ bIsMissionEntity = ((CVehicle*)pEntity)->VehicleCreatedBy == MISSION_VEHICLE;
+ else if (bIsPedList)
+ bIsMissionEntity = ((CPed*)pEntity)->CharCreatedBy == MISSION_CHAR;
+ else
+ bIsMissionEntity = ((CObject*)pEntity)->ObjectCreatedBy == MISSION_OBJECT;
+ float fRadius = pEntity->GetBoundRadius();
+ const CVector& entityPos = pEntity->GetPosition();
+ if (bIsMissionEntity &&
+ fRadius + entityPos.x >= vecStartPos.x && entityPos.x - fRadius <= vecEndPos.x &&
+ fRadius + entityPos.y >= vecStartPos.y && entityPos.y - fRadius <= vecEndPos.y &&
+ fRadius + entityPos.z >= vecStartPos.z && entityPos.z - fRadius <= vecEndPos.z &&
+ *nIntersecting < maxEntitiesToFind) {
+ if (aEntities)
+ aEntities[*nIntersecting] = pEntity;
+ ++*nIntersecting;
+ }
+ }
+ pNode = pNode->next;
+ }
+}
+
CPlayerPed*
FindPlayerPed(void)
{
@@ -961,6 +1322,155 @@ FindPlayerHeading(void)
return FindPlayerPed()->GetForward().Heading();
}
+
+void CWorld::ClearCarsFromArea(float x1, float y1, float z1, float x2, float y2, float z2)
+{
+ CVehiclePool *pVehiclePool = CPools::GetVehiclePool();
+ for (int32 i = 0; i < pVehiclePool->GetSize(); i++) {
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
+ if (pVehicle) {
+ const CVector& position = pVehicle->GetPosition();
+ if (position.x >= x1 && position.x <= x2 &&
+ position.y >= y1 && position.y <= y2 &&
+ position.z >= z1 && position.z <= z2 &&
+ !pVehicle->bIsLocked && pVehicle->CanBeDeleted()) {
+ if (pVehicle->pDriver) {
+ CPopulation::RemovePed(pVehicle->pDriver);
+ pVehicle->pDriver = nil;
+ }
+ for (int32 j = 0; j < pVehicle->m_nNumMaxPassengers; ++j) {
+ if (pVehicle->pPassengers[j]) {
+ CPopulation::RemovePed(pVehicle->pPassengers[j]);
+ pVehicle->pPassengers[j] = nil;
+ --pVehicle->m_nNumPassengers;
+ }
+ }
+ CCarCtrl::RemoveFromInterestingVehicleList(pVehicle);
+ CWorld::Remove(pVehicle);
+ delete pVehicle;
+ }
+ }
+ }
+}
+
+void
+CWorld::ClearPedsFromArea(float x1, float y1, float z1, float x2, float y2, float z2)
+{
+ CPedPool* pPedPool = CPools::GetPedPool();
+ for (int32 i = 0; i < pPedPool->GetSize(); i++) {
+ CPed* pPed = CPools::GetPedPool()->GetSlot(i);
+ if (pPed) {
+ const CVector& position = pPed->GetPosition();
+ if (!pPed->IsPlayer() && pPed->CanBeDeleted() &&
+ position.x >= x1 && position.x <= x2 &&
+ position.y >= y1 && position.y <= y2 &&
+ position.z >= z1 && position.z <= z2) {
+ CPopulation::RemovePed(pPed);
+ }
+ }
+ }
+}
+
+void
+CWorld::CallOffChaseForArea(float x1, float y1, float x2, float y2)
+{
+ CWorld::AdvanceCurrentScanCode();
+ float fStartX = x1 - 10.0f;
+ float fStartY = y1 - 10.0f;
+ float fEndX = x2 + 10.0f;
+ float fEndY = y2 + 10.0f;
+ const int32 nStartX = max(CWorld::GetSectorIndexX(fStartX), 0);
+ const int32 nStartY = max(CWorld::GetSectorIndexY(fStartY), 0);
+ const int32 nEndX = min(CWorld::GetSectorIndexX(fEndX), NUMSECTORS_X - 1);
+ const int32 nEndY = min(CWorld::GetSectorIndexY(fEndY), NUMSECTORS_Y - 1);
+ for (int32 y = nStartY; y <= nEndY; y++) {
+ for (int32 x = nStartX; x <= nEndX; x++) {
+ CSector* pSector = CWorld::GetSector(x, y);
+ CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES], x1, y1, x2, y2, fStartX, fStartY, fEndX, fEndY);
+ CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], x1, y1, x2, y2, fStartX, fStartY, fEndX, fEndY);
+ CWorld::CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS], x1, y1, x2, y2);
+ CWorld::CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], x1, y1, x2, y2);
+ }
+ }
+}
+
+void
+CWorld::CallOffChaseForAreaSectorListVehicles(CPtrList& list, float x1, float y1, float x2, float y2, float fStartX, float fStartY, float fEndX, float fEndY)
+{
+ CPtrNode* pNode = list.first;
+ while (pNode) {
+ CVehicle *pVehicle = (CVehicle*)pNode->item;
+ if (pVehicle->m_scanCode != CWorld::ms_nCurrentScanCode) {
+ pVehicle->m_scanCode = CWorld::ms_nCurrentScanCode;
+ const CVector& vehiclePos = pVehicle->GetPosition();
+ eCarMission carMission = pVehicle->AutoPilot.m_nCarMission;
+ if (pVehicle != FindPlayerVehicle() &&
+ vehiclePos.x > fStartX && vehiclePos.x < fEndX &&
+ vehiclePos.y > fStartY && vehiclePos.y < fEndY &&
+ pVehicle->bIsLawEnforcer &&
+ (carMission == MISSION_RAMPLAYER_FARAWAY || carMission == MISSION_RAMPLAYER_CLOSE ||
+ carMission == MISSION_BLOCKPLAYER_FARAWAY || carMission == MISSION_BLOCKPLAYER_CLOSE)
+ ) {
+ pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 2000;
+ CColModel* pColModel = pVehicle->GetColModel();
+ bool bInsideSphere = false;
+ for (int32 i = 0; i < pColModel->numSpheres; i++) {
+ CVector pos = pVehicle->m_matrix * pColModel->spheres[i].center;
+ float fRadius = pColModel->spheres[i].radius;
+ if (pos.x + fRadius > x1 && pos.x - fRadius < x2 && pos.y + fRadius > y1 && pos.y - fRadius < y2)
+ bInsideSphere = true;
+ // Maybe break the loop when bInsideSphere is set to true?
+ }
+ if (bInsideSphere) {
+ if (pVehicle->GetPosition().x <= (x1 + x2) * 0.5f)
+ pVehicle->m_vecMoveSpeed.x = min(pVehicle->m_vecMoveSpeed.x, 0.0f);
+ else
+ pVehicle->m_vecMoveSpeed.x = max(pVehicle->m_vecMoveSpeed.x, 0.0f);
+ if (pVehicle->GetPosition().y <= (y1 + y2) * 0.5f)
+ pVehicle->m_vecMoveSpeed.y = min(pVehicle->m_vecMoveSpeed.y, 0.0f);
+ else
+ pVehicle->m_vecMoveSpeed.y = max(pVehicle->m_vecMoveSpeed.y, 0.0f);
+ }
+ }
+ }
+ pNode = pNode->next;
+ }
+}
+
+void
+CWorld::CallOffChaseForAreaSectorListPeds(CPtrList& list, float x1, float y1, float x2, float y2)
+{
+ CPtrNode* pNode = list.first;
+ while (pNode) {
+ CPed* pPed = (CPed*)pNode->item;
+ const CVector& pedPos = pPed->GetPosition();
+ if (pPed->m_scanCode != CWorld::ms_nCurrentScanCode)
+ {
+ pPed->m_scanCode = CWorld::ms_nCurrentScanCode;
+ if (pPed != FindPlayerPed() && pPed->m_leader != FindPlayerPed() &&
+ pedPos.x > x1 && pedPos.x < x2 &&
+ pedPos.y > y1 && pedPos.y < y2 &&
+ (pPed->m_pedInObjective == FindPlayerPed() || pPed->m_carInObjective && pPed->m_carInObjective == FindPlayerVehicle()) &&
+ pPed->m_nPedState != PED_DEAD && pPed->m_nPedState != PED_DIE &&
+ (pPed->m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT ||
+ pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER ||
+ pPed->m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS)) {
+ if (pPed->IsPedInControl()) {
+ if (pPed->m_nPedType == PEDTYPE_COP)
+ ((CCopPed*)pPed)->ClearPursuit();
+ else
+ pPed->SetIdle();
+ pPed->SetObjective(OBJECTIVE_NONE);
+ }
+ else {
+ pPed->m_prevObjective = OBJECTIVE_NONE;
+ pPed->m_nLastPedState = PED_IDLE;
+ }
+ }
+ }
+ }
+}
+
void
CWorld::RemoveEntityInsteadOfProcessingIt(CEntity* ent)
{
@@ -1057,6 +1567,243 @@ CWorld::ExtinguishAllCarFiresInArea(CVector point, float range)
}
}
+void
+CWorld::AddParticles(void)
+{
+ for (int32 y = 0; y < NUMSECTORS_Y; y++) {
+ for (int32 x = 0; x < NUMSECTORS_X; x++) {
+ CSector* pSector = GetSector(x, y);
+ CEntity::AddSteamsFromGround(pSector->m_lists[ENTITYLIST_BUILDINGS]);
+ CEntity::AddSteamsFromGround(pSector->m_lists[ENTITYLIST_DUMMIES]);
+ }
+ }
+}
+
+void
+CWorld::ShutDown(void)
+{
+ for (int32 y = 0; y < NUMSECTORS_Y; y++) {
+ for (int32 x = 0; x < NUMSECTORS_X; x++) {
+ CSector *pSector = GetSector(x, y);
+ CPtrNode *pNode = pSector->m_lists[ENTITYLIST_BUILDINGS].first;
+ while (pNode) {
+ CEntity* pEntity = (CEntity*)pNode->item;
+ if (pEntity) {
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ pNode = pNode->next;
+ }
+ pNode = pSector->m_lists[ENTITYLIST_VEHICLES].first;
+ while (pNode) {
+ CEntity* pEntity = (CEntity*)pNode->item;
+ if (pEntity) {
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ pNode = pNode->next;
+ }
+ pNode = pSector->m_lists[ENTITYLIST_PEDS].first;
+ while (pNode) {
+ CEntity *pEntity = (CEntity*)pNode->item;
+ if (pEntity) {
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ pNode = pNode->next;
+ }
+ pNode = pSector->m_lists[ENTITYLIST_OBJECTS].first;
+ while (pNode) {
+ CEntity *pEntity = (CEntity*)pNode->item;
+ if (pEntity) {
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ pNode = pNode->next;
+ }
+ pNode = pSector->m_lists[ENTITYLIST_DUMMIES].first;
+ while (pNode) {
+ CEntity *pEntity = (CEntity*)pNode->item;
+ if (pEntity) {
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ pNode = pNode->next;
+ }
+ pSector->m_lists[ENTITYLIST_BUILDINGS].Flush();
+ pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush();
+ pSector->m_lists[ENTITYLIST_DUMMIES].Flush();
+ pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush();
+ }
+ }
+ for (int32 i = 0; i < 4; i ++) {
+ CPtrNode *pNode = GetBigBuildingList((eLevelName)i).first;
+ while (pNode) {
+ CEntity *pEntity = (CEntity*)pNode->item;
+ if (pEntity) {
+ // Maybe remove from world here?
+ delete pEntity;
+ }
+ pNode = pNode->next;
+ }
+ GetBigBuildingList((eLevelName)i).Flush();
+ }
+ for (int32 y = 0; y < NUMSECTORS_Y; y++) {
+ for (int32 x = 0; x < NUMSECTORS_X; x++) {
+ CSector *pSector = GetSector(x, y);
+ if (pSector->m_lists[ENTITYLIST_BUILDINGS].first) {
+ sprintf(gString, "Building list %d,%d not empty\n", x, y);
+ pSector->m_lists[ENTITYLIST_BUILDINGS].Flush();
+ }
+ if (pSector->m_lists[ENTITYLIST_DUMMIES].first) {
+ sprintf(gString, "Dummy list %d,%d not empty\n", x, y);
+ pSector->m_lists[ENTITYLIST_DUMMIES].Flush();
+ }
+ if (pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].first) {
+ sprintf(gString, "Building overlap list %d,%d not empty\n", x, y);
+ pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush();
+ }
+ if (pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP].first) {
+ sprintf(gString, "Vehicle overlap list %d,%d not empty\n", x, y);
+ pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP].Flush();
+ }
+ if (pSector->m_lists[ENTITYLIST_PEDS_OVERLAP].first) {
+ sprintf(gString, "Ped overlap list %d,%d not empty\n", x, y);
+ pSector->m_lists[ENTITYLIST_PEDS_OVERLAP].Flush();
+ }
+ if (pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP].first) {
+ sprintf(gString, "Object overlap list %d,%d not empty\n", x, y);
+ pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP].Flush();
+ }
+ if (pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].first) {
+ sprintf(gString, "Dummy overlap list %d,%d not empty\n", x, y);
+ pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush();
+ }
+ }
+ }
+ ms_listMovingEntityPtrs.Flush();
+}
+
+void
+CWorld::ClearForRestart(void)
+{
+ if (CCutsceneMgr::HasLoaded())
+ CCutsceneMgr::DeleteCutsceneData();
+ CProjectileInfo::RemoveAllProjectiles();
+ CObject::DeleteAllTempObjects();
+ CObject::DeleteAllMissionObjects();
+ CPopulation::ConvertAllObjectsToDummyObjects();
+ for (int32 y = 0; y < NUMSECTORS_Y; y++) {
+ for (int32 x = 0; x < NUMSECTORS_X; x++) {
+ CSector *pSector = GetSector(x, y);
+ CPtrNode *pNode = pSector->m_lists[ENTITYLIST_PEDS].first;
+ while (pNode) {
+ CEntity *pEntity = (CEntity*)pNode->item;
+ if (pEntity) {
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ pNode = pNode->next;
+ }
+ pNode = GetBigBuildingList(LEVEL_NONE).first;
+ while (pNode) {
+ CVehicle *pVehicle = (CVehicle*)pNode->item;
+ if (pVehicle && pVehicle->IsVehicle() && pVehicle->IsPlane()) {
+ CWorld::Remove(pVehicle);
+ delete pVehicle;
+ }
+ pNode = pNode->next;
+ }
+ pNode = pSector->m_lists[ENTITYLIST_VEHICLES].first;
+ while (pNode) {
+ CEntity* pEntity = (CEntity*)pNode->item;
+ if (pEntity) {
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ pNode = pNode->next;
+ }
+ }
+ }
+ CPools::CheckPoolsEmpty();
+}
+
+void
+CWorld::RepositionCertainDynamicObjects()
+{
+ int32 i = CPools::GetDummyPool()->GetSize();
+ while (--i >= 0) {
+ CDummy* dummy = CPools::GetDummyPool()->GetSlot(i);
+ if (dummy) {
+ RepositionOneObject(dummy);
+ }
+ }
+}
+
+void
+CWorld::RepositionOneObject(CEntity* pEntity)
+{
+ int16 modelId = pEntity->m_modelIndex;
+ if (modelId == MI_SINGLESTREETLIGHTS1
+ || modelId == MI_SINGLESTREETLIGHTS2
+ || modelId == MI_SINGLESTREETLIGHTS3
+ || modelId == MI_DOUBLESTREETLIGHTS
+ || modelId == MI_TREE1
+ || modelId == MI_TREE2
+ || modelId == MI_TREE3
+ || modelId == MI_TREE4
+ || modelId == MI_TREE5
+ || modelId == MI_TREE6
+ || modelId == MI_TREE7
+ || modelId == MI_TREE8
+ || modelId == MI_TREE9
+ || modelId == MI_TREE10
+ || modelId == MI_TREE11
+ || modelId == MI_TREE12
+ || modelId == MI_TREE13
+ || modelId == MI_TREE14
+ || modelId == MI_TRAFFICLIGHTS
+ || modelId == MI_PARKINGMETER
+ || modelId == MI_PHONEBOOTH1
+ || modelId == MI_WASTEBIN
+ || modelId == MI_BIN
+ || modelId == MI_POSTBOX1
+ || modelId == MI_NEWSSTAND
+ || modelId == MI_TRAFFICCONE
+ || modelId == MI_DUMP1
+ || modelId == MI_ROADWORKBARRIER1
+ || modelId == MI_BUSSIGN1
+ || modelId == MI_NOPARKINGSIGN1
+ || modelId == MI_PHONESIGN
+ || modelId == MI_TAXISIGN
+ || modelId == MI_FISHSTALL01
+ || modelId == MI_FISHSTALL02
+ || modelId == MI_FISHSTALL03
+ || modelId == MI_FISHSTALL04
+ || modelId == MI_BAGELSTAND2
+ || modelId == MI_FIRE_HYDRANT
+ || modelId == MI_BOLLARDLIGHT
+ || modelId == MI_PARKTABLE) {
+ CVector& position = pEntity->GetPosition();
+ float fBoundingBoxMinZ = pEntity->GetColModel()->boundingBox.min.z;
+ position.z = CWorld::FindGroundZFor3DCoord(position.x, position.y, position.z + OBJECT_REPOSITION_OFFSET_Z, nil) - fBoundingBoxMinZ;
+ pEntity->m_matrix.UpdateRW();
+ pEntity->UpdateRwFrame();
+ } else if (modelId == MI_BUOY) {
+ float fWaterLevel = 0.0f;
+ bool bFound = true;
+ const CVector& position = pEntity->GetPosition();
+ float fGroundZ = CWorld::FindGroundZFor3DCoord(position.x, position.y, position.z + OBJECT_REPOSITION_OFFSET_Z, &bFound);
+ if (CWaterLevel::GetWaterLevelNoWaves(position.x, position.y, position.z + OBJECT_REPOSITION_OFFSET_Z, &fWaterLevel)) {
+ if (!bFound || fWaterLevel > fGroundZ) {
+ CColModel* pColModel = pEntity->GetColModel();
+ float fHeight = pColModel->boundingBox.max.z - pColModel->boundingBox.min.z;
+ pEntity->GetPosition().z = 0.2f * fHeight + fWaterLevel - 0.5f * fHeight;
+ }
+ }
+ }
+}
+
void
CWorld::SetCarsOnFire(float x, float y, float z, float radius, CEntity *reason)
{
@@ -1070,6 +1817,60 @@ CWorld::SetCarsOnFire(float x, float y, float z, float radius, CEntity *reason)
}
}
+void
+CWorld::SetPedsOnFire(float x, float y, float z, float radius, CEntity* reason)
+{
+ int32 poolSize = CPools::GetPedPool()->GetSize();
+ for (int32 i = poolSize - 1; i >= 0; i--) {
+ CPed* pPed = CPools::GetPedPool()->GetSlot(i);
+ if (pPed && pPed->m_nPedState != PED_DEAD && !pPed->bInVehicle && !pPed->m_pFire && !pPed->bFireProof) {
+ if (Abs(pPed->GetPosition().z - z) < 5.0f && Abs(pPed->GetPosition().x - x) < radius && Abs(pPed->GetPosition().y - y) < radius)
+ gFireManager.StartFire(pPed, reason, 0.8f, true);
+ }
+ }
+}
+
+void
+CWorld::RemoveStaticObjects()
+{
+ for (int32 y = 0; y < NUMSECTORS_Y; y++) {
+ for (int32 x = 0; x < NUMSECTORS_X; x++) {
+ CSector* pSector = GetSector(x, y);
+ CPtrNode* pNode = pSector->m_lists[ENTITYLIST_BUILDINGS].first;
+ while (pNode) {
+ CEntity* pEntity = (CEntity*)pNode->item;
+ if (pEntity) {
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ pNode = pNode->next;
+ }
+ pNode = pSector->m_lists[ENTITYLIST_OBJECTS].first;
+ while (pNode) {
+ CEntity* pEntity = (CEntity*)pNode->item;
+ if (pEntity) {
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ pNode = pNode->next;
+ }
+ pNode = pSector->m_lists[ENTITYLIST_DUMMIES].first;
+ while (pNode) {
+ CEntity* pEntity = (CEntity*)pNode->item;
+ if (pEntity) {
+ CWorld::Remove(pEntity);
+ delete pEntity;
+ }
+ pNode = pNode->next;
+ }
+ pSector->m_lists[ENTITYLIST_BUILDINGS].Flush();
+ pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush();
+ pSector->m_lists[ENTITYLIST_DUMMIES].Flush();
+ pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush();
+ }
+ }
+}
+
void
CWorld::Process(void)
{
@@ -1248,6 +2049,147 @@ CWorld::Process(void)
}
}
+void
+CWorld::TriggerExplosion(const CVector& position, float fRadius, float fPower, CEntity* pCreator, bool bProcessVehicleBombTimer)
+{
+ CVector2D vecStartPos(position.x - fRadius, position.y - fRadius);
+ CVector2D vecEndPos(position.x + fRadius, position.y + fRadius);
+ const int32 nStartX = max(CWorld::GetSectorIndexX(vecStartPos.x), 0);
+ const int32 nStartY = max(CWorld::GetSectorIndexY(vecStartPos.y), 0);
+ const int32 nEndX = min(CWorld::GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1);
+ const int32 nEndY = min(CWorld::GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1);
+ for (int32 y = nStartY; y <= nEndY; y++) {
+ for (int32 x = nStartX; x <= nEndX; x++) {
+ CSector* pSector = CWorld::GetSector(x, y);
+ CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], position, fRadius, fPower, pCreator, bProcessVehicleBombTimer);
+ CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, fRadius, fPower, pCreator, bProcessVehicleBombTimer);
+ CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], position, fRadius, fPower, pCreator, bProcessVehicleBombTimer);
+ }
+ }
+
+}
+
+void
+CWorld::TriggerExplosionSectorList(CPtrList& list, const CVector& position, float fRadius, float fPower, CEntity* pCreator, bool bProcessVehicleBombTimer)
+{
+ CPtrNode* pNode = list.first;
+ while (pNode) {
+ CPhysical* pEntity = (CPhysical*)pNode->item;
+ CVector vecDistance = pEntity->GetPosition() - position;
+ float fMagnitude = vecDistance.Magnitude();
+ if (fRadius > fMagnitude) {
+ CWeapon::BlowUpExplosiveThings(pEntity);
+ CPed* pPed = (CPed*)pEntity;
+ CObject* pObject = (CObject*)pEntity;
+ CVehicle* pVehicle = (CVehicle*)pEntity;
+ if (!pEntity->bExplosionProof && (!pEntity->IsPed() || !pPed->bInVehicle)) {
+ if (pEntity->bIsStatic) {
+ if (pEntity->IsObject()) {
+ if (fPower > pObject->m_fUprootLimit || IsFence(pObject->m_modelIndex)) {
+ if (IsGlass(pObject->m_modelIndex)) {
+ CGlass::WindowRespondsToExplosion(pObject, position);
+ } else {
+ pObject->bIsStatic = false;
+ pObject->AddToMovingList();
+ int16 modelId = pEntity->m_modelIndex;
+ if (modelId != MI_FIRE_HYDRANT || pObject->bHasBeenDamaged) {
+ if (pEntity->IsObject() && modelId != MI_EXPLODINGBARREL && modelId != MI_PETROLPUMP)
+ pObject->bHasBeenDamaged = true;
+ } else {
+ CVector pos = pEntity->GetPosition();
+ pos.z -= 0.5f;
+ CParticleObject::AddObject(POBJECT_FIRE_HYDRANT, pos, true);
+ pObject->bHasBeenDamaged = true;
+ }
+ }
+ }
+ if (pEntity->bIsStatic) {
+ float fDamageMultiplier = (fRadius - fMagnitude) * 2.0f / fRadius;
+ float fDamage = 300.0f * min(fDamageMultiplier, 1.0f);
+ pObject->ObjectDamage(fDamage);
+ }
+ } else {
+ pEntity->bIsStatic = false;
+ pEntity->AddToMovingList();
+ }
+ }
+ if (!pEntity->bIsStatic) {
+ float fDamageMultiplier = min((fRadius - fMagnitude) * 2.0f / fRadius, 1.0f);
+ CVector vecForceDir = vecDistance * (fPower * pEntity->m_fMass * 0.00071429f * fDamageMultiplier / max(fMagnitude, 0.01f));
+ vecForceDir.z = max(vecForceDir.z, 0.0f);
+ if (pEntity == FindPlayerPed())
+ vecForceDir.z = min(vecForceDir.z, 1.0f);
+ pEntity->ApplyMoveForce(vecForceDir);
+ if (!pEntity->bPedPhysics) {
+ float fBoundRadius = pEntity->GetBoundRadius();
+ float fDistanceZ = position.z - pEntity->GetPosition().z;
+ float fPointZ = fBoundRadius;
+ if (max(fDistanceZ, -fBoundRadius) < fBoundRadius)
+ {
+ if (fDistanceZ <= -fBoundRadius)
+ fPointZ = -fBoundRadius;
+ else
+ fPointZ = fDistanceZ;
+ }
+ pEntity->ApplyTurnForce(vecForceDir.x, vecForceDir.y, vecForceDir.z, 0.0f, 0.0f, fPointZ);
+ }
+ switch (pEntity->m_type)
+ {
+ case ENTITY_TYPE_VEHICLE:
+ if (pEntity->m_status == STATUS_SIMPLE) {
+ pEntity->m_status = STATUS_PHYSICS;
+ CCarCtrl::SwitchVehicleToRealPhysics(pVehicle);
+ }
+ pVehicle->InflictDamage(pCreator, WEAPONTYPE_EXPLOSION, 1100.0f * fDamageMultiplier);
+ if (bProcessVehicleBombTimer) {
+ if (pVehicle->m_nBombTimer)
+ pVehicle->m_nBombTimer /= 10;
+ }
+ break;
+ case ENTITY_TYPE_PED: {
+ int8 direction = pPed->GetLocalDirection(-vecForceDir);
+ pPed->bIsStanding = false;
+ pPed->ApplyMoveForce(0.0, 0.0, 2.0f);
+ float fDamage = 250.0f * fDamageMultiplier;
+ pPed->InflictDamage(pCreator, WEAPONTYPE_EXPLOSION, fDamage, PEDPIECE_TORSO, direction);
+ if (pPed->m_nPedState!= PED_DIE)
+ pPed->SetFall(2000, (AnimationId)(direction + ANIM_KO_SKID_FRONT), 0);
+ if (pCreator && pCreator->IsPed()) {
+ eEventType eventType = EVENT_SHOOT_PED;
+ if (pPed->m_nPedType == PEDTYPE_COP)
+ eventType = EVENT_SHOOT_COP;
+ CEventList::RegisterEvent(eventType, EVENT_ENTITY_PED, pEntity, (CPed*)pCreator, 10000);
+ pPed->RegisterThreatWithGangPeds(pCreator);
+ }
+ break;
+ }
+ case ENTITY_TYPE_OBJECT:
+ pObject->ObjectDamage(300.0f * fDamageMultiplier);
+ break;
+ }
+ }
+ }
+ }
+ pNode = pNode->next;
+ }
+}
+
+void
+CWorld::UseDetonator(CEntity* pEntity)
+{
+ int32 i = CPools::GetVehiclePool()->GetSize();
+ while (--i >= 0) {
+ CAutomobile* pVehicle = (CAutomobile*)CPools::GetVehiclePool()->GetSlot(i);
+ if (pVehicle && !pVehicle->m_vehType && pVehicle->m_bombType == CARBOMB_REMOTE && pVehicle->m_pBombRigger == pEntity) {
+ pVehicle->m_bombType = CARBOMB_NONE;
+ pVehicle->m_nBombTimer = 500;
+ pVehicle->m_pBlowUpEntity = pVehicle->m_pBombRigger;
+ if (pVehicle->m_pBlowUpEntity)
+ pVehicle->m_pBlowUpEntity->RegisterReference(&pVehicle->m_pBlowUpEntity);
+ }
+ }
+}
+
STARTPATCHES
InjectHook(0x4AE930, CWorld::Add, PATCH_JUMP);
InjectHook(0x4AE9D0, CWorld::Remove, PATCH_JUMP);
diff --git a/src/core/World.h b/src/core/World.h
index d3f1e2d5..a1e2acfd 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -85,7 +85,7 @@ public:
}
}
static void ClearScanCodes(void);
- static void ClearExcitingStuffFromArea(const CVector &pos, float radius, uint8);
+ static void ClearExcitingStuffFromArea(const CVector &pos, float radius, bool bRemoveProjectilesAndTidyUpShadows);
static bool CameraToIgnoreThisObject(CEntity *ent);
@@ -103,19 +103,26 @@ public:
static CEntity *TestSphereAgainstSectorList(CPtrList&, CVector, float, CEntity*, bool);
static void FindObjectsInRangeSectorList(CPtrList&, CVector&, float, bool, short*, short, CEntity**);
static void FindObjectsInRange(CVector&, float, bool, short*, short, CEntity**, bool, bool, bool, bool, bool);
- static void FindObjectsOfTypeInRangeSectorList(uint32, CPtrList&, CVector&, float, bool, short*, short, CEntity**);
- static void FindObjectsOfTypeInRange(uint32, CVector&, float, bool, short*, short, CEntity**, bool, bool, bool, bool, bool);
+ static void FindObjectsOfTypeInRangeSectorList(uint32 modelId, CPtrList& list, const CVector& position, float radius, bool bCheck2DOnly, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities);
+ static void FindObjectsOfTypeInRange(uint32 modelId, const CVector& position, float radius, bool bCheck2DOnly, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies);
static float FindGroundZForCoord(float x, float y);
static float FindGroundZFor3DCoord(float x, float y, float z, bool *found);
static float FindRoofZFor3DCoord(float x, float y, float z, bool *found);
static void RemoveReferencesToDeletedObject(CEntity*);
- static void FindObjectsKindaColliding(const CVector &, float, bool, int16*, int16, CEntity **, bool, bool, bool, bool, bool);
- static void FindObjectsIntersectingCube(const CVector &, const CVector &, int16*, int16, CEntity **, bool, bool, bool, bool, bool);
+ static void FindObjectsKindaColliding(const CVector& position, float radius, bool bCheck2DOnly, int16* nCollidingEntities, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies);
+ static void FindObjectsKindaCollidingSectorList(CPtrList& list, const CVector& position, float radius, bool bCheck2DOnly, int16* nCollidingEntities, int16 maxEntitiesToFind, CEntity** aEntities);
+ static void FindObjectsIntersectingCube(const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bBuildings, bool bVehicles, bool bPeds, bool bObjects, bool bDummies);
+ static void FindObjectsIntersectingCubeSectorList(CPtrList& list, const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities);
static void FindObjectsIntersectingAngledCollisionBox(const CColBox &, const CMatrix &, const CVector &, float, float, float, float, int16*, int16, CEntity **, bool, bool, bool, bool, bool);
- static void FindMissionEntitiesIntersectingCube(const CVector&, const CVector&, int16*, int16, CEntity**, bool, bool, bool);
- static void ClearCarsFromArea(float, float, float, float, float, float);
- static void ClearPedsFromArea(float, float, float, float, float, float);
- static void CallOffChaseForArea(float, float, float, float);
+ static void FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList& list, const CColBox& boundingBox, const CMatrix& matrix, const CVector& position, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities);
+ static void FindMissionEntitiesIntersectingCube(const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bVehicles, bool bPeds, bool bObjects);
+ static void FindMissionEntitiesIntersectingCubeSectorList(CPtrList& list, const CVector& vecStartPos, const CVector& vecEndPos, int16* nIntersecting, int16 maxEntitiesToFind, CEntity** aEntities, bool bIsVehicleList, bool bIsPedList);
+
+ static void ClearCarsFromArea(float x1, float y1, float z1, float x2, float y2, float z2);
+ static void ClearPedsFromArea(float x1, float y1, float z1, float x2, float y2, float z2);
+ static void CallOffChaseForArea(float x1, float y1, float x2, float y2);
+ static void CallOffChaseForAreaSectorListVehicles(CPtrList& list, float x1, float y1, float x2, float y2, float fStartX, float fStartY, float fEndX, float fEndY);
+ static void CallOffChaseForAreaSectorListPeds(CPtrList& list, float x1, float y1, float x2, float y2);
static float GetSectorX(float f) { return ((f - WORLD_MIN_X)/SECTOR_SIZE_X); }
static float GetSectorY(float f) { return ((f - WORLD_MIN_Y)/SECTOR_SIZE_Y); }
@@ -131,19 +138,20 @@ public:
static void StopAllLawEnforcersInTheirTracks();
static void SetAllCarsCanBeDamaged(bool);
static void ExtinguishAllCarFiresInArea(CVector, float);
- static void SetCarsOnFire(float, float, float, float, CEntity*);
- static void SetPedsOnFire(float, float, float, float, CEntity*);
+ static void SetCarsOnFire(float x, float y, float z, float radius, CEntity* reason);
+ static void SetPedsOnFire(float x, float y, float z, float radius, CEntity* reason);
static void Initialise();
static void AddParticles();
static void ShutDown();
static void ClearForRestart(void);
static void RepositionCertainDynamicObjects();
+ static void RepositionOneObject(CEntity* pEntity);
static void RemoveStaticObjects();
static void Process();
- static void TriggerExplosion(const CVector &, float, float, CEntity*, bool);
-
- static void UseDetonator(CEntity *);
+ static void TriggerExplosion(const CVector& position, float fRadius, float fPower, CEntity* pCreator, bool bProcessVehicleBombTimer);
+ static void TriggerExplosionSectorList(CPtrList& list, const CVector& position, float fRadius, float fPower, CEntity* pCreator, bool bProcessVehicleBombTimer);
+ static void UseDetonator(CEntity *pEntity);
};
extern CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS];
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index ecf02f39..2046a7f9 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -350,6 +350,9 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Debug", "Draw hud", (int8*)&CHud::m_Wants_To_Draw_Hud, nil);
DebugMenuAddVarBool8("Debug", "Edit on", (int8*)&CSceneEdit::m_bEditOn, nil);
+#ifdef MENU_MAP
+ DebugMenuAddCmd("Debug", "Teleport to map waypoint", TeleportToWaypoint);
+#endif
DebugMenuAddVar("Debug", "Engine Status", &engineStatus, nil, 1, 0, 226, nil);
DebugMenuAddCmd("Debug", "Set Engine Status", SetEngineStatus);
DebugMenuAddCmd("Debug", "Fix Car", FixCar);
@@ -374,9 +377,6 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Debug", "Don't render Peds", (int8*)&gbDontRenderPeds, nil);
DebugMenuAddVarBool8("Debug", "Don't render Vehicles", (int8*)&gbDontRenderVehicles, nil);
DebugMenuAddVarBool8("Debug", "Don't render Objects", (int8*)&gbDontRenderObjects, nil);
-#ifdef MENU_MAP
- DebugMenuAddCmd("Debug", "Teleport to map waypoint", TeleportToWaypoint);
-#endif
#ifdef TOGGLEABLE_BETA_FEATURES
DebugMenuAddVarBool8("Debug", "Toggle banned particles", (int8*)&CParticle::bEnableBannedParticles, nil);
DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", (int8*)&CPed::bPopHeadsOnHeadshot, nil);
diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp
index 25e5db48..0efee4e7 100644
--- a/src/entities/Entity.cpp
+++ b/src/entities/Entity.cpp
@@ -865,6 +865,16 @@ CEntity::ModifyMatrixForBannerInWind(void)
UpdateRwFrame();
}
+void
+CEntity::AddSteamsFromGround(CPtrList& list)
+{
+ CPtrNode *pNode = list.first;
+ while (pNode) {
+ ((CEntity*)pNode->item)->AddSteamsFromGround(nil);
+ pNode = pNode->next;
+ }
+}
+
#include <new>
class CEntity_ : public CEntity
@@ -912,7 +922,7 @@ STARTPATCHES
InjectHook(0x473F60, &CEntity::DetachFromRwObject, PATCH_JUMP);
InjectHook(0x475A20, &CEntity::PreRenderForGlassWindow, PATCH_JUMP);
- InjectHook(0x50CE40, &CEntity::AddSteamsFromGround, PATCH_JUMP);
+ InjectHook(0x50CE40, (void (CEntity::*)(CVector*))& CEntity::AddSteamsFromGround, PATCH_JUMP);
InjectHook(0x475670, &CEntity::ModifyMatrixForTreeInWind, PATCH_JUMP);
InjectHook(0x475830, &CEntity::ModifyMatrixForBannerInWind, PATCH_JUMP);
InjectHook(0x4FA530, &CEntity::ProcessLightsForEntity, PATCH_JUMP);
diff --git a/src/entities/Entity.h b/src/entities/Entity.h
index ca501ba4..dadeee54 100644
--- a/src/entities/Entity.h
+++ b/src/entities/Entity.h
@@ -4,6 +4,7 @@
#include "Placeable.h"
struct CReference;
+class CPtrList;
enum eEntityType
{
@@ -152,5 +153,7 @@ public:
void ModifyMatrixForTreeInWind(void);
void ModifyMatrixForBannerInWind(void);
void ProcessLightsForEntity(void);
+
+ static void AddSteamsFromGround(CPtrList& list);
};
static_assert(sizeof(CEntity) == 0x64, "CEntity: error");
diff --git a/src/modelinfo/ModelIndices.h b/src/modelinfo/ModelIndices.h
index 309fa1bb..cc8399e7 100644
--- a/src/modelinfo/ModelIndices.h
+++ b/src/modelinfo/ModelIndices.h
@@ -496,4 +496,11 @@ IsExplosiveThingModel(int16 id)
{
return id == MI_EXPLODINGBARREL ||
id == MI_PETROLPUMP;
+}
+
+inline bool
+IsFence(int16 id)
+{
+ return id == MI_FENCE ||
+ id == MI_FENCE2;
} \ No newline at end of file
diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp
index 57713241..c22148e9 100644
--- a/src/objects/Object.cpp
+++ b/src/objects/Object.cpp
@@ -383,7 +383,7 @@ CObject::DeleteAllTempObjects()
}
void
-CObject::DeleteAllTempObjectInArea(CVector point, float fRadius)
+CObject::DeleteAllTempObjectsInArea(CVector point, float fRadius)
{
CObjectPool *objectPool = CPools::GetObjectPool();
for (int32 i = 0; i < objectPool->GetSize(); i++) {
@@ -426,5 +426,5 @@ STARTPATCHES
InjectHook(0x4BB010, &CObject::CanBeDeleted, PATCH_JUMP);
InjectHook(0x4BBE60, &CObject::DeleteAllMissionObjects, PATCH_JUMP);
InjectHook(0x4BBDF0, &CObject::DeleteAllTempObjects, PATCH_JUMP);
- InjectHook(0x4BBED0, &CObject::DeleteAllTempObjectInArea, PATCH_JUMP);
+ InjectHook(0x4BBED0, &CObject::DeleteAllTempObjectsInArea, PATCH_JUMP);
ENDPATCHES
diff --git a/src/objects/Object.h b/src/objects/Object.h
index 90663cc5..0c00f441 100644
--- a/src/objects/Object.h
+++ b/src/objects/Object.h
@@ -99,6 +99,6 @@ public:
static void DeleteAllMissionObjects();
static void DeleteAllTempObjects();
- static void DeleteAllTempObjectInArea(CVector point, float fRadius);
+ static void DeleteAllTempObjectsInArea(CVector point, float fRadius);
};
static_assert(sizeof(CObject) == 0x198, "CObject: error");
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index 412b1f04..8ea41230 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -1623,6 +1623,15 @@ CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg)
if (ped->IsPlayer())
AudioManager.PlayerJustLeftCar();
+#ifdef VC_PED_PORTS
+ if (ped->m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE) {
+ dragAssoc->SetDeleteCallback(PedSetDraggedOutCarPositionCB, ped);
+ ped->m_fHealth = 0.0f;
+ ped->SetDie(ANIM_FLOOR_HIT, 1000.0f, 0.5f);
+ return;
+ }
+#endif
+
if (quickJackedAssoc) {
dragAssoc->SetDeleteCallback(PedSetQuickDraggedOutCarPositionCB, ped);
} else {
@@ -5186,7 +5195,7 @@ CPed::SetFall(int extraTime, AnimationId animId, uint8 evenIfNotInControl)
}
if (extraTime == -1) {
- m_getUpTimer = -1;
+ m_getUpTimer = UINT32_MAX;
} else if (fallAssoc) {
if (IsPlayer()) {
m_getUpTimer = 1000.0f * fallAssoc->hierarchy->totalLength
@@ -6448,7 +6457,7 @@ CPed::ExitCar(void)
void
CPed::Fall(void)
{
- if (m_getUpTimer != -1 && CTimer::GetTimeInMilliseconds() > m_getUpTimer
+ if (m_getUpTimer != UINT32_MAX && CTimer::GetTimeInMilliseconds() > m_getUpTimer
#ifdef VC_PED_PORTS
&& bIsStanding
#endif
@@ -10663,7 +10672,7 @@ CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg)
return;
if (ped->EnteringCar()) {
- bool isLow = veh->bLowVehicle;
+ bool isLow = !!veh->bLowVehicle;
if (!veh->bIsBus)
veh->ProcessOpenDoor(ped->m_vehEnterType, ANIM_CAR_CLOSEDOOR_LHS, 1.0f);
@@ -10691,7 +10700,11 @@ CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg)
#endif
|| !veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, nil))))) {
- if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
+ if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER
+#ifdef VC_PED_PORTS
+ || ped->m_nPedState == PED_CARJACK
+#endif
+ )
veh->bIsBeingCarJacked = false;
ped->m_objective = OBJECTIVE_ENTER_CAR_AS_PASSENGER;
@@ -11027,9 +11040,9 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
PedSetInCarCB(nil, ped);
return;
}
- bool isVan = veh->bIsVan;
- bool isBus = veh->bIsBus;
- bool isLow = veh->bLowVehicle;
+ bool isVan = !!veh->bIsVan;
+ bool isBus = !!veh->bIsBus;
+ bool isLow = !!veh->bLowVehicle;
eDoors enterDoor;
switch (ped->m_vehEnterType) {
case CAR_DOOR_RF:
@@ -11144,7 +11157,7 @@ CPed::PedAnimPullPedOutCB(CAnimBlendAssociation* animAssoc, void* arg)
if (!ped->IsNotInWreckedVehicle())
return;
- bool isLow = veh->bLowVehicle;
+ bool isLow = !!veh->bLowVehicle;
int padNo;
if (ped->IsPlayer()) {
@@ -11426,7 +11439,9 @@ CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation* animAssoc, void* arg)
CMatrix pedMat(ped->GetMatrix());
CVector posAfterBeingDragged = Multiply3x3(pedMat, (itsRearDoor ? -vecPedDraggedOutCarAnimOffset : vecPedDraggedOutCarAnimOffset));
posAfterBeingDragged += ped->GetPosition();
+#ifndef VC_PED_PORTS
posAfterBeingDragged.z += 1.0f;
+#endif
CPedPlacement::FindZCoorForPed(&posAfterBeingDragged);
ped->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
ped->GetPosition() = posAfterBeingDragged;
@@ -11476,17 +11491,26 @@ CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation* animAssoc, void* arg)
&& ped->m_pMyVehicle->VehicleCreatedBy != MISSION_VEHICLE && driver
&& driver->IsPlayer() && !CTheScripts::IsPlayerOnAMission()) {
+#ifndef VC_PED_PORTS
if (CGeneral::GetRandomNumber() & 1)
ped->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, driver);
else
+#endif
ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, ped->m_pMyVehicle);
} else {
- ped->m_nPedState = PED_NONE;
- ped->m_nLastPedState = PED_NONE;
- ped->SetFlee(ped->m_pMyVehicle->GetPosition(), 10000);
- ped->bUsePedNodeSeek = true;
- ped->m_pNextPathNode = nil;
+#ifdef VC_PED_PORTS
+ if (ped->m_pedStats->m_temper > ped->m_pedStats->m_fear && ped->CharCreatedBy != MISSION_CHAR
+ && ped->m_pMyVehicle->VehicleCreatedBy != MISSION_VEHICLE && !driver
+ && FindPlayerPed()->m_carInObjective == ped->m_pMyVehicle && !CTheScripts::IsPlayerOnAMission())
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, ped->m_pMyVehicle);
+ else
+#endif
+ {
+ ped->m_nPedState = PED_NONE;
+ ped->m_nLastPedState = PED_NONE;
+ ped->SetFindPathAndFlee(ped->m_pMyVehicle->GetPosition(), 10000);
+ }
}
ped->SetGetUp();
}
@@ -12289,24 +12313,36 @@ CPed::PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *animAssoc, void
ped->Say(SOUND_PED_FLEE_RUN);
}
} else {
- if (ped->m_pedStats->m_temper <= ped->m_pedStats->m_fear
- || ped->CharCreatedBy == MISSION_CHAR || veh->VehicleCreatedBy == MISSION_VEHICLE
- || !veh->pDriver || !veh->pDriver->IsPlayer()
- || CTheScripts::IsPlayerOnAMission()) {
+ if (ped->m_pedStats->m_temper > ped->m_pedStats->m_fear
+ && ped->CharCreatedBy != MISSION_CHAR && veh->VehicleCreatedBy != MISSION_VEHICLE
+ && veh->pDriver && veh->pDriver->IsPlayer()
+ && !CTheScripts::IsPlayerOnAMission()) {
- ped->SetFlee(veh->GetPosition(), 10000);
- ped->bUsePedNodeSeek = true;
- ped->m_pNextPathNode = nil;
- if (CGeneral::GetRandomNumber() & 1 || ped->m_pedStats->m_fear > 70) {
- ped->SetMoveState(PEDMOVE_SPRINT);
- ped->Say(SOUND_PED_FLEE_SPRINT);
- } else {
- ped->Say(SOUND_PED_FLEE_RUN);
+#ifndef VC_PED_PORTS
+ if (CGeneral::GetRandomNumber() < MYRAND_MAX / 2) {
+ ped->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, veh->pDriver);
+ } else
+#endif
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, veh);
+
+ } else {
+#ifdef VC_PED_PORTS
+ if (ped->m_pedStats->m_temper > ped->m_pedStats->m_fear && ped->CharCreatedBy != MISSION_CHAR
+ && ped->m_pMyVehicle->VehicleCreatedBy != MISSION_VEHICLE && !veh->pDriver
+ && FindPlayerPed()->m_carInObjective == ped->m_pMyVehicle && !CTheScripts::IsPlayerOnAMission())
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, veh);
+ else
+#endif
+ {
+ ped->SetFindPathAndFlee(veh->GetPosition(), 10000);
+ if (CGeneral::GetRandomNumber() & 1 || ped->m_pedStats->m_fear > 70) {
+ ped->SetMoveState(PEDMOVE_SPRINT);
+ ped->Say(SOUND_PED_FLEE_SPRINT);
+ } else {
+ ped->Say(SOUND_PED_FLEE_RUN);
+ }
}
- } else if (CGeneral::GetRandomNumber() < 0x3FFF) {
- ped->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, veh->pDriver);
- } else
- ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, veh);
+ }
}
}
if (ped->m_nLastPedState == PED_IDLE)
diff --git a/src/render/Coronas.cpp b/src/render/Coronas.cpp
index 38f86f4b..d70f70d6 100644
--- a/src/render/Coronas.cpp
+++ b/src/render/Coronas.cpp
@@ -48,7 +48,7 @@ FlareDef HeadLightsFlareDef[] = {
};
-RwTexture *gpCoronaTexture[9] = { NULL };
+RwTexture *gpCoronaTexture[9] = { nil, nil, nil, nil, nil, nil, nil, nil, nil };
float CCoronas::LightsMult = 1.0f;
float CCoronas::SunScreenX;