Merge remote-tracking branch 'upstream/miami' into miami

This commit is contained in:
Nikolay Korolev 2020-05-06 01:11:18 +03:00
commit e5da4c2b4d
27 changed files with 327 additions and 792 deletions

View File

@ -109,7 +109,7 @@ end
project "reVC" project "reVC"
kind "WindowedApp" kind "WindowedApp"
targetname "re3" targetname "reVC"
targetdir "bin/%{cfg.platform}/%{cfg.buildcfg}" targetdir "bin/%{cfg.platform}/%{cfg.buildcfg}"
targetextension ".exe" targetextension ".exe"
characterset ("MBCS") characterset ("MBCS")

View File

@ -156,10 +156,7 @@ void CGarages::Init(void)
AudioEntity = DMAudio.CreateEntity(AUDIOTYPE_GARAGE, (void*)1); AudioEntity = DMAudio.CreateEntity(AUDIOTYPE_GARAGE, (void*)1);
if (AudioEntity >= 0) if (AudioEntity >= 0)
DMAudio.SetEntityStatus(AudioEntity, 1); DMAudio.SetEntityStatus(AudioEntity, 1);
AddOne( // MIAMI: removed crusher
CRUSHER_GARAGE_X1, CRUSHER_GARAGE_Y1, CRUSHER_GARAGE_Z1,
CRUSHER_GARAGE_X2, CRUSHER_GARAGE_Y2, CRUSHER_GARAGE_Z2,
GARAGE_CRUSHER, 0);
} }
#ifndef PS2 #ifndef PS2

View File

@ -302,9 +302,9 @@ CPathFind::RegisterMapObject(CTreadable *mapObject)
m_mapObjects[m_numMapObjects++] = mapObject; m_mapObjects[m_numMapObjects++] = mapObject;
} }
//--MIAMI: TODO: implement all the arguments once we can load the VC map //--MIAMI: done
void void
CPathFind::StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, bool crossing) CPathFind::StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, float width, bool crossing, uint8 spawnRate)
{ {
int i; int i;
@ -314,22 +314,26 @@ CPathFind::StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x,
InfoForTilePeds[i].x = x/16.0f; InfoForTilePeds[i].x = x/16.0f;
InfoForTilePeds[i].y = y/16.0f; InfoForTilePeds[i].y = y/16.0f;
InfoForTilePeds[i].z = z/16.0f; InfoForTilePeds[i].z = z/16.0f;
InfoForTilePeds[i].width = 8.0f*Min(width, 15.0f);
InfoForTilePeds[i].numLeftLanes = 0; InfoForTilePeds[i].numLeftLanes = 0;
InfoForTilePeds[i].numRightLanes = 0; InfoForTilePeds[i].numRightLanes = 0;
InfoForTilePeds[i].crossing = crossing; InfoForTilePeds[i].crossing = crossing;
InfoForTilePeds[i].flag02 = false; InfoForTilePeds[i].speedLimit = 0;
InfoForTilePeds[i].roadBlock = false; InfoForTilePeds[i].roadBlock = false;
InfoForTilePeds[i].disabled = false; InfoForTilePeds[i].disabled = false;
InfoForTilePeds[i].waterPath = false; InfoForTilePeds[i].waterPath = false;
InfoForTilePeds[i].flag02 = false;
InfoForTilePeds[i].betweenLevels = false; InfoForTilePeds[i].betweenLevels = false;
InfoForTilePeds[i].spawnRate = Min(spawnRate, 15);
if(node == 11) if(node == 11)
InfoForTilePeds[id*12].SwapConnectionsToBeRightWayRound(); InfoForTilePeds[id*12].SwapConnectionsToBeRightWayRound();
} }
//--MIAMI: TODO: implement all the arguments once we can load the VC map //--MIAMI: done
void void
CPathFind::StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, int8 numLeft, int8 numRight) CPathFind::StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, float width, int8 numLeft, int8 numRight,
bool disabled, bool betweenLevels, uint8 speedLimit, bool roadBlock, bool waterPath, uint8 spawnRate)
{ {
int i; int i;
@ -339,19 +343,90 @@ CPathFind::StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x,
InfoForTileCars[i].x = x/16.0f; InfoForTileCars[i].x = x/16.0f;
InfoForTileCars[i].y = y/16.0f; InfoForTileCars[i].y = y/16.0f;
InfoForTileCars[i].z = z/16.0f; InfoForTileCars[i].z = z/16.0f;
InfoForTilePeds[i].width = 8.0f*Min(width, 15.0f);
InfoForTileCars[i].numLeftLanes = numLeft; InfoForTileCars[i].numLeftLanes = numLeft;
InfoForTileCars[i].numRightLanes = numRight; InfoForTileCars[i].numRightLanes = numRight;
InfoForTileCars[i].crossing = false; InfoForTilePeds[i].crossing = false;
InfoForTileCars[i].flag02 = false; InfoForTilePeds[i].speedLimit = 0;
InfoForTileCars[i].roadBlock = false; InfoForTilePeds[i].roadBlock = false;
InfoForTileCars[i].disabled = false; InfoForTilePeds[i].disabled = false;
InfoForTileCars[i].waterPath = false; InfoForTilePeds[i].waterPath = false;
InfoForTileCars[i].betweenLevels = false; InfoForTilePeds[i].flag02 = false;
InfoForTilePeds[i].betweenLevels = false;
InfoForTilePeds[i].spawnRate = Min(spawnRate, 15);
if(node == 11) if(node == 11)
InfoForTileCars[id*12].SwapConnectionsToBeRightWayRound(); InfoForTileCars[id*12].SwapConnectionsToBeRightWayRound();
} }
//--MIAMI: done
void
CPathFind::StoreDetachedNodeInfoPed(int32 node, int8 type, int32 next, float x, float y, float z, float width, bool crossing,
bool disabled, bool betweenLevels, uint8 spawnRate)
{
int i;
if(NumDetachedPedNodeGroups >= NUMDETACHED_PEDS)
return;
i = NumDetachedPedNodeGroups*12 + node;
DetachedInfoForTilePeds[i].type = type;
DetachedInfoForTilePeds[i].next = next;
DetachedInfoForTilePeds[i].x = x/16.0f;
DetachedInfoForTilePeds[i].y = y/16.0f;
DetachedInfoForTilePeds[i].z = z/16.0f;
DetachedInfoForTilePeds[i].width = 8.0f*Min(width, 31.0f);
DetachedInfoForTilePeds[i].numLeftLanes = 0;
DetachedInfoForTilePeds[i].numRightLanes = 0;
DetachedInfoForTilePeds[i].crossing = crossing;
DetachedInfoForTilePeds[i].speedLimit = 0;
DetachedInfoForTilePeds[i].roadBlock = false;
DetachedInfoForTilePeds[i].disabled = disabled;
DetachedInfoForTilePeds[i].waterPath = false;
DetachedInfoForTilePeds[i].flag02 = false;
DetachedInfoForTilePeds[i].betweenLevels = betweenLevels;
DetachedInfoForTilePeds[i].spawnRate = Min(spawnRate, 15);
if(node == 11){
DetachedInfoForTilePeds[NumDetachedPedNodeGroups*12].SwapConnectionsToBeRightWayRound();
NumDetachedPedNodeGroups++;
}
}
//--MIAMI: done
void
CPathFind::StoreDetachedNodeInfoCar(int32 node, int8 type, int32 next, float x, float y, float z, float width, int8 numLeft, int8 numRight,
bool disabled, bool betweenLevels, uint8 speedLimit, bool roadBlock, bool waterPath, uint8 spawnRate, bool unk)
{
int i;
if(NumDetachedCarNodeGroups >= NUMDETACHED_CARS)
return;
i = NumDetachedCarNodeGroups*12 + node;
DetachedInfoForTileCars[i].type = type;
DetachedInfoForTileCars[i].next = next;
DetachedInfoForTileCars[i].x = x/16.0f;
DetachedInfoForTileCars[i].y = y/16.0f;
DetachedInfoForTileCars[i].z = z/16.0f;
DetachedInfoForTileCars[i].width = 8.0f*Min(width, 15.0f);
DetachedInfoForTileCars[i].numLeftLanes = numLeft;
DetachedInfoForTileCars[i].numRightLanes = numRight;
DetachedInfoForTileCars[i].crossing = false;
DetachedInfoForTileCars[i].speedLimit = speedLimit;
DetachedInfoForTileCars[i].roadBlock = roadBlock;
DetachedInfoForTileCars[i].disabled = disabled;
DetachedInfoForTileCars[i].waterPath = waterPath;
DetachedInfoForTileCars[i].flag02 = unk;
DetachedInfoForTileCars[i].betweenLevels = betweenLevels;
DetachedInfoForTileCars[i].spawnRate = Min(spawnRate, 15);
if(node == 11){
DetachedInfoForTileCars[NumDetachedCarNodeGroups*12].SwapConnectionsToBeRightWayRound();
NumDetachedCarNodeGroups++;
}
}
//--MIAMI: done //--MIAMI: done
void void
CPathFind::CalcNodeCoors(float x, float y, float z, int id, CVector *out) CPathFind::CalcNodeCoors(float x, float y, float z, int id, CVector *out)

View File

@ -204,8 +204,13 @@ public:
void Init(void); void Init(void);
void AllocatePathFindInfoMem(int16 numPathGroups); void AllocatePathFindInfoMem(int16 numPathGroups);
void RegisterMapObject(CTreadable *mapObject); void RegisterMapObject(CTreadable *mapObject);
void StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, bool crossing); void StoreNodeInfoPed(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, float width, bool crossing, uint8 spawnRate);
void StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, int8 numLeft, int8 numRight); void StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, float width, int8 numLeft, int8 numRight,
bool disabled, bool betweenLevels, uint8 speedLimit, bool roadBlock, bool waterPath, uint8 spawnRate);
void StoreDetachedNodeInfoPed(int32 node, int8 type, int32 next, float x, float y, float z, float width, bool crossing,
bool disabled, bool betweenLevels, uint8 spawnRate);
void StoreDetachedNodeInfoCar(int32 node, int8 type, int32 next, float x, float y, float z, float width, int8 numLeft, int8 numRight,
bool disabled, bool betweenLevels, uint8 speedLimit, bool roadBlock, bool waterPath, uint8 spawnRate, bool unk);
void CalcNodeCoors(float x, float y, float z, int32 id, CVector *out); void CalcNodeCoors(float x, float y, float z, int32 id, CVector *out);
bool LoadPathFindData(void); bool LoadPathFindData(void);
void PreparePathData(void); void PreparePathData(void);

View File

