summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/Cam.cpp2
-rw-r--r--src/core/Camera.cpp19
-rw-r--r--src/core/ColStore.cpp237
-rw-r--r--src/core/ColStore.h43
-rw-r--r--src/core/Collision.cpp151
-rw-r--r--src/core/Collision.h40
-rw-r--r--src/core/EventList.cpp2
-rw-r--r--src/core/FileLoader.cpp471
-rw-r--r--src/core/FileLoader.h17
-rw-r--r--src/core/Frontend.cpp8
-rw-r--r--src/core/Frontend.h2
-rw-r--r--src/core/Game.cpp13
-rw-r--r--src/core/Game.h32
-rw-r--r--src/core/General.h2
-rw-r--r--src/core/Pad.cpp4
-rw-r--r--src/core/PlayerInfo.cpp2
-rw-r--r--src/core/PlayerInfo.h1
-rw-r--r--src/core/Pools.h4
-rw-r--r--src/core/Streaming.cpp856
-rw-r--r--src/core/Streaming.h29
-rw-r--r--src/core/TempColModels.cpp52
-rw-r--r--src/core/User.cpp4
-rw-r--r--src/core/Wanted.cpp6
-rw-r--r--src/core/Wanted.h1
-rw-r--r--src/core/World.cpp8
-rw-r--r--src/core/World.h18
-rw-r--r--src/core/ZoneCull.cpp434
-rw-r--r--src/core/ZoneCull.h69
-rw-r--r--src/core/Zones.cpp628
-rw-r--r--src/core/Zones.h52
-rw-r--r--src/core/common.h1
-rw-r--r--src/core/config.h79
-rw-r--r--src/core/main.cpp2
-rw-r--r--src/core/re3.cpp32
-rw-r--r--src/core/templates.h9
35 files changed, 1634 insertions, 1696 deletions
diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp
index 20b262c8..ae7df51f 100644
--- a/src/core/Cam.cpp
+++ b/src/core/Cam.cpp
@@ -4905,7 +4905,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
bool correctAlpha = true;
// if (SA checks if we aren't in work car, why?) {
- if (!isCar || car->GetModelIndex() != MI_YARDIE) {
+ if (!isCar || car->GetModelIndex() != MI_VOODOO) {
correctAlpha = false;
}
else {
diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp
index 9b178f35..73bbd75e 100644
--- a/src/core/Camera.cpp
+++ b/src/core/Camera.cpp
@@ -633,7 +633,11 @@ CCamera::CamControl(void)
m_bInitialNodeFound = false;
m_bInitialNoNodeStaticsSet = false;
}
+#ifdef GTA_TRAIN
Process_Train_Camera_Control();
+#else
+ assert(0 && "this can't happen");
+#endif
}else{
if(((CVehicle*)pTargetEntity)->IsBoat())
boatTarget = true;
@@ -930,11 +934,13 @@ CCamera::CamControl(void)
if(CCullZones::CamStairsForPlayer() && CCullZones::FindZoneWithStairsAttributeForPlayer())
stairs = true;
// Some hack for Mr Whoopee in a bomb shop
+#ifndef MIAMI // uhh, check this
if(Cams[ActiveCam].Using3rdPersonMouseCam() && CCollision::ms_collisionInMemory == LEVEL_COMMERCIAL){
if(pTargetEntity->GetPosition().x < 83.0f && pTargetEntity->GetPosition().x > 18.0f &&
pTargetEntity->GetPosition().y < -305.0f && pTargetEntity->GetPosition().y > -390.0f)
disableGarageCam = true;
}
+#endif
if(!disableGarageCam && (CGarages::IsPointInAGarageCameraZone(pTargetEntity->GetPosition()) || stairs)){
if(!m_bGarageFixedCamPositionSet && m_bLookingAtPlayer){
if(pToGarageWeAreIn || stairs){
@@ -1523,7 +1529,6 @@ CCamera::UpdateTargetEntity(void)
pTargetEntity = FindPlayerVehicle();
else{
pTargetEntity = FindPlayerPed();
-#ifndef GTA_PS2_STUFF
// this keeps the camera on the player while entering cars
if(PLAYER->GetPedState() == PED_ENTER_CAR ||
PLAYER->GetPedState() == PED_CARJACK ||
@@ -1533,7 +1538,6 @@ CCamera::UpdateTargetEntity(void)
if(!enteringCar)
if(Cams[ActiveCam].CamTargetEntity != pTargetEntity)
Cams[ActiveCam].CamTargetEntity = pTargetEntity;
-#endif
}
bool cantOpen = true;
@@ -1552,16 +1556,9 @@ CCamera::UpdateTargetEntity(void)
if((PLAYER->GetPedState() == PED_CARJACK || PLAYER->GetPedState() == PED_OPEN_DOOR) && !cantOpen){
if(!enteringCar && CarZoomIndicator != CAM_ZOOM_1STPRS)
-#ifdef GTA_PS2_STUFF
-// dunno if this has any amazing effects
- {
-#endif
pTargetEntity = PLAYER->m_pMyVehicle;
if(PLAYER->m_pMyVehicle == nil)
pTargetEntity = PLAYER;
-#ifdef GTA_PS2_STUFF
- }
-#endif
}
if(PLAYER->GetPedState() == PED_EXIT_CAR)
@@ -2707,6 +2704,7 @@ CCamera::DontProcessObbeCinemaCamera(void)
bDidWeProcessAnyCinemaCam = false;
}
+#ifdef GTA_TRAIN
void
CCamera::LoadTrainCamNodes(char const *name)
{
@@ -2884,6 +2882,7 @@ CCamera::Process_Train_Camera_Control(void)
}
}
}
+#endif
void
@@ -3179,7 +3178,7 @@ CCamera::RenderMotionBlur(void)
CMBlur::MotionBlurRender(m_pRwCamera,
m_BlurRed, m_BlurGreen, m_BlurBlue,
- m_motionBlur, m_BlurType, m_imotionBlurAddAlpha);
+ m_motionBlur, m_BlurType);
}
void
diff --git a/src/core/ColStore.cpp b/src/core/ColStore.cpp
new file mode 100644
index 00000000..80bbdc77
--- /dev/null
+++ b/src/core/ColStore.cpp
@@ -0,0 +1,237 @@
+#include "common.h"
+
+#include "templates.h"
+#include "General.h"
+#include "ModelInfo.h"
+#include "Streaming.h"
+#include "FileLoader.h"
+#include "Script.h"
+#include "Timer.h"
+#include "Camera.h"
+#include "Frontend.h"
+#include "Physical.h"
+#include "ColStore.h"
+
+CPool<ColDef,ColDef> *CColStore::ms_pColPool;
+
+void
+CColStore::Initialise(void)
+{
+ if(ms_pColPool == nil)
+ ms_pColPool = new CPool<ColDef,ColDef>(COLSTORESIZE, "CollisionFiles");
+ AddColSlot("generic"); // slot 0. not streamed
+}
+
+void
+CColStore::Shutdown(void)
+{
+ int i;
+ for(i = 0; i < COLSTORESIZE; i++)
+ RemoveColSlot(i);
+ if(ms_pColPool)
+ delete ms_pColPool;
+ ms_pColPool = nil;
+}
+
+int
+CColStore::AddColSlot(const char *name)
+{
+ ColDef *def = ms_pColPool->New();
+ assert(def);
+ def->isLoaded = false;
+ def->unused = 0;
+ def->bounds.left = 1000000.0f;
+ def->bounds.top = 1000000.0f;
+ def->bounds.right = -1000000.0f;
+ def->bounds.bottom = -1000000.0f;
+ def->minIndex = INT16_MAX;
+ def->maxIndex = INT16_MIN;
+ strcpy(def->name, name);
+ return ms_pColPool->GetJustIndex(def);
+}
+
+void
+CColStore::RemoveColSlot(int slot)
+{
+ if(GetSlot(slot)){
+ if(GetSlot(slot)->isLoaded)
+ RemoveCol(slot);
+ ms_pColPool->Delete(GetSlot(slot));
+ }
+}
+
+int
+CColStore::FindColSlot(const char *name)
+{
+ ColDef *def;
+ int size = ms_pColPool->GetSize();
+ for(int i = 0; i < size; i++){
+ def = GetSlot(i);
+ if(def && !CGeneral::faststricmp(def->name, name))
+ return i;
+ }
+ return -1;
+}
+
+char*
+CColStore::GetColName(int32 slot)
+{
+ return GetSlot(slot)->name;
+}
+
+CRect&
+CColStore::GetBoundingBox(int32 slot)
+{
+ return GetSlot(slot)->bounds;
+}
+
+void
+CColStore::IncludeModelIndex(int32 slot, int32 modelIndex)
+{
+ ColDef *def = GetSlot(slot);
+ if(modelIndex < def->minIndex)
+ def->minIndex = modelIndex;
+ if(modelIndex > def->maxIndex)
+ def->maxIndex = modelIndex;
+}
+
+bool
+CColStore::LoadCol(int32 slot, uint8 *buffer, int32 bufsize)
+{
+ bool success;
+ ColDef *def = GetSlot(slot);
+ if(def->minIndex > def->maxIndex)
+ success = CFileLoader::LoadCollisionFileFirstTime(buffer, bufsize, slot);
+ else
+ success = CFileLoader::LoadCollisionFile(buffer, bufsize, slot);
+ if(success)
+ def->isLoaded = true;
+ else
+ debug("Failed to load Collision\n");
+ return success;
+}
+
+void
+CColStore::RemoveCol(int32 slot)
+{
+ int id;
+ GetSlot(slot)->isLoaded = false;
+ for(id = 0; id < MODELINFOSIZE; id++){
+ CBaseModelInfo *mi = CModelInfo::GetModelInfo(id);
+ if(mi){
+ CColModel *col = mi->GetColModel();
+ if(col && col->level == slot)
+ col->RemoveCollisionVolumes();
+ }
+ }
+}
+
+void
+CColStore::LoadAllCollision(void)
+{
+ int i;
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(GetSlot(i))
+ CStreaming::RequestCol(i, 0);
+
+ CStreaming::LoadAllRequestedModels(false);
+}
+
+void
+CColStore::RemoveAllCollision(void)
+{
+ int i;
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(GetSlot(i))
+ if(CStreaming::CanRemoveCol(i))
+ CStreaming::RemoveCol(i);
+}
+
+static bool bLoadAtSecondPosition;
+static CVector2D secondPosition;
+
+void
+CColStore::AddCollisionNeededAtPosn(const CVector2D &pos)
+{
+ bLoadAtSecondPosition = true;
+ secondPosition = pos;
+}
+
+void
+CColStore::LoadCollision(const CVector2D &pos)
+{
+ int i;
+
+ if(CStreaming::ms_disableStreaming)
+ return;
+
+ for(i = 1; i < COLSTORESIZE; i++){
+ if(GetSlot(i) == nil)
+ continue;
+
+ bool wantThisOne = false;
+
+ if(GetBoundingBox(i).IsPointInside(pos) ||
+ bLoadAtSecondPosition && GetBoundingBox(i).IsPointInside(secondPosition, -119.0f) ||
+ CGeneral::faststrcmp(GetColName(i), "yacht") == 0){
+ wantThisOne = true;
+ }else{
+ 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)
+ CStreaming::RequestCol(i, STREAMFLAGS_PRIORITY);
+ else
+ CStreaming::RemoveCol(i);
+ }
+ bLoadAtSecondPosition = false;
+}
+
+void
+CColStore::RequestCollision(const CVector2D &pos)
+{
+ int i;
+
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -115.0f))
+ CStreaming::RequestCol(i, STREAMFLAGS_PRIORITY);
+}
+
+void
+CColStore::EnsureCollisionIsInMemory(const CVector2D &pos)
+{
+ int i;
+
+ if(CStreaming::ms_disableStreaming)
+ return;
+
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -110.0f) &&
+ !CStreaming::HasColLoaded(i)){
+ CStreaming::RequestCol(i, 0);
+ if(TheCamera.GetScreenFadeStatus() == FADE_0)
+ FrontEndMenuManager.MessageScreen("LOADCOL", false);
+ CTimer::Suspend();
+ CStreaming::LoadAllRequestedModels(false);
+ CTimer::Resume();
+ }
+}
+
+//--MIAMI: done
+bool
+CColStore::HasCollisionLoaded(const CVector2D &pos)
+{
+ int i;
+
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(GetSlot(i) && GetBoundingBox(i).IsPointInside(pos, -115.0f) &&
+ !GetSlot(i)->isLoaded)
+ return false;
+ return true;
+}
diff --git a/src/core/ColStore.h b/src/core/ColStore.h
new file mode 100644
index 00000000..8e2a3a70
--- /dev/null
+++ b/src/core/ColStore.h
@@ -0,0 +1,43 @@
+#pragma once
+
+#include "templates.h"
+
+struct ColDef { // made up name
+ int32 unused;
+ bool isLoaded;
+ CRect bounds;
+ char name[20];
+ int16 minIndex;
+ int16 maxIndex;
+};
+
+class CColStore
+{
+ static CPool<ColDef,ColDef> *ms_pColPool;
+
+public:
+ static void Initialise(void);
+ static void Shutdown(void);
+ static int AddColSlot(const char *name);
+ static void RemoveColSlot(int32 slot);
+ static int FindColSlot(const char *name);
+ static char *GetColName(int32 slot);
+ static CRect &GetBoundingBox(int32 slot);
+ static void IncludeModelIndex(int32 slot, int32 modelIndex);
+ static bool LoadCol(int32 storeID, uint8 *buffer, int32 bufsize);
+ static void RemoveCol(int32 slot);
+ static void AddCollisionNeededAtPosn(const CVector2D &pos);
+ static void LoadAllCollision(void);
+ static void RemoveAllCollision(void);
+ static void LoadCollision(const CVector2D &pos);
+ static void RequestCollision(const CVector2D &pos);
+ static void EnsureCollisionIsInMemory(const CVector2D &pos);
+ static bool HasCollisionLoaded(const CVector2D &pos);
+
+ static ColDef *GetSlot(int slot) {
+ assert(slot >= 0);
+ assert(ms_pColPool);
+ assert(slot < ms_pColPool->GetSize());
+ return ms_pColPool->GetSlot(slot);
+ }
+};
diff --git a/src/core/Collision.cpp b/src/core/Collision.cpp
index 0cdacfdb..48abbd9a 100644
--- a/src/core/Collision.cpp
+++ b/src/core/Collision.cpp
@@ -20,6 +20,8 @@
#include "SurfaceTable.h"
#include "Lines.h"
#include "Collision.h"
+#include "Camera.h"
+#include "ColStore.h"
enum Direction
{
@@ -34,57 +36,30 @@ enum Direction
eLevelName CCollision::ms_collisionInMemory;
CLinkList<CColModel*> CCollision::ms_colModelCache;
+//--MIAMI: done
void
CCollision::Init(void)
{
ms_colModelCache.Init(NUMCOLCACHELINKS);
ms_collisionInMemory = LEVEL_NONE;
+ CColStore::Initialise();
}
+//--MIAMI: done
void
CCollision::Shutdown(void)
{
ms_colModelCache.Shutdown();
+ CColStore::Shutdown();
}
+//--MIAMI: done
void
CCollision::Update(void)
{
- CVector playerCoors;
- playerCoors = FindPlayerCoors();
- eLevelName level = CTheZones::m_CurrLevel;
- bool forceLevelChange = false;
-
- if(CTimer::GetTimeInMilliseconds() < 2000 || CCutsceneMgr::IsCutsceneProcessing())
- return;
-
- // hardcode a level if there are no zones
- if(level == LEVEL_NONE){
- if(CGame::currLevel == LEVEL_INDUSTRIAL &&
- playerCoors.x < 400.0f){
- level = LEVEL_COMMERCIAL;
- forceLevelChange = true;
- }else if(CGame::currLevel == LEVEL_SUBURBAN &&
- playerCoors.x > -450.0f && playerCoors.y < -1400.0f){
- level = LEVEL_COMMERCIAL;
- forceLevelChange = true;
- }else{
- if(playerCoors.x > 800.0f){
- level = LEVEL_INDUSTRIAL;
- forceLevelChange = true;
- }else if(playerCoors.x < -800.0f){
- level = LEVEL_SUBURBAN;
- forceLevelChange = true;
- }
- }
- }
- if(level != LEVEL_NONE && level != CGame::currLevel)
- CGame::currLevel = level;
- if(ms_collisionInMemory != CGame::currLevel)
- LoadCollisionWhenINeedIt(forceLevelChange);
- CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel);
}
+//--MIAMI: unused
eLevelName
GetCollisionInSectorList(CPtrList &list)
{
@@ -101,6 +76,7 @@ GetCollisionInSectorList(CPtrList &list)
return LEVEL_NONE;
}
+//--MIAMI: unused
// Get a level this sector is in based on collision models
eLevelName
GetCollisionInSector(CSector &sect)
@@ -121,111 +97,16 @@ GetCollisionInSector(CSector &sect)
return (eLevelName)level;
}
+//--MIAMI: done
void
CCollision::LoadCollisionWhenINeedIt(bool forceChange)
{
- eLevelName level, l;
- bool multipleLevels;
- CVector playerCoors;
- CVehicle *veh;
- CEntryInfoNode *ei;
- int sx, sy;
- int xmin, xmax, ymin, ymax;
- int x, y;
-
- level = LEVEL_NONE;
-
- playerCoors = FindPlayerCoors();
- sx = CWorld::GetSectorIndexX(playerCoors.x);
- sy = CWorld::GetSectorIndexY(playerCoors.y);
- multipleLevels = false;
-
- veh = FindPlayerVehicle();
- if(veh && veh->IsTrain()){
- if(((CTrain*)veh)->m_nDoorState != TRAIN_DOOR_OPEN)
- return;
- }else if(playerCoors.z < -4.0f && !CCullZones::DoINeedToLoadCollision())
- return;
-
- // Figure out whose level's collisions we're most likely to be interested in
- if(!forceChange){
- if(veh && veh->IsBoat()){
- // on water we expect to be between levels
- multipleLevels = true;
- }else{
- xmin = Max(sx - 1, 0);
- xmax = Min(sx + 1, NUMSECTORS_X-1);
- ymin = Max(sy - 1, 0);
- ymax = Min(sy + 1, NUMSECTORS_Y-1);
-
- for(x = xmin; x <= xmax; x++)
- for(y = ymin; y <= ymax; y++){
- l = GetCollisionInSector(*CWorld::GetSector(x, y));
- if(l != LEVEL_NONE){
- if(level == LEVEL_NONE)
- level = l;
- if(level != l)
- multipleLevels = true;
- }
- }
- }
-
- if(multipleLevels && veh && veh->IsBoat())
- for(ei = veh->m_entryInfoList.first; ei; ei = ei->next){
- level = GetCollisionInSector(*ei->sector);
- if(level != LEVEL_NONE)
- break;
- }
- }
-
- if(level == CGame::currLevel || forceChange){
- CTimer::Stop();
- DMAudio.SetEffectsFadeVol(0);
- CPad::StopPadsShaking();
- LoadCollisionScreen(CGame::currLevel);
- DMAudio.Service();
-
- CPopulation::DealWithZoneChange(ms_collisionInMemory, CGame::currLevel, false);
- CStreaming::RemoveIslandsNotUsed(LEVEL_INDUSTRIAL);
- CStreaming::RemoveIslandsNotUsed(LEVEL_COMMERCIAL);
- CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN);
- CStreaming::RemoveBigBuildings(LEVEL_INDUSTRIAL);
- CStreaming::RemoveBigBuildings(LEVEL_COMMERCIAL);
- CStreaming::RemoveBigBuildings(LEVEL_SUBURBAN);
- CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel);
- CStreaming::RemoveUnusedModelsInLoadedList();
- CGame::TidyUpMemory(true, true);
- CFileLoader::LoadCollisionFromDatFile(CGame::currLevel);
- ms_collisionInMemory = CGame::currLevel;
- CReplay::EmptyReplayBuffer();
- if(CGame::currLevel != LEVEL_NONE)
- LoadSplash(GetLevelSplashScreen(CGame::currLevel));
- CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
- CStreaming::RemoveUnusedBuildings(CGame::currLevel);
- CStreaming::RequestBigBuildings(CGame::currLevel);
- CStreaming::LoadAllRequestedModels(true);
- CStreaming::HaveAllBigBuildingsLoaded(CGame::currLevel);
-
- CGame::TidyUpMemory(true, true);
- CTimer::Update();
- DMAudio.SetEffectsFadeVol(127);
- }
}
+//--MIAMI: done
void
CCollision::SortOutCollisionAfterLoad(void)
{
- if(ms_collisionInMemory == CGame::currLevel)
- return;
-
- CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel);
- if(CGame::currLevel != LEVEL_NONE){
- CFileLoader::LoadCollisionFromDatFile(CGame::currLevel);
- if(!CGame::playingIntro)
- LoadSplash(GetLevelSplashScreen(CGame::currLevel));
- }
- ms_collisionInMemory = CGame::currLevel;
- CGame::TidyUpMemory(true, false);
}
void
@@ -249,14 +130,14 @@ CCollision::LoadCollisionScreen(eLevelName level)
bool
-CCollision::TestSphereSphere(const CColSphere &s1, const CColSphere &s2)
+CCollision::TestSphereSphere(const CSphere &s1, const CSphere &s2)
{
float d = s1.radius + s2.radius;
return (s1.center - s2.center).MagnitudeSqr() < d*d;
}
bool
-CCollision::TestSphereBox(const CColSphere &sph, const CColBox &box)
+CCollision::TestSphereBox(const CSphere &sph, const CBox &box)
{
if(sph.center.x + sph.radius < box.min.x) return false;
if(sph.center.x - sph.radius > box.max.x) return false;
@@ -268,7 +149,7 @@ CCollision::TestSphereBox(const CColSphere &sph, const CColBox &box)
}
bool
-CCollision::TestLineBox(const CColLine &line, const CColBox &box)
+CCollision::TestLineBox(const CColLine &line, const CBox &box)
{
float t, x, y, z;
// If either line point is in the box, we have a collision
@@ -353,7 +234,7 @@ CCollision::TestLineBox(const CColLine &line, const CColBox &box)
}
bool
-CCollision::TestVerticalLineBox(const CColLine &line, const CColBox &box)
+CCollision::TestVerticalLineBox(const CColLine &line, const CBox &box)
{
if(line.p0.x <= box.min.x) return false;
if(line.p0.y <= box.min.y) return false;
@@ -1974,7 +1855,7 @@ CColModel::CColModel(void)
vertices = nil;
triangles = nil;
trianglePlanes = nil;
- level = CGame::currLevel;
+ level = 0; // generic col slot
ownsCollisionVolumes = true;
}
diff --git a/src/core/Collision.h b/src/core/Collision.h
index 895f012a..4b0c2fb9 100644
--- a/src/core/Collision.h
+++ b/src/core/Collision.h
@@ -10,26 +10,37 @@
#define MAX_COLLISION_POINTS 32
#endif
-struct CColSphere
+struct CSphere
{
CVector center;
float radius;
+ void Set(float radius, const CVector &center) { this->center = center; this->radius = radius; }
+};
+
+struct CBox
+{
+ CVector min;
+ CVector max;
+ CVector GetSize(void) { return max - min; }
+ void Set(const CVector &min, const CVector &max) { this->min = min; this->max = max; }
+};
+
+struct CColSphere : public CSphere
+{
uint8 surface;
uint8 piece;
void Set(float radius, const CVector &center, uint8 surf, uint8 piece);
- void Set(float radius, const CVector &center) { this->center = center; this->radius = radius; }
+ using CSphere::Set;
};
-struct CColBox
+struct CColBox : public CBox
{
- CVector min;
- CVector max;
uint8 surface;
uint8 piece;
void Set(const CVector &min, const CVector &max, uint8 surf, uint8 piece);
- CVector GetSize(void) { return max - min; }
+ using CBox::Set;
};
struct CColLine
@@ -85,15 +96,16 @@ struct CStoredCollPoly
bool valid;
};
+//--MIAMI: done struct
struct CColModel
{
- CColSphere boundingSphere;
- CColBox boundingBox;
+ CSphere boundingSphere;
+ CBox boundingBox;
int16 numSpheres;
- int16 numLines;
int16 numBoxes;
int16 numTriangles;
- int32 level;
+ int8 numLines;
+ uint8 level; // colstore slot but probably still named level
bool ownsCollisionVolumes;
CColSphere *spheres;
CColLine *lines;
@@ -132,10 +144,10 @@ public:
static void CalculateTrianglePlanes(CColModel *model);
// all these return true if there's a collision
- static bool TestSphereSphere(const CColSphere &s1, const CColSphere &s2);
- static bool TestSphereBox(const CColSphere &sph, const CColBox &box);
- static bool TestLineBox(const CColLine &line, const CColBox &box);
- static bool TestVerticalLineBox(const CColLine &line, const CColBox &box);
+ static bool TestSphereSphere(const CSphere &s1, const CSphere &s2);
+ static bool TestSphereBox(const CSphere &sph, const CBox &box);
+ static bool TestLineBox(const CColLine &line, const CBox &box);
+ static bool TestVerticalLineBox(const CColLine &line, const CBox &box);
static bool TestLineTriangle(const CColLine &line, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
static bool TestLineSphere(const CColLine &line, const CColSphere &sph);
static bool TestSphereTriangle(const CColSphere &sphere, const CVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane);
diff --git a/src/core/EventList.cpp b/src/core/EventList.cpp
index 675040ea..c3508a51 100644
--- a/src/core/EventList.cpp
+++ b/src/core/EventList.cpp
@@ -67,8 +67,6 @@ CEventList::RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent
switch(entityType){
case EVENT_ENTITY_PED:
ref = CPools::GetPedRef((CPed*)ent);
- if(ent->GetModelIndex() >= MI_GANG01 && ent->GetModelIndex() <= MI_CRIMINAL02)
- copsDontCare = true;
break;
case EVENT_ENTITY_VEHICLE:
ref = CPools::GetVehicleRef((CVehicle*)ent);
diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp
index adf4b9f8..6a434bdd 100644
--- a/src/core/FileLoader.cpp
+++ b/src/core/FileLoader.cpp
@@ -24,6 +24,8 @@
#include "ZoneCull.h"
#include "CdStream.h"
#include "FileLoader.h"
+#include "Streaming.h"
+#include "ColStore.h"
char CFileLoader::ms_line[256];
@@ -46,14 +48,12 @@ CFileLoader::LoadLevel(const char *filename)
{
int fd;
RwTexDictionary *savedTxd;
- eLevelName savedLevel;
bool objectsLoaded;
char *line;
char txdname[64];
savedTxd = RwTexDictionaryGetCurrent();
objectsLoaded = false;
- savedLevel = CGame::currLevel;
if(savedTxd == nil){
savedTxd = RwTexDictionaryCreate();
RwTexDictionarySetCurrent(savedTxd);
@@ -77,12 +77,8 @@ CFileLoader::LoadLevel(const char *filename)
AddTexDictionaries(savedTxd, txd);
RwTexDictionaryDestroy(txd);
}else if(strncmp(line, "COLFILE", 7) == 0){
- int level;
- sscanf(line+8, "%d", &level);
- CGame::currLevel = (eLevelName)level;
LoadingScreenLoadingFile(line+10);
- LoadCollisionFile(line+10);
- CGame::currLevel = savedLevel;
+ LoadCollisionFile(line+10, 0);
}else if(strncmp(line, "MODELFILE", 9) == 0){
LoadingScreenLoadingFile(line + 10);
LoadModelFile(line + 10);
@@ -94,15 +90,15 @@ CFileLoader::LoadLevel(const char *filename)
LoadObjectTypes(line + 4);
}else if(strncmp(line, "IPL", 3) == 0){
if(!objectsLoaded){
- CModelInfo::ConstructMloClumps();
+ LoadingScreenLoadingFile("Collision");
CObjectData::Initialise("DATA\\OBJECT.DAT");
+ CStreaming::Init();
+ CColStore::LoadAllCollision();
+ // TODO(MIAMI): anim indices
objectsLoaded = true;
}
LoadingScreenLoadingFile(line + 4);
LoadScene(line + 4);
- }else if(strncmp(line, "MAPZONE", 7) == 0){
- LoadingScreenLoadingFile(line + 8);
- LoadMapZones(line + 8);
}else if(strncmp(line, "SPLASH", 6) == 0){
LoadSplash(GetRandomSplashScreen());
}else if(strncmp(line, "CDIMAGE", 7) == 0){
@@ -112,30 +108,13 @@ CFileLoader::LoadLevel(const char *filename)
CFileMgr::CloseFile(fd);
RwTexDictionarySetCurrent(savedTxd);
-}
-void
-CFileLoader::LoadCollisionFromDatFile(int currlevel)
-{
- int fd;
- char *line;
-
- fd = CFileMgr::OpenFile(CGame::aDatFile, "r");
- assert(fd > 0);
-
- for(line = LoadLine(fd); line; line = LoadLine(fd)){
- if(*line == '#')
- continue;
-
- if(strncmp(line, "COLFILE", 7) == 0){
- int level;
- sscanf(line+8, "%d", &level);
- if(currlevel == level)
- LoadCollisionFile(line+10);
- }
- }
-
- CFileMgr::CloseFile(fd);
+ int i;
+ for(i = 1; i < COLSTORESIZE; i++)
+ if(CColStore::GetSlot(i))
+ CColStore::GetBoundingBox(i).Grow(120.0f);
+ CWorld::RepositionCertainDynamicObjects();
+ CColStore::RemoveAllCollision();
}
char*
@@ -178,8 +157,9 @@ struct ColHeader
uint32 size;
};
+//--MIAMI: done
void
-CFileLoader::LoadCollisionFile(const char *filename)
+CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot)
{
int fd;
char modelname[24];
@@ -188,6 +168,7 @@ CFileLoader::LoadCollisionFile(const char *filename)
debug("Loading collision file %s\n", filename);
fd = CFileMgr::OpenFile(filename, "rb");
+ assert(fd > 0);
while(CFileMgr::Read(fd, (char*)&header, sizeof(header))){
assert(strncmp(header.ident, "COLL", 4) == 0);
@@ -196,10 +177,11 @@ CFileLoader::LoadCollisionFile(const char *filename)
mi = CModelInfo::GetModelInfo(modelname, nil);
if(mi){
- if(mi->GetColModel()){
+ if(mi->GetColModel() && mi->DoesOwnColModel()){
LoadCollisionModel(work_buff+24, *mi->GetColModel(), modelname);
}else{
CColModel *model = new CColModel;
+ model->level = colSlot;
LoadCollisionModel(work_buff+24, *model, modelname);
mi->SetColModel(model, true);
}
@@ -211,6 +193,80 @@ CFileLoader::LoadCollisionFile(const char *filename)
CFileMgr::CloseFile(fd);
}
+
+//--MIAMI: done
+bool
+CFileLoader::LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot)
+{
+ uint32 modelsize;
+ char modelname[24];
+ CBaseModelInfo *mi;
+ ColHeader *header;
+ int modelIndex;
+
+ while(size > 8){
+ header = (ColHeader*)buffer;
+ modelsize = header->size;
+ if(strncmp(header->ident, "COLL", 4) != 0)
+ return size-8 < CDSTREAM_SECTOR_SIZE;
+ memcpy(modelname, buffer+8, 24);
+ memcpy(work_buff, buffer+32, modelsize-24);
+ size -= 32 + (modelsize-24);
+ buffer += 32 + (modelsize-24);
+ if(modelsize > 15*1024)
+ debug("colmodel %s is huge, size %d\n", modelname, modelsize);
+
+ mi = CModelInfo::GetModelInfo(modelname, &modelIndex);
+ if(mi){
+ CColStore::IncludeModelIndex(colSlot, modelIndex);
+ CColModel *model = new CColModel;
+ model->level = colSlot;
+ LoadCollisionModel(work_buff, *model, modelname);
+ mi->SetColModel(model, true);
+ }else{
+ debug("colmodel %s can't find a modelinfo\n", modelname);
+ }
+ }
+ return true;
+}
+
+bool
+CFileLoader::LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot)
+{
+ uint32 modelsize;
+ char modelname[24];
+ CBaseModelInfo *mi;
+ ColHeader *header;
+
+ while(size > 8){
+ header = (ColHeader*)buffer;
+ modelsize = header->size;
+ if(strncmp(header->ident, "COLL", 4) != 0)
+ return size-8 < CDSTREAM_SECTOR_SIZE;
+ memcpy(modelname, buffer+8, 24);
+ memcpy(work_buff, buffer+32, modelsize-24);
+ size -= 32 + (modelsize-24);
+ buffer += 32 + (modelsize-24);
+ if(modelsize > 15*1024)
+ debug("colmodel %s is huge, size %d\n", modelname, modelsize);
+
+ mi = CModelInfo::GetModelInfo(modelname, CColStore::GetSlot(colSlot)->minIndex, CColStore::GetSlot(colSlot)->maxIndex);
+ if(mi){
+ if(mi->GetColModel()){
+ LoadCollisionModel(work_buff, *mi->GetColModel(), modelname);
+ }else{
+ CColModel *model = new CColModel;
+ model->level = colSlot;
+ LoadCollisionModel(work_buff, *model, modelname);
+ mi->SetColModel(model, true);
+ }
+ }else{
+ debug("colmodel %s can't find a modelinfo\n", modelname);
+ }
+ }
+ return true;
+}
+
void
CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
{
@@ -498,8 +554,9 @@ CFileLoader::LoadObjectTypes(const char *filename)
enum {
NONE,
OBJS,
- MLO,
+ MLO, // unused but enum still has it
TOBJ,
+ WEAP,
HIER,
CARS,
PEDS,
@@ -510,16 +567,17 @@ CFileLoader::LoadObjectTypes(const char *filename)
int fd;
int section;
int pathIndex;
- char pathTypeStr[20];
int id, pathType;
- int mlo;
+ int minID, maxID;
section = NONE;
+ minID = INT32_MAX;
+ maxID = -1;
pathIndex = -1;
- mlo = 0;
debug("Loading object types from %s...\n", filename);
fd = CFileMgr::OpenFile(filename, "rb");
+ assert(fd > 0);
for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){
if(*line == '\0' || *line == '#')
continue;
@@ -527,25 +585,27 @@ CFileLoader::LoadObjectTypes(const char *filename)
if(section == NONE){
if(strncmp(line, "objs", 4) == 0) section = OBJS;
else if(strncmp(line, "tobj", 4) == 0) section = TOBJ;
+ else if(strncmp(line, "weap", 4) == 0) section = WEAP;
else if(strncmp(line, "hier", 4) == 0) section = HIER;
else if(strncmp(line, "cars", 4) == 0) section = CARS;
else if(strncmp(line, "peds", 4) == 0) section = PEDS;
else if(strncmp(line, "path", 4) == 0) section = PATH;
else if(strncmp(line, "2dfx", 4) == 0) section = TWODFX;
}else if(strncmp(line, "end", 3) == 0){
- section = section == MLO ? OBJS : NONE;
+ section = NONE;
}else switch(section){
case OBJS:
- if(strncmp(line, "sta", 3) == 0)
- mlo = LoadMLO(line);
- else
- LoadObject(line);
- break;
- case MLO:
- LoadMLOInstance(mlo, line);
+ id = LoadObject(line);
+ if(id > maxID) maxID = id;
+ if(id < minID) minID = id;
break;
case TOBJ:
- LoadTimeObject(line);
+ id = LoadTimeObject(line);
+ if(id > maxID) maxID = id;
+ if(id < minID) minID = id;
+ break;
+ case WEAP:
+ assert(0 && "can't do this yet");
break;
case HIER:
LoadClumpObject(line);
@@ -558,17 +618,15 @@ CFileLoader::LoadObjectTypes(const char *filename)
break;
case PATH:
if(pathIndex == -1){
- id = LoadPathHeader(line, pathTypeStr);
- if(strncmp(pathTypeStr, "ped", 4) == 0)
- pathType = 1;
- else if(strncmp(pathTypeStr, "car", 4) == 0)
- pathType = 0;
+ id = LoadPathHeader(line, pathType);
pathIndex = 0;
}else{
- if(pathType == 1)
+ if(pathType == 0)
LoadPedPathNode(line, id, pathIndex);
- else if(pathType == 0)
- LoadCarPathNode(line, id, pathIndex);
+ else if (pathType == 1)
+ LoadCarPathNode(line, id, pathIndex, false);
+ else if (pathType == 2)
+ LoadCarPathNode(line, id, pathIndex, true);
pathIndex++;
if(pathIndex == 12)
pathIndex = -1;
@@ -581,9 +639,9 @@ CFileLoader::LoadObjectTypes(const char *filename)
}
CFileMgr::CloseFile(fd);
- for(id = 0; id < MODELINFOSIZE; id++){
+ for(id = minID; id <= maxID; id++){
CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
- if(mi && mi->IsSimple())
+ if(mi && mi->IsBuilding())
mi->SetupBigBuilding();
}
}
@@ -591,16 +649,20 @@ CFileLoader::LoadObjectTypes(const char *filename)
void
SetModelInfoFlags(CSimpleModelInfo *mi, uint32 flags)
{
- mi->m_normalCull = !!(flags & 1);
+ mi->m_wetRoadReflection = !!(flags & 1);
mi->m_noFade = !!(flags & 2);
mi->m_drawLast = !!(flags & (4|8));
mi->m_additive = !!(flags & 8);
mi->m_isSubway = !!(flags & 0x10);
mi->m_ignoreLight = !!(flags & 0x20);
mi->m_noZwrite = !!(flags & 0x40);
+ mi->m_noShadows = !!(flags & 0x80);
+ mi->m_ignoreDrawDist = !!(flags & 0x100);
+ mi->m_isCodeGlass = !!(flags & 0x200);
+ mi->m_isArtistGlass = !!(flags & 0x400);
}
-void
+int
CFileLoader::LoadObject(const char *line)
{
int id, numObjs;
@@ -611,7 +673,7 @@ CFileLoader::LoadObject(const char *line)
CSimpleModelInfo *mi;
if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4)
- return;
+ return 0; // game returns return value
switch(numObjs){
case 1:
@@ -643,60 +705,11 @@ CFileLoader::LoadObject(const char *line)
mi->m_firstDamaged = damaged;
mi->SetTexDictionary(txd);
MatchModelString(model, id);
-}
-
-int
-CFileLoader::LoadMLO(const char *line)
-{
- char smth[8];
- char name[24];
- int modelIndex;
- float someFloat;
-
- sscanf(line, "%s %s %d %f", smth, name, &modelIndex, &someFloat);
- CMloModelInfo *minfo = CModelInfo::AddMloModel(modelIndex);
- minfo->SetName(name);
- minfo->field_34 = someFloat;
- int instId = CModelInfo::GetMloInstanceStore().allocPtr;
- minfo->firstInstance = instId;
- minfo->lastInstance = instId;
- minfo->SetTexDictionary("generic");
- return modelIndex;
-}
-void
-CFileLoader::LoadMLOInstance(int id, const char *line)
-{
- char name[24];
- RwV3d pos, scale, rot;
- float angle;
- int modelIndex;
-
- CMloModelInfo *minfo = (CMloModelInfo*)CModelInfo::GetModelInfo(id);
- sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f",
- &modelIndex,
- name,
- &pos.x, &pos.y, &pos.z,
- &scale.x, &scale.y, &scale.z,
- &rot.x, &rot.y, &rot.z,
- &angle);
- float rad = Acos(angle) * 2.0f;
- CInstance *inst = CModelInfo::GetMloInstanceStore().alloc();
- minfo->lastInstance++;
-
- RwMatrix *matrix = RwMatrixCreate();
- RwMatrixScale(matrix, &scale, rwCOMBINEREPLACE);
- RwMatrixRotate(matrix, &rot, -RADTODEG(rad), rwCOMBINEPOSTCONCAT);
- RwMatrixTranslate(matrix, &pos, rwCOMBINEPOSTCONCAT);
-
- inst->GetMatrix() = CMatrix(matrix);
- inst->GetMatrix().UpdateRW();
-
- inst->m_modelIndex = modelIndex;
- RwMatrixDestroy(matrix);
+ return id;
}
-void
+int
CFileLoader::LoadTimeObject(const char *line)
{
int id, numObjs;
@@ -708,7 +721,7 @@ CFileLoader::LoadTimeObject(const char *line)
CTimeModelInfo *mi, *other;
if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4)
- return;
+ return 0; // game returns return value
switch(numObjs){
case 1:
@@ -744,6 +757,8 @@ CFileLoader::LoadTimeObject(const char *line)
if(other)
other->SetOtherTimeModel(id);
MatchModelString(model, id);
+
+ return id;
}
void
@@ -766,21 +781,22 @@ CFileLoader::LoadVehicleObject(const char *line)
{
int id;
char model[24], txd[24];
- char type[8], handlingId[16], gamename[32], vehclass[12];
+ char type[8], handlingId[16], gamename[32], anims[16], vehclass[12];
uint32 frequency, comprules;
int32 level, misc;
float wheelScale;
CVehicleModelInfo *mi;
char *p;
- sscanf(line, "%d %s %s %s %s %s %s %d %d %x %d %f",
+ sscanf(line, "%d %s %s %s %s %s %s %s %d %d %x %d %f",
&id, model, txd,
- type, handlingId, gamename, vehclass,
+ type, handlingId, gamename, anims, vehclass,
&frequency, &level, &comprules, &misc, &wheelScale);
mi = CModelInfo::AddVehicleModel(id);
mi->SetName(model);
mi->SetTexDictionary(txd);
+ // TODO(MIAMI): anims
for(p = gamename; *p; p++)
if(*p == '_') *p = ' ';
strncpy(mi->m_gameName, gamename, 32);
@@ -810,36 +826,34 @@ CFileLoader::LoadVehicleObject(const char *line)
mi->m_handlingId = mod_HandlingManager.GetHandlingId(handlingId);
- // Well this is kinda dumb....
- if(strncmp(vehclass, "poorfamily", 11) == 0){
+ if(strncmp(vehclass, "normal", 7) == 0)
+ mi->m_vehicleClass = CCarCtrl::NORMAL;
+ else if(strncmp(vehclass, "poorfamily", 11) == 0)
mi->m_vehicleClass = CCarCtrl::POOR;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::POOR);
- }else if(strncmp(vehclass, "richfamily", 11) == 0){
+ else if(strncmp(vehclass, "richfamily", 11) == 0)
mi->m_vehicleClass = CCarCtrl::RICH;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::RICH);
- }else if(strncmp(vehclass, "executive", 10) == 0){
+ else if(strncmp(vehclass, "executive", 10) == 0)
mi->m_vehicleClass = CCarCtrl::EXEC;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::EXEC);
- }else if(strncmp(vehclass, "worker", 7) == 0){
+ else if(strncmp(vehclass, "worker", 7) == 0)
mi->m_vehicleClass = CCarCtrl::WORKER;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::WORKER);
- }else if(strncmp(vehclass, "special", 8) == 0){
- mi->m_vehicleClass = CCarCtrl::SPECIAL;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::SPECIAL);
- }else if(strncmp(vehclass, "big", 4) == 0){
+ else if(strncmp(vehclass, "big", 4) == 0)
mi->m_vehicleClass = CCarCtrl::BIG;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::BIG);
- }else if(strncmp(vehclass, "taxi", 5) == 0){
+ else if(strncmp(vehclass, "taxi", 5) == 0)
mi->m_vehicleClass = CCarCtrl::TAXI;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::TAXI);
+ else if(strncmp(vehclass, "moped", 6) == 0)
+ mi->m_vehicleClass = CCarCtrl::MOPED;
+ else if(strncmp(vehclass, "motorbike", 10) == 0)
+ mi->m_vehicleClass = CCarCtrl::MOTORBIKE;
+ else if(strncmp(vehclass, "leisureboat", 12) == 0)
+ mi->m_vehicleClass = CCarCtrl::LEISUREBOAT;
+ else if(strncmp(vehclass, "workerboat", 11) == 0)
+ mi->m_vehicleClass = CCarCtrl::WORKERBOAT;
+ else if(strncmp(vehclass, "ignore", 11) == 0){
+ mi->m_vehicleClass = -1;
+ return;
}
+ CCarCtrl::AddToCarArray(id, mi->m_vehicleClass);
+ mi->m_frequency = frequency;
}
void
@@ -847,15 +861,16 @@ CFileLoader::LoadPedObject(const char *line)
{
int id;
char model[24], txd[24];
- char pedType[24], pedStats[24], animGroup[24];
+ char pedType[24], pedStats[24], animGroup[24], animFile[16];
int carsCanDrive;
CPedModelInfo *mi;
int animGroupId;
+ int radio1, radio2;
- if(sscanf(line, "%d %s %s %s %s %s %x",
+ sscanf(line, "%d %s %s %s %s %s %x %s %d %d",
&id, model, txd,
- pedType, pedStats, animGroup, &carsCanDrive) != 7)
- return;
+ pedType, pedStats, animGroup, &carsCanDrive,
+ animFile, &radio1, &radio2);
mi = CModelInfo::AddPedModel(id);
mi->SetName(model);
@@ -868,39 +883,54 @@ CFileLoader::LoadPedObject(const char *line)
break;
mi->m_animGroup = animGroupId;
mi->m_carsCanDrive = carsCanDrive;
-
- // ???
- CModelInfo::GetModelInfo(MI_LOPOLYGUY)->SetColModel(&CTempColModels::ms_colModelPed1);
}
int
-CFileLoader::LoadPathHeader(const char *line, char *type)
+CFileLoader::LoadPathHeader(const char *line, int &type)
{
int id;
char modelname[32];
- sscanf(line, "%s %d %s", type, &id, modelname);
+ sscanf(line, "%d %d %s", &type, &id, modelname);
return id;
}
void
CFileLoader::LoadPedPathNode(const char *line, int id, int node)
{
- int type, next, cross;
- float x, y, z, width;
-
- sscanf(line, "%d %d %d %f %f %f %f", &type, &next, &cross, &x, &y, &z, &width);
- ThePaths.StoreNodeInfoPed(id, node, type, next, x, y, z, 0, !!cross);
+ int type, next, cross, numLeft, numRight, speed, flags;
+ float x, y, z, width, spawnRate;
+
+ if(sscanf(line, "%d %d %d %f %f %f %f %d %d %d %d %f",
+ &type, &next, &cross, &x, &y, &z, &width, &numLeft, &numRight,
+ &speed, &flags, &spawnRate) != 12)
+ spawnRate = 1.0f;
+
+ if(id == -1)
+ ThePaths.StoreDetachedNodeInfoPed(node, type, next, x, y, z,
+ width, !!cross, !!(flags&1), !!(flags&4), spawnRate*15.0f);
+ else
+ ThePaths.StoreNodeInfoPed(id, node, type, next, x, y, z,
+ width, !!cross, spawnRate*15.0f);
}
void
-CFileLoader::LoadCarPathNode(const char *line, int id, int node)
+CFileLoader::LoadCarPathNode(const char *line, int id, int node, bool waterPath)
{
- int type, next, cross, numLeft, numRight;
- float x, y, z, width;
-
- sscanf(line, "%d %d %d %f %f %f %f %d %d", &type, &next, &cross, &x, &y, &z, &width, &numLeft, &numRight);
- ThePaths.StoreNodeInfoCar(id, node, type, next, x, y, z, 0, numLeft, numRight);
+ int type, next, cross, numLeft, numRight, speed, flags;
+ float x, y, z, width, spawnRate;
+
+ if(sscanf(line, "%d %d %d %f %f %f %f %d %d %d %d %f",
+ &type, &next, &cross, &x, &y, &z, &width, &numLeft, &numRight,
+ &speed, &flags, &spawnRate) != 12)
+ spawnRate = 1.0f;
+
+ if(id == -1)
+ ThePaths.StoreDetachedNodeInfoCar(node, type, next, x, y, z, width, numLeft, numRight,
+ !!(flags&1), !!(flags&4), speed, !!(flags&2), waterPath, spawnRate * 15, false);
+ else
+ ThePaths.StoreNodeInfoCar(id, node, type, next, x, y, z, 0, numLeft, numRight,
+ !!(flags&1), !!(flags&4), speed, !!(flags&2), waterPath, spawnRate * 15);
}
@@ -993,20 +1023,21 @@ CFileLoader::LoadScene(const char *filename)
INST,
ZONE,
CULL,
+ OCCL,
PICK,
PATH,
};
char *line;
int fd;
int section;
- int pathIndex;
- char pathTypeStr[20];
+ int pathType, pathIndex;
section = NONE;
pathIndex = -1;
debug("Creating objects from %s...\n", filename);
fd = CFileMgr::OpenFile(filename, "rb");
+ assert(fd > 0);
for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){
if(*line == '\0' || *line == '#')
continue;
@@ -1017,6 +1048,7 @@ CFileLoader::LoadScene(const char *filename)
else if(strncmp(line, "cull", 4) == 0) section = CULL;
else if(strncmp(line, "pick", 4) == 0) section = PICK;
else if(strncmp(line, "path", 4) == 0) section = PATH;
+ else if(strncmp(line, "occl", 4) == 0) section = OCCL;
}else if(strncmp(line, "end", 3) == 0){
section = NONE;
}else switch(section){
@@ -1029,18 +1061,24 @@ CFileLoader::LoadScene(const char *filename)
case CULL:
LoadCullZone(line);
break;
+ case OCCL:
+ // TODO(MIAMI): occlusion
+ break;
case PICK:
// unused
LoadPickup(line);
break;
case PATH:
- // unfinished in the game
if(pathIndex == -1){
- LoadPathHeader(line, pathTypeStr);
- // type not set
+ LoadPathHeader(line, pathType);
pathIndex = 0;
}else{
- // nodes not loaded
+ if(pathType == 0)
+ LoadPedPathNode(line, -1, pathIndex);
+ else if (pathType == 1)
+ LoadCarPathNode(line, -1, pathIndex, false);
+ else if (pathType == 2)
+ LoadCarPathNode(line, -1, pathIndex, true);
pathIndex++;
if(pathIndex == 12)
pathIndex = -1;
@@ -1063,18 +1101,30 @@ CFileLoader::LoadObjectInstance(const char *line)
CSimpleModelInfo *mi;
RwMatrix *xform;
CEntity *entity;
- if(sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f",
- &id, name,
+ float area;
+
+ if(sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f %f",
+ &id, name, &area,
&trans.x, &trans.y, &trans.z,
&scale.x, &scale.y, &scale.z,
- &axis.x, &axis.y, &axis.z, &angle) != 12)
- return;
+ &axis.x, &axis.y, &axis.z, &angle) != 13){
+ if(sscanf(line, "%d %s %f %f %f %f %f %f %f %f %f %f",
+ &id, name,
+ &trans.x, &trans.y, &trans.z,
+ &scale.x, &scale.y, &scale.z,
+ &axis.x, &axis.y, &axis.z, &angle) != 12)
+ return;
+ area = 0;
+ }
mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
if(mi == nil)
return;
assert(mi->IsSimple());
+ if(!CStreaming::IsObjectInCdImage(id))
+ debug("Not in cdimage %s\n", mi->GetName());
+
angle = -RADTODEG(2.0f * acosf(angle));
xform = RwMatrixCreate();
RwMatrixRotate(xform, &axis, angle, rwCOMBINEREPLACE);
@@ -1089,7 +1139,8 @@ CFileLoader::LoadObjectInstance(const char *line)
entity->SetModelIndexNoCreate(id);
entity->GetMatrix() = CMatrix(xform);
entity->m_level = CTheZones::GetLevelFromPosition(&entity->GetPosition());
- if(mi->IsSimple()){
+ entity->m_area = area;
+ if(mi->IsBuilding()){
if(mi->m_isBigBuilding)
entity->SetupBigBuilding();
if(mi->m_isSubway)
@@ -1098,14 +1149,23 @@ CFileLoader::LoadObjectInstance(const char *line)
if(mi->GetLargestLodDistance() < 2.0f)
entity->bIsVisible = false;
CWorld::Add(entity);
+
+ CColModel *col = entity->GetColModel();
+ if(col->numSpheres || col->numBoxes || col->numTriangles){
+ if(col->level != 0)
+ CColStore::GetBoundingBox(col->level).ContainRect(entity->GetBoundRect());
+ }else
+ entity->bUsesCollision = false;
+ // TODO(MIAMI): set some flag here if col min is below 6
}else{
entity = new CDummyObject;
entity->SetModelIndexNoCreate(id);
entity->GetMatrix() = CMatrix(xform);
CWorld::Add(entity);
- if(IsGlass(entity->GetModelIndex()))
+ if(IsGlass(entity->GetModelIndex()) && !mi->m_isArtistGlass)
entity->bIsVisible = false;
entity->m_level = CTheZones::GetLevelFromPosition(&entity->GetPosition());
+ entity->m_area = area;
}
RwMatrixDestroy(xform);
@@ -1150,54 +1210,7 @@ CFileLoader::LoadPickup(const char *line)
sscanf(line, "%d %f %f %f", &id, &x, &y, &z);
}
-void
-CFileLoader::LoadMapZones(const char *filename)
-{
- enum {
- NONE,
- INST,
- ZONE,
- CULL,
- PICK,
- PATH,
- };
- char *line;
- int fd;
- int section;
-
- section = NONE;
- debug("Creating zones from %s...\n", filename);
-
- fd = CFileMgr::OpenFile(filename, "rb");
- for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){
- if(*line == '\0' || *line == '#')
- continue;
-
- if(section == NONE){
- if(strncmp(line, "zone", 4) == 0) section = ZONE;
- }else if(strncmp(line, "end", 3) == 0){
- section = NONE;
- }else switch(section){
- case ZONE: {
- char name[24];
- int type, level;
- float minx, miny, minz;
- float maxx, maxy, maxz;
- if(sscanf(line, "%s %d %f %f %f %f %f %f %d",
- &name, &type,
- &minx, &miny, &minz,
- &maxx, &maxy, &maxz,
- &level) == 9)
- CTheZones::CreateMapZone(name, (eZoneType)type, minx, miny, minz, maxx, maxy, maxz, (eLevelName)level);
- }
- break;
- }
- }
- CFileMgr::CloseFile(fd);
-
- debug("Finished loading IPL\n");
-}
-
+//--MIAMI: unused
void
CFileLoader::ReloadPaths(const char *filename)
{
@@ -1208,10 +1221,10 @@ CFileLoader::ReloadPaths(const char *filename)
char *line;
int section = NONE;
int id, pathType, pathIndex = -1;
- char pathTypeStr[20];
debug("Reloading paths from %s...\n", filename);
int fd = CFileMgr::OpenFile(filename, "r");
+ assert(fd > 0);
for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) {
if (*line == '\0' || *line == '#')
continue;
@@ -1227,17 +1240,15 @@ CFileLoader::ReloadPaths(const char *filename)
switch (section) {
case PATH:
if (pathIndex == -1) {
- id = LoadPathHeader(line, pathTypeStr);
- if (strncmp(pathTypeStr, "ped", 4) == 0)
- pathType = 1;
- else if (strncmp(pathTypeStr, "car", 4) == 0)
- pathType = 0;
+ id = LoadPathHeader(line, pathType);
pathIndex = 0;
} else {
- if (pathType == 1)
+ if(pathType == 0)
LoadPedPathNode(line, id, pathIndex);
- else if (pathType == 0)
- LoadCarPathNode(line, id, pathIndex);
+ else if (pathType == 1)
+ LoadCarPathNode(line, id, pathIndex, false);
+ else if (pathType == 2)
+ LoadCarPathNode(line, id, pathIndex, true);
pathIndex++;
if (pathIndex == 12)
pathIndex = -1;
@@ -1267,6 +1278,7 @@ CFileLoader::ReloadObjectTypes(const char *filename)
CFileMgr::ChangeDir("\\DATA\\MAPS\\");
int fd = CFileMgr::OpenFile(filename, "r");
+ assert(fd > 0);
CFileMgr::ChangeDir("\\");
for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) {
if (*line == '\0' || *line == '#')
@@ -1342,6 +1354,7 @@ CFileLoader::ReLoadScene(const char *filename)
char *line;
CFileMgr::ChangeDir("\\DATA\\");
int fd = CFileMgr::OpenFile(filename, "r");
+ assert(fd > 0);
CFileMgr::ChangeDir("\\");
for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) {
diff --git a/src/core/FileLoader.h b/src/core/FileLoader.h
index 87b8fe61..959c919e 100644
--- a/src/core/FileLoader.h
+++ b/src/core/FileLoader.h
@@ -5,10 +5,11 @@ class CFileLoader
static char ms_line[256];
public:
static void LoadLevel(const char *filename);
- static void LoadCollisionFromDatFile(int currlevel);
static char *LoadLine(int fd);
static RwTexDictionary *LoadTexDictionary(const char *filename);
- static void LoadCollisionFile(const char *filename);
+ static void LoadCollisionFile(const char *filename, uint8 colSlot);
+ static bool LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlot);
+ static bool LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot);
static void LoadCollisionModel(uint8 *buf, struct CColModel &model, char *name);
static void LoadModelFile(const char *filename);
static RpAtomic *FindRelatedModelInfoCB(RpAtomic *atomic, void *data);
@@ -22,16 +23,14 @@ public:
static void AddTexDictionaries(RwTexDictionary *dst, RwTexDictionary *src);
static void LoadObjectTypes(const char *filename);
- static void LoadObject(const char *line);
- static int LoadMLO(const char *line);
- static void LoadMLOInstance(int id, const char *line);
- static void LoadTimeObject(const char *line);
+ static int LoadObject(const char *line);
+ static int LoadTimeObject(const char *line);
static void LoadClumpObject(const char *line);
static void LoadVehicleObject(const char *line);
static void LoadPedObject(const char *line);
- static int LoadPathHeader(const char *line, char *type);
+ static int LoadPathHeader(const char *line, int &type);
static void LoadPedPathNode(const char *line, int id, int node);
- static void LoadCarPathNode(const char *line, int id, int node);
+ static void LoadCarPathNode(const char *line, int id, int node, bool waterPath);
static void Load2dEffect(const char *line);
static void LoadScene(const char *filename);
@@ -40,8 +39,6 @@ public:
static void LoadCullZone(const char *line);
static void LoadPickup(const char *line);
- static void LoadMapZones(const char *filename);
-
static void ReloadPaths(const char *filename);
static void ReloadObjectTypes(const char *filename);
static void ReloadObject(const char *line);
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index 827e2ca7..06b9a151 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -1079,10 +1079,10 @@ CMenuManager::Draw()
rightText = TheText.Get(gbBigWhiteDebugLightSwitchedOn ? "FEM_ON" : "FEM_OFF");
break;
case MENUACTION_PEDROADGROUPS:
- rightText = TheText.Get(gbShowPedRoadGroups ? "FEM_ON" : "FEM_OFF");
+ // REMOVED(MIAMI)
break;
case MENUACTION_CARROADGROUPS:
- rightText = TheText.Get(gbShowCarRoadGroups ? "FEM_ON" : "FEM_OFF");
+ // REMOVED(MIAMI)
break;
case MENUACTION_COLLISIONPOLYS:
rightText = TheText.Get(gbShowCollisionPolys ? "FEM_ON" : "FEM_OFF");
@@ -4923,11 +4923,11 @@ CMenuManager::ProcessOnOffMenuOptions()
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
break;
case MENUACTION_PEDROADGROUPS:
- gbShowPedRoadGroups = !gbShowPedRoadGroups;
+ // REMOVED(MIAMI)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
break;
case MENUACTION_CARROADGROUPS:
- gbShowCarRoadGroups = !gbShowCarRoadGroups;
+ // REMOVED(MIAMI)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SUCCESS, 0);
break;
case MENUACTION_COLLISIONPOLYS:
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index 3286f275..a6ca4aa0 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -624,6 +624,8 @@ public:
void LoadAllTextures();
void LoadSettings();
void MessageScreen(const char *);
+ // TODO(MIAMI): implement the second argument
+ void MessageScreen(const char *str, bool) { MessageScreen(str); }
void PickNewPlayerColour();
void PrintBriefs();
static void PrintErrorMessage();
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index 969e0cdf..3ea85659 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -89,6 +89,7 @@
eLevelName CGame::currLevel;
+int32 CGame::currArea;
bool CGame::bDemoMode = true;
bool CGame::nastyGame = true;
bool CGame::frenchGame;
@@ -264,7 +265,7 @@ bool CGame::Initialise(const char* datFile)
strcpy(aDatFile, datFile);
CPools::Initialise();
CIniFile::LoadIniFile();
- currLevel = LEVEL_INDUSTRIAL;
+ currLevel = LEVEL_BEACH;
LoadingScreen("Loading the Game", "Loading generic textures", GetRandomSplashScreen());
gameTxdSlot = CTxdStore::AddTxdSlot("generic");
CTxdStore::Create(gameTxdSlot);
@@ -319,7 +320,6 @@ bool CGame::Initialise(const char* datFile)
CDraw::SetFOV(120.0f);
CDraw::ms_fLODDistance = 500.0f;
LoadingScreen("Loading the Game", "Setup streaming", nil);
- CStreaming::Init();
CStreaming::LoadInitialVehicles();
CStreaming::LoadInitialPeds();
CStreaming::RequestBigBuildings(LEVEL_NONE);
@@ -367,10 +367,7 @@ bool CGame::Initialise(const char* datFile)
CWaterCannons::Init();
CBridge::Init();
CGarages::Init();
- LoadingScreen("Loading the Game", "Position dynamic objects", nil);
- CWorld::RepositionCertainDynamicObjects();
LoadingScreen("Loading the Game", "Initialise vehicle paths", nil);
- CCullZones::ResolveVisibilities();
CTrain::InitTrains();
CPlane::InitPlanes();
CCredits::Init();
@@ -381,7 +378,6 @@ bool CGame::Initialise(const char* datFile)
CTheScripts::Process();
TheCamera.Process();
LoadingScreen("Loading the Game", "Load scene", nil);
- CModelInfo::RemoveColModelsFromOtherLevels(currLevel);
CCollision::ms_collisionInMemory = currLevel;
for (int i = 0; i < MAX_PADS; i++)
CPad::GetPad(i)->Clear(true);
@@ -487,7 +483,6 @@ void CGame::ReInitGameObjectVariables(void)
CSpecialFX::Init();
CWaterCannons::Init();
CParticle::ReloadConfig();
- CCullZones::ResolveVisibilities();
if ( !FrontEndMenuManager.m_bWantToLoad )
{
@@ -519,8 +514,6 @@ void CGame::ReloadIPLs(void)
CRoadBlocks::Init();
CCranes::InitCranes();
CGarages::Init();
- CWorld::RepositionCertainDynamicObjects();
- CCullZones::ResolveVisibilities();
CRenderer::SortBIGBuildings();
CTimer::Update();
}
@@ -592,7 +585,7 @@ void CGame::InitialiseWhenRestarting(void)
CTimer::Initialise();
FrontEndMenuManager.m_bWantToLoad = false;
ReInitGameObjectVariables();
- currLevel = LEVEL_INDUSTRIAL;
+ currLevel = LEVEL_NONE;
CCollision::SortOutCollisionAfterLoad();
}
}
diff --git a/src/core/Game.h b/src/core/Game.h
index 48f31abc..ed9ded4f 100644
--- a/src/core/Game.h
+++ b/src/core/Game.h
@@ -3,15 +3,37 @@
enum eLevelName {
LEVEL_IGNORE = -1, // beware, this is only used in CPhysical's m_nZoneLevel
LEVEL_NONE = 0,
- LEVEL_INDUSTRIAL,
- LEVEL_COMMERCIAL,
- LEVEL_SUBURBAN
+ LEVEL_BEACH,
+ LEVEL_MAINLAND
+};
+
+enum eAreaName {
+ AREA_MAIN_MAP,
+ AREA_HOTEL,
+ AREA_MANSION,
+ AREA_BANK,
+ AREA_MALL,
+ AREA_STRIP_CLUB,
+ AREA_LAWYERS,
+ AREA_COFFEE_SHOP,
+ AREA_CONCERT_HALL,
+ AREA_STUDIO,
+ AREA_RIFLE_RANGE,
+ AREA_BIKER_BAR,
+ AREA_POLICE_STATION,
+ AREA_EVERYWHERE,
+ AREA_DIRT,
+ AREA_BLOOD,
+ AREA_OVALRING,
+ AREA_MALIBU_CLUB,
+ AREA_PRINT_WORKS
};
class CGame
{
public:
static eLevelName currLevel;
+ static int32 currArea;
static bool bDemoMode;
static bool nastyGame;
static bool frenchGame;
@@ -36,9 +58,13 @@ public:
static void ShutDownForRestart(void);
static void InitialiseWhenRestarting(void);
static void Process(void);
+
+ static bool IsInInterior(void) { return currArea != AREA_MAIN_MAP; }
// NB: these do something on PS2
static void TidyUpMemory(bool, bool);
static void DrasticTidyUpMemory(bool);
static void ProcessTidyUpMemory(void);
};
+
+inline bool IsAreaVisible(int area) { return area == CGame::currArea || area == AREA_EVERYWHERE; }
diff --git a/src/core/General.h b/src/core/General.h
index 7ffa99de..3188d82b 100644
--- a/src/core/General.h
+++ b/src/core/General.h
@@ -145,4 +145,6 @@ public:
static int32 GetRandomNumberInRange(int32 low, int32 high)
{ return low + (high - low)*(GetRandomNumber()/float(MYRAND_MAX + 1)); }
+ static void SetRandomSeed(int32 seed)
+ { mysrand(seed); }
};
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index da86d15e..b996dc28 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -140,9 +140,9 @@ void ChangePlayerCheat()
do
{
do
- modelId = CGeneral::GetRandomNumberInRange(0, MI_CAS_WOM+1);
+ modelId = CGeneral::GetRandomNumberInRange(0, MI_WFYG2+1);
while (!CModelInfo::GetModelInfo(modelId));
- } while (modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL04 || modelId == MI_TAXI_D);
+ } while (modelId == MI_TAXI_D);
uint8 flags = CStreaming::ms_aInfoForModel[modelId].m_flags;
ped->DeleteRwObject();
diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp
index ec6d3023..3db42d8b 100644
--- a/src/core/PlayerInfo.cpp
+++ b/src/core/PlayerInfo.cpp
@@ -354,7 +354,7 @@ CPlayerInfo::Process(void)
bool startTaxiTimer = true;
if (m_bUnusedTaxiThing && m_pPed->bInVehicle) {
CVehicle *veh = m_pPed->m_pMyVehicle;
- if ((veh->GetModelIndex() == MI_TAXI || veh->GetModelIndex() == MI_CABBIE || veh->GetModelIndex() == MI_BORGNINE)
+ if (veh->IsTaxi()
&& veh->pDriver == m_pPed && veh->m_nNumPassengers != 0) {
for (uint32 timePassed = CTimer::GetTimeInMilliseconds() - m_nUnusedTaxiTimer; timePassed >= 1000; m_nUnusedTaxiTimer += 1000) {
timePassed -= 1000;
diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h
index e970e42d..c649d49d 100644
--- a/src/core/PlayerInfo.h
+++ b/src/core/PlayerInfo.h
@@ -80,4 +80,3 @@ public:
~CPlayerInfo() { };
};
-static_assert(sizeof(CPlayerInfo) == 0x13C, "CPlayerInfo: error");
diff --git a/src/core/Pools.h b/src/core/Pools.h
index b0ba6598..2f0537ff 100644
--- a/src/core/Pools.h
+++ b/src/core/Pools.h
@@ -4,7 +4,7 @@
#include "Lists.h"
#include "Treadable.h"
#include "Object.h"
-#include "CutsceneHead.h"
+#include "CutsceneObject.h"
#include "PlayerPed.h"
#include "Automobile.h"
#include "DummyPed.h"
@@ -16,7 +16,7 @@ typedef CPool<CPed,CPlayerPed> CPedPool;
typedef CPool<CVehicle,CAutomobile> CVehiclePool;
typedef CPool<CBuilding> CBuildingPool;
typedef CPool<CTreadable> CTreadablePool;
-typedef CPool<CObject, CCutsceneHead> CObjectPool;
+typedef CPool<CObject, CCutsceneObject> CObjectPool;
typedef CPool<CDummy, CDummyPed> CDummyPool;
typedef CPool<cAudioScriptObject> CAudioScriptObjectPool;
diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp
index f24192ef..eb7fc8f5 100644
--- a/src/core/Streaming.cpp
+++ b/src/core/Streaming.cpp
@@ -18,7 +18,6 @@
#include "FileMgr.h"
#include "FileLoader.h"
#include "Zones.h"
-#include "ZoneCull.h"
#include "Radar.h"
#include "Camera.h"
#include "Record.h"
@@ -28,10 +27,10 @@
#include "CutsceneMgr.h"
#include "CdStream.h"
#include "Streaming.h"
-#ifdef FIX_BUGS
#include "Replay.h"
-#endif
#include "main.h"
+#include "ColStore.h"
+#include "DMAudio.h"
bool CStreaming::ms_disableStreaming;
bool CStreaming::ms_bLoadingBigModel;
@@ -51,9 +50,9 @@ int32 CStreaming::ms_channelError;
int32 CStreaming::ms_numVehiclesLoaded;
int32 CStreaming::ms_vehiclesLoaded[MAXVEHICLESLOADED];
int32 CStreaming::ms_lastVehicleDeleted;
+bool CStreaming::ms_bIsPedFromPedGroupLoaded[NUMMODELSPERPEDGROUP];
CDirectory *CStreaming::ms_pExtraObjectsDir;
int32 CStreaming::ms_numPriorityRequests;
-bool CStreaming::ms_hasLoadedLODs;
int32 CStreaming::ms_currentPedGrp;
int32 CStreaming::ms_currentPedLoading;
int32 CStreaming::ms_lastCullZone;
@@ -66,17 +65,12 @@ uint32 CStreaming::ms_memoryAvailable;
int32 desiredNumVehiclesLoaded = 12;
-CEntity *pIslandLODindustEntity;
-CEntity *pIslandLODcomIndEntity;
-CEntity *pIslandLODcomSubEntity;
-CEntity *pIslandLODsubIndEntity;
-CEntity *pIslandLODsubComEntity;
-int32 islandLODindust;
-int32 islandLODcomInd;
-int32 islandLODcomSub;
-int32 islandLODsubInd;
-int32 islandLODsubCom;
+CEntity *pIslandLODmainlandEntity;
+CEntity *pIslandLODbeachEntity;
+int32 islandLODmainland;
+int32 islandLODbeach;
+//--MIAMI: done
bool
CStreamingInfo::GetCdPosnAndSize(uint32 &posn, uint32 &size)
{
@@ -87,6 +81,7 @@ CStreamingInfo::GetCdPosnAndSize(uint32 &posn, uint32 &size)
return true;
}
+//--MIAMI: done
void
CStreamingInfo::SetCdPosnAndSize(uint32 posn, uint32 size)
{
@@ -94,6 +89,7 @@ CStreamingInfo::SetCdPosnAndSize(uint32 posn, uint32 size)
m_size = size;
}
+//--MIAMI: done
void
CStreamingInfo::AddToList(CStreamingInfo *link)
{
@@ -104,6 +100,7 @@ CStreamingInfo::AddToList(CStreamingInfo *link)
m_next->m_prev = this;
}
+//--MIAMI: done
void
CStreamingInfo::RemoveFromList(void)
{
@@ -113,6 +110,7 @@ CStreamingInfo::RemoveFromList(void)
m_prev = nil;
}
+//--MIAMI: done
void
CStreaming::Init2(void)
{
@@ -182,13 +180,15 @@ CStreaming::Init2(void)
ms_vehiclesLoaded[i] = -1;
ms_numVehiclesLoaded = 0;
+ for(i = 0; i < ARRAY_SIZE(ms_bIsPedFromPedGroupLoaded); i++)
+ ms_bIsPedFromPedGroupLoaded[i] = false;
+
ms_pExtraObjectsDir = new CDirectory(EXTRADIRSIZE);
ms_numPriorityRequests = 0;
- ms_hasLoadedLODs = true;
ms_currentPedGrp = -1;
ms_lastCullZone = -1; // unused because RemoveModelsNotVisibleFromCullzone is gone
ms_loadedGangs = 0;
- ms_currentPedLoading = 8; // unused, whatever it is
+ ms_currentPedLoading = NUMMODELSPERPEDGROUP; // unused, whatever it is
LoadCdDirectory();
@@ -199,48 +199,20 @@ CStreaming::Init2(void)
ms_pStreamingBuffer[1] = ms_pStreamingBuffer[0] + ms_streamingBufferSize*CDSTREAM_SECTOR_SIZE;
debug("Streaming buffer size is %d sectors", ms_streamingBufferSize);
- // PC only, figure out how much memory we got
-#ifdef GTA_PC
#define MB (1024*1024)
- extern unsigned long _dwMemAvailPhys;
- ms_memoryAvailable = (_dwMemAvailPhys - 10*MB)/2;
- if(ms_memoryAvailable < 50*MB)
- ms_memoryAvailable = 50*MB;
- desiredNumVehiclesLoaded = (ms_memoryAvailable/MB - 50)/3 + 12;
- if(desiredNumVehiclesLoaded > MAXVEHICLESLOADED)
- desiredNumVehiclesLoaded = MAXVEHICLESLOADED;
+ ms_memoryAvailable = 65*MB;
+ desiredNumVehiclesLoaded = 25;
debug("Memory allocated to Streaming is %dMB", ms_memoryAvailable/MB);
#undef MB
-#endif
// find island LODs
- pIslandLODindustEntity = nil;
- pIslandLODcomIndEntity = nil;
- pIslandLODcomSubEntity = nil;
- pIslandLODsubIndEntity = nil;
- pIslandLODsubComEntity = nil;
- islandLODindust = -1;
- islandLODcomInd = -1;
- islandLODcomSub = -1;
- islandLODsubInd = -1;
- islandLODsubCom = -1;
- CModelInfo::GetModelInfo("IslandLODInd", &islandLODindust);
- CModelInfo::GetModelInfo("IslandLODcomIND", &islandLODcomInd);
- CModelInfo::GetModelInfo("IslandLODcomSUB", &islandLODcomSub);
- CModelInfo::GetModelInfo("IslandLODsubIND", &islandLODsubInd);
- CModelInfo::GetModelInfo("IslandLODsubCOM", &islandLODsubCom);
-
- for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){
- CBuilding *building = CPools::GetBuildingPool()->GetSlot(i);
- if(building == nil)
- continue;
- if(building->GetModelIndex() == islandLODindust) pIslandLODindustEntity = building;
- if(building->GetModelIndex() == islandLODcomInd) pIslandLODcomIndEntity = building;
- if(building->GetModelIndex() == islandLODcomSub) pIslandLODcomSubEntity = building;
- if(building->GetModelIndex() == islandLODsubInd) pIslandLODsubIndEntity = building;
- if(building->GetModelIndex() == islandLODsubCom) pIslandLODsubComEntity = building;
- }
+ pIslandLODmainlandEntity = nil;
+ pIslandLODbeachEntity = nil;
+ islandLODmainland = -1;
+ islandLODbeach = -1;
+ CModelInfo::GetModelInfo("IslandLODmainland", &islandLODmainland);
+ CModelInfo::GetModelInfo("IslandLODbeach", &islandLODbeach);
}
void
@@ -266,6 +238,7 @@ CStreaming::Init(void)
#endif
}
+//--MIAMI: done
void
CStreaming::Shutdown(void)
{
@@ -275,10 +248,10 @@ CStreaming::Shutdown(void)
delete ms_pExtraObjectsDir;
}
+//--MIAMI: done
void
CStreaming::Update(void)
{
- CEntity *train;
CStreamingInfo *si, *prev;
bool requestedSubway = false;
@@ -292,31 +265,32 @@ CStreaming::Update(void)
if(CTimer::GetIsPaused())
return;
- train = FindPlayerTrain();
- if(train && train->GetPosition().z < 0.0f){
- RequestSubway();
- requestedSubway = true;
- }else if(!ms_disableStreaming)
+ LoadBigBuildingsWhenNeeded();
+ if(!ms_disableStreaming && TheCamera.GetPosition().z < 55.0f)
AddModelsToRequestList(TheCamera.GetPosition());
DeleteFarAwayRwObjects(TheCamera.GetPosition());
if(!ms_disableStreaming &&
- !CCutsceneMgr::IsRunning() &&
- !requestedSubway &&
- !CGame::playingIntro &&
+ !CCutsceneMgr::IsCutsceneProcessing() &&
ms_numModelsRequested < 5 &&
- !CRenderer::m_loadingPriority
-#ifdef FIX_BUGS
- && !CReplay::IsPlayingBack()
-#endif
- ){
+ !CRenderer::m_loadingPriority &&
+ CGame::currArea == AREA_MAIN_MAP &&
+ !CReplay::IsPlayingBack()){
StreamVehiclesAndPeds();
StreamZoneModels(FindPlayerCoors());
}
LoadRequestedModels();
+ if(CWorld::Players[0].m_pRemoteVehicle){
+ CColStore::AddCollisionNeededAtPosn(FindPlayerCoors());
+ CColStore::LoadCollision(CWorld::Players[0].m_pRemoteVehicle->GetPosition());
+ CColStore::EnsureCollisionIsInMemory(CWorld::Players[0].m_pRemoteVehicle->GetPosition());
+ }else{
+ CColStore::LoadCollision(FindPlayerCoors());
+ CColStore::EnsureCollisionIsInMemory(FindPlayerCoors());
+ }
for(si = ms_endRequestedList.m_prev; si != &ms_startRequestedList; si = prev){
prev = si->m_prev;
@@ -325,6 +299,7 @@ CStreaming::Update(void)
}
}
+//--MIAMI: done
void
CStreaming::LoadCdDirectory(void)
{
@@ -338,12 +313,6 @@ CStreaming::LoadCdDirectory(void)
ms_imageOffsets[3] = -1;
ms_imageOffsets[4] = -1;
ms_imageOffsets[5] = -1;
- ms_imageOffsets[6] = -1;
- ms_imageOffsets[7] = -1;
- ms_imageOffsets[8] = -1;
- ms_imageOffsets[9] = -1;
- ms_imageOffsets[10] = -1;
- ms_imageOffsets[11] = -1;
ms_imageSize = GetGTA3ImgSize();
// PS2 uses CFileMgr::GetCdFile on all IMG files to fill the array
#endif
@@ -359,12 +328,12 @@ CStreaming::LoadCdDirectory(void)
ms_imageSize /= CDSTREAM_SECTOR_SIZE;
}
+//--MIAMI: done
void
CStreaming::LoadCdDirectory(const char *dirname, int n)
{
int fd, lastID, imgSelector;
- int modelId, txdId;
- uint32 posn, size;
+ int modelId;
CDirectory::DirectoryInfo direntry;
char *dot;
@@ -375,23 +344,23 @@ CStreaming::LoadCdDirectory(const char *dirname, int n)
imgSelector = n<<24;
assert(sizeof(direntry) == 32);
while(CFileMgr::Read(fd, (char*)&direntry, sizeof(direntry))){
- dot = strchr(direntry.name, '.');
- if(dot) *dot = '\0';
+ bool bAddToStreaming = false;
+
if(direntry.size > (uint32)ms_streamingBufferSize)
ms_streamingBufferSize = direntry.size;
+ direntry.name[23] = '\0';
+ dot = strchr(direntry.name, '.');
+ if(dot == nil || dot-direntry.name > 20){
+ debug("%s is too long\n", direntry.name);
+ lastID = -1;
+ continue;
+ }
- if(!CGeneral::faststrcmp(dot+1, "DFF") || !CGeneral::faststrcmp(dot+1, "dff")){
+ *dot = '\0';
+
+ if(strncasecmp(dot+1, "DFF", 3) == 0){
if(CModelInfo::GetModelInfo(direntry.name, &modelId)){
- if(ms_aInfoForModel[modelId].GetCdPosnAndSize(posn, size)){
- debug("%s appears more than once in %s\n", direntry.name, dirname);
- lastID = -1;
- }else{
- direntry.offset |= imgSelector;
- ms_aInfoForModel[modelId].SetCdPosnAndSize(direntry.offset, direntry.size);
- if(lastID != -1)
- ms_aInfoForModel[lastID].m_nextID = modelId;
- lastID = modelId;
- }
+ bAddToStreaming = true;
}else{
#ifdef FIX_BUGS
// remember which cdimage this came from
@@ -401,27 +370,63 @@ CStreaming::LoadCdDirectory(const char *dirname, int n)
#endif
lastID = -1;
}
- }else if(!CGeneral::faststrcmp(dot+1, "TXD") || !CGeneral::faststrcmp(dot+1, "txd")){
- txdId = CTxdStore::FindTxdSlot(direntry.name);
- if(txdId == -1)
- txdId = CTxdStore::AddTxdSlot(direntry.name);
- if(ms_aInfoForModel[txdId + STREAM_OFFSET_TXD].GetCdPosnAndSize(posn, size)){
- debug("%s appears more than once in %s\n", direntry.name, dirname);
+ }else if(strncasecmp(dot+1, "TXD", 3) == 0){
+ modelId = CTxdStore::FindTxdSlot(direntry.name);
+ if(modelId == -1)
+ modelId = CTxdStore::AddTxdSlot(direntry.name);
+ modelId += STREAM_OFFSET_TXD;
+ bAddToStreaming = true;
+ }else if(strncasecmp(dot+1, "COL", 3) == 0){
+ modelId = CColStore::FindColSlot(direntry.name);
+ if(modelId == -1)
+ modelId = CColStore::AddColSlot(direntry.name);
+ modelId += STREAM_OFFSET_COL;
+ bAddToStreaming = true;
+ }else if(strncasecmp(dot+1, "IFP", 3) == 0){
+ modelId = CAnimManager::RegisterAnimBlock(direntry.name);
+ modelId += STREAM_OFFSET_ANIM;
+ bAddToStreaming = true;
+ }else{
+ *dot = '.';
+ lastID = -1;
+ }
+
+ if(bAddToStreaming){
+ if(ms_aInfoForModel[modelId].GetCdSize()){
+ debug("%s.%s appears more than once in %s\n", direntry.name, dot+1, dirname);
lastID = -1;
}else{
direntry.offset |= imgSelector;
- ms_aInfoForModel[txdId + STREAM_OFFSET_TXD].SetCdPosnAndSize(direntry.offset, direntry.size);
+ ms_aInfoForModel[modelId].SetCdPosnAndSize(direntry.offset, direntry.size);
if(lastID != -1)
- ms_aInfoForModel[lastID].m_nextID = txdId + STREAM_OFFSET_TXD;
- lastID = txdId + STREAM_OFFSET_TXD;
+ ms_aInfoForModel[lastID].m_nextID = modelId;
+ lastID = modelId;
}
- }else
- lastID = -1;
+ }
}
CFileMgr::CloseFile(fd);
}
+static char*
+GetObjectName(int streamId)
+{
+ static char objname[32];
+ if(streamId < STREAM_OFFSET_TXD)
+ sprintf(objname, "%s.dff", CModelInfo::GetModelInfo(streamId)->GetName());
+ else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL)
+ sprintf(objname, "%s.txd", CTxdStore::GetTxdName(streamId-STREAM_OFFSET_TXD));
+ else if(streamId >= STREAM_OFFSET_COL && streamId < STREAM_OFFSET_ANIM)
+ sprintf(objname, "%s.col", CColStore::GetColName(streamId-STREAM_OFFSET_COL));
+ else{
+ assert(streamId < NUMSTREAMINFO);
+ sprintf(objname, "%s.ifp", CAnimManager::GetAnimationBlock(streamId-STREAM_OFFSET_ANIM)->name);
+ }
+ return objname;
+}
+
+
+//--MIAMI: done
bool
CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
{
@@ -443,22 +448,25 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
// Model
mi = CModelInfo::GetModelInfo(streamId);
- // Txd has to be loaded
- if(CTxdStore::GetSlot(mi->GetTxdSlot())->texDict == nil){
- debug("failed to load %s because TXD %s is not in memory\n", mi->GetName(), CTxdStore::GetTxdName(mi->GetTxdSlot()));
+ // Txd and anim have to be loaded
+ int animId = mi->GetAnimFileIndex();
+ if(CTxdStore::GetSlot(mi->GetTxdSlot())->texDict == nil ||
+ animId != -1 && !CAnimManager::GetAnimationBlock(animId)->isLoaded){
RemoveModel(streamId);
- RemoveTxd(mi->GetTxdSlot());
ReRequestModel(streamId);
RwStreamClose(stream, &mem);
return false;
}
- // Set Txd to use
+ // Set Txd and anims to use
CTxdStore::AddRef(mi->GetTxdSlot());
+ if(animId != -1)
+ CAnimManager::AddAnimBlockRef(animId);
CTxdStore::SetCurrentTxd(mi->GetTxdSlot());
if(mi->IsSimple()){
success = CFileLoader::LoadAtomicFile(stream, streamId);
+ // TODO(MIAMI)? complain if file is not pre-instanced. we hardly are interested in that
} else if (mi->GetModelType() == MITYPE_VEHICLE) {
// load vehicles in two parts
CModelInfo::GetModelInfo(streamId)->AddRef();
@@ -470,9 +478,12 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
}
UpdateMemoryUsed();
- // Txd no longer needed unless we only read part of the file
- if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED)
+ // Txd and anims no longer needed unless we only read part of the file
+ if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED){
CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot());
+ if(animId != -1)
+ CAnimManager::RemoveAnimBlockRefWithoutDelete(animId);
+ }
if(!success){
debug("Failed to load %s\n", CModelInfo::GetModelInfo(streamId)->GetName());
@@ -481,9 +492,8 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
RwStreamClose(stream, &mem);
return false;
}
- }else{
+ }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){
// Txd
- assert(streamId < NUMSTREAMINFO);
if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY) == 0 &&
!IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD)){
RemoveModel(streamId);
@@ -506,20 +516,28 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
RwStreamClose(stream, &mem);
return false;
}
+ }else if(streamId >= STREAM_OFFSET_COL && streamId < STREAM_OFFSET_ANIM){
+ if(!CColStore::LoadCol(streamId-STREAM_OFFSET_COL, mem.start, mem.length)){
+ debug("Failed to load %s.col\n", CColStore::GetColName(streamId - STREAM_OFFSET_COL));
+ RemoveModel(streamId);
+ ReRequestModel(streamId);
+ RwStreamClose(stream, &mem);
+ return false;
+ }
+ }else if(streamId >= STREAM_OFFSET_ANIM){
+ assert(streamId < NUMSTREAMINFO);
+ if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY) == 0 &&
+ !AreAnimsUsedByRequestedModels(streamId - STREAM_OFFSET_ANIM)){
+ RemoveModel(streamId);
+ RwStreamClose(stream, &mem);
+ return false;
+ }
+ CAnimManager::LoadAnimFile(stream, true, nil);
+ CAnimManager::CreateAnimAssocGroups();
}
RwStreamClose(stream, &mem);
- // We shouldn't even end up here unless load was successful
- if(!success){
- ReRequestModel(streamId);
- if(streamId < STREAM_OFFSET_TXD)
- debug("Failed to load %s.dff\n", mi->GetName());
- else
- debug("Failed to load %s.txd\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD));
- return false;
- }
-
if(streamId < STREAM_OFFSET_TXD){
// Model
// Vehicles and Peds not in loaded list
@@ -534,12 +552,14 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
smi->m_alpha = 0;
}
- if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_CANT_REMOVE) == 0)
+ if(CanRemoveModel(streamId))
ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList);
}
- }else{
- // Txd
- if((ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_CANT_REMOVE) == 0)
+ }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL ||
+ streamId >= STREAM_OFFSET_ANIM){
+ assert(streamId < NUMSTREAMINFO);
+ // Txd and anims
+ if(CanRemoveModel(streamId))
ms_aInfoForModel[streamId].AddToList(&ms_startLoadedList);
}
@@ -551,17 +571,13 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();
timeDiff = endTime - startTime;
- if(timeDiff > 5){
- if(streamId < STREAM_OFFSET_TXD)
- debug("model %s took %d ms\n", CModelInfo::GetModelInfo(streamId)->GetName(), timeDiff);
- else
- debug("txd %s took %d ms\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD), timeDiff);
- }
+ if(timeDiff > 5)
+ debug("%s took %d ms\n", GetObjectName(streamId), timeDiff);
return true;
}
-
+//--MIAMI: done
bool
CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId)
{
@@ -592,11 +608,15 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId)
success = AddToLoadedVehiclesList(streamId);
mi->RemoveRef();
CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot());
- }else{
+ if(mi->GetAnimFileIndex() != -1)
+ CAnimManager::RemoveAnimBlockRefWithoutDelete(mi->GetAnimFileIndex());
+ }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){
// Txd
CTxdStore::AddRef(streamId - STREAM_OFFSET_TXD);
success = CTxdStore::FinishLoadTxd(streamId - STREAM_OFFSET_TXD, stream);
CTxdStore::RemoveRefWithoutDelete(streamId - STREAM_OFFSET_TXD);
+ }else{
+ assert(0 && "invalid streamId");
}
RwStreamClose(stream, &mem);
@@ -614,16 +634,13 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId)
endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();
timeDiff = endTime - startTime;
- if(timeDiff > 5){
- if(streamId < STREAM_OFFSET_TXD)
- debug("finish model %s took %d ms\n", CModelInfo::GetModelInfo(streamId)->GetName(), timeDiff);
- else
- debug("finish txd %s took %d ms\n", CTxdStore::GetTxdName(streamId - STREAM_OFFSET_TXD), timeDiff);
- }
+ if(timeDiff > 5)
+ debug("%s took %d ms\n", GetObjectName(streamId), timeDiff);
return true;
}
+//--MIAMI: done
void
CStreaming::RequestModel(int32 id, int32 flags)
{
@@ -652,15 +669,20 @@ CStreaming::RequestModel(int32 id, int32 flags)
// reinsert into list
if(ms_aInfoForModel[id].m_next){
ms_aInfoForModel[id].RemoveFromList();
- if((ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0)
+ if(CanRemoveModel(id))
ms_aInfoForModel[id].AddToList(&ms_startLoadedList);
}
}else if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_NOTLOADED ||
ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED){ // how can this be true again?
if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_NOTLOADED){
- if(id < STREAM_OFFSET_TXD)
- RequestTxd(CModelInfo::GetModelInfo(id)->GetTxdSlot(), flags);
+ if(id < STREAM_OFFSET_TXD){
+ mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
+ RequestTxd(mi->GetTxdSlot(), flags);
+ int anim = mi->GetAnimFileIndex();
+ if(anim != -1)
+ RequestAnim(anim, STREAMFLAGS_DEPENDENCY);
+ }
ms_aInfoForModel[id].AddToList(&ms_startRequestedList);
ms_numModelsRequested++;
if(flags & STREAMFLAGS_PRIORITY)
@@ -672,51 +694,28 @@ CStreaming::RequestModel(int32 id, int32 flags)
}
}
+#define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE
+
+//--MIAMI: done
void
-CStreaming::RequestSubway(void)
-{
- RequestModel(MI_SUBWAY1, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY2, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY3, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY4, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY5, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY6, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY7, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY8, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY9, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY10, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY11, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY12, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY13, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY14, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY15, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY16, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY17, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBWAY18, STREAMFLAGS_NOFADE);
-
- switch(CGame::currLevel){
- case LEVEL_INDUSTRIAL:
- RequestModel(MI_SUBPLATFORM_IND, STREAMFLAGS_NOFADE);
- break;
- case LEVEL_COMMERCIAL:
- if(FindPlayerTrain()->GetPosition().y < -700.0f){
- RequestModel(MI_SUBPLATFORM_COMS, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBPLATFORM_COMS2, STREAMFLAGS_NOFADE);
- }else{
- RequestModel(MI_SUBPLATFORM_COMN, STREAMFLAGS_NOFADE);
- }
- break;
- case LEVEL_SUBURBAN:
- RequestModel(MI_SUBPLATFORM_SUB, STREAMFLAGS_NOFADE);
- RequestModel(MI_SUBPLATFORM_SUB2, STREAMFLAGS_NOFADE);
- break;
+CStreaming::RequestBigBuildings(eLevelName level)
+{
+ int i, n;
+ CBuilding *b;
+
+ n = CPools::GetBuildingPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
+ b = CPools::GetBuildingPool()->GetSlot(i);
+ if(b && b->bIsBIGBuilding && b->m_level == level)
+ if(!b->bStreamBIGBuilding)
+ RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS);
}
+ RequestIslands(level);
}
-#define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_PRIORITY
-
+//--MIAMI: done
void
-CStreaming::RequestBigBuildings(eLevelName level)
+CStreaming::RequestBigBuildings(eLevelName level, const CVector &pos)
{
int i, n;
CBuilding *b;
@@ -725,31 +724,90 @@ CStreaming::RequestBigBuildings(eLevelName level)
for(i = n; i >= 0; i--){
b = CPools::GetBuildingPool()->GetSlot(i);
if(b && b->bIsBIGBuilding && b->m_level == level)
- RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS);
+ if(b->bStreamBIGBuilding){
+ if(CRenderer::ShouldModelBeStreamed(b))
+ RequestModel(b->GetModelIndex(), 0);
+ }else
+ RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS);
}
RequestIslands(level);
- ms_hasLoadedLODs = false;
}
+//--MIAMI: done
+void
+CStreaming::InstanceBigBuildings(eLevelName level, const CVector &pos)
+{
+ int i, n;
+ CBuilding *b;
+
+ n = CPools::GetBuildingPool()->GetSize()-1;
+ for(i = n; i >= 0; i--){
+ b = CPools::GetBuildingPool()->GetSlot(i);
+ if(b && b->bIsBIGBuilding && b->m_level == level &&
+ b->bStreamBIGBuilding && b->m_rwObject == nil)
+ if(CRenderer::ShouldModelBeStreamed(b))
+ b->CreateRwObject();
+ }
+}
+
+//--MIAMI: done
+void
+CStreaming::InstanceLoadedModelsInSectorList(CPtrList &list)
+{
+ CPtrNode *node;
+ CEntity *e;
+ for(node = list.first; node; node = node->next) {
+ e = (CEntity *)node->item;
+ if(IsAreaVisible(e->m_area) && e->m_rwObject == nil)
+ e->CreateRwObject();
+ }
+}
+
+//--MIAMI: done
+void
+CStreaming::InstanceLoadedModels(const CVector &pos)
+{
+ int minX = CWorld::GetSectorIndexX(pos.x - 80.0f);
+ if(minX <= 0) minX = 0;
+
+ int minY = CWorld::GetSectorIndexY(pos.y - 80.0f);
+ if(minY <= 0) minY = 0;
+
+ int maxX = CWorld::GetSectorIndexX(pos.x + 80.0f);
+ if(maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
+
+ int maxY = CWorld::GetSectorIndexY(pos.y + 80.0f);
+ if(maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
+
+ int x, y;
+ for(y = minY; y <= maxY; y++){
+ for(x = minX; x <= maxX; x++){
+ CSector *sector = CWorld::GetSector(x, y);
+ InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_BUILDINGS]);
+ InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]);
+ InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_OBJECTS]);
+ InstanceLoadedModelsInSectorList(sector->m_lists[ENTITYLIST_DUMMIES]);
+ }
+ }
+}
+
+//--MIAMI: done
void
CStreaming::RequestIslands(eLevelName level)
{
switch(level){
- case LEVEL_INDUSTRIAL:
- RequestModel(islandLODcomInd, BIGBUILDINGFLAGS);
- RequestModel(islandLODsubInd, BIGBUILDINGFLAGS);
+ case LEVEL_MAINLAND:
+ if(islandLODbeach != -1)
+ RequestModel(islandLODbeach, BIGBUILDINGFLAGS);
break;
- case LEVEL_COMMERCIAL:
- RequestModel(islandLODindust, BIGBUILDINGFLAGS);
- RequestModel(islandLODsubCom, BIGBUILDINGFLAGS);
- break;
- case LEVEL_SUBURBAN:
- RequestModel(islandLODindust, BIGBUILDINGFLAGS);
- RequestModel(islandLODcomSub, BIGBUILDINGFLAGS);
+ case LEVEL_BEACH:
+ if(islandLODmainland != -1)
+ RequestModel(islandLODmainland, BIGBUILDINGFLAGS);
break;
}
}
+//--MIAMI: TODO
void
CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flags)
{
@@ -791,24 +849,28 @@ CStreaming::RequestSpecialModel(int32 modelId, const char *modelName, int32 flag
RequestModel(modelId, flags);
}
+//--MIAMI: done
void
CStreaming::RequestSpecialChar(int32 charId, const char *modelName, int32 flags)
{
RequestSpecialModel(charId + MI_SPECIAL01, modelName, flags);
}
+//--MIAMI: done
bool
CStreaming::HasSpecialCharLoaded(int32 id)
{
return HasModelLoaded(id + MI_SPECIAL01);
}
+//--MIAMI: done
void
CStreaming::SetMissionDoesntRequireSpecialChar(int32 id)
{
return SetMissionDoesntRequireModel(id + MI_SPECIAL01);
}
+//--MIAMI: done
void
CStreaming::DecrementRef(int32 id)
{
@@ -819,6 +881,7 @@ CStreaming::DecrementRef(int32 id)
}
}
+//--MIAMI: done
void
CStreaming::RemoveModel(int32 id)
{
@@ -830,8 +893,14 @@ CStreaming::RemoveModel(int32 id)
if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED){
if(id < STREAM_OFFSET_TXD)
CModelInfo::GetModelInfo(id)->DeleteRwObject();
- else
+ else if(id >= STREAM_OFFSET_TXD && id < STREAM_OFFSET_COL)
CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD);
+ else if(id >= STREAM_OFFSET_COL && id < STREAM_OFFSET_ANIM)
+ CColStore::RemoveCol(id - STREAM_OFFSET_COL);
+ else if(id >= STREAM_OFFSET_ANIM){
+ assert(id < NUMSTREAMINFO);
+ CAnimManager::RemoveAnimBlock(id - STREAM_OFFSET_ANIM);
+ }
ms_memoryUsed -= ms_aInfoForModel[id].GetCdSize()*CDSTREAM_SECTOR_SIZE;
}
@@ -852,24 +921,30 @@ CStreaming::RemoveModel(int32 id)
if(ms_aInfoForModel[id].m_loadState == STREAMSTATE_STARTED){
if(id < STREAM_OFFSET_TXD)
RpClumpGtaCancelStream();
- else
+ else if(id >= STREAM_OFFSET_TXD && id < STREAM_OFFSET_COL)
CTxdStore::RemoveTxd(id - STREAM_OFFSET_TXD);
+ else if(id >= STREAM_OFFSET_COL && id < STREAM_OFFSET_ANIM)
+ CColStore::RemoveCol(id - STREAM_OFFSET_COL);
+ else if(id >= STREAM_OFFSET_ANIM){
+ assert(id < NUMSTREAMINFO);
+ CAnimManager::RemoveAnimBlock(id - STREAM_OFFSET_ANIM);
+ }
}
ms_aInfoForModel[id].m_loadState = STREAMSTATE_NOTLOADED;
}
+//--MIAMI: done
void
CStreaming::RemoveUnusedBuildings(eLevelName level)
{
- if(level != LEVEL_INDUSTRIAL)
- RemoveBuildings(LEVEL_INDUSTRIAL);
- if(level != LEVEL_COMMERCIAL)
- RemoveBuildings(LEVEL_COMMERCIAL);
- if(level != LEVEL_SUBURBAN)
- RemoveBuildings(LEVEL_SUBURBAN);
+ if(level != LEVEL_BEACH)
+ RemoveBuildings(LEVEL_BEACH);
+ if(level != LEVEL_MAINLAND)
+ RemoveBuildings(LEVEL_MAINLAND);
}
+//--MIAMI: done
void
CStreaming::RemoveBuildings(eLevelName level)
{
@@ -930,18 +1005,18 @@ CStreaming::RemoveBuildings(eLevelName level)
}
}
+//--MIAMI: done
void
CStreaming::RemoveUnusedBigBuildings(eLevelName level)
{
- if(level != LEVEL_INDUSTRIAL)
- RemoveBigBuildings(LEVEL_INDUSTRIAL);
- if(level != LEVEL_COMMERCIAL)
- RemoveBigBuildings(LEVEL_COMMERCIAL);
- if(level != LEVEL_SUBURBAN)
- RemoveBigBuildings(LEVEL_SUBURBAN);
+ if(level != LEVEL_BEACH)
+ RemoveBigBuildings(LEVEL_BEACH);
+ if(level != LEVEL_MAINLAND)
+ RemoveBigBuildings(LEVEL_MAINLAND);
RemoveIslandsNotUsed(level);
}
+//--MIAMI: done
void
DeleteIsland(CEntity *island)
{
@@ -955,35 +1030,33 @@ DeleteIsland(CEntity *island)
}
}
+//--MIAMI: done
void
CStreaming::RemoveIslandsNotUsed(eLevelName level)
{
+ int i;
+ if(pIslandLODmainlandEntity == nil)
+ for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){
+ CBuilding *building = CPools::GetBuildingPool()->GetSlot(i);
+ if(building == nil)
+ continue;
+ if(building->GetModelIndex() == islandLODmainland)
+ pIslandLODmainlandEntity = building;
+ if(building->GetModelIndex() == islandLODbeach)
+ pIslandLODbeachEntity = building;
+ }
+
switch(level){
- case LEVEL_INDUSTRIAL:
- DeleteIsland(pIslandLODindustEntity);
- DeleteIsland(pIslandLODcomSubEntity);
- DeleteIsland(pIslandLODsubComEntity);
- break;
- case LEVEL_COMMERCIAL:
- DeleteIsland(pIslandLODcomIndEntity);
- DeleteIsland(pIslandLODcomSubEntity);
- DeleteIsland(pIslandLODsubIndEntity);
+ case LEVEL_MAINLAND:
+ DeleteIsland(pIslandLODmainlandEntity);
break;
- case LEVEL_SUBURBAN:
- DeleteIsland(pIslandLODsubIndEntity);
- DeleteIsland(pIslandLODsubComEntity);
- DeleteIsland(pIslandLODcomIndEntity);
- break;
- default:
- DeleteIsland(pIslandLODindustEntity);
- DeleteIsland(pIslandLODcomIndEntity);
- DeleteIsland(pIslandLODcomSubEntity);
- DeleteIsland(pIslandLODsubIndEntity);
- DeleteIsland(pIslandLODsubComEntity);
+ case LEVEL_BEACH:
+ DeleteIsland(pIslandLODbeachEntity);
break;
}
}
+//--MIAMI: done
void
CStreaming::RemoveBigBuildings(eLevelName level)
{
@@ -1015,8 +1088,7 @@ CStreaming::RemoveLoadedVehicle(void)
if(ms_lastVehicleDeleted == MAXVEHICLESLOADED)
ms_lastVehicleDeleted = 0;
id = ms_vehiclesLoaded[ms_lastVehicleDeleted];
- if(id != -1 &&
- (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0 && CModelInfo::GetModelInfo(id)->GetNumRefs() == 0 &&
+ if(id != -1 && CanRemoveModel(id) && CModelInfo::GetModelInfo(id)->GetNumRefs() == 0 &&
ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED)
goto found;
}
@@ -1025,33 +1097,47 @@ found:
RemoveModel(ms_vehiclesLoaded[ms_lastVehicleDeleted]);
ms_numVehiclesLoaded--;
ms_vehiclesLoaded[ms_lastVehicleDeleted] = -1;
+ CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id);
+ if (pVehicleInfo->m_vehicleClass != -1)
+ CCarCtrl::RemoveFromLoadedVehicleArray(id, pVehicleInfo->m_vehicleClass);
return true;
}
+//--MIAMI: done
bool
-CStreaming::RemoveLeastUsedModel(void)
+CStreaming::RemoveLeastUsedModel(uint32 excludeMask)
{
CStreamingInfo *si;
int streamId;
for(si = ms_endLoadedList.m_prev; si != &ms_startLoadedList; si = si->m_prev){
+ if(si->m_flags & excludeMask)
+ continue;
streamId = si - ms_aInfoForModel;
if(streamId < STREAM_OFFSET_TXD){
if (CModelInfo::GetModelInfo(streamId)->GetNumRefs() == 0) {
RemoveModel(streamId);
return true;
}
- }else{
+ }else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){
if(CTxdStore::GetNumRefs(streamId - STREAM_OFFSET_TXD) == 0 &&
!IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD)){
RemoveModel(streamId);
return true;
}
+ }else if(streamId >= STREAM_OFFSET_ANIM){
+ assert(streamId < NUMSTREAMINFO);
+ if(CAnimManager::GetNumRefsToAnimBlock(streamId - STREAM_OFFSET_ANIM) == 0 &&
+ !AreAnimsUsedByRequestedModels(streamId - STREAM_OFFSET_ANIM)){
+ RemoveModel(streamId);
+ return true;
+ }
}
}
- return ms_numVehiclesLoaded > 7 && RemoveLoadedVehicle();
+ return (ms_numVehiclesLoaded > 7 || CGame::currArea != AREA_MAIN_MAP && ms_numVehiclesLoaded > 4) && RemoveLoadedVehicle();
}
+//--MIAMI: done
void
CStreaming::RemoveAllUnusedModels(void)
{
@@ -1062,7 +1148,6 @@ CStreaming::RemoveAllUnusedModels(void)
for(i = NUM_DEFAULT_MODELS; i < MODELINFOSIZE; i++){
if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED &&
- ms_aInfoForModel[i].m_flags & STREAMFLAGS_DONT_REMOVE &&
CModelInfo::GetModelInfo(i)->GetNumRefs() == 0) {
RemoveModel(i);
ms_aInfoForModel[i].m_loadState = STREAMSTATE_NOTLOADED;
@@ -1070,30 +1155,14 @@ CStreaming::RemoveAllUnusedModels(void)
}
}
-bool
-CStreaming::RemoveReferencedTxds(int32 mem)
-{
- CStreamingInfo *si;
- int streamId;
-
- for(si = ms_endLoadedList.m_prev; si != &ms_startLoadedList; si = si->m_prev){
- streamId = si - ms_aInfoForModel;
- if(streamId >= STREAM_OFFSET_TXD &&
- CTxdStore::GetNumRefs(streamId-STREAM_OFFSET_TXD) == 0){
- RemoveModel(streamId);
- if(ms_memoryUsed < mem)
- return true;
- }
- }
- return false;
-}
-
+//--MIAMI: done
void
CStreaming::RemoveUnusedModelsInLoadedList(void)
{
// empty
}
+//--MIAMI: done
bool
CStreaming::IsTxdUsedByRequestedModels(int32 txdId)
{
@@ -1122,6 +1191,34 @@ CStreaming::IsTxdUsedByRequestedModels(int32 txdId)
return false;
}
+bool
+CStreaming::AreAnimsUsedByRequestedModels(int32 animId)
+{
+ CStreamingInfo *si;
+ int streamId;
+ int i;
+
+ for(si = ms_startRequestedList.m_next; si != &ms_endRequestedList; si = si->m_next){
+ streamId = si - ms_aInfoForModel;
+ if(streamId < STREAM_OFFSET_TXD &&
+ CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex() == animId)
+ return true;
+ }
+
+ for(i = 0; i < 4; i++){
+ streamId = ms_channel[0].streamIds[i];
+ if(streamId != -1 && streamId < STREAM_OFFSET_TXD &&
+ CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex() == animId)
+ return true;
+ streamId = ms_channel[1].streamIds[i];
+ if(streamId != -1 && streamId < STREAM_OFFSET_TXD &&
+ CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex() == animId)
+ return true;
+ }
+
+ return false;
+}
+
int32
CStreaming::GetAvailableVehicleSlot(void)
{
@@ -1153,8 +1250,8 @@ CStreaming::AddToLoadedVehiclesList(int32 modelId)
// find vehicle we can remove
for(i = 0; i < MAXVEHICLESLOADED; i++){
id = ms_vehiclesLoaded[ms_lastVehicleDeleted];
- if(id != -1 &&
- (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0 && CModelInfo::GetModelInfo(id)->GetNumRefs() == 0)
+ if(id != -1 && CanRemoveModel(id) &&
+ CModelInfo::GetModelInfo(id)->GetNumRefs() == 0)
goto found;
ms_lastVehicleDeleted++;
if(ms_lastVehicleDeleted == MAXVEHICLESLOADED)
@@ -1170,13 +1267,21 @@ found:
ms_lastVehicleDeleted = id;
// this is more that we wanted actually
ms_numVehiclesLoaded++;
- }else
+ }
+ else{
RemoveModel(id);
+ CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id);
+ if (pVehicleInfo->m_vehicleClass != -1)
+ CCarCtrl::RemoveFromLoadedVehicleArray(id, pVehicleInfo->m_vehicleClass);
+ }
}
ms_vehiclesLoaded[ms_lastVehicleDeleted++] = modelId;
if(ms_lastVehicleDeleted == MAXVEHICLESLOADED)
ms_lastVehicleDeleted = 0;
+ CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo(modelId);
+ if (pVehicleInfo->m_vehicleClass != -1)
+ CCarCtrl::AddToLoadedVehicleArray(modelId, pVehicleInfo->m_vehicleClass, pVehicleInfo->m_frequency);
return true;
}
@@ -1188,41 +1293,6 @@ CStreaming::IsObjectInCdImage(int32 id)
}
void
-CStreaming::HaveAllBigBuildingsLoaded(eLevelName level)
-{
- int i, n;
- CEntity *e;
-
- if(ms_hasLoadedLODs)
- return;
-
- if(level == LEVEL_INDUSTRIAL){
- if(ms_aInfoForModel[islandLODcomInd].m_loadState != STREAMSTATE_LOADED ||
- ms_aInfoForModel[islandLODsubInd].m_loadState != STREAMSTATE_LOADED)
- return;
- }else if(level == LEVEL_COMMERCIAL){
- if(ms_aInfoForModel[islandLODindust].m_loadState != STREAMSTATE_LOADED ||
- ms_aInfoForModel[islandLODsubCom].m_loadState != STREAMSTATE_LOADED)
- return;
- }else if(level == LEVEL_SUBURBAN){
- if(ms_aInfoForModel[islandLODindust].m_loadState != STREAMSTATE_LOADED ||
- ms_aInfoForModel[islandLODcomSub].m_loadState != STREAMSTATE_LOADED)
- return;
- }
-
- n = CPools::GetBuildingPool()->GetSize()-1;
- for(i = n; i >= 0; i--){
- e = CPools::GetBuildingPool()->GetSlot(i);
- if(e && e->bIsBIGBuilding && e->m_level == level &&
- ms_aInfoForModel[e->GetModelIndex()].m_loadState != STREAMSTATE_LOADED)
- return;
- }
-
- RemoveUnusedBigBuildings(level);
- ms_hasLoadedLODs = true;
-}
-
-void
CStreaming::SetModelIsDeletable(int32 id)
{
ms_aInfoForModel[id].m_flags &= ~STREAMFLAGS_DONT_REMOVE;
@@ -1241,6 +1311,7 @@ CStreaming::SetModelTxdIsDeletable(int32 id)
SetModelIsDeletable(CModelInfo::GetModelInfo(id)->GetTxdSlot() + STREAM_OFFSET_TXD);
}
+//--MIAMI: done
void
CStreaming::SetMissionDoesntRequireModel(int32 id)
{
@@ -1325,28 +1396,40 @@ CStreaming::StreamVehiclesAndPeds(void)
else
SetModelIsDeletable(MI_CHOPPER);
+ if (FindPlayerPed()->m_pWanted->AreMiamiViceRequired()) {
+ //TODO(MIAMI): miami vice peds
+ RequestModel(MI_VICECHEE, STREAMFLAGS_DONT_REMOVE);
+ }
+ else {
+ SetModelIsDeletable(MI_VICECHEE);
+ //TODO(MIAMI): miami vice peds
+ }
+
if(timeBeforeNextLoad >= 0)
timeBeforeNextLoad--;
else if(ms_numVehiclesLoaded <= desiredNumVehiclesLoaded){
- for(i = 1; i <= 10; i++){
- model = CCarCtrl::ChooseCarModel(modelQualityClass);
- modelQualityClass++;
- if(modelQualityClass >= CCarCtrl::TOTAL_CUSTOM_CLASSES)
- modelQualityClass = 0;
-
- // check if we want to load this model
- if(ms_aInfoForModel[model].m_loadState == STREAMSTATE_NOTLOADED &&
- ((CVehicleModelInfo*)CModelInfo::GetModelInfo(model))->m_level & (1 << (CGame::currLevel-1)))
- break;
+ CZoneInfo zone;
+ CTheZones::GetZoneInfoForTimeOfDay(&FindPlayerCoors(), &zone);
+ int32 maxReq = -1;
+ int32 mostRequestedRating = 0;
+ for(i = 0; i < CCarCtrl::TOTAL_CUSTOM_CLASSES; i++){
+ if(CCarCtrl::NumRequestsOfCarRating[i] > maxReq &&
+ ((i == 0 && zone.carThreshold[0] != 0) ||
+ (i != 0 && zone.carThreshold[i] != zone.carThreshold[i-1]))) {
+ maxReq = CCarCtrl::NumRequestsOfCarRating[i];
+ mostRequestedRating = i;
+ }
}
-
- if(i <= 10){
+ model = CCarCtrl::ChooseCarModelToLoad(mostRequestedRating);
+ if(!HasModelLoaded(model)){
RequestModel(model, STREAMFLAGS_DEPENDENCY);
- timeBeforeNextLoad = 500;
+ timeBeforeNextLoad = 350;
}
+ CCarCtrl::NumRequestsOfCarRating[mostRequestedRating] = 0;
}
}
+//--MIAMI: TODO
void
CStreaming::StreamZoneModels(const CVector &pos)
{
@@ -1372,44 +1455,36 @@ CStreaming::StreamZoneModels(const CVector &pos)
for(i = 0; i < NUMMODELSPERPEDGROUP; i++){
if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] == -1)
break;
- RequestModel(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i], STREAMFLAGS_DONT_REMOVE);
+ RequestModel(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i], STREAMFLAGS_DEPENDENCY);
}
}
RequestModel(MI_MALE01, STREAMFLAGS_DONT_REMOVE);
+ //RequestModel(MI_HMOCA, STREAMFLAGS_DONT_REMOVE);
gangsToLoad = 0;
gangCarsToLoad = 0;
- if(info.gangDensity[0] != 0) gangsToLoad |= 1<<0;
- if(info.gangDensity[1] != 0) gangsToLoad |= 1<<1;
- if(info.gangDensity[2] != 0) gangsToLoad |= 1<<2;
- if(info.gangDensity[3] != 0) gangsToLoad |= 1<<3;
- if(info.gangDensity[4] != 0) gangsToLoad |= 1<<4;
- if(info.gangDensity[5] != 0) gangsToLoad |= 1<<5;
- if(info.gangDensity[6] != 0) gangsToLoad |= 1<<6;
- if(info.gangDensity[7] != 0) gangsToLoad |= 1<<7;
- if(info.gangDensity[8] != 0) gangsToLoad |= 1<<8;
- if(info.gangThreshold[0] != info.copDensity) gangCarsToLoad |= 1<<0;
- if(info.gangThreshold[1] != info.gangThreshold[0]) gangCarsToLoad |= 1<<1;
- if(info.gangThreshold[2] != info.gangThreshold[1]) gangCarsToLoad |= 1<<2;
- if(info.gangThreshold[3] != info.gangThreshold[2]) gangCarsToLoad |= 1<<3;
- if(info.gangThreshold[4] != info.gangThreshold[3]) gangCarsToLoad |= 1<<4;
- if(info.gangThreshold[5] != info.gangThreshold[4]) gangCarsToLoad |= 1<<5;
- if(info.gangThreshold[6] != info.gangThreshold[5]) gangCarsToLoad |= 1<<6;
- if(info.gangThreshold[7] != info.gangThreshold[6]) gangCarsToLoad |= 1<<7;
- if(info.gangThreshold[8] != info.gangThreshold[7]) gangCarsToLoad |= 1<<8;
+ if(info.gangPedThreshold[0] != info.copPedThreshold)
+ gangsToLoad = 1;
+ for(i = 1; i < NUM_GANGS; i++)
+ if(info.gangPedThreshold[i] != info.gangPedThreshold[i-1])
+ gangsToLoad |= 1<<i;
+ if(info.gangThreshold[0] != info.copThreshold)
+ gangCarsToLoad = 1;
+ for(i = 1; i < NUM_GANGS; i++)
+ if(info.gangThreshold[i] != info.gangThreshold[i-1])
+ gangCarsToLoad |= 1<<i;
if(gangsToLoad == ms_loadedGangs && gangCarsToLoad == ms_loadedGangCars)
return;
- // This makes things simpler than the game does it
gangsToLoad |= gangCarsToLoad;
for(i = 0; i < NUM_GANGS; i++){
bit = 1<<i;
if(gangsToLoad & bit && (ms_loadedGangs & bit) == 0){
- RequestModel(MI_GANG01 + i*2, STREAMFLAGS_DONT_REMOVE);
- RequestModel(MI_GANG01 + i*2 + 1, STREAMFLAGS_DONT_REMOVE);
+ RequestModel(MI_GANG01 + i*2, STREAMFLAGS_DEPENDENCY);
+ RequestModel(MI_GANG01 + i*2 + 1, STREAMFLAGS_DEPENDENCY);
ms_loadedGangs |= bit;
}else if((gangsToLoad & bit) == 0 && ms_loadedGangs & bit){
SetModelIsDeletable(MI_GANG01 + i*2);
@@ -1419,8 +1494,12 @@ CStreaming::StreamZoneModels(const CVector &pos)
ms_loadedGangs &= ~bit;
}
- if(gangCarsToLoad & bit && (ms_loadedGangCars & bit) == 0){
- RequestModel(CGangs::GetGangInfo(i)->m_nVehicleMI, STREAMFLAGS_DONT_REMOVE);
+ // TODO(MIAMI): check this
+ if(CGangs::GetGangInfo(i)->m_nVehicleMI < 0)
+ continue;
+
+ if((gangCarsToLoad & bit) && (ms_loadedGangCars & bit) == 0){
+ RequestModel(CGangs::GetGangInfo(i)->m_nVehicleMI, STREAMFLAGS_DEPENDENCY);
}else if((gangCarsToLoad & bit) == 0 && ms_loadedGangCars & bit){
SetModelIsDeletable(CGangs::GetGangInfo(i)->m_nVehicleMI);
SetModelTxdIsDeletable(CGangs::GetGangInfo(i)->m_nVehicleMI);
@@ -1435,7 +1514,7 @@ CStreaming::RemoveCurrentZonesModels(void)
int i;
if(ms_currentPedGrp != -1)
- for(i = 0; i < 8; i++){
+ for(i = 0; i < NUMMODELSPERPEDGROUP; i++){
if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] == -1)
break;
if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != MI_MALE01)
@@ -1454,6 +1533,42 @@ CStreaming::RemoveCurrentZonesModels(void)
ms_loadedGangCars = 0;
}
+void
+CStreaming::LoadBigBuildingsWhenNeeded(void)
+{
+ // Very much like CCollision::Update and CCollision::LoadCollisionWhenINeedIt
+ if(CCutsceneMgr::IsCutsceneProcessing())
+ return;
+
+ if(CTheZones::m_CurrLevel == LEVEL_NONE ||
+ CTheZones::m_CurrLevel == CGame::currLevel)
+ return;
+
+ CTimer::Suspend();
+ CGame::currLevel = CTheZones::m_CurrLevel;
+ DMAudio.SetEffectsFadeVol(0);
+ CPad::StopPadsShaking();
+ CCollision::LoadCollisionScreen(CGame::currLevel);
+ DMAudio.Service();
+
+ // CPopulation::DealWithZoneChange is unused in VC
+ RemoveUnusedBigBuildings(CGame::currLevel);
+ RemoveUnusedBuildings(CGame::currLevel);
+ RemoveUnusedModelsInLoadedList();
+ CGame::TidyUpMemory(true, true);
+
+ CReplay::EmptyReplayBuffer();
+ if(CGame::currLevel != LEVEL_NONE)
+ LoadSplash(GetLevelSplashScreen(CGame::currLevel));
+
+ CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition());
+ CStreaming::LoadAllRequestedModels(true);
+
+ CGame::TidyUpMemory(true, true);
+ CTimer::Resume();
+ DMAudio.SetEffectsFadeVol(127);
+}
+
// Find starting offset of the cdimage we next want to read
// Not useful at all on PC...
@@ -1500,6 +1615,7 @@ ModelNotLoaded(int32 modelId)
}
inline bool TxdNotLoaded(int32 txdId) { return ModelNotLoaded(txdId + STREAM_OFFSET_TXD); }
+inline bool AnimNotLoaded(int32 animId) { return animId != -1 && ModelNotLoaded(animId + STREAM_OFFSET_ANIM); }
// Find stream id of next requested file in cdimage
int32
@@ -1524,14 +1640,20 @@ CStreaming::GetNextFileOnCd(int32 lastPosn, bool priority)
if(priority && ms_numPriorityRequests != 0 && !si->IsPriority())
continue;
- // request Txd if necessary
+ // request Txds or anims if necessary
if(streamId < STREAM_OFFSET_TXD){
int txdId = CModelInfo::GetModelInfo(streamId)->GetTxdSlot();
if(TxdNotLoaded(txdId)){
ReRequestTxd(txdId);
continue;
}
- }
+ int animId = CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex();
+ if(AnimNotLoaded(animId)){
+ ReRequestAnim(animId);
+ continue;
+ }
+ }else if(streamId >= STREAM_OFFSET_ANIM && CCutsceneMgr::IsCutsceneProcessing())
+ continue;
if(ms_aInfoForModel[streamId].GetCdPosnAndSize(posn, size)){
if(posn < posnFirst){
@@ -1574,6 +1696,7 @@ CStreaming::GetNextFileOnCd(int32 lastPosn, bool priority)
* TODO: two-part files
*/
+//--MIAMI: done
// Make channel read from disc
void
CStreaming::RequestModelStream(int32 ch)
@@ -1588,13 +1711,18 @@ CStreaming::RequestModelStream(int32 ch)
imgOffset = GetCdImageOffset(lastPosn);
streamId = GetNextFileOnCd(lastPosn - imgOffset, true);
- if(streamId == -1)
- return;
-
- // remove Txds that aren't requested anymore
- while(streamId >= STREAM_OFFSET_TXD){
- if(ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY ||
- IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD))
+ // remove Txds and Anims that aren't requested anymore
+ while(streamId != -1){
+ if(ms_aInfoForModel[streamId].m_flags & STREAMFLAGS_KEEP_IN_MEMORY)
+ break;
+ if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){
+ if(IsTxdUsedByRequestedModels(streamId - STREAM_OFFSET_TXD))
+ break;
+ }else if(streamId >= STREAM_OFFSET_ANIM){
+ assert(streamId < NUMSTREAMINFO);
+ if(AreAnimsUsedByRequestedModels(streamId - STREAM_OFFSET_ANIM))
+ break;
+ }else
break;
RemoveModel(streamId);
// so try next file
@@ -1631,7 +1759,8 @@ CStreaming::RequestModelStream(int32 ch)
if(streamId < STREAM_OFFSET_TXD){
if (havePed && CModelInfo::GetModelInfo(streamId)->GetModelType() == MITYPE_PED ||
haveBigFile && CModelInfo::GetModelInfo(streamId)->GetModelType() == MITYPE_VEHICLE ||
- TxdNotLoaded(CModelInfo::GetModelInfo(streamId)->GetTxdSlot()))
+ TxdNotLoaded(CModelInfo::GetModelInfo(streamId)->GetTxdSlot()) ||
+ AnimNotLoaded(CModelInfo::GetModelInfo(streamId)->GetAnimFileIndex()))
break;
}else{
if(haveBigFile && size > 200)
@@ -1678,6 +1807,7 @@ CStreaming::RequestModelStream(int32 ch)
ms_channel[ch].numTries = 0;
}
+//--MIAMI: done
// Load data previously read from disc
bool
CStreaming::ProcessLoadingChannel(int32 ch)
@@ -1712,10 +1842,10 @@ CStreaming::ProcessLoadingChannel(int32 ch)
if(id < STREAM_OFFSET_TXD && CModelInfo::GetModelInfo(id)->GetModelType() == MITYPE_VEHICLE &&
ms_numVehiclesLoaded >= desiredNumVehiclesLoaded &&
!RemoveLoadedVehicle() &&
- ((ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0 || GetAvailableVehicleSlot() == -1)){
+ (CanRemoveModel(id) || GetAvailableVehicleSlot() == -1)){
// can't load vehicle
RemoveModel(id);
- if(ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE)
+ if(!CanRemoveModel(id))
ReRequestModel(id);
else if(CTxdStore::GetNumRefs(CModelInfo::GetModelInfo(id)->GetTxdSlot()) == 0)
RemoveTxd(CModelInfo::GetModelInfo(id)->GetTxdSlot());
@@ -1747,6 +1877,7 @@ CStreaming::ProcessLoadingChannel(int32 ch)
return true;
}
+//--MIAMI: done
void
CStreaming::RetryLoadFile(int32 ch)
{
@@ -1783,6 +1914,7 @@ CStreaming::RetryLoadFile(int32 ch)
}
}
+//--MIAMI: done
void
CStreaming::LoadRequestedModels(void)
{
@@ -1807,6 +1939,7 @@ CStreaming::LoadRequestedModels(void)
}
}
+//--MIAMI: done
void
CStreaming::LoadAllRequestedModels(bool priority)
{
@@ -1860,6 +1993,7 @@ CStreaming::LoadAllRequestedModels(bool priority)
bInsideLoadAll = false;
}
+//--MIAMI: done
void
CStreaming::FlushChannels(void)
{
@@ -1881,6 +2015,7 @@ CStreaming::FlushChannels(void)
ProcessLoadingChannel(1);
}
+//--MIAMI: done
void
CStreaming::FlushRequestList(void)
{
@@ -1989,8 +2124,7 @@ CStreaming::ProcessEntitiesInSectorList(CPtrList &list, float x, float y, float
if(xmin < pos.x && pos.x < xmax &&
ymin < pos.y && pos.y < ymax &&
(CVector2D(x, y) - pos).MagnitudeSqr() < lodDistSq)
- if(CRenderer::IsEntityCullZoneVisible(e))
- RequestModel(e->GetModelIndex(), 0);
+ RequestModel(e->GetModelIndex(), 0);
}
}
}
@@ -2013,8 +2147,7 @@ CStreaming::ProcessEntitiesInSectorList(CPtrList &list)
(!e->IsObject() || ((CObject*)e)->ObjectCreatedBy != TEMP_OBJECT)){
CTimeModelInfo *mi = (CTimeModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex());
if (mi->GetModelType() != MITYPE_TIME || CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff()))
- if(CRenderer::IsEntityCullZoneVisible(e))
- RequestModel(e->GetModelIndex(), 0);
+ RequestModel(e->GetModelIndex(), 0);
}
}
}
@@ -2252,9 +2385,6 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem)
}
}
- if(RemoveReferencedTxds(mem))
- return;
-
// As last resort, delete objects from the last step more aggressively
for(y = ymin; y <= ymax; y++){
for(x = xmax; x != xmin; x -= inc){
@@ -2316,9 +2446,6 @@ CStreaming::DeleteRwObjectsBehindCamera(int32 mem)
}
}
- if(RemoveReferencedTxds(mem))
- return;
-
// As last resort, delete objects from the last step more aggressively
for(x = xmin; x <= xmax; x++){
for(y = ymax; y != ymin; y -= inc){
@@ -2417,12 +2544,13 @@ CStreaming::MakeSpaceFor(int32 size)
// but it's not nice....
while((uint32)ms_memoryUsed >= ms_memoryAvailable - size)
- if(!RemoveLeastUsedModel()){
+ if(!RemoveLeastUsedModel(STREAMFLAGS_20)){
DeleteRwObjectsBehindCamera(ms_memoryAvailable - size);
return;
}
}
+//--MIAMI: done
void
CStreaming::LoadScene(const CVector &pos)
{
@@ -2437,16 +2565,44 @@ CStreaming::LoadScene(const CVector &pos)
RemoveModel(si - ms_aInfoForModel);
}
CRenderer::m_loadingPriority = false;
- CCullZones::ForceCullZoneCoors(pos);
DeleteAllRwObjects();
+ if(level == LEVEL_NONE)
+ level = CGame::currLevel;
+ CGame::currLevel = level;
+ RemoveUnusedBigBuildings(level);
+ RequestBigBuildings(level, pos);
+ RequestBigBuildings(LEVEL_NONE, pos);
+ RemoveIslandsNotUsed(level);
+ LoadAllRequestedModels(false);
+ InstanceBigBuildings(level, pos);
+ InstanceBigBuildings(LEVEL_NONE, pos);
AddModelsToRequestList(pos);
CRadar::StreamRadarSections(pos);
- RemoveUnusedBigBuildings(level);
- RequestBigBuildings(level);
+
+ if (!CGame::IsInInterior()) {
+ for (int i = 0; i < 5; i++) {
+ CZoneInfo zone;
+ CTheZones::GetZoneInfoForTimeOfDay(&pos, &zone);
+ int32 model = CCarCtrl::ChooseCarModelToLoad(CCarCtrl::ChooseCarRating(&zone));
+ CStreaming::RequestModel(model, STREAMFLAGS_DEPENDENCY);
+ }
+ }
LoadAllRequestedModels(false);
+ InstanceLoadedModels(pos);
+
+ for(int i = 0; i < NUMSTREAMINFO; i++)
+ ms_aInfoForModel[i].m_flags &= ~STREAMFLAGS_20;
debug("End load scene\n");
}
+//--MIAMI: done
+void
+CStreaming::LoadSceneCollision(const CVector &pos)
+{
+ CColStore::LoadCollision(pos);
+ CStreaming::LoadAllRequestedModels(false);
+}
+
void
CStreaming::MemoryCardSave(uint8 *buf, uint32 *size)
{
diff --git a/src/core/Streaming.h b/src/core/Streaming.h
index 84434769..22316ee1 100644
--- a/src/core/Streaming.h
+++ b/src/core/Streaming.h
@@ -4,7 +4,9 @@
enum {
STREAM_OFFSET_TXD = MODELINFOSIZE,
- NUMSTREAMINFO = STREAM_OFFSET_TXD+TXDSTORESIZE
+ STREAM_OFFSET_COL = STREAM_OFFSET_TXD+TXDSTORESIZE,
+ STREAM_OFFSET_ANIM = STREAM_OFFSET_COL+COLSTORESIZE,
+ NUMSTREAMINFO = STREAM_OFFSET_ANIM+NUMANIMBLOCKS
};
enum StreamFlags
@@ -14,6 +16,7 @@ enum StreamFlags
STREAMFLAGS_DEPENDENCY = 0x04, // Is this right?
STREAMFLAGS_PRIORITY = 0x08,
STREAMFLAGS_NOFADE = 0x10,
+ STREAMFLAGS_20 = 0x20, // TODO(MIAMI): what's this
STREAMFLAGS_CANT_REMOVE = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED,
STREAMFLAGS_KEEP_IN_MEMORY = STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_SCRIPTOWNED|STREAMFLAGS_DEPENDENCY,
@@ -92,9 +95,9 @@ public:
static int32 ms_numVehiclesLoaded;
static int32 ms_vehiclesLoaded[MAXVEHICLESLOADED];
static int32 ms_lastVehicleDeleted;
+ static bool ms_bIsPedFromPedGroupLoaded[NUMMODELSPERPEDGROUP];
static CDirectory *ms_pExtraObjectsDir;
static int32 ms_numPriorityRequests;
- static bool ms_hasLoadedLODs;
static int32 ms_currentPedGrp;
static int32 ms_lastCullZone;
static uint16 ms_loadedGangs;
@@ -115,14 +118,25 @@ public:
static bool FinishLoadingLargeFile(int8 *buf, int32 streamId);
static bool HasModelLoaded(int32 id) { return ms_aInfoForModel[id].m_loadState == STREAMSTATE_LOADED; }
static bool HasTxdLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_TXD); }
+ static bool HasColLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_COL); }
+ static bool HasAnimLoaded(int32 id) { return HasModelLoaded(id+STREAM_OFFSET_ANIM); }
static bool CanRemoveModel(int32 id) { return (ms_aInfoForModel[id].m_flags & STREAMFLAGS_CANT_REMOVE) == 0; }
static bool CanRemoveTxd(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_TXD); }
+ static bool CanRemoveCol(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_COL); }
+ static bool CanRemoveAnim(int32 id) { return CanRemoveModel(id+STREAM_OFFSET_ANIM); }
static void RequestModel(int32 model, int32 flags);
static void ReRequestModel(int32 model) { RequestModel(model, ms_aInfoForModel[model].m_flags); }
static void RequestTxd(int32 txd, int32 flags) { RequestModel(txd + STREAM_OFFSET_TXD, flags); }
static void ReRequestTxd(int32 txd) { ReRequestModel(txd + STREAM_OFFSET_TXD); }
- static void RequestSubway(void);
+ static void RequestCol(int32 col, int32 flags) { RequestModel(col + STREAM_OFFSET_COL, flags); }
+ static void ReRequestCol(int32 col) { ReRequestModel(col + STREAM_OFFSET_COL); }
+ static void RequestAnim(int32 col, int32 flags) { RequestModel(col + STREAM_OFFSET_ANIM, flags); }
+ static void ReRequestAnim(int32 col) { ReRequestModel(col + STREAM_OFFSET_ANIM); }
static void RequestBigBuildings(eLevelName level);
+ static void RequestBigBuildings(eLevelName level, const CVector &pos);
+ static void InstanceBigBuildings(eLevelName level, const CVector &pos);
+ static void InstanceLoadedModelsInSectorList(CPtrList &list);
+ static void InstanceLoadedModels(const CVector &pos);
static void RequestIslands(eLevelName level);
static void RequestSpecialModel(int32 modelId, const char *modelName, int32 flags);
static void RequestSpecialChar(int32 charId, const char *modelName, int32 flags);
@@ -131,21 +145,22 @@ public:
static void DecrementRef(int32 id);
static void RemoveModel(int32 id);
static void RemoveTxd(int32 id) { RemoveModel(id + STREAM_OFFSET_TXD); }
+ static void RemoveCol(int32 id) { RemoveModel(id + STREAM_OFFSET_COL); }
+ static void RemoveAnim(int32 id) { RemoveModel(id + STREAM_OFFSET_ANIM); }
static void RemoveUnusedBuildings(eLevelName level);
static void RemoveBuildings(eLevelName level);
static void RemoveUnusedBigBuildings(eLevelName level);
static void RemoveIslandsNotUsed(eLevelName level);
static void RemoveBigBuildings(eLevelName level);
static bool RemoveLoadedVehicle(void);
- static bool RemoveLeastUsedModel(void);
+ static bool RemoveLeastUsedModel(uint32 excludeMask);
static void RemoveAllUnusedModels(void);
static void RemoveUnusedModelsInLoadedList(void);
- static bool RemoveReferencedTxds(int32 mem);
static int32 GetAvailableVehicleSlot(void);
static bool IsTxdUsedByRequestedModels(int32 txdId);
+ static bool AreAnimsUsedByRequestedModels(int32 animId);
static bool AddToLoadedVehiclesList(int32 modelId);
static bool IsObjectInCdImage(int32 id);
- static void HaveAllBigBuildingsLoaded(eLevelName level);
static void SetModelIsDeletable(int32 id);
static void SetModelTxdIsDeletable(int32 id);
static void SetMissionDoesntRequireModel(int32 id);
@@ -154,6 +169,7 @@ public:
static void StreamVehiclesAndPeds(void);
static void StreamZoneModels(const CVector &pos);
static void RemoveCurrentZonesModels(void);
+ static void LoadBigBuildingsWhenNeeded(void);
static int32 GetCdImageOffset(int32 lastPosn);
static int32 GetNextFileOnCd(int32 position, bool priority);
@@ -183,6 +199,7 @@ public:
static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, int32 mem);
static void LoadScene(const CVector &pos);
+ static void LoadSceneCollision(const CVector &pos);
static void MemoryCardSave(uint8 *buffer, uint32 *length);
static void MemoryCardLoad(uint8 *buffer, uint32 length);
diff --git a/src/core/TempColModels.cpp b/src/core/TempColModels.cpp
index 79d6252b..70ded11b 100644
--- a/src/core/TempColModels.cpp
+++ b/src/core/TempColModels.cpp
@@ -41,13 +41,13 @@ CTempColModels::Initialise(void)
int i;
- ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
- ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0);
+ ms_colModelBBox.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
+ ms_colModelBBox.boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f));
ms_colModelBBox.level = LEVEL_NONE;
for (i = 0; i < ARRAY_SIZE(ms_colModelCutObj); i++) {
- ms_colModelCutObj[i].boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
- ms_colModelCutObj[i].boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f), SURFACE_DEFAULT, 0);
+ ms_colModelCutObj[i].boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
+ ms_colModelCutObj[i].boundingBox.Set(CVector(-2.0f, -2.0f, -2.0f), CVector(2.0f, 2.0f, 2.0f));
ms_colModelCutObj[i].level = LEVEL_NONE;
}
@@ -69,8 +69,8 @@ CTempColModels::Initialise(void)
s_aPedSpheres[i].piece = 0;
}
- ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
- ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f), SURFACE_DEFAULT, 0);
+ ms_colModelPed1.boundingSphere.Set(1.25f, CVector(0.0f, 0.0f, 0.0f));
+ ms_colModelPed1.boundingBox.Set(CVector(-0.35f, -0.35f, -1.0f), CVector(0.35f, 0.35f, 0.9f));
SET_COLMODEL_SPHERES(ms_colModelPed1, s_aPedSpheres);
// Ped 2 Spheres
@@ -88,8 +88,8 @@ CTempColModels::Initialise(void)
s_aPed2Spheres[i].piece = 0;
}
- ms_colModelPed2.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
- ms_colModelPed2.boundingBox.Set(CVector(-0.7f, -0.7f, -1.2f), CVector(0.7f, 0.7f, 0.0f), SURFACE_DEFAULT, 0);
+ ms_colModelPed2.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
+ ms_colModelPed2.boundingBox.Set(CVector(-0.7f, -0.7f, -1.2f), CVector(0.7f, 0.7f, 0.0f));
SET_COLMODEL_SPHERES(ms_colModelPed2, s_aPed2Spheres);
@@ -114,8 +114,8 @@ CTempColModels::Initialise(void)
s_aPedGSpheres[2].piece = 0;
s_aPedGSpheres[3].piece = 6;
- ms_colModelPedGroundHit.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
- ms_colModelPedGroundHit.boundingBox.Set(CVector(-0.4f, -1.0f, -1.25f), CVector(0.4f, 1.2f, -0.5f), SURFACE_DEFAULT, 0);
+ ms_colModelPedGroundHit.boundingSphere.Set(2.0f, CVector(0.0f, 0.0f, 0.0f));
+ ms_colModelPedGroundHit.boundingBox.Set(CVector(-0.4f, -1.0f, -1.25f), CVector(0.4f, 1.2f, -0.5f));
SET_COLMODEL_SPHERES(ms_colModelPedGroundHit, s_aPedGSpheres);
@@ -134,8 +134,8 @@ CTempColModels::Initialise(void)
s_aDoorSpheres[i].piece = 0;
}
- ms_colModelDoor1.boundingSphere.Set(1.5f, CVector(0.0f, -0.6f, 0.0f), SURFACE_DEFAULT, 0);
- ms_colModelDoor1.boundingBox.Set(CVector(-0.3f, 0.0f, -0.6f), CVector(0.3f, -1.2f, 0.6f), SURFACE_DEFAULT, 0);
+ ms_colModelDoor1.boundingSphere.Set(1.5f, CVector(0.0f, -0.6f, 0.0f));
+ ms_colModelDoor1.boundingBox.Set(CVector(-0.3f, 0.0f, -0.6f), CVector(0.3f, -1.2f, 0.6f));
SET_COLMODEL_SPHERES(ms_colModelDoor1, s_aDoorSpheres);
@@ -154,8 +154,8 @@ CTempColModels::Initialise(void)
s_aBumperSpheres[i].piece = 0;
}
- ms_colModelBumper1.boundingSphere.Set(2.2f, CVector(0.0f, -0.6f, 0.0f), SURFACE_DEFAULT, 0);
- ms_colModelBumper1.boundingBox.Set(CVector(-1.2f, -0.3f, -0.2f), CVector(1.2f, 0.3f, -0.2f), SURFACE_DEFAULT, 0);
+ ms_colModelBumper1.boundingSphere.Set(2.2f, CVector(0.0f, -0.6f, 0.0f));
+ ms_colModelBumper1.boundingBox.Set(CVector(-1.2f, -0.3f, -0.2f), CVector(1.2f, 0.3f, -0.2f));
SET_COLMODEL_SPHERES(ms_colModelBumper1, s_aBumperSpheres);
@@ -174,8 +174,8 @@ CTempColModels::Initialise(void)
s_aPanelSpheres[i].piece = 0;
}
- ms_colModelPanel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
- ms_colModelPanel1.boundingBox.Set(CVector(-0.3f, -0.6f, -0.15f), CVector(0.3f, 0.6f, 0.15f), SURFACE_DEFAULT, 0);
+ ms_colModelPanel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f));
+ ms_colModelPanel1.boundingBox.Set(CVector(-0.3f, -0.6f, -0.15f), CVector(0.3f, 0.6f, 0.15f));
SET_COLMODEL_SPHERES(ms_colModelPanel1, s_aPanelSpheres);
@@ -194,8 +194,8 @@ CTempColModels::Initialise(void)
s_aBonnetSpheres[i].piece = 0;
}
- ms_colModelBonnet1.boundingSphere.Set(1.7f, CVector(0.0f, 0.5f, 0.0f), SURFACE_DEFAULT, 0);
- ms_colModelBonnet1.boundingBox.Set(CVector(-0.7f, -0.2f, -0.3f), CVector(0.7f, 1.2f, 0.3f), SURFACE_DEFAULT, 0);
+ ms_colModelBonnet1.boundingSphere.Set(1.7f, CVector(0.0f, 0.5f, 0.0f));
+ ms_colModelBonnet1.boundingBox.Set(CVector(-0.7f, -0.2f, -0.3f), CVector(0.7f, 1.2f, 0.3f));
SET_COLMODEL_SPHERES(ms_colModelBonnet1, s_aBonnetSpheres);
@@ -214,8 +214,8 @@ CTempColModels::Initialise(void)
s_aBootSpheres[i].piece = 0;
}
- ms_colModelBoot1.boundingSphere.Set(1.4f, CVector(0.0f, -0.4f, 0.0f), SURFACE_DEFAULT, 0);
- ms_colModelBoot1.boundingBox.Set(CVector(-0.7f, -0.9f, -0.3f), CVector(0.7f, 0.2f, 0.3f), SURFACE_DEFAULT, 0);
+ ms_colModelBoot1.boundingSphere.Set(1.4f, CVector(0.0f, -0.4f, 0.0f));
+ ms_colModelBoot1.boundingBox.Set(CVector(-0.7f, -0.9f, -0.3f), CVector(0.7f, 0.2f, 0.3f));
SET_COLMODEL_SPHERES(ms_colModelBoot1, s_aBootSpheres);
@@ -236,8 +236,8 @@ CTempColModels::Initialise(void)
s_aWheelSpheres[i].piece = 0;
}
- ms_colModelWheel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
- ms_colModelWheel1.boundingBox.Set(CVector(-0.7f, -0.4f, -0.4f), CVector(0.7f, 0.4f, 0.4f), SURFACE_DEFAULT, 0);
+ ms_colModelWheel1.boundingSphere.Set(1.4f, CVector(0.0f, 0.0f, 0.0f));
+ ms_colModelWheel1.boundingBox.Set(CVector(-0.7f, -0.4f, -0.4f), CVector(0.7f, 0.4f, 0.4f));
SET_COLMODEL_SPHERES(ms_colModelWheel1, s_aWheelSpheres);
@@ -258,8 +258,8 @@ CTempColModels::Initialise(void)
s_aBodyPartSpheres1[i].piece = 0;
}
- ms_colModelBodyPart1.boundingSphere.Set(0.7f, CVector(0.4f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
- ms_colModelBodyPart1.boundingBox.Set(CVector(-0.3f, -0.3f, -0.3f), CVector(1.1f, 0.3f, 0.3f), SURFACE_DEFAULT, 0);
+ ms_colModelBodyPart1.boundingSphere.Set(0.7f, CVector(0.4f, 0.0f, 0.0f));
+ ms_colModelBodyPart1.boundingBox.Set(CVector(-0.3f, -0.3f, -0.3f), CVector(1.1f, 0.3f, 0.3f));
SET_COLMODEL_SPHERES(ms_colModelBodyPart1, s_aBodyPartSpheres1);
@@ -280,8 +280,8 @@ CTempColModels::Initialise(void)
s_aBodyPartSpheres2[i].piece = 0;
}
- ms_colModelBodyPart2.boundingSphere.Set(0.5f, CVector(0.25f, 0.0f, 0.0f), SURFACE_DEFAULT, 0);
- ms_colModelBodyPart2.boundingBox.Set(CVector(-0.2f, -0.2f, -0.2f), CVector(0.7f, 0.2f, 0.2f), SURFACE_DEFAULT, 0);
+ ms_colModelBodyPart2.boundingSphere.Set(0.5f, CVector(0.25f, 0.0f, 0.0f));
+ ms_colModelBodyPart2.boundingBox.Set(CVector(-0.2f, -0.2f, -0.2f), CVector(0.7f, 0.2f, 0.2f));
SET_COLMODEL_SPHERES(ms_colModelBodyPart2, s_aBodyPartSpheres2);
diff --git a/src/core/User.cpp b/src/core/User.cpp
index f906ae44..716d6393 100644
--- a/src/core/User.cpp
+++ b/src/core/User.cpp
@@ -32,8 +32,8 @@ void
CPlaceName::Process()
{
CVector pos = CWorld::Players[CWorld::PlayerInFocus].GetPos();
- CZone *navigZone = CTheZones::FindSmallestZonePositionType(&pos, ZONE_NAVIG);
- CZone *defaultZone = CTheZones::FindSmallestZonePositionType(&pos, ZONE_DEFAULT);
+ CZone *navigZone = CTheZones::FindSmallestNavigationZoneForPosition(&pos, false, true);
+ CZone *defaultZone = CTheZones::FindSmallestNavigationZoneForPosition(&pos, true, false);
if (navigZone == nil) m_pZone = nil;
if (defaultZone == nil) m_pZone2 = nil;
diff --git a/src/core/Wanted.cpp b/src/core/Wanted.cpp
index 7508c9f4..ff82edad 100644
--- a/src/core/Wanted.cpp
+++ b/src/core/Wanted.cpp
@@ -40,6 +40,12 @@ CWanted::Initialise()
}
bool
+CWanted::AreMiamiViceRequired()
+{
+ return m_nWantedLevel >= 3;
+}
+
+bool
CWanted::AreSwatRequired()
{
return m_nWantedLevel == 4 || m_bSwatRequired;
diff --git a/src/core/Wanted.h b/src/core/Wanted.h
index e3e407b0..0e0e70c3 100644
--- a/src/core/Wanted.h
+++ b/src/core/Wanted.h
@@ -31,6 +31,7 @@ public:
public:
void Initialise();
+ bool AreMiamiViceRequired();
bool AreSwatRequired();
bool AreFbiRequired();
bool AreArmyRequired();
diff --git a/src/core/World.cpp b/src/core/World.cpp
index c884f1ed..29505481 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -920,6 +920,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
bool ignoreSomeObjects)
{
static CColModel sphereCol;
+ CColSphere sphere;
sphereCol.boundingSphere.center.x = 0.0f;
sphereCol.boundingSphere.center.y = 0.0f;
@@ -932,7 +933,8 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
sphereCol.boundingBox.max.y = radius;
sphereCol.boundingBox.max.z = radius;
sphereCol.numSpheres = 1;
- sphereCol.spheres = &sphereCol.boundingSphere;
+ sphere.Set(radius, CVector(0.0f, 0.0f, 0.0f));
+ sphereCol.spheres = &sphere;
sphereCol.numLines = 0;
sphereCol.numBoxes = 0;
sphereCol.numTriangles = 0;
@@ -1201,7 +1203,7 @@ CWorld::FindObjectsIntersectingCubeSectorList(CPtrList &list, const CVector &vec
}
void
-CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox &boundingBox, const CMatrix &matrix,
+CWorld::FindObjectsIntersectingAngledCollisionBox(const CBox &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,
@@ -1261,7 +1263,7 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox &boundingBox, co
}
void
-CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList &list, const CColBox &boundingBox,
+CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList &list, const CBox &boundingBox,
const CMatrix &matrix, const CVector &position,
int16 *nEntitiesFound, int16 maxEntitiesToFind,
CEntity **aEntities)
diff --git a/src/core/World.h b/src/core/World.h
index ab3f0192..19d480ff 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -4,19 +4,19 @@
#include "Lists.h"
#include "PlayerInfo.h"
-/* Sectors span from -2000 to 2000 in x and y.
- * With 100x100 sectors, each is 40x40 units. */
+/* Sectors span from -2400 to 1600 in x and -2000 to 2000 y.
+ * With 80x80 sectors, each is 50x50 units. */
-#define SECTOR_SIZE_X (40.0f)
-#define SECTOR_SIZE_Y (40.0f)
+#define SECTOR_SIZE_X (50.0f)
+#define SECTOR_SIZE_Y (50.0f)
-#define NUMSECTORS_X (100)
-#define NUMSECTORS_Y (100)
+#define NUMSECTORS_X (80)
+#define NUMSECTORS_Y (80)
#define WORLD_SIZE_X (NUMSECTORS_X * SECTOR_SIZE_X)
#define WORLD_SIZE_Y (NUMSECTORS_Y * SECTOR_SIZE_Y)
-#define WORLD_MIN_X (-2000.0f)
+#define WORLD_MIN_X (-2400.0f)
#define WORLD_MIN_Y (-2000.0f)
#define WORLD_MAX_X (WORLD_MIN_X + WORLD_SIZE_X)
@@ -113,8 +113,8 @@ public:
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 FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList& list, const CColBox& boundingBox, const CMatrix& matrix, const CVector& position, int16* nEntitiesFound, int16 maxEntitiesToFind, CEntity** aEntities);
+ static void FindObjectsIntersectingAngledCollisionBox(const CBox &, const CMatrix &, const CVector &, float, float, float, float, int16*, int16, CEntity **, bool, bool, bool, bool, bool);
+ static void FindObjectsIntersectingAngledCollisionBoxSectorList(CPtrList& list, const CBox& 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);
diff --git a/src/core/ZoneCull.cpp b/src/core/ZoneCull.cpp
index 6dcd0f18..729cc35d 100644
--- a/src/core/ZoneCull.cpp
+++ b/src/core/ZoneCull.cpp
@@ -11,207 +11,22 @@
#include "ZoneCull.h"
#include "Zones.h"
-int32 CCullZones::NumCullZones;
-CCullZone CCullZones::aZones[NUMCULLZONES];
int32 CCullZones::NumAttributeZones;
CAttributeZone CCullZones::aAttributeZones[NUMATTRIBZONES];
-uint16 CCullZones::aIndices[NUMZONEINDICES];
-int16 CCullZones::aPointersToBigBuildingsForBuildings[NUMBUILDINGS];
-int16 CCullZones::aPointersToBigBuildingsForTreadables[NUMTREADABLES];
int32 CCullZones::CurrentWantedLevelDrop_Player;
int32 CCullZones::CurrentFlags_Camera;
int32 CCullZones::CurrentFlags_Player;
-int32 CCullZones::OldCullZone;
-int32 CCullZones::EntityIndicesUsed;
bool CCullZones::bCurrentSubwayIsInvisible;
-bool CCullZones::bCullZonesDisabled;
-
void
CCullZones::Init(void)
{
- int i;
-
NumAttributeZones = 0;
CurrentWantedLevelDrop_Player = 0;
CurrentFlags_Camera = 0;
CurrentFlags_Player = 0;
bCurrentSubwayIsInvisible = false;
- NumCullZones = 0;
- OldCullZone = -1;
- EntityIndicesUsed = 0;
-
- for(i = 0; i < NUMBUILDINGS; i++)
- aPointersToBigBuildingsForBuildings[i] = -1;
- for(i = 0; i < NUMTREADABLES; i++)
- aPointersToBigBuildingsForTreadables[i] = -1;
-}
-
-bool CCullZone::TestLine(CVector vec1, CVector vec2)
-{
- CColPoint colPoint;
- CEntity *entity;
-
- if (CWorld::ProcessLineOfSight(vec1, vec2, colPoint, entity, true, false, false, false, false, true, false))
- return true;
- if (CWorld::ProcessLineOfSight(CVector(vec1.x + 0.05f, vec1.y, vec1.z), CVector(vec2.x + 0.05f, vec2.y, vec2.z), colPoint, entity, true, false, false, false, false, true, false))
- return true;
- if (CWorld::ProcessLineOfSight(CVector(vec1.x - 0.05f, vec1.y, vec1.z), CVector(vec2.x - 0.05f, vec2.y, vec2.z), colPoint, entity, true, false, false, false, false, true, false))
- return true;
- if (CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y + 0.05f, vec1.z), CVector(vec2.x, vec2.y + 0.05f, vec2.z), colPoint, entity, true, false, false, false, false, true, false))
- return true;
- if (CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y - 0.05f, vec1.z), CVector(vec2.x, vec2.y - 0.05f, vec2.z), colPoint, entity, true, false, false, false, false, true, false))
- return true;
- if (CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y, vec1.z + 0.05f), CVector(vec2.x, vec2.y, vec2.z + 0.05f), colPoint, entity, true, false, false, false, false, true, false))
- return true;
- return CWorld::ProcessLineOfSight(CVector(vec1.x, vec1.y, vec1.z - 0.05f), CVector(vec2.x, vec2.y, vec2.z - 0.05f), colPoint, entity, true, false, false, false, false, true, false);
-}
-
-
-uint16* pTempArrayIndices;
-int TempEntityIndicesUsed;
-
-void
-CCullZones::ResolveVisibilities(void)
-{
- int fd;
-
- CFileMgr::SetDir("");
- fd = CFileMgr::OpenFile("DATA\\cullzone.dat", "rb");
- if(fd > 0){
- CFileMgr::Read(fd, (char*)&NumCullZones, sizeof(NumCullZones));
- CFileMgr::Read(fd, (char*)aZones, sizeof(aZones));
- CFileMgr::Read(fd, (char*)&NumAttributeZones, sizeof(NumAttributeZones));
- CFileMgr::Read(fd, (char*)aAttributeZones, sizeof(aAttributeZones));
- CFileMgr::Read(fd, (char*)aIndices, sizeof(aIndices));
- CFileMgr::Read(fd, (char*)aPointersToBigBuildingsForBuildings, sizeof(aPointersToBigBuildingsForBuildings));
- CFileMgr::Read(fd, (char*)aPointersToBigBuildingsForTreadables, sizeof(aPointersToBigBuildingsForTreadables));
- CFileMgr::CloseFile(fd);
- }else{
-#if 0
- // TODO: implement code from mobile to generate data here
- EntityIndicesUsed = 0;
- BuildListForBigBuildings();
- pTempArrayIndices = new uint16[140000];
- TempEntityIndicesUsed = 0;
-
- for (int i = 0; i < NumCullZones; i++) {
- DoVisibilityTestCullZone(i, true);
- }
-
- CompressIndicesArray();
- delete[] pTempArrayIndices;
-
- fd = CFileMgr::OpenFileForWriting("data\\cullzone.dat");
- if (fd != 0) {
- CFileMgr::Write(fd, (char*)&NumCullZones, sizeof(NumCullZones));
- CFileMgr::Write(fd, (char*)aZones, sizeof(aZones));
- CFileMgr::Write(fd, (char*)&NumAttributeZones, sizeof(NumAttributeZones));
- CFileMgr::Write(fd, (char*)&aAttributeZones, sizeof(aAttributeZones));
- CFileMgr::Write(fd, (char*)&aIndices, sizeof(aIndices));
- CFileMgr::Write(fd, (char*)&aPointersToBigBuildingsForBuildings, sizeof(aPointersToBigBuildingsForBuildings));
- CFileMgr::Write(fd, (char*)&aPointersToBigBuildingsForTreadables, sizeof(aPointersToBigBuildingsForTreadables));
- CFileMgr::CloseFile(fd);
- }
-#endif
- }
-}
-
-void
-CCullZones::BuildListForBigBuildings()
-{
- for (int i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--) {
- CBuilding *building = CPools::GetBuildingPool()->GetSlot(i);
- if (building == nil || !building->bIsBIGBuilding) continue;
- CSimpleModelInfo *nonlod = (CSimpleModelInfo*)((CSimpleModelInfo *)CModelInfo::GetModelInfo(building->GetModelIndex()))->m_atomics[2];
- if (nonlod == nil) continue;
-
- for (int j = i; j >= 0; j--) {
- CBuilding *building2 = CPools::GetBuildingPool()->GetSlot(j);
- if (building2 == nil || building2->bIsBIGBuilding) continue;
- if (CModelInfo::GetModelInfo(building2->GetModelIndex()) == nonlod) {
- if ((building2->GetPosition() - building->GetPosition()).Magnitude() < 5.0f) {
- aPointersToBigBuildingsForBuildings[j] = i;
- }
- }
- }
-
- for (int j = CPools::GetTreadablePool()->GetSize()-1; j >= 0; j--) {
- CTreadable *treadable = CPools::GetTreadablePool()->GetSlot(j);
- if (treadable == nil || treadable->bIsBIGBuilding) continue;
- if (CModelInfo::GetModelInfo(treadable->GetModelIndex()) == nonlod) {
- if ((treadable->GetPosition() - building->GetPosition()).Magnitude() < 5.0f) {
- aPointersToBigBuildingsForTreadables[j] = i;
- }
- }
- }
- }
-}
-
-void
-CCullZones::DoVisibilityTestCullZone(int zoneId, bool doIt)
-{
- aZones[zoneId].m_groupIndexCount[0] = 0;
- aZones[zoneId].m_groupIndexCount[1] = 0;
- aZones[zoneId].m_groupIndexCount[2] = 0;
- aZones[zoneId].m_indexStart = TempEntityIndicesUsed;
- aZones[zoneId].FindTestPoints();
-
- if (!doIt) return;
-
- for (int i = CPools::GetBuildingPool()->GetSize() - 1; i >= 0; i--) {
- CBuilding *building = CPools::GetBuildingPool()->GetSlot(i);
- if (building != nil && !building->bIsBIGBuilding && aZones[zoneId].IsEntityCloseEnoughToZone(building, aPointersToBigBuildingsForBuildings[i] != -1)) {
- CBuilding *building2 = nil;
- if (aPointersToBigBuildingsForBuildings[i] != -1)
- building2 = CPools::GetBuildingPool()->GetSlot(aPointersToBigBuildingsForBuildings[i]);
-
- if (!aZones[zoneId].TestEntityVisibilityFromCullZone(building, 0.0f, building2)) {
- pTempArrayIndices[TempEntityIndicesUsed++] = i;
- aZones[zoneId].m_groupIndexCount[0]++;
- }
- }
- }
-
- for (int i = CPools::GetTreadablePool()->GetSize() - 1; i >= 0; i--) {
- CTreadable* building = CPools::GetTreadablePool()->GetSlot(i);
- if (building != nil && aZones[zoneId].IsEntityCloseEnoughToZone(building, aPointersToBigBuildingsForTreadables[i] != -1)) {
- CTreadable* building2 = nil;
- if (aPointersToBigBuildingsForTreadables[i] != -1)
- building2 = CPools::GetTreadablePool()->GetSlot(aPointersToBigBuildingsForTreadables[i]);
-
- if (!aZones[zoneId].TestEntityVisibilityFromCullZone(building, 10.0f, building2)) {
- pTempArrayIndices[TempEntityIndicesUsed++] = i;
- aZones[zoneId].m_groupIndexCount[1]++;
- }
- }
- }
-
- for (int i = CPools::GetTreadablePool()->GetSize() - 1; i >= 0; i--) {
- CTreadable *building = CPools::GetTreadablePool()->GetSlot(i);
- if (building != nil && aZones[zoneId].CalcDistToCullZoneSquared(building->GetPosition().x, building->GetPosition().y) < 40000.0f) {
- int start = aZones[zoneId].m_groupIndexCount[0] + aZones[zoneId].m_indexStart;
- int end = aZones[zoneId].m_groupIndexCount[1] + start;
-
- bool alreadyAdded = false;
-
- for (int k = start; k < end; k++) {
- if (aIndices[k] == i)
- alreadyAdded = true;
- }
-
- if (!alreadyAdded) {
- CBuilding *building2 = nil;
- if (aPointersToBigBuildingsForTreadables[i] != -1)
- building2 = CPools::GetBuildingPool()->GetSlot(aPointersToBigBuildingsForTreadables[i]);
- if (!aZones[zoneId].TestEntityVisibilityFromCullZone(building, 0.0f, building2)) {
- pTempArrayIndices[TempEntityIndicesUsed++] = i;
- aZones[zoneId].m_groupIndexCount[2]++;
- }
- }
- }
- }
}
void
@@ -219,14 +34,9 @@ CCullZones::Update(void)
{
bool invisible;
- if(bCullZonesDisabled)
- return;
-
switch(CTimer::GetFrameCounter() & 7){
case 0:
case 4:
- /* Update Cull zone */
- ForceCullZoneCoors(TheCamera.GetGameCamPosition());
break;
case 2:
@@ -250,28 +60,6 @@ CCullZones::Update(void)
void
CCullZones::ForceCullZoneCoors(CVector coors)
{
- int32 z;
- z = FindCullZoneForCoors(coors);
- if(z != OldCullZone){
- if(OldCullZone >= 0)
- aZones[OldCullZone].DoStuffLeavingZone();
- if(z >= 0)
- aZones[z].DoStuffEnteringZone();
- OldCullZone = z;
- }
-}
-
-int32
-CCullZones::FindCullZoneForCoors(CVector coors)
-{
- int i;
-
- for(i = 0; i < NumCullZones; i++)
- if(coors.x >= aZones[i].minx && coors.x <= aZones[i].maxx &&
- coors.y >= aZones[i].miny && coors.y <= aZones[i].maxy &&
- coors.z >= aZones[i].minz && coors.z <= aZones[i].maxz)
- return i;
- return -1;
}
int32
@@ -346,218 +134,16 @@ CCullZones::AddCullZone(CVector const &position,
float minz, float maxz,
uint16 flag, int16 wantedLevel)
{
- CCullZone *cull;
CAttributeZone *attrib;
- CVector v;
- if((flag & ATTRZONE_NOTCULLZONE) == 0){
- cull = &aZones[NumCullZones++];
- v = position;
- // WTF is this?
- if((v-CVector(1032.14f, -624.255f, 24.93f)).Magnitude() < 1.0f)
- v = CVector(1061.7f, -613.0f, 19.0f);
- if((v-CVector(1029.48f, -495.757f, 21.98f)).Magnitude() < 1.0f)
- v = CVector(1061.4f, -506.0f, 18.5f);
- cull->position.x = clamp(v.x, minx, maxx);
- cull->position.y = clamp(v.y, miny, maxy);
- cull->position.z = clamp(v.z, minz, maxz);
- cull->minx = minx;
- cull->maxx = maxx;
- cull->miny = miny;
- cull->maxy = maxy;
- cull->minz = minz;
- cull->maxz = maxz;
- cull->m_groupIndexCount[0] = 0;
- cull->m_groupIndexCount[1] = 0;
- cull->m_groupIndexCount[2] = 0;
- cull->m_indexStart = 0;
- }
- if(flag & ~ATTRZONE_NOTCULLZONE){
- attrib = &aAttributeZones[NumAttributeZones++];
- attrib->minx = minx;
- attrib->maxx = maxx;
- attrib->miny = miny;
- attrib->maxy = maxy;
- attrib->minz = minz;
- attrib->maxz = maxz;
- attrib->attributes = flag;
- attrib->wantedLevel = wantedLevel;
- }
+ assert(NumAttributeZones < NUMATTRIBZONES);
+ attrib = &aAttributeZones[NumAttributeZones++];
+ attrib->minx = minx;
+ attrib->maxx = maxx;
+ attrib->miny = miny;
+ attrib->maxy = maxy;
+ attrib->minz = minz;
+ attrib->maxz = maxz;
+ attrib->attributes = flag;
+ attrib->wantedLevel = wantedLevel;
}
-
-
-void
-CCullZone::DoStuffLeavingZone(void)
-{
- int i;
-
- for(i = 0; i < m_numBuildings; i++)
- DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[m_indexStart + i]);
- for(; i < m_numBuildings + m_numTreadablesPlus10m + m_numTreadables ; i++)
- DoStuffLeavingZone_OneTreadableBoth(CCullZones::aIndices[m_indexStart + i]);
-}
-
-void
-CCullZone::DoStuffLeavingZone_OneBuilding(uint16 i)
-{
- int16 bb;
- int j;
-
- if(i < 6000){
- CPools::GetBuildingPool()->GetSlot(i)->bZoneCulled = false;
- bb = CCullZones::aPointersToBigBuildingsForBuildings[i];
- if(bb != -1)
- CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = false;
- }else{
- i -= 6000;
- for(j = 0; j < 3; j++)
- DoStuffLeavingZone_OneBuilding(CCullZones::aIndices[i+j]);
- }
-}
-
-void
-CCullZone::DoStuffLeavingZone_OneTreadableBoth(uint16 i)
-{
- int16 bb;
- int j;
-
- if(i < 6000){
- CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled = false;
- CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled2 = false;
- bb = CCullZones::aPointersToBigBuildingsForTreadables[i];
- if(bb != -1)
- CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = false;
- }else{
- i -= 6000;
- for(j = 0; j < 3; j++)
- DoStuffLeavingZone_OneTreadableBoth(CCullZones::aIndices[i+j]);
- }
-}
-
-void
-CCullZone::DoStuffEnteringZone(void)
-{
- int i;
-
- for(i = 0; i < m_numBuildings; i++)
- DoStuffEnteringZone_OneBuilding(CCullZones::aIndices[m_indexStart + i]);
- for(; i < m_numBuildings + m_numTreadablesPlus10m; i++)
- DoStuffEnteringZone_OneTreadablePlus10m(CCullZones::aIndices[m_indexStart + i]);
- for(; i < m_numBuildings + m_numTreadablesPlus10m + m_numTreadables; i++)
- DoStuffEnteringZone_OneTreadable(CCullZones::aIndices[m_indexStart + i]);
-}
-
-void
-CCullZone::DoStuffEnteringZone_OneBuilding(uint16 i)
-{
- int16 bb;
- int j;
-
- if(i < 6000){
- CPools::GetBuildingPool()->GetSlot(i)->bZoneCulled = true;
- bb = CCullZones::aPointersToBigBuildingsForBuildings[i];
- if(bb != -1)
- CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = true;
- }else{
- i -= 6000;
- for(j = 0; j < 3; j++)
- DoStuffEnteringZone_OneBuilding(CCullZones::aIndices[i+j]);
- }
-}
-
-void
-CCullZone::DoStuffEnteringZone_OneTreadablePlus10m(uint16 i)
-{
- int16 bb;
- int j;
-
- if(i < 6000){
- CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled = true;
- CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled2 = true;
- bb = CCullZones::aPointersToBigBuildingsForTreadables[i];
- if(bb != -1)
- CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = true;
- }else{
- i -= 6000;
- for(j = 0; j < 3; j++)
- DoStuffEnteringZone_OneTreadablePlus10m(CCullZones::aIndices[i+j]);
- }
-}
-
-void
-CCullZone::DoStuffEnteringZone_OneTreadable(uint16 i)
-{
- int16 bb;
- int j;
-
- if(i < 6000){
- CPools::GetTreadablePool()->GetSlot(i)->bZoneCulled = true;
- bb = CCullZones::aPointersToBigBuildingsForTreadables[i];
- if(bb != -1)
- CPools::GetBuildingPool()->GetSlot(bb)->bZoneCulled = true;
- }else{
- i -= 6000;
- for(j = 0; j < 3; j++)
- DoStuffEnteringZone_OneTreadable(CCullZones::aIndices[i+j]);
- }
-}
-
-float
-CCullZone::CalcDistToCullZoneSquared(float x, float y)
-{
- float rx, ry;
-
- if (x < minx) rx = sq(x - minx);
- else if (x > maxx) rx = sq(x - maxx);
- else rx = 0.0f;
-
- if (y < miny) ry = sq(y - miny);
- else if (y > maxy) ry = sq(y - maxy);
- else ry = 0.0f;
-
- return rx + ry;
-}
-
-bool
-CCullZone::IsEntityCloseEnoughToZone(CEntity *entity, bool checkLevel)
-{
- const CVector &pos = entity->GetPosition();
-
- CSimpleModelInfo *minfo = (CSimpleModelInfo*)CModelInfo::GetModelInfo(entity->GetModelIndex());
- float distToZone = CalcDistToCullZone(pos.x, pos.y);
- float lodDist;
- if (minfo->m_isSubway)
- lodDist = minfo->GetLargestLodDistance() + 30.0f;
- else
- lodDist = minfo->GetLargestLodDistance() + 50.0f;
-
- if (lodDist > distToZone) return true;
- if (!checkLevel) return false;
- return CTheZones::GetLevelFromPosition(&pos) == CTheZones::GetLevelFromPosition(&CVector(minx, miny, minz));
-}
-
-bool
-CCullZones::DoWeHaveMoreThanXOccurencesOfSet(int32 count, uint16 *set)
-{
- int32 curCount;
- int32 start;
- int32 size;
-
- for (int i = 0; i < NumCullZones; i++) {
- curCount = 0;
- for (int group = 0; group < 3; group++) {
- aZones[i].GetGroupStartAndSize(group, start, size);
-
- int unk = 0; // TODO: figure out
- for (int j = 0; j < size; j++) {
- for (int k = 0; k < 3; k++) {
- if (set[k] == pTempArrayIndices[start+j])
- unk++;
- }
- }
- if (unk == 3 && ++curCount >= count)
- return true;
- }
- }
- return false;
-} \ No newline at end of file
diff --git a/src/core/ZoneCull.h b/src/core/ZoneCull.h
index 9bc07b8c..e76b7a44 100644
--- a/src/core/ZoneCull.h
+++ b/src/core/ZoneCull.h
@@ -1,57 +1,5 @@
class CEntity;
-class CCullZone
-{
-public:
- CVector position;
- float minx;
- float maxx;
- float miny;
- float maxy;
- float minz;
- float maxz;
-
- int32 m_indexStart;
- int16 m_groupIndexCount[3];
- int16 m_numBuildings;
- int16 m_numTreadablesPlus10m;
- int16 m_numTreadables;
-
- void DoStuffLeavingZone(void);
- static void DoStuffLeavingZone_OneBuilding(uint16 i);
- static void DoStuffLeavingZone_OneTreadableBoth(uint16 i);
- void DoStuffEnteringZone(void);
- static void DoStuffEnteringZone_OneBuilding(uint16 i);
- static void DoStuffEnteringZone_OneTreadablePlus10m(uint16 i);
- static void DoStuffEnteringZone_OneTreadable(uint16 i);
-
-
- static bool TestLine(CVector a1, CVector a2);
- float CalcDistToCullZoneSquared(float x, float y);
- float CalcDistToCullZone(float x, float y) { return Sqrt(CalcDistToCullZoneSquared(x, y)); };
- bool IsEntityCloseEnoughToZone(CEntity* entity, bool checkLevel);
-
- void GetGroupStartAndSize(int32 groupid, int32 &start, int32 &size) {
- switch (groupid) {
- case 1:
- start = m_groupIndexCount[0] + m_indexStart;
- size = m_groupIndexCount[1];
- break;
- case 2:
- start = m_groupIndexCount[0] + m_groupIndexCount[1] + m_indexStart;
- size = m_groupIndexCount[2];
- break;
- default:
- start = m_indexStart;
- size = m_groupIndexCount[0];
- break;
- }
- }
-
- void FindTestPoints() {}; // todo
- bool TestEntityVisibilityFromCullZone(CEntity*, float, CEntity*) { return false; }; // todo
-};
-
enum eZoneAttribs
{
ATTRZONE_CAMCLOSEIN = 1,
@@ -79,27 +27,17 @@ struct CAttributeZone
class CCullZones
{
public:
- static int32 NumCullZones;
- static CCullZone aZones[NUMCULLZONES];
static int32 NumAttributeZones;
static CAttributeZone aAttributeZones[NUMATTRIBZONES];
- static uint16 aIndices[NUMZONEINDICES];
- static int16 aPointersToBigBuildingsForBuildings[NUMBUILDINGS];
- static int16 aPointersToBigBuildingsForTreadables[NUMTREADABLES];
static int32 CurrentWantedLevelDrop_Player;
static int32 CurrentFlags_Camera;
static int32 CurrentFlags_Player;
- static int32 OldCullZone;
- static int32 EntityIndicesUsed;
static bool bCurrentSubwayIsInvisible;
- static bool bCullZonesDisabled;
static void Init(void);
- static void ResolveVisibilities(void);
static void Update(void);
static void ForceCullZoneCoors(CVector coors);
- static int32 FindCullZoneForCoors(CVector coors);
static int32 FindAttributesForCoors(CVector coors, int32 *wantedLevel);
static CAttributeZone *FindZoneWithStairsAttributeForPlayer(void);
static void MarkSubwayAsInvisible(bool visible);
@@ -117,9 +55,6 @@ public:
static bool CamNoRain(void) { return (CurrentFlags_Camera & ATTRZONE_NORAIN) != 0; }
static int32 GetWantedLevelDrop(void) { return CurrentWantedLevelDrop_Player; }
- static void BuildListForBigBuildings();
- static void DoVisibilityTestCullZone(int zoneId, bool doIt);
- static bool DoWeHaveMoreThanXOccurencesOfSet(int32 count, uint16 *set);
-
- static void CompressIndicesArray() {};// todo
+ //--MIAMI: TODO
+ static bool PoliceAbandonCars(void) { return false; }
};
diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp
index 22c0735a..c0fa7cbe 100644
--- a/src/core/Zones.cpp
+++ b/src/core/Zones.cpp
@@ -9,133 +9,137 @@
#include "World.h"
eLevelName CTheZones::m_CurrLevel;
-CZone *CTheZones::m_pPlayersZone;
int16 CTheZones::FindIndex;
uint16 CTheZones::NumberOfAudioZones;
int16 CTheZones::AudioZoneArray[NUMAUDIOZONES];
uint16 CTheZones::TotalNumberOfMapZones;
-uint16 CTheZones::TotalNumberOfZones;
-CZone CTheZones::ZoneArray[NUMZONES];
+uint16 CTheZones::TotalNumberOfInfoZones;
+uint16 CTheZones::TotalNumberOfNavigationZones;
+CZone CTheZones::InfoZoneArray[NUMINFOZONES];
CZone CTheZones::MapZoneArray[NUMMAPZONES];
+CZone CTheZones::NavigationZoneArray[NUMNAVIGZONES];
uint16 CTheZones::TotalNumberOfZoneInfos;
-CZoneInfo CTheZones::ZoneInfoArray[2*NUMZONES];
+CZoneInfo CTheZones::ZoneInfoArray[2*NUMINFOZONES];
-#define SWAPF(a, b) { float t; t = a; a = b; b = t; }
-
-inline bool IsNormalZone(int type) { return type == ZONE_DEFAULT || type == ZONE_NAVIG || type == ZONE_INFO; }
-static void
-CheckZoneInfo(CZoneInfo *info)
-{
- assert(info->carThreshold[0] >= 0);
- assert(info->carThreshold[0] <= info->carThreshold[1]);
- assert(info->carThreshold[1] <= info->carThreshold[2]);
- assert(info->carThreshold[2] <= info->carThreshold[3]);
- assert(info->carThreshold[3] <= info->carThreshold[4]);
- assert(info->carThreshold[4] <= info->carThreshold[5]);
- assert(info->carThreshold[5] <= info->copThreshold);
- assert(info->copThreshold <= info->gangThreshold[0]);
- assert(info->gangThreshold[0] <= info->gangThreshold[1]);
- assert(info->gangThreshold[1] <= info->gangThreshold[2]);
- assert(info->gangThreshold[2] <= info->gangThreshold[3]);
- assert(info->gangThreshold[3] <= info->gangThreshold[4]);
- assert(info->gangThreshold[4] <= info->gangThreshold[5]);
- assert(info->gangThreshold[5] <= info->gangThreshold[6]);
- assert(info->gangThreshold[6] <= info->gangThreshold[7]);
- assert(info->gangThreshold[7] <= info->gangThreshold[8]);
-}
+#define SWAPF(a, b) { float t; t = a; a = b; b = t; }
+//--MIAMI: done
wchar*
CZone::GetTranslatedName(void)
{
return TheText.Get(name);
}
+//--MIAMI: done
void
CTheZones::Init(void)
{
- int i;
+ int i, j;
for(i = 0; i < NUMAUDIOZONES; i++)
AudioZoneArray[i] = -1;
NumberOfAudioZones = 0;
- for(i = 0; i < NUMZONES; i++)
- memset(&ZoneArray[i], 0, sizeof(CZone));
-
- CZoneInfo *zonei;
- int x = 1000/6;
- for(i = 0; i < 2*NUMZONES; i++){
- zonei = &ZoneInfoArray[i];
- zonei->carDensity = 10;
- zonei->carThreshold[0] = x;
- zonei->carThreshold[1] = zonei->carThreshold[0] + x;
- zonei->carThreshold[2] = zonei->carThreshold[1] + x;
- zonei->carThreshold[3] = zonei->carThreshold[2] + x;
- zonei->carThreshold[4] = zonei->carThreshold[3];
- zonei->carThreshold[5] = zonei->carThreshold[4];
- zonei->copThreshold = zonei->carThreshold[5] + x;
- zonei->gangThreshold[0] = zonei->copThreshold;
- zonei->gangThreshold[1] = zonei->gangThreshold[0];
- zonei->gangThreshold[2] = zonei->gangThreshold[1];
- zonei->gangThreshold[3] = zonei->gangThreshold[2];
- zonei->gangThreshold[4] = zonei->gangThreshold[3];
- zonei->gangThreshold[5] = zonei->gangThreshold[4];
- zonei->gangThreshold[6] = zonei->gangThreshold[5];
- zonei->gangThreshold[7] = zonei->gangThreshold[6];
- zonei->gangThreshold[8] = zonei->gangThreshold[7];
- CheckZoneInfo(zonei);
+ for(i = 0; i < NUMNAVIGZONES; i++)
+ memset(&NavigationZoneArray[i], 0, sizeof(CZone));
+
+ for(i = 0; i < NUMINFOZONES; i++)
+ memset(&InfoZoneArray[i], 0, sizeof(CZone));
+
+ int x = 1000/9;
+ for(i = 0; i < 2*NUMINFOZONES; i++){
+ // Cars
+
+ ZoneInfoArray[i].carDensity = 10;
+ ZoneInfoArray[i].carThreshold[0] = x;
+ ZoneInfoArray[i].carThreshold[1] = ZoneInfoArray[i].carThreshold[0] + x;
+ ZoneInfoArray[i].carThreshold[2] = ZoneInfoArray[i].carThreshold[1] + x;
+ ZoneInfoArray[i].carThreshold[3] = ZoneInfoArray[i].carThreshold[2] + x;
+ ZoneInfoArray[i].carThreshold[4] = ZoneInfoArray[i].carThreshold[3] + x;
+ ZoneInfoArray[i].carThreshold[5] = ZoneInfoArray[i].carThreshold[4] + x;
+ ZoneInfoArray[i].carThreshold[6] = ZoneInfoArray[i].carThreshold[5] + x;
+ ZoneInfoArray[i].carThreshold[7] = ZoneInfoArray[i].carThreshold[6] + x;
+ ZoneInfoArray[i].carThreshold[8] = 1000;
+
+ ZoneInfoArray[i].boatThreshold[0] = 500;
+ ZoneInfoArray[i].boatThreshold[1] = 1000;
+
+ // What's going on here? this looks more like density
+ ZoneInfoArray[i].copThreshold = 50;
+ for(j = 0; j < NUM_GANGS; j++)
+ ZoneInfoArray[i].gangThreshold[j] = ZoneInfoArray[i].copThreshold;
+
+ // Peds
+
+ ZoneInfoArray[i].pedDensity = 12;
+
+ // What's going on here? this looks more like density
+ ZoneInfoArray[i].copPedThreshold = 50;
+ for(j = 0; j < NUM_GANGS; j++)
+ ZoneInfoArray[i].gangPedThreshold[j] = ZoneInfoArray[i].copPedThreshold;
+
+ ZoneInfoArray[i].pedGroup = 0;
}
TotalNumberOfZoneInfos = 1; // why 1?
- TotalNumberOfZones = 1;
+ TotalNumberOfNavigationZones = 1;
+ TotalNumberOfInfoZones = 1;
+
+ strcpy(InfoZoneArray[0].name, "CITYINF");
+ InfoZoneArray[0].minx = -2400.0f;
+ InfoZoneArray[0].miny = -2000.0f;
+ InfoZoneArray[0].minz = -500.0f;
+ InfoZoneArray[0].maxx = 1600.0f;
+ InfoZoneArray[0].maxy = 2000.0f;
+ InfoZoneArray[0].maxz = 500.0f;
+ InfoZoneArray[0].level = LEVEL_NONE;
+ InfoZoneArray[0].type = ZONE_INFO;
+
+ strcpy(NavigationZoneArray[0].name, "VICE_C");
+ NavigationZoneArray[0].minx = -2400.0f;
+ NavigationZoneArray[0].miny = -2000.0f;
+ NavigationZoneArray[0].minz = -500.0f;
+ NavigationZoneArray[0].maxx = 1600.0f;
+ NavigationZoneArray[0].maxy = 2000.0f;
+ NavigationZoneArray[0].maxz = 500.0f;
+ NavigationZoneArray[0].level = LEVEL_NONE;
+ NavigationZoneArray[0].type = ZONE_NAVIG;
m_CurrLevel = LEVEL_NONE;
- m_pPlayersZone = &ZoneArray[0];
-
- strcpy(ZoneArray[0].name, "CITYZON");
- ZoneArray[0].minx = -4000.0f;
- ZoneArray[0].miny = -4000.0f;
- ZoneArray[0].minz = -500.0f;
- ZoneArray[0].maxx = 4000.0f;
- ZoneArray[0].maxy = 4000.0f;
- ZoneArray[0].maxz = 500.0f;
- ZoneArray[0].level = LEVEL_NONE;
for(i = 0; i < NUMMAPZONES; i++){
memset(&MapZoneArray[i], 0, sizeof(CZone));
MapZoneArray[i].type = ZONE_MAPZONE;
}
-
- TotalNumberOfMapZones = 1;
-
strcpy(MapZoneArray[0].name, "THEMAP");
- MapZoneArray[0].minx = -4000.0f;
- MapZoneArray[0].miny = -4000.0f;
+ MapZoneArray[0].minx = -2400.0f;
+ MapZoneArray[0].miny = -2000.0f;
MapZoneArray[0].minz = -500.0f;
- MapZoneArray[0].maxx = 4000.0f;
- MapZoneArray[0].maxy = 4000.0f;
+ MapZoneArray[0].maxx = 1600.0f;
+ MapZoneArray[0].maxy = 2000.0f;
MapZoneArray[0].maxz = 500.0f;
MapZoneArray[0].level = LEVEL_NONE;
}
+//--MIAMI: done
void
CTheZones::Update(void)
{
CVector pos;
pos = FindPlayerCoors();
- m_pPlayersZone = FindSmallestZonePosition(&pos);
m_CurrLevel = GetLevelFromPosition(&pos);
}
+//--MIAMI: done
void
CTheZones::CreateZone(char *name, eZoneType type,
float minx, float miny, float minz,
float maxx, float maxy, float maxz,
eLevelName level)
{
+ char tmpname[24];
char *p;
- char tmpname[8];
if(minx > maxx) SWAPF(minx, maxx);
if(miny > maxy) SWAPF(miny, maxy);
@@ -144,73 +148,94 @@ CTheZones::CreateZone(char *name, eZoneType type,
// make upper case
for(p = name; *p; p++) if(islower(*p)) *p = toupper(*p);
- // add zone
strncpy(tmpname, name, 7);
tmpname[7] = '\0';
- strcpy(ZoneArray[TotalNumberOfZones].name, tmpname);
- ZoneArray[TotalNumberOfZones].type = type;
- ZoneArray[TotalNumberOfZones].minx = minx;
- ZoneArray[TotalNumberOfZones].miny = miny;
- ZoneArray[TotalNumberOfZones].minz = minz;
- ZoneArray[TotalNumberOfZones].maxx = maxx;
- ZoneArray[TotalNumberOfZones].maxy = maxy;
- ZoneArray[TotalNumberOfZones].maxz = maxz;
- ZoneArray[TotalNumberOfZones].level = level;
- if(IsNormalZone(type)){
- ZoneArray[TotalNumberOfZones].zoneinfoDay = TotalNumberOfZoneInfos++;
- ZoneArray[TotalNumberOfZones].zoneinfoNight = TotalNumberOfZoneInfos++;
- }
- TotalNumberOfZones++;
-}
-
-void
-CTheZones::CreateMapZone(char *name, eZoneType type,
- float minx, float miny, float minz,
- float maxx, float maxy, float maxz,
- eLevelName level)
-{
- CZone *zone;
- char *p;
-
- if(minx > maxx) SWAPF(minx, maxx);
- if(miny > maxy) SWAPF(miny, maxy);
- if(minz > maxz) SWAPF(minz, maxz);
-
- // make upper case
- for(p = name; *p; p++) if(islower(*p)) *p = toupper(*p);
// add zone
- zone = &MapZoneArray[TotalNumberOfMapZones++];
- strncpy(zone->name, name, 7);
- zone->name[7] = '\0';
- zone->type = type;
- zone->minx = minx;
- zone->miny = miny;
- zone->minz = minz;
- zone->maxx = maxx;
- zone->maxy = maxy;
- zone->maxz = maxz;
- zone->level = level;
+ switch(type){
+ case ZONE_DEFAULT:
+ case ZONE_NAVIG:
+ assert(TotalNumberOfNavigationZones < NUMNAVIGZONES);
+ strcpy(NavigationZoneArray[TotalNumberOfNavigationZones].name, tmpname);
+ NavigationZoneArray[TotalNumberOfNavigationZones].type = type;
+ NavigationZoneArray[TotalNumberOfNavigationZones].minx = minx;
+ NavigationZoneArray[TotalNumberOfNavigationZones].miny = miny;
+ NavigationZoneArray[TotalNumberOfNavigationZones].minz = minz;
+ NavigationZoneArray[TotalNumberOfNavigationZones].maxx = maxx;
+ NavigationZoneArray[TotalNumberOfNavigationZones].maxy = maxy;
+ NavigationZoneArray[TotalNumberOfNavigationZones].maxz = maxz;
+ NavigationZoneArray[TotalNumberOfNavigationZones].level = level;
+ TotalNumberOfNavigationZones++;
+ break;
+ case ZONE_INFO:
+ assert(TotalNumberOfInfoZones < NUMINFOZONES);
+ strcpy(InfoZoneArray[TotalNumberOfInfoZones].name, tmpname);
+ InfoZoneArray[TotalNumberOfInfoZones].type = type;
+ InfoZoneArray[TotalNumberOfInfoZones].minx = minx;
+ InfoZoneArray[TotalNumberOfInfoZones].miny = miny;
+ InfoZoneArray[TotalNumberOfInfoZones].minz = minz;
+ InfoZoneArray[TotalNumberOfInfoZones].maxx = maxx;
+ InfoZoneArray[TotalNumberOfInfoZones].maxy = maxy;
+ InfoZoneArray[TotalNumberOfInfoZones].maxz = maxz;
+ InfoZoneArray[TotalNumberOfInfoZones].level = level;
+ InfoZoneArray[TotalNumberOfInfoZones].zoneinfoDay = TotalNumberOfZoneInfos++;
+ InfoZoneArray[TotalNumberOfInfoZones].zoneinfoNight = TotalNumberOfZoneInfos++;
+ TotalNumberOfInfoZones++;
+ break;
+ case ZONE_MAPZONE:
+ assert(TotalNumberOfMapZones < NUMMAPZONES);
+ strcpy(MapZoneArray[TotalNumberOfMapZones].name, tmpname);
+ MapZoneArray[TotalNumberOfMapZones].type = type;
+ MapZoneArray[TotalNumberOfMapZones].minx = minx;
+ MapZoneArray[TotalNumberOfMapZones].miny = miny;
+ MapZoneArray[TotalNumberOfMapZones].minz = minz;
+ MapZoneArray[TotalNumberOfMapZones].maxx = maxx;
+ MapZoneArray[TotalNumberOfMapZones].maxy = maxy;
+ MapZoneArray[TotalNumberOfMapZones].maxz = maxz;
+ MapZoneArray[TotalNumberOfMapZones].level = level;
+ TotalNumberOfMapZones++;
+ break;
+ }
}
+//--MIAMI: done
void
CTheZones::PostZoneCreation(void)
{
int i;
- for(i = 1; i < TotalNumberOfZones; i++)
- InsertZoneIntoZoneHierarchy(&ZoneArray[i]);
+ for(i = 1; i < TotalNumberOfNavigationZones; i++)
+ InsertZoneIntoZoneHierarchy(&NavigationZoneArray[i]);
InitialiseAudioZoneArray();
}
+//--MIAMI: done, but does nothing
+void
+CTheZones::CheckZonesForOverlap(void)
+{
+ int i, j;
+ char str[116];
+
+ for(i = 1; i < TotalNumberOfInfoZones; i++){
+ ZoneIsEntirelyContainedWithinOtherZone(&InfoZoneArray[i], &InfoZoneArray[0]);
+
+ for(j = 1; j < TotalNumberOfInfoZones; j++)
+ if(i != j && ZoneIsEntirelyContainedWithinOtherZone(&InfoZoneArray[i], &InfoZoneArray[j]))
+ sprintf(str, "Info zone %s contains %s\n",
+ &InfoZoneArray[j].name, &InfoZoneArray[i].name);
+ }
+}
+
+//--MIAMI: done
void
CTheZones::InsertZoneIntoZoneHierarchy(CZone *zone)
{
zone->child = nil;
zone->parent = nil;
zone->next = nil;
- InsertZoneIntoZoneHierRecursive(zone, &ZoneArray[0]);
+ InsertZoneIntoZoneHierRecursive(zone, &NavigationZoneArray[0]);
}
+//--MIAMI: done
bool
CTheZones::InsertZoneIntoZoneHierRecursive(CZone *inner, CZone *outer)
{
@@ -254,6 +279,7 @@ CTheZones::InsertZoneIntoZoneHierRecursive(CZone *inner, CZone *outer)
return true;
}
+//--MIAMI: done
bool
CTheZones::ZoneIsEntirelyContainedWithinOtherZone(CZone *inner, CZone *outer)
{
@@ -278,6 +304,7 @@ CTheZones::ZoneIsEntirelyContainedWithinOtherZone(CZone *inner, CZone *outer)
return true;
}
+//--MIAMI: done
bool
CTheZones::PointLiesWithinZone(const CVector *v, CZone *zone)
{
@@ -286,6 +313,7 @@ CTheZones::PointLiesWithinZone(const CVector *v, CZone *zone)
zone->minz <= v->z && v->z <= zone->maxz;
}
+//--MIAMI: done
eLevelName
CTheZones::GetLevelFromPosition(CVector const *v)
{
@@ -299,35 +327,35 @@ CTheZones::GetLevelFromPosition(CVector const *v)
return MapZoneArray[0].level;
}
+//--MIAMI: done
CZone*
-CTheZones::FindSmallestZonePosition(const CVector *v)
+CTheZones::FindInformationZoneForPosition(const CVector *v)
{
- CZone *best = &ZoneArray[0];
- // zone to test next
- CZone *zone = ZoneArray[0].child;
- while(zone)
- // if in zone, descent into children
- if(PointLiesWithinZone(v, zone)){
- best = zone;
- zone = zone->child;
- // otherwise try next zone
- }else
- zone = zone->next;
- return best;
+ int i;
+// char tmp[116];
+// if(!PointLiesWithinZone(v, &InfoZoneArray[0]))
+// sprintf(tmp, "x = %.3f y= %.3f z = %.3f\n", v.x, v.y, v.z);
+ for(i = 1; i < TotalNumberOfInfoZones; i++)
+ if(PointLiesWithinZone(v, &InfoZoneArray[i]))
+ return &InfoZoneArray[i];
+ return &InfoZoneArray[0];
}
+//--MIAMI: done
CZone*
-CTheZones::FindSmallestZonePositionType(const CVector *v, eZoneType type)
+CTheZones::FindSmallestNavigationZoneForPosition(const CVector *v, bool findDefault, bool findNavig)
{
CZone *best = nil;
- if(ZoneArray[0].type == type)
- best = &ZoneArray[0];
+ if(findDefault && NavigationZoneArray[0].type == ZONE_DEFAULT ||
+ findNavig && NavigationZoneArray[0].type == ZONE_NAVIG)
+ best = &NavigationZoneArray[0];
// zone to test next
- CZone *zone = ZoneArray[0].child;
+ CZone *zone = NavigationZoneArray[0].child;
while(zone)
// if in zone, descent into children
if(PointLiesWithinZone(v, zone)){
- if(zone->type == type)
+ if(findDefault && zone->type == ZONE_DEFAULT ||
+ findNavig && zone->type == ZONE_NAVIG)
best = zone;
zone = zone->child;
// otherwise try next zone
@@ -336,43 +364,73 @@ CTheZones::FindSmallestZonePositionType(const CVector *v, eZoneType type)
return best;
}
-CZone*
-CTheZones::FindSmallestZonePositionILN(const CVector *v)
+//--MIAMI: done
+int16
+CTheZones::FindZoneByLabelAndReturnIndex(char *name, eZoneType type)
{
- CZone *best = nil;
- if(IsNormalZone(ZoneArray[0].type))
- best = &ZoneArray[0];
- // zone to test next
- CZone *zone = ZoneArray[0].child;
- while(zone)
- // if in zone, descent into children
- if(PointLiesWithinZone(v, zone)){
- if(IsNormalZone(zone->type))
- best = zone;
- zone = zone->child;
- // otherwise try next zone
- }else
- zone = zone->next;
- return best;
+ char str[8];
+ memset(str, 0, 8);
+ strncpy(str, name, 8);
+ switch(type){
+ case ZONE_DEFAULT:
+ case ZONE_NAVIG:
+ for(FindIndex = 0; FindIndex < TotalNumberOfNavigationZones; FindIndex++)
+ if(strcmp(GetNavigationZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+
+ case ZONE_INFO:
+ for(FindIndex = 0; FindIndex < TotalNumberOfInfoZones; FindIndex++)
+ if(strcmp(GetInfoZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+
+ case ZONE_MAPZONE:
+ for(FindIndex = 0; FindIndex < TotalNumberOfMapZones; FindIndex++)
+ if(strcmp(GetMapZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+ }
+ return -1;
}
+//--MIAMI: done
int16
-CTheZones::FindZoneByLabelAndReturnIndex(char *name)
+CTheZones::FindNextZoneByLabelAndReturnIndex(char *name, eZoneType type)
{
char str[8];
+ ++FindIndex;
memset(str, 0, 8);
strncpy(str, name, 8);
- for(FindIndex = 0; FindIndex < TotalNumberOfZones; FindIndex++)
- if(strcmp(GetZone(FindIndex)->name, name) == 0)
- return FindIndex;
+ switch(type){
+ case ZONE_DEFAULT:
+ case ZONE_NAVIG:
+ for(; FindIndex < TotalNumberOfNavigationZones; FindIndex++)
+ if(strcmp(GetNavigationZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+
+ case ZONE_INFO:
+ for(; FindIndex < TotalNumberOfInfoZones; FindIndex++)
+ if(strcmp(GetInfoZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+
+ case ZONE_MAPZONE:
+ for(; FindIndex < TotalNumberOfMapZones; FindIndex++)
+ if(strcmp(GetMapZone(FindIndex)->name, name) == 0)
+ return FindIndex;
+ break;
+ }
return -1;
}
+//--MIAMI: done
CZoneInfo*
CTheZones::GetZoneInfo(const CVector *v, uint8 day)
{
CZone *zone;
- zone = FindSmallestZonePositionILN(v);
+ zone = FindInformationZoneForPosition(v);
if(zone == nil)
return &ZoneInfoArray[0];
return &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight];
@@ -383,6 +441,7 @@ CTheZones::GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info)
{
CZoneInfo *day, *night;
float d, n;
+ int i;
day = GetZoneInfo(pos, 1);
night = GetZoneInfo(pos, 0);
@@ -402,109 +461,60 @@ CTheZones::GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info)
n = 1.0f - d;
}
info->carDensity = day->carDensity * d + night->carDensity * n;
- info->carThreshold[0] = day->carThreshold[0] * d + night->carThreshold[0] * n;
- info->carThreshold[1] = day->carThreshold[1] * d + night->carThreshold[1] * n;
- info->carThreshold[2] = day->carThreshold[2] * d + night->carThreshold[2] * n;
- info->carThreshold[3] = day->carThreshold[3] * d + night->carThreshold[3] * n;
- info->carThreshold[4] = day->carThreshold[4] * d + night->carThreshold[4] * n;
- info->carThreshold[5] = day->carThreshold[5] * d + night->carThreshold[5] * n;
- info->copThreshold = day->copThreshold * d + night->copThreshold * n;
- info->gangThreshold[0] = day->gangThreshold[0] * d + night->gangThreshold[0] * n;
- info->gangThreshold[1] = day->gangThreshold[1] * d + night->gangThreshold[1] * n;
- info->gangThreshold[2] = day->gangThreshold[2] * d + night->gangThreshold[2] * n;
- info->gangThreshold[3] = day->gangThreshold[3] * d + night->gangThreshold[3] * n;
- info->gangThreshold[4] = day->gangThreshold[4] * d + night->gangThreshold[4] * n;
- info->gangThreshold[5] = day->gangThreshold[5] * d + night->gangThreshold[5] * n;
- info->gangThreshold[6] = day->gangThreshold[6] * d + night->gangThreshold[6] * n;
- info->gangThreshold[7] = day->gangThreshold[7] * d + night->gangThreshold[7] * n;
- info->gangThreshold[8] = day->gangThreshold[8] * d + night->gangThreshold[8] * n;
+ for(i = 0; i < ARRAY_SIZE(info->carThreshold); i++)
+ info->carThreshold[i] = day->carThreshold[i] * d + night->carThreshold[i] * n;
+ for(i = 0; i < ARRAY_SIZE(info->boatThreshold); i++)
+ info->boatThreshold[i] = day->boatThreshold[i] * d + night->boatThreshold[i] * n;
+ for(i = 0; i < ARRAY_SIZE(info->gangThreshold); i++)
+ info->gangThreshold[i] = day->gangThreshold[i] * d + night->gangThreshold[i] * n;
+ info->copThreshold = day->copThreshold * d + night->copThreshold * n;
info->pedDensity = day->pedDensity * d + night->pedDensity * n;
- info->copDensity = day->copDensity * d + night->copDensity * n;
- info->gangDensity[0] = day->gangDensity[0] * d + night->gangDensity[0] * n;
- info->gangDensity[1] = day->gangDensity[1] * d + night->gangDensity[1] * n;
- info->gangDensity[2] = day->gangDensity[2] * d + night->gangDensity[2] * n;
- info->gangDensity[3] = day->gangDensity[3] * d + night->gangDensity[3] * n;
- info->gangDensity[4] = day->gangDensity[4] * d + night->gangDensity[4] * n;
- info->gangDensity[5] = day->gangDensity[5] * d + night->gangDensity[5] * n;
- info->gangDensity[6] = day->gangDensity[6] * d + night->gangDensity[6] * n;
- info->gangDensity[7] = day->gangDensity[7] * d + night->gangDensity[7] * n;
- info->gangDensity[8] = day->gangDensity[8] * d + night->gangDensity[8] * n;
+ info->copPedThreshold = day->copPedThreshold * d + night->copPedThreshold * n;
+ for(i = 0; i < ARRAY_SIZE(info->gangPedThreshold); i++)
+ info->gangPedThreshold[i] = day->gangPedThreshold[i] * d + night->gangPedThreshold[i] * n;
}
if(CClock::GetIsTimeInRange(5, 19))
info->pedGroup = day->pedGroup;
else
info->pedGroup = night->pedGroup;
-
- CheckZoneInfo(info);
}
void
CTheZones::SetZoneCarInfo(uint16 zoneid, uint8 day, int16 carDensity,
- int16 gang0Num, int16 gang1Num, int16 gang2Num,
- int16 gang3Num, int16 gang4Num, int16 gang5Num,
- int16 gang6Num, int16 gang7Num, int16 gang8Num,
- int16 copNum,
- int16 car0Num, int16 car1Num, int16 car2Num,
- int16 car3Num, int16 car4Num, int16 car5Num)
+ int16 copCarDensity, const int16 *gangCarDensities)
{
CZone *zone;
CZoneInfo *info;
- zone = GetZone(zoneid);
+ zone = GetInfoZone(zoneid);
info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight];
- CheckZoneInfo(info);
-
- if(carDensity != -1) info->carDensity = carDensity;
- int16 oldCar1Num = info->carThreshold[1] - info->carThreshold[0];
- int16 oldCar2Num = info->carThreshold[2] - info->carThreshold[1];
- int16 oldCar3Num = info->carThreshold[3] - info->carThreshold[2];
- int16 oldCar4Num = info->carThreshold[4] - info->carThreshold[3];
- int16 oldCar5Num = info->carThreshold[5] - info->carThreshold[4];
- int16 oldCopNum = info->copThreshold - info->carThreshold[5];
- int16 oldGang0Num = info->gangThreshold[0] - info->copThreshold;
- int16 oldGang1Num = info->gangThreshold[1] - info->gangThreshold[0];
- int16 oldGang2Num = info->gangThreshold[2] - info->gangThreshold[1];
- int16 oldGang3Num = info->gangThreshold[3] - info->gangThreshold[2];
- int16 oldGang4Num = info->gangThreshold[4] - info->gangThreshold[3];
- int16 oldGang5Num = info->gangThreshold[5] - info->gangThreshold[4];
- int16 oldGang6Num = info->gangThreshold[6] - info->gangThreshold[5];
- int16 oldGang7Num = info->gangThreshold[7] - info->gangThreshold[6];
- int16 oldGang8Num = info->gangThreshold[8] - info->gangThreshold[7];
-
- if(car0Num != -1) info->carThreshold[0] = car0Num;
- if(car1Num != -1) info->carThreshold[1] = info->carThreshold[0] + car1Num;
- else info->carThreshold[1] = info->carThreshold[0] + oldCar1Num;
- if(car2Num != -1) info->carThreshold[2] = info->carThreshold[1] + car2Num;
- else info->carThreshold[2] = info->carThreshold[1] + oldCar2Num;
- if(car3Num != -1) info->carThreshold[3] = info->carThreshold[2] + car3Num;
- else info->carThreshold[3] = info->carThreshold[2] + oldCar3Num;
- if(car4Num != -1) info->carThreshold[4] = info->carThreshold[3] + car4Num;
- else info->carThreshold[4] = info->carThreshold[3] + oldCar4Num;
- if(car5Num != -1) info->carThreshold[5] = info->carThreshold[4] + car5Num;
- else info->carThreshold[5] = info->carThreshold[4] + oldCar5Num;
- if(copNum != -1) info->copThreshold = info->carThreshold[5] + copNum;
- else info->copThreshold = info->carThreshold[5] + oldCopNum;
- if(gang0Num != -1) info->gangThreshold[0] = info->copThreshold + gang0Num;
- else info->gangThreshold[0] = info->copThreshold + oldGang0Num;
- if(gang1Num != -1) info->gangThreshold[1] = info->gangThreshold[0] + gang1Num;
- else info->gangThreshold[1] = info->gangThreshold[0] + oldGang1Num;
- if(gang2Num != -1) info->gangThreshold[2] = info->gangThreshold[1] + gang2Num;
- else info->gangThreshold[2] = info->gangThreshold[1] + oldGang2Num;
- if(gang3Num != -1) info->gangThreshold[3] = info->gangThreshold[2] + gang3Num;
- else info->gangThreshold[3] = info->gangThreshold[2] + oldGang3Num;
- if(gang4Num != -1) info->gangThreshold[4] = info->gangThreshold[3] + gang4Num;
- else info->gangThreshold[4] = info->gangThreshold[3] + oldGang4Num;
- if(gang5Num != -1) info->gangThreshold[5] = info->gangThreshold[4] + gang5Num;
- else info->gangThreshold[5] = info->gangThreshold[4] + oldGang5Num;
- if(gang6Num != -1) info->gangThreshold[6] = info->gangThreshold[5] + gang6Num;
- else info->gangThreshold[6] = info->gangThreshold[5] + oldGang6Num;
- if(gang7Num != -1) info->gangThreshold[7] = info->gangThreshold[6] + gang7Num;
- else info->gangThreshold[7] = info->gangThreshold[6] + oldGang7Num;
- if(gang8Num != -1) info->gangThreshold[8] = info->gangThreshold[7] + gang8Num;
- else info->gangThreshold[8] = info->gangThreshold[7] + oldGang8Num;
-
- CheckZoneInfo(info);
+ info->carDensity = carDensity;
+ info->copThreshold = copCarDensity;
+ info->gangThreshold[0] = gangCarDensities[0] + copCarDensity;
+ info->gangThreshold[1] = gangCarDensities[1] + info->gangThreshold[0];
+ info->gangThreshold[2] = gangCarDensities[2] + info->gangThreshold[1];
+ info->gangThreshold[3] = gangCarDensities[3] + info->gangThreshold[2];
+ info->gangThreshold[4] = gangCarDensities[4] + info->gangThreshold[3];
+ info->gangThreshold[5] = gangCarDensities[5] + info->gangThreshold[4];
+ info->gangThreshold[6] = gangCarDensities[6] + info->gangThreshold[5];
+ info->gangThreshold[7] = gangCarDensities[7] + info->gangThreshold[6];
+ info->gangThreshold[8] = gangCarDensities[8] + info->gangThreshold[7];
+}
+
+void CTheZones::SetZoneCivilianCarInfo(uint16 zoneid, uint8 day,
+ const int16* carDensities, const int16* boatDensities)
+{
+ CZone* zone;
+ CZoneInfo* info;
+ zone = GetInfoZone(zoneid);
+ info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight];
+ info->carThreshold[0] = carDensities[0];
+ for (int i = 1; i < CCarCtrl::NUM_CAR_CLASSES; i++)
+ info->carThreshold[i] = carDensities[i] + info->carThreshold[i-1];
+ info->boatThreshold[0] = boatDensities[0];
+ for (int i = 1; i < CCarCtrl::NUM_BOAT_CLASSES; i++)
+ info->boatThreshold[i] = boatDensities[i] + info->boatThreshold[i - 1];
}
void
@@ -515,48 +525,59 @@ CTheZones::SetZonePedInfo(uint16 zoneid, uint8 day, int16 pedDensity,
{
CZone *zone;
CZoneInfo *info;
- zone = GetZone(zoneid);
+ zone = GetInfoZone(zoneid);
info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight];
- if(pedDensity != -1) info->pedDensity = pedDensity;
- if(copDensity != -1) info->copDensity = copDensity;
- if(gang0Density != -1) info->gangDensity[0] = gang0Density;
- if(gang1Density != -1) info->gangDensity[1] = gang1Density;
- if(gang2Density != -1) info->gangDensity[2] = gang2Density;
- if(gang3Density != -1) info->gangDensity[3] = gang3Density;
- if(gang4Density != -1) info->gangDensity[4] = gang4Density;
- if(gang5Density != -1) info->gangDensity[5] = gang5Density;
- if(gang6Density != -1) info->gangDensity[6] = gang6Density;
- if(gang7Density != -1) info->gangDensity[7] = gang7Density;
- if(gang8Density != -1) info->gangDensity[8] = gang8Density;
+ info->pedDensity = pedDensity;
+ info->copPedThreshold = copDensity;
+ info->gangPedThreshold[0] = gang0Density;
+ info->gangPedThreshold[1] = gang1Density;
+ info->gangPedThreshold[2] = gang2Density;
+ info->gangPedThreshold[3] = gang3Density;
+ info->gangPedThreshold[4] = gang4Density;
+ info->gangPedThreshold[5] = gang5Density;
+ info->gangPedThreshold[6] = gang6Density;
+ info->gangPedThreshold[7] = gang7Density;
+ info->gangPedThreshold[8] = gang8Density;
+
+ info->gangPedThreshold[0] += info->copPedThreshold;
+ info->gangPedThreshold[1] = info->gangPedThreshold[0];
+ info->gangPedThreshold[2] = info->gangPedThreshold[1];
+ info->gangPedThreshold[3] = info->gangPedThreshold[2];
+ info->gangPedThreshold[4] = info->gangPedThreshold[3];
+ info->gangPedThreshold[5] = info->gangPedThreshold[4];
+ info->gangPedThreshold[6] = info->gangPedThreshold[5];
+ info->gangPedThreshold[7] = info->gangPedThreshold[6];
+ info->gangPedThreshold[8] = info->gangPedThreshold[7];
}
+//--MIAMI: done, unused
void
CTheZones::SetCarDensity(uint16 zoneid, uint8 day, uint16 cardensity)
{
CZone *zone;
- zone = GetZone(zoneid);
- if(IsNormalZone(zone->type))
- ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].carDensity = cardensity;
+ zone = GetInfoZone(zoneid);
+ ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].carDensity = cardensity;
}
+//--MIAMI: done, unused
void
CTheZones::SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity)
{
CZone *zone;
- zone = GetZone(zoneid);
- if(IsNormalZone(zone->type))
- ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedDensity = peddensity;
+ zone = GetInfoZone(zoneid);
+ ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedDensity = peddensity;
}
+//--MIAMI: done
void
CTheZones::SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup)
{
CZone *zone;
- zone = GetZone(zoneid);
- if(IsNormalZone(zone->type))
- ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedGroup = pedgroup;
+ zone = GetInfoZone(zoneid);
+ ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedGroup = pedgroup;
}
+//--MIAMI: done
int16
CTheZones::FindAudioZone(CVector *pos)
{
@@ -568,18 +589,7 @@ CTheZones::FindAudioZone(CVector *pos)
return -1;
}
-eLevelName
-CTheZones::FindZoneForPoint(const CVector &pos)
-{
- if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("IND_ZON"))))
- return LEVEL_INDUSTRIAL;
- if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("COM_ZON"))))
- return LEVEL_COMMERCIAL;
- if(PointLiesWithinZone(&pos, GetZone(FindZoneByLabelAndReturnIndex("SUB_ZON"))))
- return LEVEL_SUBURBAN;
- return LEVEL_NONE;
-}
-
+//--MIAMI: done
void
CTheZones::AddZoneToAudioZoneArray(CZone *zone)
{
@@ -590,12 +600,14 @@ CTheZones::AddZoneToAudioZoneArray(CZone *zone)
/* This is a bit stupid */
z = -1;
- for(i = 0; i < NUMZONES; i++)
- if(&ZoneArray[i] == zone)
+ for(i = 0; i < NUMNAVIGZONES; i++)
+ if(&NavigationZoneArray[i] == zone)
z = i;
+ assert(NumberOfAudioZones < NUMAUDIOZONES);
AudioZoneArray[NumberOfAudioZones++] = z;
}
+//--MIAMI: done
void
CTheZones::InitialiseAudioZoneArray(void)
{
@@ -603,7 +615,7 @@ CTheZones::InitialiseAudioZoneArray(void)
CZone *zone;
gonext = false;
- zone = &ZoneArray[0];
+ zone = &NavigationZoneArray[0];
// Go deep first,
// set gonext when backing up a level to visit the next child
while(zone)
@@ -627,6 +639,7 @@ CTheZones::InitialiseAudioZoneArray(void)
}
}
+//--MIAMI: TODO
void
CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
{
@@ -634,32 +647,39 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
int i;
*size = SAVE_HEADER_SIZE
- + sizeof(int32) // GetIndexForZonePointer
+ sizeof(m_CurrLevel) + sizeof(FindIndex)
+ sizeof(int16) // padding
- + sizeof(ZoneArray) + sizeof(ZoneInfoArray)
- + sizeof(TotalNumberOfZones) + sizeof(TotalNumberOfZoneInfos)
+ + sizeof(NavigationZoneArray) + sizeof(InfoZoneArray) + sizeof(ZoneInfoArray)
+ + sizeof(TotalNumberOfNavigationZones) + sizeof(TotalNumberOfInfoZones) + sizeof(TotalNumberOfZoneInfos)
+ sizeof(MapZoneArray) + sizeof(AudioZoneArray)
+ sizeof(TotalNumberOfMapZones) + sizeof(NumberOfAudioZones);
WriteSaveHeader(buffer, 'Z', 'N', 'S', '\0', *size - SAVE_HEADER_SIZE);
- WriteSaveBuf(buffer, GetIndexForZonePointer(m_pPlayersZone));
WriteSaveBuf(buffer, m_CurrLevel);
WriteSaveBuf(buffer, FindIndex);
WriteSaveBuf(buffer, (int16)0); // padding
- for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){
- CZone *zone = WriteSaveBuf(buffer, ZoneArray[i]);
- zone->child = (CZone*)GetIndexForZonePointer(ZoneArray[i].child);
- zone->parent = (CZone*)GetIndexForZonePointer(ZoneArray[i].parent);
- zone->next = (CZone*)GetIndexForZonePointer(ZoneArray[i].next);
+// TODO(MIAMI): implement SaveOneZone
+ for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++){
+ CZone *zone = WriteSaveBuf(buffer, NavigationZoneArray[i]);
+ zone->child = (CZone*)GetIndexForZonePointer(NavigationZoneArray[i].child);
+ zone->parent = (CZone*)GetIndexForZonePointer(NavigationZoneArray[i].parent);
+ zone->next = (CZone*)GetIndexForZonePointer(NavigationZoneArray[i].next);
+ }
+
+ for(i = 0; i < ARRAY_SIZE(InfoZoneArray); i++){
+ CZone *zone = WriteSaveBuf(buffer, InfoZoneArray[i]);
+ zone->child = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].child);
+ zone->parent = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].parent);
+ zone->next = (CZone*)GetIndexForZonePointer(InfoZoneArray[i].next);
}
for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
WriteSaveBuf(buffer, ZoneInfoArray[i]);
- WriteSaveBuf(buffer, TotalNumberOfZones);
+ WriteSaveBuf(buffer, TotalNumberOfNavigationZones);
+ WriteSaveBuf(buffer, TotalNumberOfInfoZones);
WriteSaveBuf(buffer, TotalNumberOfZoneInfos);
for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++) {
@@ -687,6 +707,7 @@ CTheZones::SaveAllZones(uint8 *buffer, uint32 *size)
VALIDATESAVEBUF(*size)
}
+//--MIAMI: TODO
void
CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
{
@@ -695,23 +716,32 @@ CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
CheckSaveHeader(buffer, 'Z', 'N', 'S', '\0', size - SAVE_HEADER_SIZE);
- m_pPlayersZone = GetPointerForZoneIndex(ReadSaveBuf<int32>(buffer));
m_CurrLevel = ReadSaveBuf<eLevelName>(buffer);
FindIndex = ReadSaveBuf<int16>(buffer);
ReadSaveBuf<int16>(buffer);
- for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){
- ZoneArray[i] = ReadSaveBuf<CZone>(buffer);
+// TODO(MIAMI): implement LoadOneZone
+ for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++){
+ NavigationZoneArray[i] = ReadSaveBuf<CZone>(buffer);
+
+ NavigationZoneArray[i].child = GetPointerForZoneIndex((int32)NavigationZoneArray[i].child);
+ NavigationZoneArray[i].parent = GetPointerForZoneIndex((int32)NavigationZoneArray[i].parent);
+ NavigationZoneArray[i].next = GetPointerForZoneIndex((int32)NavigationZoneArray[i].next);
+ }
+
+ for(i = 0; i < ARRAY_SIZE(InfoZoneArray); i++){
+ InfoZoneArray[i] = ReadSaveBuf<CZone>(buffer);
- ZoneArray[i].child = GetPointerForZoneIndex((int32)ZoneArray[i].child);
- ZoneArray[i].parent = GetPointerForZoneIndex((int32)ZoneArray[i].parent);
- ZoneArray[i].next = GetPointerForZoneIndex((int32)ZoneArray[i].next);
+ InfoZoneArray[i].child = GetPointerForZoneIndex((int32)InfoZoneArray[i].child);
+ InfoZoneArray[i].parent = GetPointerForZoneIndex((int32)InfoZoneArray[i].parent);
+ InfoZoneArray[i].next = GetPointerForZoneIndex((int32)InfoZoneArray[i].next);
}
for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
ZoneInfoArray[i] = ReadSaveBuf<CZoneInfo>(buffer);
- TotalNumberOfZones = ReadSaveBuf<int16>(buffer);
+ TotalNumberOfNavigationZones = ReadSaveBuf<int16>(buffer);
+ TotalNumberOfInfoZones = ReadSaveBuf<int16>(buffer);
TotalNumberOfZoneInfos = ReadSaveBuf<int16>(buffer);
for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++){
diff --git a/src/core/Zones.h b/src/core/Zones.h
index 67800569..8d5af182 100644
--- a/src/core/Zones.h
+++ b/src/core/Zones.h
@@ -2,6 +2,7 @@
#include "Game.h"
#include "Gangs.h"
+#include "CarCtrl.h"
enum eZoneType
{
@@ -37,31 +38,33 @@ class CZoneInfo
public:
// Car data
int16 carDensity;
- int16 carThreshold[6];
- int16 copThreshold;
+ int16 carThreshold[CCarCtrl::NUM_CAR_CLASSES];
+ int16 boatThreshold[CCarCtrl::NUM_BOAT_CLASSES];
int16 gangThreshold[NUM_GANGS];
+ int16 copThreshold;
// Ped data
uint16 pedDensity;
- uint16 copDensity;
- uint16 gangDensity[NUM_GANGS];
+ uint16 gangPedThreshold[NUM_GANGS];
+ uint16 copPedThreshold;
uint16 pedGroup;
};
class CTheZones
{
- static CZone *m_pPlayersZone;
static int16 FindIndex;
static uint16 NumberOfAudioZones;
static int16 AudioZoneArray[NUMAUDIOZONES];
static uint16 TotalNumberOfMapZones;
- static uint16 TotalNumberOfZones;
- static CZone ZoneArray[NUMZONES];
+ static uint16 TotalNumberOfInfoZones;
+ static uint16 TotalNumberOfNavigationZones;
+ static CZone InfoZoneArray[NUMINFOZONES];
static CZone MapZoneArray[NUMMAPZONES];
+ static CZone NavigationZoneArray[NUMNAVIGZONES];
static uint16 TotalNumberOfZoneInfos;
- static CZoneInfo ZoneInfoArray[2*NUMZONES];
+ static CZoneInfo ZoneInfoArray[2*NUMINFOZONES];
public:
static eLevelName m_CurrLevel;
@@ -71,31 +74,27 @@ public:
float minx, float miny, float minz,
float maxx, float maxy, float maxz,
eLevelName level);
- static void CreateMapZone(char *name, eZoneType type,
- float minx, float miny, float minz,
- float maxx, float maxy, float maxz,
- eLevelName level);
- static CZone *GetZone(uint16 i) { return &ZoneArray[i]; }
- static CZone *GetAudioZone(uint16 i) { return &ZoneArray[AudioZoneArray[i]]; }
+ static CZone *GetInfoZone(uint16 i) { return &InfoZoneArray[i]; }
+ static CZone *GetNavigationZone(uint16 i) { return &NavigationZoneArray[i]; }
+ static CZone *GetMapZone(uint16 i) { return &MapZoneArray[i]; }
+ static CZone *GetAudioZone(uint16 i) { return &InfoZoneArray[AudioZoneArray[i]]; }
static void PostZoneCreation(void);
+ static void CheckZonesForOverlap(void);
static void InsertZoneIntoZoneHierarchy(CZone *zone);
static bool InsertZoneIntoZoneHierRecursive(CZone *z1, CZone *z2);
static bool ZoneIsEntirelyContainedWithinOtherZone(CZone *z1, CZone *z2);
static bool PointLiesWithinZone(const CVector *v, CZone *zone);
static eLevelName GetLevelFromPosition(const CVector *v);
- static CZone *FindSmallestZonePosition(const CVector *v);
- static CZone *FindSmallestZonePositionType(const CVector *v, eZoneType type);
- static CZone *FindSmallestZonePositionILN(const CVector *v);
- static int16 FindZoneByLabelAndReturnIndex(char *name);
+ static CZone *FindInformationZoneForPosition(const CVector *v);
+ static CZone *FindSmallestNavigationZoneForPosition(const CVector *v, bool findDefault, bool findNavig);
+ static int16 FindZoneByLabelAndReturnIndex(char *name, eZoneType type);
+ static int16 FindNextZoneByLabelAndReturnIndex(char *name, eZoneType type);
static CZoneInfo *GetZoneInfo(const CVector *v, uint8 day);
static void GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info);
static void SetZoneCarInfo(uint16 zoneid, uint8 day, int16 carDensity,
- int16 gang0Num, int16 gang1Num, int16 gang2Num,
- int16 gang3Num, int16 gang4Num, int16 gang5Num,
- int16 gang6Num, int16 gang7Num, int16 gang8Num,
- int16 copNum,
- int16 car0Num, int16 car1Num, int16 car2Num,
- int16 car3Num, int16 car4Num, int16 car5Num);
+ int16 copCarDensity, const int16 *gangCarDensities /*[NUMGANGS]*/);
+ static void SetZoneCivilianCarInfo(uint16 zoneid, uint8 day,
+ const int16* carDensities, const int16* boatDensities);
static void SetZonePedInfo(uint16 zoneid, uint8 day, int16 pedDensity,
int16 gang0Density, int16 gang1Density, int16 gang2Density, int16 gang3Density,
int16 gang4Density, int16 gang5Density, int16 gang6Density, int16 gang7Density,
@@ -104,9 +103,8 @@ public:
static void SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity);
static void SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup);
static int16 FindAudioZone(CVector *pos);
- static eLevelName FindZoneForPoint(const CVector &pos);
- static CZone *GetPointerForZoneIndex(int32 i) { return i == -1 ? nil : &ZoneArray[i]; }
- static int32 GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - ZoneArray; }
+ static CZone *GetPointerForZoneIndex(int32 i) { return i == -1 ? nil : &InfoZoneArray[i]; }
+ static int32 GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - InfoZoneArray; }
static void AddZoneToAudioZoneArray(CZone *zone);
static void InitialiseAudioZoneArray(void);
static void SaveAllZones(uint8 *buffer, uint32 *length);
diff --git a/src/core/common.h b/src/core/common.h
index ff8580a1..8f400a46 100644
--- a/src/core/common.h
+++ b/src/core/common.h
@@ -187,6 +187,7 @@ public:
#if (defined(_MSC_VER))
extern int strcasecmp(const char *str1, const char *str2);
+extern int strncasecmp(const char *str1, const char *str2, size_t len);
#endif
#define clamp(v, low, high) ((v)<(low) ? (low) : (v)>(high) ? (high) : (v))
diff --git a/src/core/config.h b/src/core/config.h
index 20e5d679..dd4628d5 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -3,51 +3,51 @@
enum Config {
NUMPLAYERS = 1,
- NUMCDIMAGES = 12, // gta3.img duplicates (not used on PC)
+ NUMCDIMAGES = 6, // gta3.img duplicates (not used on PC)
MAX_CDIMAGES = 8, // additional cdimages
MAX_CDCHANNELS = 5,
- MODELINFOSIZE = 5500,
- TXDSTORESIZE = 850,
- EXTRADIRSIZE = 128,
+ MODELINFOSIZE = 6500,
+ TXDSTORESIZE = 1385,
+ COLSTORESIZE = 31,
+ EXTRADIRSIZE = 256,
CUTSCENEDIRSIZE = 512,
- SIMPLEMODELSIZE = 5000,
- MLOMODELSIZE = 1,
- MLOINSTANCESIZE = 1,
- TIMEMODELSIZE = 30,
+ SIMPLEMODELSIZE = 3885,
+ TIMEMODELSIZE = 385,
CLUMPMODELSIZE = 5,
- PEDMODELSIZE = 90,
- VEHICLEMODELSIZE = 120,
- XTRACOMPSMODELSIZE = 2,
- TWODFXSIZE = 2000,
+ WEAPONMODELSIZE = 37,
+ PEDMODELSIZE = 130,
+ VEHICLEMODELSIZE = 110,
+ TWODFXSIZE = 1210,
MAXVEHICLESLOADED = 50, // 70 on mobile
- NUMOBJECTINFO = 168, // object.dat
+ NUMOBJECTINFO = 400, // TODO(MIAMI): fantasy // object.dat
// Pool sizes
- NUMPTRNODES = 30000, // 26000 on PS2
- NUMENTRYINFOS = 5400, // 3200 on PS2
- NUMPEDS = 140, // 90 on PS2
- NUMVEHICLES = 110, // 70 on PS2
- NUMBUILDINGS = 5500, // 4915 on PS2
- NUMTREADABLES = 1214,
- NUMOBJECTS = 450,
- NUMDUMMIES = 2802, // 2368 on PS2
- NUMAUDIOSCRIPTOBJECTS = 256,
- NUMCUTSCENEOBJECTS = 50,
-
- NUMANIMBLOCKS = 2,
- NUMANIMATIONS = 250,
+ NUMPTRNODES = 50000,
+ NUMENTRYINFOS = 5400, // only 3200 in VC???
+ NUMPEDS = 140,
+ NUMVEHICLES = 110,
+ NUMBUILDINGS = 7000,
+ NUMTREADABLES = 1214, // 1 in VC
+ NUMOBJECTS = 460,
+ NUMDUMMIES = 2802, // 2340 in VC
+ NUMAUDIOSCRIPTOBJECTS = 256, // 192 in VC
+ NUMCUTSCENEOBJECTS = 50, // does not exist in VC
+ // TODO(MIAMI): colmodel pool
+
+ NUMANIMBLOCKS = 35,
+ NUMANIMATIONS = 450,
NUMTEMPOBJECTS = 30,
// Path data
- NUM_PATHNODES = 4930,
- NUM_CARPATHLINKS = 2076,
+ NUM_PATHNODES = 9650,
+ NUM_CARPATHLINKS = 3500,
NUM_MAPOBJECTS = 1250,
- NUM_PATHCONNECTIONS = 10260,
+ NUM_PATHCONNECTIONS = 20400,
// Link list lengths
NUMALPHALIST = 20,
@@ -56,20 +56,19 @@ enum Config {
NUMREFERENCES = 800,
// Zones
- NUMAUDIOZONES = 36,
- NUMZONES = 50,
- NUMMAPZONES = 25,
+ NUMAUDIOZONES = 14,
+ NUMINFOZONES = 169,
+ NUMMAPZONES = 39,
+ NUMNAVIGZONES = 20,
// Cull zones
- NUMCULLZONES = 512,
- NUMATTRIBZONES = 288,
- NUMZONEINDICES = 55000,
+ NUMATTRIBZONES = 704,
- NUMHANDLINGS = 57,
+ NUMHANDLINGS = 106,
PATHNODESIZE = 4500,
- NUMWEATHERS = 4,
+ NUMWEATHERS = 7,
NUMHOURS = 24,
NUMEXTRADIRECTIONALS = 4,
@@ -109,11 +108,11 @@ enum Config {
NUMPEDROUTES = 200,
NUMPHONES = 50,
- NUMPEDGROUPS = 31,
- NUMMODELSPERPEDGROUP = 8,
+ NUMPEDGROUPS = 67,
+ NUMMODELSPERPEDGROUP = 16,
NUMSHOTINFOS = 100,
- NUMROADBLOCKS = 600,
+ NUMROADBLOCKS = 300,
NUMVISIBLEENTITIES = 2000,
NUMINVISIBLEENTITIES = 150,
diff --git a/src/core/main.cpp b/src/core/main.cpp
index 37a5673f..6bf8228d 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -1138,7 +1138,7 @@ void
InitialiseGame(void)
{
LoadingScreen(nil, nil, "loadsc0");
- CGame::Initialise("DATA\\GTA3.DAT");
+ CGame::Initialise("DATA\\GTA_VC.DAT");
}
RsEventStatus
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index 2c07836a..a2c0a9a3 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -194,11 +194,17 @@ ResetCamStatics(void)
}
static const char *carnames[] = {
- "landstal", "idaho", "stinger", "linerun", "peren", "sentinel", "patriot", "firetruk", "trash", "stretch", "manana", "infernus", "blista", "pony",
- "mule", "cheetah", "ambulan", "fbicar", "moonbeam", "esperant", "taxi", "kuruma", "bobcat", "mrwhoop", "bfinject", "corpse", "police", "enforcer",
- "securica", "banshee", "predator", "bus", "rhino", "barracks", "train", "chopper", "dodo", "coach", "cabbie", "stallion", "rumpo", "rcbandit",
- "bellyup", "mrwongs", "mafia", "yardie", "yakuza", "diablos", "columb", "hoods", "airtrain", "deaddodo", "speeder", "reefer", "panlant", "flatbed",
- "yankee", "escape", "borgnine", "toyz", "ghost",
+ "landstal", "idaho", "stinger", "linerun", "peren", "sentinel", "rio", "firetruk", "trash", "stretch", "manana",
+ "infernus", "voodoo", "pony", "mule", "cheetah", "ambulan", "fbicar", "moonbeam", "esperant", "taxi", "washing",
+ "bobcat", "mrwhoop", "bfinject", "hunter", "police", "enforcer", "securica", "banshee", "predator", "bus",
+ "rhino", "barracks", "cuban", "chopper", "angel", "coach", "cabbie", "stallion", "rumpo", "rcbandit", "romero",
+ "packer", "sentxs", "admiral", "squalo", "seaspar", "pizzaboy", "gangbur", "airtrain", "deaddodo", "speeder",
+ "reefer", "tropic", "flatbed", "yankee", "caddy", "zebra", "topfun", "skimmer", "pcj600", "faggio", "freeway",
+ "rcbaron", "rcraider", "glendale", "oceanic", "sanchez", "sparrow", "patriot", "lovefist", "coastg", "dinghy",
+ "hermes", "sabre", "sabretur", "pheonix", "walton", "regina", "comet", "deluxo", "burrito", "spand", "marquis",
+ "baggage", "kaufman", "maverick", "vcnmav", "rancher", "fbiranch", "virgo", "greenwoo", "jetmax", "hotring",
+ "sandking", "blistac", "polmav", "boxville", "benson", "mesa", "rcgoblin", "hotrina", "hotrinb",
+ "bloodra", "bloodrb", "vicechee"
};
static std::list<CTweakVar *> TweakVarsList;
@@ -293,14 +299,12 @@ DebugMenuPopulate(void)
DebugMenuAddCmd("Cheats", "Nasty limbs", NastyLimbsCheat);
static int spawnCarId = MI_LANDSTAL;
- e = DebugMenuAddVar("Spawn", "Spawn Car ID", &spawnCarId, nil, 1, MI_LANDSTAL, MI_GHOST, carnames);
+ e = DebugMenuAddVar("Spawn", "Spawn Car ID", &spawnCarId, nil, 1, MI_LANDSTAL, MI_VICECHEE, carnames);
DebugMenuEntrySetWrap(e, true);
DebugMenuAddCmd("Spawn", "Spawn Car", [](){
- if(spawnCarId == MI_TRAIN ||
- spawnCarId == MI_CHOPPER ||
+ if(spawnCarId == MI_CHOPPER ||
spawnCarId == MI_AIRTRAIN ||
- spawnCarId == MI_DEADDODO ||
- spawnCarId == MI_ESCAPE)
+ spawnCarId == MI_DEADDODO)
return;
SpawnCar(spawnCarId);
});
@@ -312,13 +316,13 @@ DebugMenuPopulate(void)
DebugMenuAddCmd("Spawn", "Spawn Cheetah", [](){ SpawnCar(MI_CHEETAH); });
DebugMenuAddCmd("Spawn", "Spawn Esperanto", [](){ SpawnCar(MI_ESPERANT); });
DebugMenuAddCmd("Spawn", "Spawn Stallion", [](){ SpawnCar(MI_STALLION); });
- DebugMenuAddCmd("Spawn", "Spawn Kuruma", [](){ SpawnCar(MI_KURUMA); });
+ DebugMenuAddCmd("Spawn", "Spawn Washington", [](){ SpawnCar(MI_WASHING); });
DebugMenuAddCmd("Spawn", "Spawn Taxi", [](){ SpawnCar(MI_TAXI); });
DebugMenuAddCmd("Spawn", "Spawn Police", [](){ SpawnCar(MI_POLICE); });
DebugMenuAddCmd("Spawn", "Spawn Enforcer", [](){ SpawnCar(MI_ENFORCER); });
DebugMenuAddCmd("Spawn", "Spawn Banshee", [](){ SpawnCar(MI_BANSHEE); });
- DebugMenuAddCmd("Spawn", "Spawn Yakuza", [](){ SpawnCar(MI_YAKUZA); });
- DebugMenuAddCmd("Spawn", "Spawn Yardie", [](){ SpawnCar(MI_YARDIE); });
+ DebugMenuAddCmd("Spawn", "Spawn Cuban", [](){ SpawnCar(MI_CUBAN); });
+ DebugMenuAddCmd("Spawn", "Spawn Voodoo", [](){ SpawnCar(MI_VOODOO); });
DebugMenuAddCmd("Spawn", "Spawn Dodo", [](){ SpawnCar(MI_DODO); });
DebugMenuAddCmd("Spawn", "Spawn Rhino", [](){ SpawnCar(MI_RHINO); });
DebugMenuAddCmd("Spawn", "Spawn Firetruck", [](){ SpawnCar(MI_FIRETRUCK); });
@@ -334,8 +338,6 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Render", "Show Ped Paths", &gbShowPedPaths, nil);
DebugMenuAddVarBool8("Render", "Show Car Paths", &gbShowCarPaths, nil);
DebugMenuAddVarBool8("Render", "Show Car Path Links", &gbShowCarPathsLinks, nil);
- DebugMenuAddVarBool8("Render", "Show Ped Road Groups", &gbShowPedRoadGroups, nil);
- DebugMenuAddVarBool8("Render", "Show Car Road Groups", &gbShowCarRoadGroups, nil);
DebugMenuAddVarBool8("Render", "Show Collision Lines", &gbShowCollisionLines, nil);
DebugMenuAddVarBool8("Render", "Show Collision Polys", &gbShowCollisionPolys, nil);
DebugMenuAddVarBool8("Render", "Don't render Buildings", &gbDontRenderBuildings, nil);
diff --git a/src/core/templates.h b/src/core/templates.h
index 4f7b8490..465e3bef 100644
--- a/src/core/templates.h
+++ b/src/core/templates.h
@@ -44,18 +44,20 @@ class CPool
int m_allocPtr;
public:
+ // TODO(MIAMI): remove ctor without name argument
CPool(int size){
// TODO: use new here
m_entries = (U*)malloc(sizeof(U)*size);
m_flags = (Flags*)malloc(sizeof(Flags)*size);
m_size = size;
- m_allocPtr = 0;
+ m_allocPtr = -1;
for(int i = 0; i < size; i++){
m_flags[i].id = 0;
m_flags[i].free = 1;
}
}
-
+ CPool(int size, const char *name)
+ : CPool(size) {}
~CPool() {
Flush();
}
@@ -131,7 +133,7 @@ public:
// TODO: the cast is unsafe
return (int)((U*)entry - m_entries);
}
- int GetNoOfUsedSpaces(void) const{
+ int GetNoOfUsedSpaces(void) const {
int i;
int n = 0;
for(i = 0; i < m_size; i++)
@@ -162,6 +164,7 @@ public:
memcpy(entries, m_entries, sizeof(U)*m_size);
debug("Stored:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */
}
+ int32 GetNoOfFreeSpaces() const { return GetSize() - GetNoOfUsedSpaces(); }
};
template<typename T>