summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/control/CarAI.cpp4
-rw-r--r--src/control/CarCtrl.cpp6
-rw-r--r--src/control/Script.cpp92
-rw-r--r--src/control/Script.h3
-rw-r--r--src/core/ColStore.cpp11
-rw-r--r--src/core/World.cpp14
-rw-r--r--src/entities/Entity.cpp2
-rw-r--r--src/entities/Entity.h2
-rw-r--r--src/entities/Physical.cpp14
-rw-r--r--src/peds/Ped.cpp4
-rw-r--r--src/vehicles/Automobile.cpp2
-rw-r--r--src/weapons/BulletInfo.cpp4
-rw-r--r--src/weapons/Weapon.cpp10
13 files changed, 138 insertions, 30 deletions
diff --git a/src/control/CarAI.cpp b/src/control/CarAI.cpp
index 571a62d2..0330d80d 100644
--- a/src/control/CarAI.cpp
+++ b/src/control/CarAI.cpp
@@ -146,7 +146,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
case MISSION_BLOCKPLAYER_CLOSE:
if (FindSwitchDistanceFar(pVehicle) >= (FindPlayerCoors() - pVehicle->GetPosition()).Magnitude2D() ||
pVehicle->AutoPilot.m_bIgnorePathfinding) {
- if (FindPlayerVehicle() && FindPlayerVehicle()->GetMoveSpeed().Magnitude() < 0.05f)
+ if (FindPlayerVehicle() && FindPlayerVehicle()->GetMoveSpeed().Magnitude() < 0.04f)
#ifdef FIX_BUGS
pVehicle->m_nTimeBlocked += CTimer::GetTimeStepInMilliseconds();
#else
@@ -155,7 +155,7 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
else
pVehicle->m_nTimeBlocked = 0;
if (!FindPlayerVehicle() || FindPlayerVehicle()->IsUpsideDown() ||
- FindPlayerVehicle()->GetMoveSpeed().Magnitude() < 0.05f && pVehicle->m_nTimeBlocked > TIME_COPS_WAIT_TO_EXIT_AFTER_STOPPING) {
+ FindPlayerVehicle()->GetMoveSpeed().Magnitude() < 0.04f && pVehicle->m_nTimeBlocked > TIME_COPS_WAIT_TO_EXIT_AFTER_STOPPING) {
if (pVehicle->bIsLawEnforcer &&
(pVehicle->GetModelIndex() != MI_RHINO || pVehicle->m_randomSeed > 10000) &&
(FindPlayerCoors() - pVehicle->GetPosition()).Magnitude2D() < 10.0f) {
diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp
index 5dfb73d0..a4769d56 100644
--- a/src/control/CarCtrl.cpp
+++ b/src/control/CarCtrl.cpp
@@ -90,14 +90,16 @@ uint32 aCarsToKeepTime[MAX_CARS_TO_KEEP];
void
CCarCtrl::GenerateRandomCars()
{
- if (CCutsceneMgr::IsRunning())
+ if (CCutsceneMgr::IsRunning()) {
+ CountDownToCarsAtStart = 2;
return;
+ }
if (NumRandomCars < 30){
if (CountDownToCarsAtStart == 0){
GenerateOneRandomCar();
}
else if (--CountDownToCarsAtStart == 0) {
- for (int i = 0; i < 50; i++)
+ for (int i = 0; i < 100; i++)
GenerateOneRandomCar();
CTheCarGenerators::GenerateEvenIfPlayerIsCloseCounter = 20;
}
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index 8db2db81..3636e5e8 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -13,6 +13,7 @@
#include "CarGen.h"
#include "CivilianPed.h"
#include "Clock.h"
+#include "ColStore.h"
#include "CopPed.h"
#include "Coronas.h"
#include "Cranes.h"
@@ -170,10 +171,46 @@ void CMissionCleanup::AddEntityToList(int32 id, uint8 type)
m_nCount++;
}
+static void PossiblyWakeThisEntity(CPhysical* pEntity)
+{
+ if (!pEntity->bIsStaticWaitingForCollision)
+ return;
+ if (CColStore::HasCollisionLoaded(pEntity->GetPosition())) {
+ pEntity->bIsStaticWaitingForCollision = false;
+ if (!pEntity->IsStatic())
+ pEntity->AddToMovingList();
+ }
+}
+
void CMissionCleanup::RemoveEntityFromList(int32 id, uint8 type)
{
for (int i = 0; i < MAX_CLEANUP; i++){
if (m_sEntities[i].type == type && m_sEntities[i].id == id){
+ switch (m_sEntities[i].type) {
+ case CLEANUP_CAR:
+ {
+ CVehicle* v = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id);
+ if (v)
+ PossiblyWakeThisEntity(v);
+ break;
+ }
+ case CLEANUP_CHAR:
+ {
+ CPed* p = CPools::GetPedPool()->GetAt(m_sEntities[i].id);
+ if (p)
+ PossiblyWakeThisEntity(p);
+ break;
+ }
+ case CLEANUP_OBJECT:
+ {
+ CObject* o = CPools::GetObjectPool()->GetAt(m_sEntities[i].id);
+ if (o)
+ PossiblyWakeThisEntity(o);
+ break;
+ }
+ default:
+ break;
+ }
m_sEntities[i].id = 0;
m_sEntities[i].type = CLEANUP_UNUSED;
m_nCount--;
@@ -181,6 +218,52 @@ void CMissionCleanup::RemoveEntityFromList(int32 id, uint8 type)
}
}
+void CMissionCleanup::CheckIfCollisionHasLoadedForMissionObject()
+{
+ for (int i = 0; i < MAX_CLEANUP; i++) {
+ switch (m_sEntities[i].type) {
+ case CLEANUP_CAR:
+ {
+ CVehicle* v = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id);
+ if (v)
+ PossiblyWakeThisEntity(v);
+ break;
+ }
+ case CLEANUP_CHAR:
+ {
+ CPed* p = CPools::GetPedPool()->GetAt(m_sEntities[i].id);
+ if (p)
+ PossiblyWakeThisEntity(p);
+ break;
+ }
+ case CLEANUP_OBJECT:
+ {
+ CObject* o = CPools::GetObjectPool()->GetAt(m_sEntities[i].id);
+ if (o)
+ PossiblyWakeThisEntity(o);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+CPhysical* CMissionCleanup::DoesThisEntityWaitForCollision(int i)
+{
+ if (m_sEntities[i].type == CLEANUP_CAR) {
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id);
+ if (pVehicle && pVehicle->GetStatus() != STATUS_WRECKED)
+ return pVehicle;
+ }
+ else if (m_sEntities[i].type == CLEANUP_CHAR) {
+ CPed* pPed = CPools::GetPedPool()->GetAt(m_sEntities[i].id);
+ if (pPed && !pPed->DyingOrDead())
+ return pPed;
+ }
+ return nil;
+}
+
void CMissionCleanup::Process()
{
CPopulation::m_AllRandomPedsThisType = -1;
@@ -646,6 +729,7 @@ void CTheScripts::Process()
float timeStep = CTimer::GetTimeStepInMilliseconds();
UpsideDownCars.UpdateTimers();
StuckCars.Process();
+ MissionCleanup.CheckIfCollisionHasLoadedForMissionObject();
DrawScriptSpheres();
if (FailCurrentMission)
--FailCurrentMission;
@@ -1728,6 +1812,8 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
ped->SetPosition(pos);
ped->SetOrientation(0.0f, 0.0f, 0.0f);
CTheScripts::ClearSpaceForMissionEntity(pos, ped);
+ if (m_bIsMissionScript)
+ ped->bIsStaticWaitingForCollision = true;
CWorld::Add(ped);
ped->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pos);
CPopulation::ms_nTotalMissionPeds++;
@@ -1946,6 +2032,8 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
boat->AutoPilot.m_nCarMission = MISSION_NONE;
boat->AutoPilot.m_nTempAction = TEMPACT_NONE; /* Animation ID? */
boat->AutoPilot.m_nCruiseSpeed = boat->AutoPilot.m_fMaxTrafficSpeed = 20.0f;
+ if (m_bIsMissionScript)
+ boat->bIsStaticWaitingForCollision = true;
CWorld::Add(boat);
handle = CPools::GetVehiclePool()->GetIndex(boat);
}
@@ -1970,6 +2058,8 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
car->bEngineOn = false;
car->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pos);
car->bHasBeenOwnedByPlayer = true;
+ if (m_bIsMissionScript)
+ car->bIsStaticWaitingForCollision = true;
CWorld::Add(car);
handle = CPools::GetVehiclePool()->GetIndex(car);
}
@@ -7324,6 +7414,8 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
ped->SetPosition(pos);
ped->SetOrientation(0.0f, 0.0f, 0.0f);
CTheScripts::ClearSpaceForMissionEntity(pos, ped);
+ if (m_bIsMissionScript)
+ ped->bIsStaticWaitingForCollision = true;
CWorld::Add(ped);
ped->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pos);
CPopulation::ms_nTotalMissionPeds++;
diff --git a/src/control/Script.h b/src/control/Script.h
index a44fc7c1..46c6ae20 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -6,6 +6,7 @@
class CEntity;
class CBuilding;
+class CPhysical;
class CVehicle;
class CPed;
class CObject;
@@ -131,6 +132,8 @@ public:
void AddEntityToList(int32, uint8);
void RemoveEntityFromList(int32, uint8);
void Process();
+ void CheckIfCollisionHasLoadedForMissionObject();
+ CPhysical* DoesThisEntityWaitForCollision(int i);
};
struct CUpsideDownCarCheckEntry
diff --git a/src/core/ColStore.cpp b/src/core/ColStore.cpp
index 0715ae6e..feaf08c7 100644
--- a/src/core/ColStore.cpp
+++ b/src/core/ColStore.cpp
@@ -9,6 +9,7 @@
#include "Timer.h"
#include "Camera.h"
#include "Frontend.h"
+#include "Physical.h"
#include "ColStore.h"
CPool<ColDef,ColDef> *CColStore::ms_pColPool;
@@ -174,7 +175,13 @@ CColStore::LoadCollision(const CVector2D &pos)
CGeneral::faststrcmp(GetColName(i), "yacht") == 0){
wantThisOne = true;
}else{
- // TODO: check mission cleanup list
+ for (int j = 0; j < MAX_CLEANUP; j++) {
+ CPhysical* pEntity = CTheScripts::MissionCleanup.DoesThisEntityWaitForCollision(j);
+ if (pEntity /* !pEntity->bDontLoadCollision && !pEntity->bIsFrozen */) {
+ if (GetBoundingBox(i).IsPointInside(pEntity->GetPosition(), -80.0f))
+ wantThisOne = true;
+ }
+ }
}
if(wantThisOne)
@@ -221,7 +228,7 @@ CColStore::HasCollisionLoaded(const CVector2D &pos)
int i;
for(i = 1; i < COLSTORESIZE; i++)
- if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -110.0f) &&
+ if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -115.0f) &&
!GetSlot(i)->isLoaded)
return false;
return true;
diff --git a/src/core/World.cpp b/src/core/World.cpp
index 37ad6221..29505481 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -75,7 +75,7 @@ CWorld::Add(CEntity *ent)
if(ent->IsBuilding() || ent->IsDummy()) return;
- if(!ent->bIsStatic) ((CPhysical *)ent)->AddToMovingList();
+ if(!ent->IsStatic()) ((CPhysical *)ent)->AddToMovingList();
}
void
@@ -90,7 +90,7 @@ CWorld::Remove(CEntity *ent)
if(ent->IsBuilding() || ent->IsDummy()) return;
- if(!ent->bIsStatic) ((CPhysical *)ent)->RemoveFromMovingList();
+ if(!ent->IsStatic()) ((CPhysical *)ent)->RemoveFromMovingList();
}
void
@@ -1953,7 +1953,7 @@ CWorld::Process(void)
RemoveEntityInsteadOfProcessingIt(movingEnt);
} else {
movingEnt->ProcessControl();
- if(movingEnt->bIsStatic) { movingEnt->RemoveFromMovingList(); }
+ if(movingEnt->IsStatic()) { movingEnt->RemoveFromMovingList(); }
}
}
bForceProcessControl = true;
@@ -1964,7 +1964,7 @@ CWorld::Process(void)
RemoveEntityInsteadOfProcessingIt(movingEnt);
} else {
movingEnt->ProcessControl();
- if(movingEnt->bIsStatic) { movingEnt->RemoveFromMovingList(); }
+ if(movingEnt->IsStatic()) { movingEnt->RemoveFromMovingList(); }
}
}
}
@@ -2117,7 +2117,7 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa
CObject *pObject = (CObject *)pEntity;
CVehicle *pVehicle = (CVehicle *)pEntity;
if(!pEntity->bExplosionProof && (!pEntity->IsPed() || !pPed->bInVehicle)) {
- if(pEntity->bIsStatic) {
+ if(pEntity->IsStatic()) {
if(pEntity->IsObject()) {
if (fPower > pObject->m_fUprootLimit || IsFence(pObject->GetModelIndex())) {
if (IsGlass(pObject->GetModelIndex())) {
@@ -2141,7 +2141,7 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa
}
}
}
- if(pEntity->bIsStatic) {
+ if(pEntity->IsStatic()) {
float fDamageMultiplier =
(fRadius - fMagnitude) * 2.0f / fRadius;
float fDamage = 300.0f * Min(fDamageMultiplier, 1.0f);
@@ -2152,7 +2152,7 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa
pEntity->AddToMovingList();
}
}
- if(!pEntity->bIsStatic) {
+ if(!pEntity->IsStatic()) {
float fDamageMultiplier = Min((fRadius - fMagnitude) * 2.0f / fRadius, 1.0f);
CVector vecForceDir =
vecDistance * (fPower * pEntity->m_fMass * 0.00071429f * fDamageMultiplier /
diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp
index 6c7a628e..e3ecf50f 100644
--- a/src/entities/Entity.cpp
+++ b/src/entities/Entity.cpp
@@ -74,6 +74,8 @@ CEntity::CEntity(void)
bDistanceFade = false;
m_flagE2 = false;
+ bIsStaticWaitingForCollision = false;
+
m_scanCode = 0;
m_modelIndex = -1;
m_rwObject = nil;
diff --git a/src/entities/Entity.h b/src/entities/Entity.h
index 0534de27..e85e40f7 100644
--- a/src/entities/Entity.h
+++ b/src/entities/Entity.h
@@ -84,6 +84,7 @@ public:
// flagsE
uint32 m_flagE2 : 1;
// TODO(MIAMI)
+ uint32 bIsStaticWaitingForCollision : 1; // this is used by script created entities - they are static until the collision is loaded below them
uint16 m_scanCode;
uint16 m_randomSeed;
@@ -98,6 +99,7 @@ public:
eEntityStatus GetStatus() const { return (eEntityStatus)m_status; }
void SetStatus(eEntityStatus status) { m_status = status; }
CColModel *GetColModel(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel(); }
+ bool IsStatic(void) { return bIsStatic || bIsStaticWaitingForCollision; }
#ifdef COMPATIBLE_SAVES
void SaveEntityFlags(uint8*& buf);
void LoadEntityFlags(uint8*& buf);
diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp
index fe270645..bbe69167 100644
--- a/src/entities/Physical.cpp
+++ b/src/entities/Physical.cpp
@@ -324,7 +324,7 @@ CPhysical::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
AddCollisionRecord(ent);
if(!ent->IsBuilding()) // Can't this catch dummies too?
((CPhysical*)ent)->AddCollisionRecord(this);
- if(ent->IsBuilding() || ent->bIsStatic)
+ if(ent->IsBuilding() || ent->IsStatic())
this->bHasHitWall = true;
}
return numSpheres;
@@ -539,7 +539,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
timestepB = B->bIsHeavy ? 2.0f : 1.0f;
float speedA, speedB;
- if(B->bIsStatic){
+ if(B->IsStatic()){
if(A->bPedPhysics){
speedA = DotProduct(A->m_vecMoveSpeed, colpoint.normal);
if(speedA < 0.0f){
@@ -622,7 +622,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
}
}
- if(B->bIsStatic)
+ if(B->IsStatic())
return false;
if(!B->bInfiniteMass)
B->AddToMovingList();
@@ -1079,7 +1079,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
CObject *Aobj = (CObject*)A;
if(Aobj->ObjectCreatedBy != TEMP_OBJECT &&
!Aobj->bHasBeenDamaged &&
- Aobj->bIsStatic){
+ Aobj->IsStatic()){
if(Aobj->m_pCollidingEntity == B)
Aobj->m_pCollidingEntity = nil;
}else if(Aobj->m_pCollidingEntity != B){
@@ -1096,7 +1096,7 @@ CPhysical::ProcessShiftSectorList(CPtrList *lists)
CObject *Bobj = (CObject*)B;
if(Bobj->ObjectCreatedBy != TEMP_OBJECT &&
!Bobj->bHasBeenDamaged &&
- Bobj->bIsStatic){
+ Bobj->IsStatic()){
if(Bobj->m_pCollidingEntity == A)
Bobj->m_pCollidingEntity = nil;
}else if(Bobj->m_pCollidingEntity != A){
@@ -1414,7 +1414,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
skipCollision = true;
else if(Aobj->ObjectCreatedBy == TEMP_OBJECT ||
Aobj->bHasBeenDamaged ||
- !Aobj->bIsStatic){
+ !Aobj->IsStatic()){
if(Aobj->m_pCollidingEntity == B)
skipCollision = true;
else{
@@ -1433,7 +1433,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
skipCollision = true;
else if(Bobj->ObjectCreatedBy == TEMP_OBJECT ||
Bobj->bHasBeenDamaged ||
- !Bobj->bIsStatic){
+ !Bobj->IsStatic()){
if(Bobj->m_pCollidingEntity == A)
skipCollision = true;
else{
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index 0a0a807d..7286e677 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -14853,11 +14853,11 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
if (!collidingEnt->IsBuilding())
((CPhysical*)collidingEnt)->AddCollisionRecord(this);
- if (ourCollidedSpheres > 0 && (collidingEnt->IsBuilding() || collidingEnt->bIsStatic)) {
+ if (ourCollidedSpheres > 0 && (collidingEnt->IsBuilding() || collidingEnt->IsStatic())) {
bHasHitWall = true;
}
}
- if (collidingEnt->IsBuilding() || collidingEnt->bIsStatic) {
+ if (collidingEnt->IsBuilding() || collidingEnt->IsStatic()) {
if (bWasStanding) {
CVector sphereNormal;
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index 8b267c09..4f0029ef 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -2190,7 +2190,7 @@ CAutomobile::ProcessEntityCollision(CEntity *ent, CColPoint *colpoints)
}
// move body cast
- if(phys->bIsStatic){
+ if(phys->IsStatic()){
phys->bIsStatic = false;
phys->m_nStaticFrames = 0;
phys->ApplyMoveForce(m_vecMoveSpeed / Sqrt(speed));
diff --git a/src/weapons/BulletInfo.cpp b/src/weapons/BulletInfo.cpp
index b7270f4b..83b6471e 100644
--- a/src/weapons/BulletInfo.cpp
+++ b/src/weapons/BulletInfo.cpp
@@ -156,11 +156,11 @@ void CBulletInfo::Update(void)
if (pHitEntity->IsObject()) {
CObject* pObject = (CObject*)pHitEntity;
if (!pObject->bInfiniteMass) {
- if (pObject->bIsStatic && pObject->m_fUprootLimit <= 0.0f) {
+ if (pObject->IsStatic() && pObject->m_fUprootLimit <= 0.0f) {
pObject->bIsStatic = false;
pObject->AddToMovingList();
}
- if (!pObject->bIsStatic)
+ if (!pObject->IsStatic())
pObject->ApplyMoveForce(-BULLET_HIT_FORCE * point.normal);
}
}
diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp
index e9b917de..17ce64c0 100644
--- a/src/weapons/Weapon.cpp
+++ b/src/weapons/Weapon.cpp
@@ -1047,13 +1047,13 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
if ( !victimObject->bInfiniteMass )
{
- if ( victimObject->bIsStatic && victimObject->m_fUprootLimit <= 0.0f )
+ if ( victimObject->IsStatic() && victimObject->m_fUprootLimit <= 0.0f )
{
victimObject->bIsStatic = false;
victimObject->AddToMovingList();
}
- if ( !victimObject->bIsStatic )
+ if ( !victimObject->IsStatic())
{
CVector moveForce = point->normal*-4.0f;
victimObject->ApplyMoveForce(moveForce.x, moveForce.y, moveForce.z);
@@ -1296,13 +1296,13 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
if ( !victimObject->bInfiniteMass )
{
- if ( victimObject->bIsStatic && victimObject->m_fUprootLimit <= 0.0f )
+ if ( victimObject->IsStatic() && victimObject->m_fUprootLimit <= 0.0f )
{
victimObject->bIsStatic = false;
victimObject->AddToMovingList();
}
- if ( !victimObject->bIsStatic )
+ if ( !victimObject->IsStatic())
{
CVector moveForce = point.normal*-5.0f;
victimObject->ApplyMoveForce(moveForce.x, moveForce.y, moveForce.z);
@@ -2232,7 +2232,7 @@ CWeapon::BlowUpExplosiveThings(CEntity *thing)
object->m_vecMoveSpeed.x += float((CGeneral::GetRandomNumber()&255) - 128) * 0.0002f;
object->m_vecMoveSpeed.y += float((CGeneral::GetRandomNumber()&255) - 128) * 0.0002f;
- if ( object->bIsStatic )
+ if ( object->IsStatic())
{
object->bIsStatic = false;
object->AddToMovingList();