@ -11,503 +11,97 @@
#include "World.h" #include "World.h"
uint16 CRecordDataForGame::RecordingState; uint16 CRecordDataForGame::RecordingState;
uint8* CRecordDataForGame::pDataBuffer;
uint8* CRecordDataForGame::pDataBufferPointer;
int CRecordDataForGame::FId;
tGameBuffer CRecordDataForGame::pDataBufferForFrame;
#define MEMORY_FOR_GAME_RECORD (150000)
void CRecordDataForGame::Init(void) void CRecordDataForGame::Init(void)
{ {
RecordingState = STATE_NONE; RecordingState = STATE_NONE;
delete[] pDataBuffer;
pDataBufferPointer = nil;
pDataBuffer = nil;
#ifndef GTA_PS2 // this stuff is not present on PS2
FId = CFileMgr::OpenFile("playback.dat", "r");
if (FId <= 0) {
if ((FId = CFileMgr::OpenFile("record.dat", "r")) <= 0)
RecordingState = STATE_NONE;
else {
CFileMgr::CloseFile(FId);
FId = CFileMgr::OpenFileForWriting("record.dat");
RecordingState = STATE_RECORD;
}
}
else {
RecordingState = STATE_PLAYBACK;
}
if (RecordingState == STATE_PLAYBACK) {
pDataBufferPointer = new uint8[MEMORY_FOR_GAME_RECORD];
pDataBuffer = pDataBufferPointer;
pDataBuffer[CFileMgr::Read(FId, (char*)pDataBufferPointer, MEMORY_FOR_GAME_RECORD) + 8] = (uint8)-1;
CFileMgr::CloseFile(FId);
}
#else
RecordingState = STATE_NONE; // second time to make sure
#endif
} }
void CRecordDataForGame::SaveOrRetrieveDataForThisFrame(void) void CRecordDataForGame::SaveOrRetrieveDataForThisFrame(void)
{ {
switch (RecordingState) {
case STATE_RECORD:
{
pDataBufferForFrame.m_fTimeStep = CTimer::GetTimeStep();
pDataBufferForFrame.m_nTimeInMilliseconds = CTimer::GetTimeInMilliseconds();
pDataBufferForFrame.m_nSizeOfPads[0] = 0;
pDataBufferForFrame.m_nSizeOfPads[1] = 0;
pDataBufferForFrame.m_nChecksum = CalcGameChecksum();
uint8* pController1 = PackCurrentPadValues(pDataBufferForFrame.m_ControllerBuffer, &CPad::GetPad(0)->OldState, &CPad::GetPad(0)->NewState);
pDataBufferForFrame.m_nSizeOfPads[0] = (pController1 - pDataBufferForFrame.m_ControllerBuffer) / 2;
uint8* pController2 = PackCurrentPadValues(pController1, &CPad::GetPad(1)->OldState, &CPad::GetPad(1)->NewState);
pDataBufferForFrame.m_nSizeOfPads[1] = (pController2 - pController1) / 2;
uint8* pEndPtr = pController2;
if ((pDataBufferForFrame.m_nSizeOfPads[0] + pDataBufferForFrame.m_nSizeOfPads[1]) & 1)
pEndPtr += 2;
CFileMgr::Write(FId, (char*)&pDataBufferForFrame, pEndPtr - (uint8*)&pDataBufferForFrame);
break;
}
case STATE_PLAYBACK:
if (pDataBufferPointer[8] == (uint8)-1)
CPad::GetPad(0)->NewState.Clear();
else {
tGameBuffer* pData = (tGameBuffer*)pDataBufferPointer;
CTimer::SetTimeInMilliseconds(pData->m_nTimeInMilliseconds);
CTimer::SetTimeStep(pData->m_fTimeStep);
uint8 size1 = pData->m_nSizeOfPads[0];
uint8 size2 = pData->m_nSizeOfPads[1];
pDataBufferPointer = (uint8*)&pData->m_ControllerBuffer;
pDataBufferPointer = UnPackCurrentPadValues(pDataBufferPointer, size1, &CPad::GetPad(0)->NewState);
pDataBufferPointer = UnPackCurrentPadValues(pDataBufferPointer, size2, &CPad::GetPad(1)->NewState);
if ((size1 + size2) & 1)
pDataBufferPointer += 2;
if (pData->m_nChecksum != CalcGameChecksum())
printf("Playback out of sync\n");
}
}
} }
#define PROCESS_BUTTON_STATE_STORE(buf, os, ns, field, id) \
do { \
if (os->field != ns->field){ \
*buf++ = id; \
*buf++ = ns->field; \
} \
} while (0);
uint8* CRecordDataForGame::PackCurrentPadValues(uint8* buf, CControllerState* os, CControllerState* ns) uint8* CRecordDataForGame::PackCurrentPadValues(uint8* buf, CControllerState* os, CControllerState* ns)
{ {
PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftStickX, 0); return nil;
PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftStickY, 1);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, RightStickX, 2);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, RightStickY, 3);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftShoulder1, 4);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftShoulder2, 5);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, RightShoulder1, 6);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, RightShoulder2, 7);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, DPadUp, 8);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, DPadDown, 9);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, DPadLeft, 10);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, DPadRight, 11);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, Start, 12);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, Select, 13);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, Square, 14);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, Triangle, 15);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, Cross, 16);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, Circle, 17);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftShock, 18);
PROCESS_BUTTON_STATE_STORE(buf, os, ns, RightShock, 19);
return buf;
} }
#undef PROCESS_BUTTON_STATE_STORE
#define PROCESS_BUTTON_STATE_RESTORE(buf, state, field, id) case id: state->field = *buf++; break;
uint8* CRecordDataForGame::UnPackCurrentPadValues(uint8* buf, uint8 total, CControllerState* state) uint8* CRecordDataForGame::UnPackCurrentPadValues(uint8* buf, uint8 total, CControllerState* state)
{ {
for (uint8 i = 0; i < total; i++) { return nil;
switch (*buf++) {
PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftStickX, 0);
PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftStickY, 1);
PROCESS_BUTTON_STATE_RESTORE(buf, state, RightStickX, 2);
PROCESS_BUTTON_STATE_RESTORE(buf, state, RightStickY, 3);
PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftShoulder1, 4);
PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftShoulder2, 5);
PROCESS_BUTTON_STATE_RESTORE(buf, state, RightShoulder1, 6);
PROCESS_BUTTON_STATE_RESTORE(buf, state, RightShoulder2, 7);
PROCESS_BUTTON_STATE_RESTORE(buf, state, DPadUp, 8);
PROCESS_BUTTON_STATE_RESTORE(buf, state, DPadDown, 9);
PROCESS_BUTTON_STATE_RESTORE(buf, state, DPadLeft, 10);
PROCESS_BUTTON_STATE_RESTORE(buf, state, DPadRight, 11);
PROCESS_BUTTON_STATE_RESTORE(buf, state, Start, 12);
PROCESS_BUTTON_STATE_RESTORE(buf, state, Select, 13);
PROCESS_BUTTON_STATE_RESTORE(buf, state, Square, 14);
PROCESS_BUTTON_STATE_RESTORE(buf, state, Triangle, 15);
PROCESS_BUTTON_STATE_RESTORE(buf, state, Cross, 16);
PROCESS_BUTTON_STATE_RESTORE(buf, state, Circle, 17);
PROCESS_BUTTON_STATE_RESTORE(buf, state, LeftShock, 18);
PROCESS_BUTTON_STATE_RESTORE(buf, state, RightShock, 19);
}
}
return buf;
} }
#undef PROCESS_BUTTON_STATE_RESTORE
uint16 CRecordDataForGame::CalcGameChecksum(void) uint16 CRecordDataForGame::CalcGameChecksum(void)
{ {
uint32 checksum = 0; return 0;
int i = CPools::GetPedPool()->GetSize();
while (i--) {
CPed* pPed = CPools::GetPedPool()->GetSlot(i);
if (!pPed)
continue;
checksum ^= pPed->GetModelIndex() ^ *(uint32*)&pPed->GetPosition().z ^ *(uint32*)&pPed->GetPosition().y ^ *(uint32*)&pPed->GetPosition().x;
}
i = CPools::GetVehiclePool()->GetSize();
while (i--) {
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
if (!pVehicle)
continue;
checksum ^= pVehicle->GetModelIndex() ^ *(uint32*)&pVehicle->GetPosition().z ^ *(uint32*)&pVehicle->GetPosition().y ^ *(uint32*)&pVehicle->GetPosition().x;
}
return checksum ^ checksum >> 16;
} }
uint8 CRecordDataForChase::Status; uint8 CRecordDataForChase::Status;
int CRecordDataForChase::PositionChanges;
uint8 CRecordDataForChase::CurrentCar;
CAutomobile* CRecordDataForChase::pChaseCars[NUM_CHASE_CARS];
uint32 CRecordDataForChase::AnimStartTime;
float CRecordDataForChase::AnimTime;
CCarStateEachFrame* CRecordDataForChase::pBaseMemForCar[NUM_CHASE_CARS];
float CRecordDataForChase::TimeMultiplier;
int CRecordDataForChase::FId2;
#define CHASE_SCENE_LENGTH_IN_SECONDS (80)
#define CHASE_SCENE_FRAMES_PER_SECOND (15) // skipping every second frame
#define CHASE_SCENE_FRAMES_IN_RECORDING (CHASE_SCENE_LENGTH_IN_SECONDS * CHASE_SCENE_FRAMES_PER_SECOND)
#define CHASE_SCENE_LENGTH_IN_FRAMES (CHASE_SCENE_FRAMES_IN_RECORDING * 2)
void CRecordDataForChase::Init(void) void CRecordDataForChase::Init(void)
{ {
Status = STATE_NONE; Status = STATE_NONE;
PositionChanges = 0;
CurrentCar = 0;
for (int i = 0; i < NUM_CHASE_CARS; i++)
pChaseCars[i] = nil;
AnimStartTime = 0;
} }
void CRecordDataForChase::SaveOrRetrieveDataForThisFrame(void) void CRecordDataForChase::SaveOrRetrieveDataForThisFrame(void)
{ {
switch (Status) {
case STATE_NONE:
return;
case STATE_RECORD:
{
if ((CTimer::GetFrameCounter() & 1) == 0)
StoreInfoForCar(pChaseCars[CurrentCar], &pBaseMemForCar[CurrentCar][CTimer::GetFrameCounter() / 2]);
if (CTimer::GetFrameCounter() < CHASE_SCENE_LENGTH_IN_FRAMES * 2)
return;
CFileMgr::SetDir("data\\paths");
sprintf(gString, "chase%d.dat", CurrentCar);
int fid = CFileMgr::OpenFileForWriting(gString);
uint32 fs = CHASE_SCENE_LENGTH_IN_FRAMES * sizeof(CCarStateEachFrame);
printf("FileSize:%d\n", fs);
CFileMgr::Write(fid, (char*)pBaseMemForCar[CurrentCar], fs);
CFileMgr::CloseFile(fid);
CFileMgr::SetDir("");
sprintf(gString, "car%d.max", CurrentCar);
int fid2 = CFileMgr::OpenFileForWriting(gString);
for (int i = 0; i < CHASE_SCENE_FRAMES_IN_RECORDING; i++) {
// WTF? Was it ever used?
#ifdef FIX_BUGS
CCarStateEachFrame* pState = pBaseMemForCar[CurrentCar];
#else
CCarStateEachFrame* pState = (CCarStateEachFrame*)pChaseCars[CurrentCar];
#endif
CVector right = CVector(pState->rightX, pState->rightY, pState->rightZ) / INT8_MAX;
CVector forward = CVector(pState->forwardX, pState->forwardY, pState->forwardZ) / INT8_MAX;
CVector up = CrossProduct(right, forward);
sprintf(gString, "%f %f %f\n", pState->pos.x, pState->pos.y, pState->pos.z);
CFileMgr::Write(fid2, gString, strlen(gString) - 1);
sprintf(gString, "%f %f %f\n", right.x, right.y, right.z);
CFileMgr::Write(fid2, gString, strlen(gString) - 1);
sprintf(gString, "%f %f %f\n", forward.x, forward.y, forward.z);
CFileMgr::Write(fid2, gString, strlen(gString) - 1);
sprintf(gString, "%f %f %f\n", up.x, up.y, up.z);
CFileMgr::Write(fid2, gString, strlen(gString) - 1);
}
CFileMgr::CloseFile(fid2);
}
case STATE_PLAYBACK:
case STATE_PLAYBACK_BEFORE_RECORDING:
case STATE_PLAYBACK_INIT:
break;
}
} }
struct tCoors {
CVector pos;
float angle;
};
// I guess developer was filling this with actual data before running the game
tCoors NewCoorsForRecordedCars[7];
void CRecordDataForChase::SaveOrRetrieveCarPositions(void) void CRecordDataForChase::SaveOrRetrieveCarPositions(void)
{ {
switch (Status) {
case STATE_NONE:
return;
case STATE_RECORD:
case STATE_PLAYBACK_BEFORE_RECORDING:
for (int i = 0; i < NUM_CHASE_CARS; i++) {
if (i != CurrentCar && CTimer::GetFrameCounter()) {
RestoreInfoForCar(pChaseCars[i], &pBaseMemForCar[i][CTimer::GetFrameCounter() / 2], false);
pChaseCars[i]->GetMatrix().UpdateRW();
pChaseCars[i]->UpdateRwFrame();
}
}
if (Status == STATE_PLAYBACK_BEFORE_RECORDING && CTimer::GetFrameCounter()) {
RestoreInfoForCar(pChaseCars[CurrentCar], &pBaseMemForCar[CurrentCar][CTimer::GetFrameCounter() / 2], false);
pChaseCars[CurrentCar]->GetMatrix().UpdateRW();
pChaseCars[CurrentCar]->UpdateRwFrame();
}
if (CPad::GetPad(0)->GetLeftShockJustDown() && CPad::GetPad(0)->GetRightShockJustDown()) {
if (!CPad::GetPad(0)->GetRightShockJustDown()) {
pChaseCars[CurrentCar]->SetPosition(NewCoorsForRecordedCars[PositionChanges].pos);
pChaseCars[CurrentCar]->SetMoveSpeed(0.0f, 0.0f, 0.0f);
pChaseCars[CurrentCar]->GetMatrix().SetRotateZOnly(DEGTORAD(NewCoorsForRecordedCars[PositionChanges].angle));
++PositionChanges;
}
if (Status == STATE_PLAYBACK_BEFORE_RECORDING) {
Status = STATE_RECORD;
pChaseCars[CurrentCar]->SetStatus(STATUS_PLAYER);
}
}
break;
case STATE_PLAYBACK_INIT:
Status = STATE_PLAYBACK;
break;
case STATE_PLAYBACK:
{
TimeMultiplier += CTimer::GetTimeStepNonClippedInSeconds();
float EndOfFrameTime = CHASE_SCENE_FRAMES_PER_SECOND * Min(CHASE_SCENE_LENGTH_IN_SECONDS, TimeMultiplier);
for (int i = 0; i < NUM_CHASE_CARS; i++) {
if (!pBaseMemForCar[i])
continue;
if (!pChaseCars[i])
continue;
if (EndOfFrameTime < CHASE_SCENE_FRAMES_IN_RECORDING - 1) {
int FlooredEOFTime = EndOfFrameTime;
RestoreInfoForCar(pChaseCars[i], &pBaseMemForCar[i][FlooredEOFTime], false);
CMatrix tmp;
float dp = EndOfFrameTime - FlooredEOFTime;
RestoreInfoForMatrix(tmp, &pBaseMemForCar[i][FlooredEOFTime + 1]);
pChaseCars[i]->GetRight() += (tmp.GetRight() - pChaseCars[i]->GetRight()) * dp;
pChaseCars[i]->GetForward() += (tmp.GetForward() - pChaseCars[i]->GetForward()) * dp;
pChaseCars[i]->GetUp() += (tmp.GetUp() - pChaseCars[i]->GetUp()) * dp;
pChaseCars[i]->GetMatrix().GetPosition() += (tmp.GetPosition() - pChaseCars[i]->GetPosition()) * dp;
}
else{
RestoreInfoForCar(pChaseCars[i], &pBaseMemForCar[i][CHASE_SCENE_FRAMES_IN_RECORDING - 1], true);
if (i == 0)
pChaseCars[i]->GetMatrix().GetPosition().z += 0.2f;
}
pChaseCars[i]->GetMatrix().UpdateRW();
pChaseCars[i]->UpdateRwFrame();
pChaseCars[i]->RemoveAndAdd();
}
break;
}
}
} }
void CRecordDataForChase::StoreInfoForCar(CAutomobile* pCar, CCarStateEachFrame* pState) void CRecordDataForChase::StoreInfoForCar(CAutomobile* pCar, CCarStateEachFrame* pState)
{ {
pState->rightX = INT8_MAX * pCar->GetRight().x;
pState->rightY = INT8_MAX * pCar->GetRight().y;
pState->rightZ = INT8_MAX * pCar->GetRight().z;
pState->forwardX = INT8_MAX * pCar->GetForward().x;
pState->forwardY = INT8_MAX * pCar->GetForward().y;
pState->forwardZ = INT8_MAX * pCar->GetForward().z;
pState->pos = pCar->GetPosition();
pState->velX = 0.5f * INT16_MAX * pCar->GetMoveSpeed().x;
pState->velY = 0.5f * INT16_MAX * pCar->GetMoveSpeed().y;
pState->velZ = 0.5f * INT16_MAX * pCar->GetMoveSpeed().z;
pState->wheel = 20 * pCar->m_fSteerAngle;
pState->gas = 100 * pCar->m_fGasPedal;
pState->brake = 100 * pCar->m_fBrakePedal;
pState->handbrake = pCar->bIsHandbrakeOn;
} }
void CRecordDataForChase::RestoreInfoForMatrix(CMatrix& matrix, CCarStateEachFrame* pState) void CRecordDataForChase::RestoreInfoForMatrix(CMatrix& matrix, CCarStateEachFrame* pState)
{ {
matrix.GetRight() = CVector(pState->rightX, pState->rightY, pState->rightZ) / INT8_MAX;
matrix.GetForward() = CVector(pState->forwardX, pState->forwardY, pState->forwardZ) / INT8_MAX;
matrix.GetUp() = CrossProduct(matrix.GetRight(), matrix.GetForward());
matrix.GetPosition() = pState->pos;
} }
void CRecordDataForChase::RestoreInfoForCar(CAutomobile* pCar, CCarStateEachFrame* pState, bool stop) void CRecordDataForChase::RestoreInfoForCar(CAutomobile* pCar, CCarStateEachFrame* pState, bool stop)
{ {
CVector oldPos = pCar->GetPosition();
RestoreInfoForMatrix(pCar->GetMatrix(), pState);
pCar->SetMoveSpeed(CVector(pState->velX, pState->velY, pState->velZ) / INT16_MAX / 0.5f);
pCar->SetTurnSpeed(0.0f, 0.0f, 0.0f);
pCar->m_fSteerAngle = pState->wheel / 20.0f;
pCar->m_fGasPedal = pState->gas / 100.0f;
pCar->m_fBrakePedal = pState->brake / 100.0f;
pCar->bIsHandbrakeOn = pState->handbrake;
if ((oldPos - pCar->GetPosition()).Magnitude() > 15.0f) {
if (pCar == pChaseCars[14]) {
pCar->m_currentColour1 = 58;
pCar->m_currentColour2 = 1;
}
else
pCar->GetModelInfo()->ChooseVehicleColour(pCar->m_currentColour1, pCar->m_currentColour2);
}
pCar->m_fHealth = Min(pCar->m_fHealth, 500.0f);
if (stop) {
pCar->m_fGasPedal = 0.0f;
pCar->m_fBrakePedal = 0.0f;
pCar->SetMoveSpeed(0.0f, 0.0f, 0.0f);
pCar->bIsHandbrakeOn = false;
}
} }
void CRecordDataForChase::ProcessControlCars(void) void CRecordDataForChase::ProcessControlCars(void)
{ {
if (Status != STATE_PLAYBACK)
return;
for (int i = 0; i < NUM_CHASE_CARS; i++) {
if (pChaseCars[i])
pChaseCars[i]->ProcessControl();
}
} }
#if (defined(GTA_PS2) || defined(FIX_BUGS))
bool CRecordDataForChase::ShouldThisPadBeLeftAlone(uint8 pad) bool CRecordDataForChase::ShouldThisPadBeLeftAlone(uint8 pad)
{ {
// may be wrong return false;
if (Status == STATE_NONE || Status == STATE_PLAYBACK)
return false;
return pad != 0;
} }
#endif
void CRecordDataForChase::GiveUsACar(int32 mi, CVector pos, float angle, CAutomobile** ppCar, uint8 colour1, uint8 colour2) void CRecordDataForChase::GiveUsACar(int32 mi, CVector pos, float angle, CAutomobile** ppCar, uint8 colour1, uint8 colour2)
{ {
CStreaming::RequestModel(mi, STREAMFLAGS_DEPENDENCY);
CStreaming::LoadAllRequestedModels(false);
if (!CStreaming::HasModelLoaded(mi))
return;
CAutomobile* pCar = new CAutomobile(mi, MISSION_VEHICLE);
pCar->SetPosition(pos);
pCar->SetStatus(STATUS_PLAYER_PLAYBACKFROMBUFFER);
pCar->GetMatrix().SetRotateZOnly(DEGTORAD(angle));
pCar->pDriver = nil;
pCar->m_currentColour1 = colour1;
pCar->m_currentColour2 = colour2;
CWorld::Add(pCar);
*ppCar = pCar;
} }
//--MIAMI: unused
void RemoveUnusedCollision(void) void RemoveUnusedCollision(void)
{ {
} }
void CRecordDataForChase::StartChaseScene(float startTime) void CRecordDataForChase::StartChaseScene(float startTime)
{ {
char filename[28];
SetUpCarsForChaseScene();
Status = STATE_PLAYBACK;
AnimTime = startTime;
AnimStartTime = CTimer::GetTimeInMilliseconds();
RemoveUnusedCollision();
CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN);
CGame::TidyUpMemory(true, true);
CStreaming::ImGonnaUseStreamingMemory();
CFileMgr::SetDir("data\\paths");
for (int i = 0; i < NUM_CHASE_CARS; i++) {
if (!pChaseCars[i]) {
pBaseMemForCar[i] = nil;
continue;
}
sprintf(filename, "chase%d.dat", i);
FId2 = CFileMgr::OpenFile(filename, "rb");
if (FId2 <= 0) {
pBaseMemForCar[i] = nil;
continue;
}
pBaseMemForCar[i] = new CCarStateEachFrame[CHASE_SCENE_FRAMES_IN_RECORDING];
for (int j = 0; j < CHASE_SCENE_FRAMES_IN_RECORDING; j++) {
CFileMgr::Read(FId2, (char*)&pBaseMemForCar[i][j], sizeof(CCarStateEachFrame));
CFileMgr::Seek(FId2, sizeof(CCarStateEachFrame), 1);
}
CFileMgr::CloseFile(FId2);
}
CFileMgr::SetDir("");
CStreaming::IHaveUsedStreamingMemory();
TimeMultiplier = 0.0f;
} }
void CRecordDataForChase::CleanUpChaseScene(void) void CRecordDataForChase::CleanUpChaseScene(void)
{ {
if (Status != STATE_PLAYBACK_INIT && Status != STATE_PLAYBACK)
return;
Status = STATE_NONE;
CleanUpCarsForChaseScene();
for (int i = 0; i < NUM_CHASE_CARS; i++) {
if (pBaseMemForCar[i]) {
delete[] pBaseMemForCar[i];
pBaseMemForCar[i] = nil;
}
}
} }
void CRecordDataForChase::SetUpCarsForChaseScene(void) void CRecordDataForChase::SetUpCarsForChaseScene(void)
{ {
GiveUsACar(MI_POLICE, CVector(273.54221f, -1167.1907f, 24.880601f), 63.0f, &pChaseCars[0], 2, 1);
GiveUsACar(MI_ENFORCER, CVector(231.1783f, -1388.8322f, 25.978201f), 90.0f, &pChaseCars[1], 2, 1);
GiveUsACar(MI_TAXI, CVector(184.3156f, -1473.251f, 25.978201f), 0.0f, &pChaseCars[4], 6, 6);
GiveUsACar(MI_CHEETAH, CVector(173.8868f, -1377.6514f, 25.978201f), 0.0f, &pChaseCars[6], 4, 5);
GiveUsACar(MI_STINGER, CVector(102.5946f, -943.93628f, 25.9781f), 270.0f, &pChaseCars[7], 53, 53);
GiveUsACar(MI_CHEETAH, CVector(-177.7157f, -862.18652f, 25.978201f), 155.0f, &pChaseCars[10], 41, 1);
GiveUsACar(MI_STINGER, CVector(-170.56979f, -889.02362f, 25.978201f), 154.0f, &pChaseCars[11], 10, 10);
GiveUsACar(MI_KURUMA, CVector(402.60809f, -917.49628f, 37.381001f), 90.0f, &pChaseCars[14], 34, 1);
GiveUsACar(MI_TAXI, CVector(-33.496201f, -938.4563f, 25.9781f), 266.0f, &pChaseCars[16], 6, 6);
GiveUsACar(MI_KURUMA, CVector(49.363098f, -987.60498f, 25.9781f), 0.0f, &pChaseCars[18], 51, 1);
GiveUsACar(MI_TAXI, CVector(179.0049f, -1154.6686f, 25.9781f), 0.0f, &pChaseCars[19], 6, 76);
GiveUsACar(MI_RUMPO, CVector(-28.9762f, -1031.3367f, 25.990601f), 242.0f, &pChaseCars[2], 1, 75);
GiveUsACar(MI_PATRIOT, CVector(114.1564f, -796.69379f, 24.978201f), 180.0f, &pChaseCars[3], 0, 0);
} }
void CRecordDataForChase::CleanUpCarsForChaseScene(void) void CRecordDataForChase::CleanUpCarsForChaseScene(void)
{ {
for (int i = 0; i < NUM_CHASE_CARS; i++)
RemoveCarFromChase(i);
} }
void CRecordDataForChase::RemoveCarFromChase(int32 i) void CRecordDataForChase::RemoveCarFromChase(int32 i)
{ {
if (!pChaseCars[i])
return;
CWorld::Remove(pChaseCars[i]);
delete pChaseCars[i];
pChaseCars[i] = nil;
} }
CVehicle* CRecordDataForChase::TurnChaseCarIntoScriptCar(int32 i) CVehicle* CRecordDataForChase::TurnChaseCarIntoScriptCar(int32 i)
{ {
CVehicle* pVehicle = pChaseCars[i]; return nil;
pChaseCars[i] = nil;
pVehicle->SetStatus(STATUS_PHYSICS);
return pVehicle;
} }

View File

@ -80,13 +80,13 @@ CRestart::FindClosestHospitalRestartPoint(const CVector &pos, CVector *outPos, f
return; return;
} }
eLevelName curlevel = CTheZones::FindZoneForPoint(pos); eLevelName curlevel = CTheZones::GetLevelFromPosition(pos);
float fMinDist = 16000000.0f; float fMinDist = 16000000.0f;
int closestPoint = NUM_RESTART_POINTS; int closestPoint = NUM_RESTART_POINTS;
// find closest point on this level // find closest point on this level
for (int i = 0; i < NumberOfHospitalRestarts; i++) { for (int i = 0; i < NumberOfHospitalRestarts; i++) {
if (CTheZones::FindZoneForPoint(HospitalRestartPoints[i]) == (OverrideHospitalLevel != LEVEL_NONE ? OverrideHospitalLevel : curlevel)) { if (CTheZones::GetLevelFromPosition(HospitalRestartPoints[i]) == (OverrideHospitalLevel != LEVEL_NONE ? OverrideHospitalLevel : curlevel)) {
float dist = (pos - HospitalRestartPoints[i]).MagnitudeSqr(); float dist = (pos - HospitalRestartPoints[i]).MagnitudeSqr();
if (fMinDist >= dist) { if (fMinDist >= dist) {
fMinDist = dist; fMinDist = dist;
@ -127,13 +127,13 @@ CRestart::FindClosestPoliceRestartPoint(const CVector &pos, CVector *outPos, flo
return; return;
} }
eLevelName curlevel = CTheZones::FindZoneForPoint(pos); eLevelName curlevel = CTheZones::GetLevelFromPosition(pos);
float fMinDist = 16000000.0f; float fMinDist = 16000000.0f;
int closestPoint = NUM_RESTART_POINTS; int closestPoint = NUM_RESTART_POINTS;
// find closest point on this level // find closest point on this level
for (int i = 0; i < NumberOfPoliceRestarts; i++) { for (int i = 0; i < NumberOfPoliceRestarts; i++) {
if (CTheZones::FindZoneForPoint(PoliceRestartPoints[i]) == (OverridePoliceStationLevel != LEVEL_NONE ? OverridePoliceStationLevel : curlevel)) { if (CTheZones::GetLevelFromPosition(PoliceRestartPoints[i]) == (OverridePoliceStationLevel != LEVEL_NONE ? OverridePoliceStationLevel : curlevel)) {
float dist = (pos - PoliceRestartPoints[i]).MagnitudeSqr(); float dist = (pos - PoliceRestartPoints[i]).MagnitudeSqr();
if (fMinDist >= dist) { if (fMinDist >= dist) {
fMinDist = dist; fMinDist = dist;

View File

@ -589,7 +589,7 @@ void CRunningScript::Init()
#ifdef USE_DEBUG_SCRIPT_LOADER #ifdef USE_DEBUG_SCRIPT_LOADER
int open_script() int open_script()
{ {
static int scriptToLoad = 0; static int scriptToLoad = 1;
if (GetAsyncKeyState('G') & 0x8000) if (GetAsyncKeyState('G') & 0x8000)
scriptToLoad = 0; scriptToLoad = 0;
@ -600,7 +600,7 @@ int open_script()
switch (scriptToLoad) { switch (scriptToLoad) {
case 0: return CFileMgr::OpenFile("main.scm", "rb"); case 0: return CFileMgr::OpenFile("main.scm", "rb");
case 1: return CFileMgr::OpenFile("main_freeroam.scm", "rb"); case 1: return CFileMgr::OpenFile("freeroam_miami.scm", "rb");
case 2: return CFileMgr::OpenFile("main_d.scm", "rb"); case 2: return CFileMgr::OpenFile("main_d.scm", "rb");
} }
return CFileMgr::OpenFile("main.scm", "rb"); return CFileMgr::OpenFile("main.scm", "rb");
@ -7252,7 +7252,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
if (total == 0) if (total == 0)
CWorld::FindObjectsOfTypeInRangeSectorList(mi, CWorld::GetBigBuildingList(LEVEL_NONE), pos, range, true, &total, 16, apEntities); CWorld::FindObjectsOfTypeInRangeSectorList(mi, CWorld::GetBigBuildingList(LEVEL_NONE), pos, range, true, &total, 16, apEntities);
if (total == 0) if (total == 0)
CWorld::FindObjectsOfTypeInRangeSectorList(mi, CWorld::GetBigBuildingList(CTheZones::FindZoneForPoint(pos)), pos, range, true, &total, 16, apEntities); CWorld::FindObjectsOfTypeInRangeSectorList(mi, CWorld::GetBigBuildingList(CTheZones::GetLevelFromPosition(pos)), pos, range, true, &total, 16, apEntities);
CEntity* pClosestEntity = nil; CEntity* pClosestEntity = nil;
float min_dist = 2.0f * range; float min_dist = 2.0f * range;
for (int i = 0; i < total; i++) { for (int i = 0; i < total; i++) {
@ -8006,7 +8006,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
if (total == 0) if (total == 0)
CWorld::FindObjectsOfTypeInRangeSectorList(mi1, CWorld::GetBigBuildingList(LEVEL_NONE), pos, radius, true, &total, 16, apEntities); CWorld::FindObjectsOfTypeInRangeSectorList(mi1, CWorld::GetBigBuildingList(LEVEL_NONE), pos, radius, true, &total, 16, apEntities);
if (total == 0) if (total == 0)
CWorld::FindObjectsOfTypeInRangeSectorList(mi1, CWorld::GetBigBuildingList(CTheZones::FindZoneForPoint(pos)), pos, radius, true, &total, 16, apEntities); CWorld::FindObjectsOfTypeInRangeSectorList(mi1, CWorld::GetBigBuildingList(CTheZones::GetLevelFromPosition(pos)), pos, radius, true, &total, 16, apEntities);
CEntity* pClosestEntity = nil; CEntity* pClosestEntity = nil;
float min_dist = 2.0f * radius; float min_dist = 2.0f * radius;
for (int i = 0; i < total; i++) { for (int i = 0; i < total; i++) {

View File

@ -3182,12 +3182,14 @@ CCamera::GetScreenFadeStatus(void)
void void
CCamera::RenderMotionBlur(void) CCamera::RenderMotionBlur(void)
{ {
#ifndef MIAMI // temporary
if(m_BlurType == 0) if(m_BlurType == 0)
return; return;
CMBlur::MotionBlurRender(m_pRwCamera, CMBlur::MotionBlurRender(m_pRwCamera,
m_BlurRed, m_BlurGreen, m_BlurBlue, m_BlurRed, m_BlurGreen, m_BlurBlue,
m_motionBlur, m_BlurType, m_imotionBlurAddAlpha); m_motionBlur, m_BlurType, m_imotionBlurAddAlpha);
#endif
} }
void void

View File

@ -99,9 +99,6 @@ CFileLoader::LoadLevel(const char *filename)
} }
LoadingScreenLoadingFile(line + 4); LoadingScreenLoadingFile(line + 4);
LoadScene(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){ }else if(strncmp(line, "SPLASH", 6) == 0){
LoadSplash(GetRandomSplashScreen()); LoadSplash(GetRandomSplashScreen());
}else if(strncmp(line, "CDIMAGE", 7) == 0){ }else if(strncmp(line, "CDIMAGE", 7) == 0){
@ -171,6 +168,7 @@ CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot)
debug("Loading collision file %s\n", filename); debug("Loading collision file %s\n", filename);
fd = CFileMgr::OpenFile(filename, "rb"); fd = CFileMgr::OpenFile(filename, "rb");
assert(fd > 0);
while(CFileMgr::Read(fd, (char*)&header, sizeof(header))){ while(CFileMgr::Read(fd, (char*)&header, sizeof(header))){
assert(strncmp(header.ident, "COLL", 4) == 0); assert(strncmp(header.ident, "COLL", 4) == 0);
@ -554,7 +552,9 @@ CFileLoader::LoadObjectTypes(const char *filename)
enum { enum {
NONE, NONE,
OBJS, OBJS,
MLO, // unused but enum still has it
TOBJ, TOBJ,
WEAP,
HIER, HIER,
CARS, CARS,
PEDS, PEDS,
@ -565,16 +565,17 @@ CFileLoader::LoadObjectTypes(const char *filename)
int fd; int fd;
int section; int section;
int pathIndex; int pathIndex;
char pathTypeStr[20];
int id, pathType; int id, pathType;
int mlo; int minID, maxID;
section = NONE; section = NONE;
minID = INT32_MAX;
maxID = -1;
pathIndex = -1; pathIndex = -1;
mlo = 0;
debug("Loading object types from %s...\n", filename); debug("Loading object types from %s...\n", filename);
fd = CFileMgr::OpenFile(filename, "rb"); fd = CFileMgr::OpenFile(filename, "rb");
assert(fd > 0);
for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){ for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){
if(*line == '\0' || *line == '#') if(*line == '\0' || *line == '#')
continue; continue;
@ -582,6 +583,7 @@ CFileLoader::LoadObjectTypes(const char *filename)
if(section == NONE){ if(section == NONE){
if(strncmp(line, "objs", 4) == 0) section = OBJS; if(strncmp(line, "objs", 4) == 0) section = OBJS;
else if(strncmp(line, "tobj", 4) == 0) section = TOBJ; 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, "hier", 4) == 0) section = HIER;
else if(strncmp(line, "cars", 4) == 0) section = CARS; else if(strncmp(line, "cars", 4) == 0) section = CARS;
else if(strncmp(line, "peds", 4) == 0) section = PEDS; else if(strncmp(line, "peds", 4) == 0) section = PEDS;
@ -591,10 +593,17 @@ CFileLoader::LoadObjectTypes(const char *filename)
section = NONE; section = NONE;
}else switch(section){ }else switch(section){
case OBJS: case OBJS:
LoadObject(line); id = LoadObject(line);
if(id > maxID) maxID = id;
if(id < minID) minID = id;
break; break;
case TOBJ: 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; break;
case HIER: case HIER:
LoadClumpObject(line); LoadClumpObject(line);
@ -607,17 +616,15 @@ CFileLoader::LoadObjectTypes(const char *filename)
break; break;
case PATH: case PATH:
if(pathIndex == -1){ if(pathIndex == -1){
id = LoadPathHeader(line, pathTypeStr); id = LoadPathHeader(line, pathType);
if(strncmp(pathTypeStr, "ped", 4) == 0)
pathType = 1;
else if(strncmp(pathTypeStr, "car", 4) == 0)
pathType = 0;
pathIndex = 0; pathIndex = 0;
}else{ }else{
if(pathType == 1) if(pathType == 0)
LoadPedPathNode(line, id, pathIndex); LoadPedPathNode(line, id, pathIndex);
else if(pathType == 0) else if (pathType == 1)
LoadCarPathNode(line, id, pathIndex); LoadCarPathNode(line, id, pathIndex, false);
else if (pathType == 2)
LoadCarPathNode(line, id, pathIndex, true);
pathIndex++; pathIndex++;
if(pathIndex == 12) if(pathIndex == 12)
pathIndex = -1; pathIndex = -1;
@ -630,7 +637,7 @@ CFileLoader::LoadObjectTypes(const char *filename)
} }
CFileMgr::CloseFile(fd); CFileMgr::CloseFile(fd);
for(id = 0; id < MODELINFOSIZE; id++){ for(id = minID; id <= maxID; id++){
CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id); CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
if(mi && mi->IsSimple()) if(mi && mi->IsSimple())
mi->SetupBigBuilding(); mi->SetupBigBuilding();
@ -640,16 +647,20 @@ CFileLoader::LoadObjectTypes(const char *filename)
void void
SetModelInfoFlags(CSimpleModelInfo *mi, uint32 flags) SetModelInfoFlags(CSimpleModelInfo *mi, uint32 flags)
{ {
mi->m_normalCull = !!(flags & 1); mi->m_wetRoadReflection = !!(flags & 1);
mi->m_noFade = !!(flags & 2); mi->m_noFade = !!(flags & 2);
mi->m_drawLast = !!(flags & (4|8)); mi->m_drawLast = !!(flags & (4|8));
mi->m_additive = !!(flags & 8); mi->m_additive = !!(flags & 8);
mi->m_isSubway = !!(flags & 0x10); mi->m_isSubway = !!(flags & 0x10);
mi->m_ignoreLight = !!(flags & 0x20); mi->m_ignoreLight = !!(flags & 0x20);
mi->m_noZwrite = !!(flags & 0x40); 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) CFileLoader::LoadObject(const char *line)
{ {
int id, numObjs; int id, numObjs;
@ -660,7 +671,7 @@ CFileLoader::LoadObject(const char *line)
CSimpleModelInfo *mi; CSimpleModelInfo *mi;
if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4) if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4)
return; return 0; // game returns return value
switch(numObjs){ switch(numObjs){
case 1: case 1:
@ -692,9 +703,11 @@ CFileLoader::LoadObject(const char *line)
mi->m_firstDamaged = damaged; mi->m_firstDamaged = damaged;
mi->SetTexDictionary(txd); mi->SetTexDictionary(txd);
MatchModelString(model, id); MatchModelString(model, id);
return id;
} }
void int
CFileLoader::LoadTimeObject(const char *line) CFileLoader::LoadTimeObject(const char *line)
{ {
int id, numObjs; int id, numObjs;
@ -706,7 +719,7 @@ CFileLoader::LoadTimeObject(const char *line)
CTimeModelInfo *mi, *other; CTimeModelInfo *mi, *other;
if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4) if(sscanf(line, "%d %s %s %d", &id, model, txd, &numObjs) != 4)
return; return 0; // game returns return value
switch(numObjs){ switch(numObjs){
case 1: case 1:
@ -742,6 +755,8 @@ CFileLoader::LoadTimeObject(const char *line)
if(other) if(other)
other->SetOtherTimeModel(id); other->SetOtherTimeModel(id);
MatchModelString(model, id); MatchModelString(model, id);
return id;
} }
void void
@ -872,33 +887,51 @@ CFileLoader::LoadPedObject(const char *line)
} }
int int
CFileLoader::LoadPathHeader(const char *line, char *type) CFileLoader::LoadPathHeader(const char *line, int &type)
{ {
int id; int id;
char modelname[32]; char modelname[32];
sscanf(line, "%s %d %s", type, &id, modelname); sscanf(line, "%d %d %s", &type, &id, modelname);
return id; return id;
} }
void void
CFileLoader::LoadPedPathNode(const char *line, int id, int node) CFileLoader::LoadPedPathNode(const char *line, int id, int node)
{ {
int type, next, cross; int type, next, cross, numLeft, numRight, speed, flags;
float x, y, z, width; float x, y, z, width, spawnRate;
sscanf(line, "%d %d %d %f %f %f %f", &type, &next, &cross, &x, &y, &z, &width); if(sscanf(line, "%d %d %d %f %f %f %f %d %d %d %d %f",
ThePaths.StoreNodeInfoPed(id, node, type, next, x, y, z, 0, !!cross); &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 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; int type, next, cross, numLeft, numRight, speed, flags;
float x, y, z, width; float x, y, z, width, spawnRate;
sscanf(line, "%d %d %d %f %f %f %f %d %d", &type, &next, &cross, &x, &y, &z, &width, &numLeft, &numRight); if(sscanf(line, "%d %d %d %f %f %f %f %d %d %d %d %f",
ThePaths.StoreNodeInfoCar(id, node, type, next, x, y, z, 0, numLeft, numRight); &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, false);
else
ThePaths.StoreNodeInfoCar(id, node, type, next, x, y, z, 0, numLeft, numRight,
!!(flags&1), !!(flags&4), speed, !!(flags&2), waterPath, spawnRate);
} }
@ -991,20 +1024,21 @@ CFileLoader::LoadScene(const char *filename)
INST, INST,
ZONE, ZONE,
CULL, CULL,
OCCL,
PICK, PICK,
PATH, PATH,
}; };
char *line; char *line;
int fd; int fd;
int section; int section;
int pathIndex; int pathType, pathIndex;
char pathTypeStr[20];
section = NONE; section = NONE;
pathIndex = -1; pathIndex = -1;
debug("Creating objects from %s...\n", filename); debug("Creating objects from %s...\n", filename);
fd = CFileMgr::OpenFile(filename, "rb"); fd = CFileMgr::OpenFile(filename, "rb");
assert(fd > 0);
for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){ for(line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)){
if(*line == '\0' || *line == '#') if(*line == '\0' || *line == '#')
continue; continue;
@ -1015,6 +1049,7 @@ CFileLoader::LoadScene(const char *filename)
else if(strncmp(line, "cull", 4) == 0) section = CULL; else if(strncmp(line, "cull", 4) == 0) section = CULL;
else if(strncmp(line, "pick", 4) == 0) section = PICK; else if(strncmp(line, "pick", 4) == 0) section = PICK;
else if(strncmp(line, "path", 4) == 0) section = PATH; 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){ }else if(strncmp(line, "end", 3) == 0){
section = NONE; section = NONE;
}else switch(section){ }else switch(section){
@ -1027,18 +1062,24 @@ CFileLoader::LoadScene(const char *filename)
case CULL: case CULL:
LoadCullZone(line); LoadCullZone(line);
break; break;
case OCCL:
// TODO(MIAMI): occlusion
break;
case PICK: case PICK:
// unused // unused
LoadPickup(line); LoadPickup(line);
break; break;
case PATH: case PATH:
// unfinished in the game
if(pathIndex == -1){ if(pathIndex == -1){
LoadPathHeader(line, pathTypeStr); LoadPathHeader(line, pathType);
// type not set
pathIndex = 0; pathIndex = 0;
}else{ }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++; pathIndex++;
if(pathIndex == 12) if(pathIndex == 12)
pathIndex = -1; pathIndex = -1;
@ -1122,9 +1163,7 @@ CFileLoader::LoadObjectInstance(const char *line)
entity->SetModelIndexNoCreate(id); entity->SetModelIndexNoCreate(id);
entity->GetMatrix() = CMatrix(xform); entity->GetMatrix() = CMatrix(xform);
CWorld::Add(entity); CWorld::Add(entity);
// TODO(MIAMI) if(IsGlass(entity->GetModelIndex()) && !mi->m_isArtistGlass)
//--MIAMI: TODO
if(IsGlass(entity->GetModelIndex()))
entity->bIsVisible = false; entity->bIsVisible = false;
entity->m_level = CTheZones::GetLevelFromPosition(entity->GetPosition()); entity->m_level = CTheZones::GetLevelFromPosition(entity->GetPosition());
entity->m_area = area; entity->m_area = area;
@ -1172,54 +1211,7 @@ CFileLoader::LoadPickup(const char *line)
sscanf(line, "%d %f %f %f", &id, &x, &y, &z); sscanf(line, "%d %f %f %f", &id, &x, &y, &z);
} }
void //--MIAMI: unused
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");
}
void void
CFileLoader::ReloadPaths(const char *filename) CFileLoader::ReloadPaths(const char *filename)
{ {
@ -1230,10 +1222,10 @@ CFileLoader::ReloadPaths(const char *filename)
char *line; char *line;
int section = NONE; int section = NONE;
int id, pathType, pathIndex = -1; int id, pathType, pathIndex = -1;
char pathTypeStr[20];
debug("Reloading paths from %s...\n", filename); debug("Reloading paths from %s...\n", filename);
int fd = CFileMgr::OpenFile(filename, "r"); int fd = CFileMgr::OpenFile(filename, "r");
assert(fd > 0);
for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) { for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) {
if (*line == '\0' || *line == '#') if (*line == '\0' || *line == '#')
continue; continue;
@ -1249,17 +1241,15 @@ CFileLoader::ReloadPaths(const char *filename)
switch (section) { switch (section) {
case PATH: case PATH:
if (pathIndex == -1) { if (pathIndex == -1) {
id = LoadPathHeader(line, pathTypeStr); id = LoadPathHeader(line, pathType);
if (strncmp(pathTypeStr, "ped", 4) == 0)
pathType = 1;
else if (strncmp(pathTypeStr, "car", 4) == 0)
pathType = 0;
pathIndex = 0; pathIndex = 0;
} else { } else {
if (pathType == 1) if(pathType == 0)
LoadPedPathNode(line, id, pathIndex); LoadPedPathNode(line, id, pathIndex);
else if (pathType == 0) else if (pathType == 1)
LoadCarPathNode(line, id, pathIndex); LoadCarPathNode(line, id, pathIndex, false);
else if (pathType == 2)
LoadCarPathNode(line, id, pathIndex, true);
pathIndex++; pathIndex++;
if (pathIndex == 12) if (pathIndex == 12)
pathIndex = -1; pathIndex = -1;
@ -1289,6 +1279,7 @@ CFileLoader::ReloadObjectTypes(const char *filename)
CFileMgr::ChangeDir("\\DATA\\MAPS\\"); CFileMgr::ChangeDir("\\DATA\\MAPS\\");
int fd = CFileMgr::OpenFile(filename, "r"); int fd = CFileMgr::OpenFile(filename, "r");
assert(fd > 0);
CFileMgr::ChangeDir("\\"); CFileMgr::ChangeDir("\\");
for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) { for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) {
if (*line == '\0' || *line == '#') if (*line == '\0' || *line == '#')
@ -1364,6 +1355,7 @@ CFileLoader::ReLoadScene(const char *filename)
char *line; char *line;
CFileMgr::ChangeDir("\\DATA\\"); CFileMgr::ChangeDir("\\DATA\\");
int fd = CFileMgr::OpenFile(filename, "r"); int fd = CFileMgr::OpenFile(filename, "r");
assert(fd > 0);
CFileMgr::ChangeDir("\\"); CFileMgr::ChangeDir("\\");
for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) { for (line = CFileLoader::LoadLine(fd); line; line = CFileLoader::LoadLine(fd)) {

View File

@ -23,14 +23,14 @@ public:
static void AddTexDictionaries(RwTexDictionary *dst, RwTexDictionary *src); static void AddTexDictionaries(RwTexDictionary *dst, RwTexDictionary *src);
static void LoadObjectTypes(const char *filename); static void LoadObjectTypes(const char *filename);
static void LoadObject(const char *line); static int LoadObject(const char *line);
static void LoadTimeObject(const char *line); static int LoadTimeObject(const char *line);
static void LoadClumpObject(const char *line); static void LoadClumpObject(const char *line);
static void LoadVehicleObject(const char *line); static void LoadVehicleObject(const char *line);
static void LoadPedObject(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 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 Load2dEffect(const char *line);
static void LoadScene(const char *filename); static void LoadScene(const char *filename);
@ -39,8 +39,6 @@ public:
static void LoadCullZone(const char *line); static void LoadCullZone(const char *line);
static void LoadPickup(const char *line); static void LoadPickup(const char *line);
static void LoadMapZones(const char *filename);
static void ReloadPaths(const char *filename); static void ReloadPaths(const char *filename);
static void ReloadObjectTypes(const char *filename); static void ReloadObjectTypes(const char *filename);
static void ReloadObject(const char *line); static void ReloadObject(const char *line);

View File

@ -265,7 +265,7 @@ bool CGame::Initialise(const char* datFile)
strcpy(aDatFile, datFile); strcpy(aDatFile, datFile);
CPools::Initialise(); CPools::Initialise();
CIniFile::LoadIniFile(); CIniFile::LoadIniFile();
currLevel = LEVEL_INDUSTRIAL; currLevel = LEVEL_BEACH;
LoadingScreen("Loading the Game", "Loading generic textures", GetRandomSplashScreen()); LoadingScreen("Loading the Game", "Loading generic textures", GetRandomSplashScreen());
gameTxdSlot = CTxdStore::AddTxdSlot("generic"); gameTxdSlot = CTxdStore::AddTxdSlot("generic");
CTxdStore::Create(gameTxdSlot); CTxdStore::Create(gameTxdSlot);
@ -588,7 +588,7 @@ void CGame::InitialiseWhenRestarting(void)
CTimer::Initialise(); CTimer::Initialise();
FrontEndMenuManager.m_bWantToLoad = false; FrontEndMenuManager.m_bWantToLoad = false;
ReInitGameObjectVariables(); ReInitGameObjectVariables();
currLevel = LEVEL_INDUSTRIAL; currLevel = LEVEL_NONE;
CCollision::SortOutCollisionAfterLoad(); CCollision::SortOutCollisionAfterLoad();
} }
} }

View File

@ -3,9 +3,30 @@
enum eLevelName { enum eLevelName {
LEVEL_IGNORE = -1, // beware, this is only used in CPhysical's m_nZoneLevel LEVEL_IGNORE = -1, // beware, this is only used in CPhysical's m_nZoneLevel
LEVEL_NONE = 0, LEVEL_NONE = 0,
LEVEL_INDUSTRIAL, LEVEL_BEACH,
LEVEL_COMMERCIAL, LEVEL_MAINLAND
LEVEL_SUBURBAN };
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
}; };
enum eVisibilityArea enum eVisibilityArea
@ -66,3 +87,5 @@ public:
static void DrasticTidyUpMemory(bool); static void DrasticTidyUpMemory(bool);
static void ProcessTidyUpMemory(void); static void ProcessTidyUpMemory(void);
}; };
inline bool IsAreaVisible(int area) { return area == CGame::currArea || area == AREA_EVERYWHERE; }

View File

@ -64,16 +64,10 @@ uint32 CStreaming::ms_memoryAvailable;
int32 desiredNumVehiclesLoaded = 12; int32 desiredNumVehiclesLoaded = 12;
CEntity *pIslandLODindustEntity; CEntity *pIslandLODmainlandEntity;
CEntity *pIslandLODcomIndEntity; CEntity *pIslandLODbeachEntity;
CEntity *pIslandLODcomSubEntity; int32 islandLODmainland;
CEntity *pIslandLODsubIndEntity; int32 islandLODbeach;
CEntity *pIslandLODsubComEntity;
int32 islandLODindust;
int32 islandLODcomInd;
int32 islandLODcomSub;
int32 islandLODsubInd;
int32 islandLODsubCom;
bool bool
CStreamingInfo::GetCdPosnAndSize(uint32 &posn, uint32 &size) CStreamingInfo::GetCdPosnAndSize(uint32 &posn, uint32 &size)
@ -212,21 +206,12 @@ CStreaming::Init2(void)
// find island LODs // find island LODs
pIslandLODindustEntity = nil; pIslandLODmainlandEntity = nil;
pIslandLODcomIndEntity = nil; pIslandLODbeachEntity = nil;
pIslandLODcomSubEntity = nil; islandLODmainland = -1;
pIslandLODsubIndEntity = nil; islandLODbeach = -1;
pIslandLODsubComEntity = nil; CModelInfo::GetModelInfo("IslandLODmainland", &islandLODmainland);
islandLODindust = -1; CModelInfo::GetModelInfo("IslandLODbeach", &islandLODbeach);
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);
} }
void void
@ -678,47 +663,6 @@ CStreaming::RequestModel(int32 id, int32 flags)
} }
} }
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;
}
}
#define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE #define BIGBUILDINGFLAGS STREAMFLAGS_DONT_REMOVE
void void
@ -772,21 +716,18 @@ CStreaming::InstanceBigBuildings(eLevelName level, const CVector &pos)
} }
} }
//--MIAMI: done
void void
CStreaming::RequestIslands(eLevelName level) CStreaming::RequestIslands(eLevelName level)
{ {
switch(level){ switch(level){
case LEVEL_INDUSTRIAL: case LEVEL_MAINLAND:
RequestModel(islandLODcomInd, BIGBUILDINGFLAGS); if(islandLODbeach != -1)
RequestModel(islandLODsubInd, BIGBUILDINGFLAGS); RequestModel(islandLODbeach, BIGBUILDINGFLAGS);
break; break;
case LEVEL_COMMERCIAL: case LEVEL_BEACH:
RequestModel(islandLODindust, BIGBUILDINGFLAGS); if(islandLODmainland != -1)
RequestModel(islandLODsubCom, BIGBUILDINGFLAGS); RequestModel(islandLODmainland, BIGBUILDINGFLAGS);
break;
case LEVEL_SUBURBAN:
RequestModel(islandLODindust, BIGBUILDINGFLAGS);
RequestModel(islandLODcomSub, BIGBUILDINGFLAGS);
break; break;
} }
} }
@ -906,16 +847,14 @@ CStreaming::RemoveModel(int32 id)
ms_aInfoForModel[id].m_loadState = STREAMSTATE_NOTLOADED; ms_aInfoForModel[id].m_loadState = STREAMSTATE_NOTLOADED;
} }
//--MIAMI: change islands //--MIAMI: done
void void
CStreaming::RemoveUnusedBuildings(eLevelName level) CStreaming::RemoveUnusedBuildings(eLevelName level)
{ {
if(level != LEVEL_INDUSTRIAL) if(level != LEVEL_BEACH)
RemoveBuildings(LEVEL_INDUSTRIAL); RemoveBuildings(LEVEL_BEACH);
if(level != LEVEL_COMMERCIAL) if(level != LEVEL_MAINLAND)
RemoveBuildings(LEVEL_COMMERCIAL); RemoveBuildings(LEVEL_MAINLAND);
if(level != LEVEL_SUBURBAN)
RemoveBuildings(LEVEL_SUBURBAN);
} }
//--MIAMI: done //--MIAMI: done
@ -979,16 +918,14 @@ CStreaming::RemoveBuildings(eLevelName level)
} }
} }
//--MIAMI: change islands //--MIAMI: done
void void
CStreaming::RemoveUnusedBigBuildings(eLevelName level) CStreaming::RemoveUnusedBigBuildings(eLevelName level)
{ {
if(level != LEVEL_INDUSTRIAL) if(level != LEVEL_BEACH)
RemoveBigBuildings(LEVEL_INDUSTRIAL); RemoveBigBuildings(LEVEL_BEACH);
if(level != LEVEL_COMMERCIAL) if(level != LEVEL_MAINLAND)
RemoveBigBuildings(LEVEL_COMMERCIAL); RemoveBigBuildings(LEVEL_MAINLAND);
if(level != LEVEL_SUBURBAN)
RemoveBigBuildings(LEVEL_SUBURBAN);
RemoveIslandsNotUsed(level); RemoveIslandsNotUsed(level);
} }
@ -1009,40 +946,23 @@ void
CStreaming::RemoveIslandsNotUsed(eLevelName level) CStreaming::RemoveIslandsNotUsed(eLevelName level)
{ {
int i; int i;
if(pIslandLODindustEntity == nil) if(pIslandLODmainlandEntity == nil)
for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){ for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){
CBuilding *building = CPools::GetBuildingPool()->GetSlot(i); CBuilding *building = CPools::GetBuildingPool()->GetSlot(i);
if(building == nil) if(building == nil)
continue; continue;
if(building->GetModelIndex() == islandLODindust) pIslandLODindustEntity = building; if(building->GetModelIndex() == islandLODmainland)
if(building->GetModelIndex() == islandLODcomInd) pIslandLODcomIndEntity = building; pIslandLODmainlandEntity = building;
if(building->GetModelIndex() == islandLODcomSub) pIslandLODcomSubEntity = building; if(building->GetModelIndex() == islandLODbeach)
if(building->GetModelIndex() == islandLODsubInd) pIslandLODsubIndEntity = building; pIslandLODbeachEntity = building;
if(building->GetModelIndex() == islandLODsubCom) pIslandLODsubComEntity = building;
} }
switch(level){ switch(level){
case LEVEL_INDUSTRIAL: case LEVEL_MAINLAND:
DeleteIsland(pIslandLODindustEntity); DeleteIsland(pIslandLODmainlandEntity);
DeleteIsland(pIslandLODcomSubEntity);
DeleteIsland(pIslandLODsubComEntity);
break; break;
case LEVEL_COMMERCIAL: case LEVEL_BEACH:
DeleteIsland(pIslandLODcomIndEntity); DeleteIsland(pIslandLODbeachEntity);
DeleteIsland(pIslandLODcomSubEntity);
DeleteIsland(pIslandLODsubIndEntity);
break;
case LEVEL_SUBURBAN:
DeleteIsland(pIslandLODsubIndEntity);
DeleteIsland(pIslandLODsubComEntity);
DeleteIsland(pIslandLODcomIndEntity);
break;
default:
DeleteIsland(pIslandLODindustEntity);
DeleteIsland(pIslandLODcomIndEntity);
DeleteIsland(pIslandLODcomSubEntity);
DeleteIsland(pIslandLODsubIndEntity);
DeleteIsland(pIslandLODsubComEntity);
break; break;
} }
} }

View File

@ -4,19 +4,19 @@
#include "Lists.h" #include "Lists.h"
#include "PlayerInfo.h" #include "PlayerInfo.h"
/* Sectors span from -2000 to 2000 in x and y. /* Sectors span from -2400 to 1600 in x and -2000 to 2000 y.
* With 100x100 sectors, each is 40x40 units. */ * With 80x80 sectors, each is 50x50 units. */
#define SECTOR_SIZE_X (40.0f) #define SECTOR_SIZE_X (50.0f)
#define SECTOR_SIZE_Y (40.0f) #define SECTOR_SIZE_Y (50.0f)
#define NUMSECTORS_X (100) #define NUMSECTORS_X (80)
#define NUMSECTORS_Y (100) #define NUMSECTORS_Y (80)
#define WORLD_SIZE_X (NUMSECTORS_X * SECTOR_SIZE_X) #define WORLD_SIZE_X (NUMSECTORS_X * SECTOR_SIZE_X)
#define WORLD_SIZE_Y (NUMSECTORS_Y * SECTOR_SIZE_Y) #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_MIN_Y (-2000.0f)
#define WORLD_MAX_X (WORLD_MIN_X + WORLD_SIZE_X) #define WORLD_MAX_X (WORLD_MIN_X + WORLD_SIZE_X)

View File

@ -139,7 +139,11 @@ CTheZones::CreateZone(char *name, eZoneType type,
for(p = name; *p; p++) if(islower(*p)) *p = toupper(*p); for(p = name; *p; p++) if(islower(*p)) *p = toupper(*p);
// add zone // add zone
zone = &ZoneArray[TotalNumberOfZones++]; // TODO(MIAMI): do this properly, also navig zones
if(type == ZONE_MAPZONE)
zone = &MapZoneArray[TotalNumberOfMapZones++];
else
zone = &ZoneArray[TotalNumberOfZones++];
strncpy(zone->name, name, 7); strncpy(zone->name, name, 7);
zone->name[7] = '\0'; zone->name[7] = '\0';
zone->type = type; zone->type = type;
@ -156,36 +160,6 @@ CTheZones::CreateZone(char *name, eZoneType type,
} }
} }
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;
}
void void
CTheZones::PostZoneCreation(void) CTheZones::PostZoneCreation(void)
{ {
@ -565,18 +539,6 @@ CTheZones::FindAudioZone(CVector *pos)
return -1; 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;
}
void void
CTheZones::AddZoneToAudioZoneArray(CZone *zone) CTheZones::AddZoneToAudioZoneArray(CZone *zone)
{ {

View File

@ -71,10 +71,6 @@ public:
float minx, float miny, float minz, float minx, float miny, float minz,
float maxx, float maxy, float maxz, float maxx, float maxy, float maxz,
eLevelName level); 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 *GetZone(uint16 i) { return &ZoneArray[i]; }
static void PostZoneCreation(void); static void PostZoneCreation(void);
static void InsertZoneIntoZoneHierarchy(CZone *zone); static void InsertZoneIntoZoneHierarchy(CZone *zone);
@ -103,7 +99,6 @@ public:
static void SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity); static void SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity);
static void SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup); static void SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup);
static int16 FindAudioZone(CVector *pos); static int16 FindAudioZone(CVector *pos);
static eLevelName FindZoneForPoint(const CVector &pos);
static CZone *GetPointerForZoneIndex(int32 i) { return i == -1 ? nil : &ZoneArray[i]; } static CZone *GetPointerForZoneIndex(int32 i) { return i == -1 ? nil : &ZoneArray[i]; }
static int32 GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - ZoneArray; } static int32 GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - ZoneArray; }
static void AddZoneToAudioZoneArray(CZone *zone); static void AddZoneToAudioZoneArray(CZone *zone);

View File

@ -23,7 +23,7 @@ enum Config {
MAXVEHICLESLOADED = 50, // 70 on mobile MAXVEHICLESLOADED = 50, // 70 on mobile
NUMOBJECTINFO = 168, // object.dat NUMOBJECTINFO = 400, // TODO(MIAMI): fantasy // object.dat
// Pool sizes // Pool sizes
NUMPTRNODES = 50000, NUMPTRNODES = 50000,

View File

@ -1134,7 +1134,7 @@ void
InitialiseGame(void) InitialiseGame(void)
{ {
LoadingScreen(nil, nil, "loadsc0"); LoadingScreen(nil, nil, "loadsc0");
CGame::Initialise("DATA\\GTA3.DAT"); CGame::Initialise("DATA\\GTA_VC.DAT");
} }
RsEventStatus RsEventStatus

View File

@ -323,6 +323,7 @@ CEntity::UpdateRwFrame(void)
} }
} }
//--MIAMI: done
void void
CEntity::SetupBigBuilding(void) CEntity::SetupBigBuilding(void)
{ {
@ -335,15 +336,10 @@ CEntity::SetupBigBuilding(void)
m_level = CTheZones::GetLevelFromPosition(GetPosition()); m_level = CTheZones::GetLevelFromPosition(GetPosition());
if(mi->m_lodDistances[0] <= 2000.0f) if(mi->m_lodDistances[0] <= 2000.0f)
bStreamBIGBuilding = true; bStreamBIGBuilding = true;
// TODO(MIAMI): the stuff down there isn't right yet if(mi->m_lodDistances[0] > 2500.0f || mi->m_ignoreDrawDist)
if(m_level == LEVEL_NONE){
if(mi->GetTxdSlot() != CTxdStore::FindTxdSlot("generic")){
mi->SetTexDictionary("generic");
printf("%d:%s txd has been set to generic\n", m_modelIndex, mi->GetName());
}
}
if(mi->m_lodDistances[0] > 2000.0f)
m_level = LEVEL_NONE; m_level = LEVEL_NONE;
else if(m_level == LEVEL_NONE)
printf("%s isn't in a level\n", mi->GetName());
} }
CRect CRect

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "ModelInfo.h"
#define MODELINDICES \ #define MODELINDICES \
X("fire_hydrant", MI_FIRE_HYDRANT, 0x5F5A00) \ X("fire_hydrant", MI_FIRE_HYDRANT, 0x5F5A00) \
X("bagelstnd02", MI_BAGELSTAND2, 0x5F59FC) \ X("bagelstnd02", MI_BAGELSTAND2, 0x5F59FC) \
@ -370,14 +372,8 @@ void TestModelIndices(void);
inline bool inline bool
IsGlass(int16 id) IsGlass(int16 id)
{ {
return id == MI_GLASS1 || CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(id);
id == MI_GLASS2 || return mi->IsSimple() && (mi->m_isCodeGlass || mi->m_isArtistGlass);
id == MI_GLASS3 ||
id == MI_GLASS4 ||
id == MI_GLASS5 ||
id == MI_GLASS6 ||
id == MI_GLASS7 ||
id == MI_GLASS8;
} }
inline bool inline bool

View File

@ -55,7 +55,7 @@ CSimpleModelInfo::Init(void)
m_atomics[2] = nil; m_atomics[2] = nil;
m_numAtomics = 0; m_numAtomics = 0;
m_firstDamaged = 0; m_firstDamaged = 0;
m_normalCull = 0; m_wetRoadReflection = 0;
m_isDamaged = 0; m_isDamaged = 0;
m_isBigBuilding = 0; m_isBigBuilding = 0;
m_noFade = 0; m_noFade = 0;
@ -64,6 +64,10 @@ CSimpleModelInfo::Init(void)
m_isSubway = 0; m_isSubway = 0;
m_ignoreLight = 0; m_ignoreLight = 0;
m_noZwrite = 0; m_noZwrite = 0;
m_noShadows = 0;
m_ignoreDrawDist = 0;
m_isCodeGlass = 0;
m_isArtistGlass = 0;
} }
void void
@ -154,6 +158,8 @@ CSimpleModelInfo::FindRelatedModel(void)
} }
} }
#define NEAR_DRAW_DIST 0.0f // 100.0f in liberty city
void void
CSimpleModelInfo::SetupBigBuilding(void) CSimpleModelInfo::SetupBigBuilding(void)
{ {
@ -162,9 +168,13 @@ CSimpleModelInfo::SetupBigBuilding(void)
m_isBigBuilding = 1; m_isBigBuilding = 1;
FindRelatedModel(); FindRelatedModel();
related = GetRelatedModel(); related = GetRelatedModel();
if(related) if(related){
m_lodDistances[2] = related->GetLargestLodDistance()/TheCamera.LODDistMultiplier; m_lodDistances[2] = related->GetLargestLodDistance()/TheCamera.LODDistMultiplier;
else if(m_drawLast){
m_lodDistances[2] = 100.0f; m_drawLast = false;
debug("%s was draw last\n", GetName());
}
}else
m_lodDistances[2] = NEAR_DRAW_DIST;
} }
} }

View File

@ -14,15 +14,22 @@ public:
uint16 m_firstDamaged : 2; // 0: no damage model uint16 m_firstDamaged : 2; // 0: no damage model
// 1: 1 and 2 are damage models // 1: 1 and 2 are damage models
// 2: 2 is damage model // 2: 2 is damage model
uint16 m_normalCull : 1; uint16 m_wetRoadReflection : 1;
uint16 m_isDamaged : 1; uint16 m_isDamaged : 1;
uint16 m_isBigBuilding : 1; uint16 m_isBigBuilding : 1;
uint16 m_noFade : 1; uint16 m_noFade : 1;
uint16 m_drawLast : 1; uint16 m_drawLast : 1;
uint16 m_additive : 1; uint16 m_additive : 1;
uint16 m_isSubway : 1; uint16 m_isSubway : 1;
uint16 m_ignoreLight : 1; uint16 m_ignoreLight : 1;
uint16 m_noZwrite : 1; uint16 m_noZwrite : 1;
uint16 m_noShadows : 1;
uint16 m_ignoreDrawDist : 1;
uint16 m_isCodeGlass : 1;
uint16 m_isArtistGlass : 1;
CSimpleModelInfo(void) : CBaseModelInfo(MITYPE_SIMPLE) {} CSimpleModelInfo(void) : CBaseModelInfo(MITYPE_SIMPLE) {}
CSimpleModelInfo(ModelInfoType id) : CBaseModelInfo(id) {} CSimpleModelInfo(ModelInfoType id) : CBaseModelInfo(id) {}

View File

@ -31,6 +31,10 @@
// Transition areas between zones // Transition areas between zones
const RegenerationPoint aSafeZones[] = { const RegenerationPoint aSafeZones[] = {
// TODO(MIAMI): this is totally bogus
{ LEVEL_BEACH, LEVEL_MAINLAND, 400.0f, 814.0f, -954.0f, -903.0f, 30.0f, 100.0f,
CVector(790.0f, -917.0f, 39.0f), CVector(775.0f, -921.0f, 39.0f), CVector(424.0f, -942.0f, 38.0f), CVector(439.0f, -938.0f, 38.0f) },
#ifndef MIAMI
{ LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 400.0f, 814.0f, -954.0f, -903.0f, 30.0f, 100.0f, { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 400.0f, 814.0f, -954.0f, -903.0f, 30.0f, 100.0f,
CVector(790.0f, -917.0f, 39.0f), CVector(775.0f, -921.0f, 39.0f), CVector(424.0f, -942.0f, 38.0f), CVector(439.0f, -938.0f, 38.0f) }, CVector(790.0f, -917.0f, 39.0f), CVector(775.0f, -921.0f, 39.0f), CVector(424.0f, -942.0f, 38.0f), CVector(439.0f, -938.0f, 38.0f) },
{ LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 555.0f, 711.0f, 118.0f, 186.0f, -30.0f, -10.0f, { LEVEL_INDUSTRIAL, LEVEL_COMMERCIAL, 555.0f, 711.0f, 118.0f, 186.0f, -30.0f, -10.0f,
@ -47,6 +51,7 @@ const RegenerationPoint aSafeZones[] = {
CVector(-321.0f, -1043.0f, -13.2f), CVector(-328.0f, -1045.0f, -13.2f), CVector(-398.0f, -1044.0f, -13.5f), CVector(-390.0f, -1040.5f, -13.5f) }, CVector(-321.0f, -1043.0f, -13.2f), CVector(-328.0f, -1045.0f, -13.2f), CVector(-398.0f, -1044.0f, -13.5f), CVector(-390.0f, -1040.5f, -13.5f) },
{ LEVEL_COMMERCIAL, LEVEL_SUBURBAN, -425.0f, -280.0f, -471.0f, -447.0f, -20.0f, -5.0f, { LEVEL_COMMERCIAL, LEVEL_SUBURBAN, -425.0f, -280.0f, -471.0f, -447.0f, -20.0f, -5.0f,
CVector(-292.0f, -457.0f, -11.6f), CVector(-310.0f, -461.0f, -11.6f), CVector(-413.0f, -461.0f, -11.5f), CVector(-399.0f, -457.0f, -11.3f) } CVector(-292.0f, -457.0f, -11.6f), CVector(-310.0f, -461.0f, -11.6f), CVector(-413.0f, -461.0f, -11.5f), CVector(-399.0f, -457.0f, -11.3f) }
#endif
}; };
PedGroup CPopulation::ms_pPedGroups[NUMPEDGROUPS]; PedGroup CPopulation::ms_pPedGroups[NUMPEDGROUPS];
@ -109,7 +114,6 @@ CPopulation::Initialise()
ms_nTotalCivPeds = 0; ms_nTotalCivPeds = 0;
LoadPedGroups(); LoadPedGroups();
DealWithZoneChange(LEVEL_COMMERCIAL, LEVEL_INDUSTRIAL, true);
debug("CPopulation ready\n"); debug("CPopulation ready\n");
} }
@ -335,49 +339,10 @@ CPopulation::ChooseGangOccupation(int gangId)
return firstGangModel; return firstGangModel;
} }
//--MIAMI: done
void void
CPopulation::DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool forceIndustrialZone) CPopulation::DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool forceIndustrialZone)
{ {
bZoneChangeHasHappened = true;
CVector findSafeZoneAround;
int safeZone;
if (forceIndustrialZone) {
// Commercial to industrial transition area on Callahan Bridge
findSafeZoneAround.x = 690.0f;
findSafeZoneAround.y = -920.0f;
findSafeZoneAround.z = 42.0f;
} else {
findSafeZoneAround = FindPlayerCoors();
}
eLevelName level;
FindCollisionZoneForCoors(&findSafeZoneAround, &safeZone, &level);
// We aren't in a "safe zone", find closest one
if (safeZone < 0)
FindClosestZoneForCoors(&findSafeZoneAround, &safeZone, oldLevel, newLevel);
// No, there should be one!
if (safeZone < 0) {
if (newLevel == LEVEL_INDUSTRIAL) {
safeZone = 0;
} else if (newLevel == LEVEL_SUBURBAN) {
safeZone = 4;
}
}
if (aSafeZones[safeZone].srcLevel == newLevel) {
CPopulation::RegenerationPoint_a = aSafeZones[safeZone].srcPosA;
CPopulation::RegenerationPoint_b = aSafeZones[safeZone].srcPosB;
CPopulation::RegenerationForward = aSafeZones[safeZone].destPosA - aSafeZones[safeZone].srcPosA;
RegenerationForward.Normalise();
} else if (aSafeZones[safeZone].destLevel == newLevel) {
CPopulation::RegenerationPoint_a = aSafeZones[safeZone].destPosA;
CPopulation::RegenerationPoint_b = aSafeZones[safeZone].destPosB;
CPopulation::RegenerationForward = aSafeZones[safeZone].srcPosA - aSafeZones[safeZone].destPosA;
RegenerationForward.Normalise();
}
} }
void void

View File

@ -375,7 +375,8 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
// Simple ModelInfo // Simple ModelInfo
// TODO(MIAMI): area if(!IsAreaVisible(ent->m_area))
return VIS_INVISIBLE;
dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude(); dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude();
@ -469,7 +470,8 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent)
CTimeModelInfo *ti; CTimeModelInfo *ti;
int32 other; int32 other;
// TODO(MIAMI): area if(!IsAreaVisible(ent->m_area))
return VIS_INVISIBLE;
bool request = true; bool request = true;
if(mi->GetModelType() == MITYPE_TIME){ if(mi->GetModelType() == MITYPE_TIME){

View File

@ -14,8 +14,8 @@
#define HUGE_SECTOR_SIZE 128 #define HUGE_SECTOR_SIZE 128
#define EXTRAHUGE_SECTOR_SIZE 256 #define EXTRAHUGE_SECTOR_SIZE 256
#define WATER_START_X -2048.0f #define WATER_START_X (-2048.0f - 400.0f)
#define WATER_END_X 2048.0f #define WATER_END_X (2048.0f - 400.0f)
#define WATER_START_Y -2048.0f #define WATER_START_Y -2048.0f
#define WATER_END_Y 2048.0f #define WATER_END_Y 2048.0f

View File

@ -708,11 +708,6 @@ CVisibilityPlugins::SetAtomicModelInfo(RpAtomic *atomic,
{ {
AtomicExt *ext = ATOMICEXT(atomic); AtomicExt *ext = ATOMICEXT(atomic);
ext->modelInfo = modelInfo; ext->modelInfo = modelInfo;
switch (modelInfo->GetModelType())
case MITYPE_SIMPLE:
case MITYPE_TIME:
if(modelInfo->m_normalCull)
SetAtomicRenderCallback(atomic, RenderObjNormalAtomic);
} }
CSimpleModelInfo* CSimpleModelInfo*

View File

@ -57,7 +57,8 @@ void CCranes::InitCranes(void)
} }
} }
} }
for (CPtrNode* pNode = CWorld::GetBigBuildingList(LEVEL_INDUSTRIAL).first; pNode; pNode = pNode->next) { // TODO(MIAMI): LEVEL_MAINLAND just so it compiles
for (CPtrNode* pNode = CWorld::GetBigBuildingList(LEVEL_MAINLAND).first; pNode; pNode = pNode->next) {
CEntity* pEntity = (CEntity*)pNode->item; CEntity* pEntity = (CEntity*)pNode->item;
if (MODELID_CRANE_1 == pEntity->GetModelIndex() || if (MODELID_CRANE_1 == pEntity->GetModelIndex() ||
MODELID_CRANE_2 == pEntity->GetModelIndex() || MODELID_CRANE_2 == pEntity->GetModelIndex() ||