1
0
Fork 0
mirror of https://git.rip/DMCA_FUCKER/re3.git synced 2024-11-05 11:25:54 +00:00

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"
kind "WindowedApp"
targetname "re3"
targetname "reVC"
targetdir "bin/%{cfg.platform}/%{cfg.buildcfg}"
targetextension ".exe"
characterset ("MBCS")

View file

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

View file

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

View file

@ -204,8 +204,13 @@ public:
void Init(void);
void AllocatePathFindInfoMem(int16 numPathGroups);
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 StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, int8 numLeft, int8 numRight);
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, 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);
bool LoadPathFindData(void);
void PreparePathData(void);

View file

@ -11,503 +11,97 @@
#include "World.h"
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)
{
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)
{
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)
{
PROCESS_BUTTON_STATE_STORE(buf, os, ns, LeftStickX, 0);
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;
return nil;
}
#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)
{
for (uint8 i = 0; i < total; i++) {
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;
return nil;
}
#undef PROCESS_BUTTON_STATE_RESTORE
uint16 CRecordDataForGame::CalcGameChecksum(void)
{
uint32 checksum = 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;
return 0;
}
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
// may be wrong
if (Status == STATE_NONE || Status == STATE_PLAYBACK)
return false;
return pad != 0;
return false;
}
#endif
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 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)
{
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)
{
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)
{
for (int i = 0; i < NUM_CHASE_CARS; i++)
RemoveCarFromChase(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* pVehicle = pChaseCars[i];
pChaseCars[i] = nil;
pVehicle->SetStatus(STATUS_PHYSICS);
return pVehicle;
return nil;
}

View file

@ -80,13 +80,13 @@ CRestart::FindClosestHospitalRestartPoint(const CVector &pos, CVector *outPos, f
return;
}
eLevelName curlevel = CTheZones::FindZoneForPoint(pos);
eLevelName curlevel = CTheZones::GetLevelFromPosition(pos);
float fMinDist = 16000000.0f;
int closestPoint = NUM_RESTART_POINTS;
// find closest point on this level
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();
if (fMinDist >= dist) {
fMinDist = dist;
@ -127,13 +127,13 @@ CRestart::FindClosestPoliceRestartPoint(const CVector &pos, CVector *outPos, flo
return;
}
eLevelName curlevel = CTheZones::FindZoneForPoint(pos);
eLevelName curlevel = CTheZones::GetLevelFromPosition(pos);
float fMinDist = 16000000.0f;
int closestPoint = NUM_RESTART_POINTS;
// find closest point on this level
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();
if (fMinDist >= dist) {
fMinDist = dist;

View file

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

View file

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

View file

@ -99,9 +99,6 @@ CFileLoader::LoadLevel(const char *filename)
}
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){
@ -171,6 +168,7 @@ CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot)
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);
@ -554,7 +552,9 @@ CFileLoader::LoadObjectTypes(const char *filename)
enum {
NONE,
OBJS,
MLO, // unused but enum still has it
TOBJ,
WEAP,
HIER,
CARS,
PEDS,
@ -565,16 +565,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;
@ -582,6 +583,7 @@ 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;
@ -591,10 +593,17 @@ CFileLoader::LoadObjectTypes(const char *filename)
section = NONE;
}else switch(section){
case OBJS:
LoadObject(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);
@ -607,17 +616,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;
@ -630,7 +637,7 @@ 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())
mi->SetupBigBuilding();
@ -640,16 +647,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;
@ -660,7 +671,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:
@ -692,9 +703,11 @@ CFileLoader::LoadObject(const char *line)
mi->m_firstDamaged = damaged;
mi->SetTexDictionary(txd);
MatchModelString(model, id);
return id;
}
void
int
CFileLoader::LoadTimeObject(const char *line)
{
int id, numObjs;
@ -706,7 +719,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:
@ -742,6 +755,8 @@ CFileLoader::LoadTimeObject(const char *line)
if(other)
other->SetOtherTimeModel(id);
MatchModelString(model, id);
return id;
}
void
@ -872,33 +887,51 @@ CFileLoader::LoadPedObject(const char *line)
}
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;
int type, next, cross, numLeft, numRight, speed, flags;
float x, y, z, width, spawnRate;
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);
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;
int type, next, cross, numLeft, numRight, speed, flags;
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);
ThePaths.StoreNodeInfoCar(id, node, type, next, x, y, z, 0, numLeft, numRight);
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, 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,
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;
@ -1015,6 +1049,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){
@ -1027,18 +1062,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;
@ -1122,9 +1163,7 @@ CFileLoader::LoadObjectInstance(const char *line)
entity->SetModelIndexNoCreate(id);
entity->GetMatrix() = CMatrix(xform);
CWorld::Add(entity);
// TODO(MIAMI)
//--MIAMI: TODO
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;
@ -1172,54 +1211,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)
{
@ -1230,10 +1222,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;
@ -1249,17 +1241,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;
@ -1289,6 +1279,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 == '#')
@ -1364,6 +1355,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)) {

View file

@ -23,14 +23,14 @@ public:
static void AddTexDictionaries(RwTexDictionary *dst, RwTexDictionary *src);
static void LoadObjectTypes(const char *filename);
static void LoadObject(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);
@ -39,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);

View file

@ -265,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);
@ -588,7 +588,7 @@ void CGame::InitialiseWhenRestarting(void)
CTimer::Initialise();
FrontEndMenuManager.m_bWantToLoad = false;
ReInitGameObjectVariables();
currLevel = LEVEL_INDUSTRIAL;
currLevel = LEVEL_NONE;
CCollision::SortOutCollisionAfterLoad();
}
}

View file

@ -3,9 +3,30 @@
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
};
enum eVisibilityArea
@ -66,3 +87,5 @@ public:
static void DrasticTidyUpMemory(bool);
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;
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;
bool
CStreamingInfo::GetCdPosnAndSize(uint32 &posn, uint32 &size)
@ -212,21 +206,12 @@ CStreaming::Init2(void)
// 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);
pIslandLODmainlandEntity = nil;
pIslandLODbeachEntity = nil;
islandLODmainland = -1;
islandLODbeach = -1;
CModelInfo::GetModelInfo("IslandLODmainland", &islandLODmainland);
CModelInfo::GetModelInfo("IslandLODbeach", &islandLODbeach);
}
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
void
@ -772,21 +716,18 @@ CStreaming::InstanceBigBuildings(eLevelName level, const CVector &pos)
}
}
//--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;
}
}
@ -906,16 +847,14 @@ CStreaming::RemoveModel(int32 id)
ms_aInfoForModel[id].m_loadState = STREAMSTATE_NOTLOADED;
}
//--MIAMI: change islands
//--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
@ -979,16 +918,14 @@ CStreaming::RemoveBuildings(eLevelName level)
}
}
//--MIAMI: change islands
//--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);
}
@ -1009,40 +946,23 @@ void
CStreaming::RemoveIslandsNotUsed(eLevelName level)
{
int i;
if(pIslandLODindustEntity == nil)
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() == 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;
if(building->GetModelIndex() == islandLODmainland)
pIslandLODmainlandEntity = building;
if(building->GetModelIndex() == islandLODbeach)
pIslandLODbeachEntity = building;
}
switch(level){
case LEVEL_INDUSTRIAL:
DeleteIsland(pIslandLODindustEntity);
DeleteIsland(pIslandLODcomSubEntity);
DeleteIsland(pIslandLODsubComEntity);
case LEVEL_MAINLAND:
DeleteIsland(pIslandLODmainlandEntity);
break;
case LEVEL_COMMERCIAL:
DeleteIsland(pIslandLODcomIndEntity);
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);
case LEVEL_BEACH:
DeleteIsland(pIslandLODbeachEntity);
break;
}
}

View file

@ -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)

View file

@ -139,7 +139,11 @@ CTheZones::CreateZone(char *name, eZoneType type,
for(p = name; *p; p++) if(islower(*p)) *p = toupper(*p);
// 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);
zone->name[7] = '\0';
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
CTheZones::PostZoneCreation(void)
{
@ -565,18 +539,6 @@ 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;
}
void
CTheZones::AddZoneToAudioZoneArray(CZone *zone)
{

View file

@ -71,10 +71,6 @@ 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 void PostZoneCreation(void);
static void InsertZoneIntoZoneHierarchy(CZone *zone);
@ -103,7 +99,6 @@ 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 void AddZoneToAudioZoneArray(CZone *zone);

View file

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

View file

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

View file

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

View file

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

View file

@ -55,7 +55,7 @@ CSimpleModelInfo::Init(void)
m_atomics[2] = nil;
m_numAtomics = 0;
m_firstDamaged = 0;
m_normalCull = 0;
m_wetRoadReflection = 0;
m_isDamaged = 0;
m_isBigBuilding = 0;
m_noFade = 0;
@ -64,6 +64,10 @@ CSimpleModelInfo::Init(void)
m_isSubway = 0;
m_ignoreLight = 0;
m_noZwrite = 0;
m_noShadows = 0;
m_ignoreDrawDist = 0;
m_isCodeGlass = 0;
m_isArtistGlass = 0;
}
void
@ -154,6 +158,8 @@ CSimpleModelInfo::FindRelatedModel(void)
}
}
#define NEAR_DRAW_DIST 0.0f // 100.0f in liberty city
void
CSimpleModelInfo::SetupBigBuilding(void)
{
@ -162,9 +168,13 @@ CSimpleModelInfo::SetupBigBuilding(void)
m_isBigBuilding = 1;
FindRelatedModel();
related = GetRelatedModel();
if(related)
if(related){
m_lodDistances[2] = related->GetLargestLodDistance()/TheCamera.LODDistMultiplier;
else
m_lodDistances[2] = 100.0f;
if(m_drawLast){
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
// 1: 1 and 2 are damage models
// 2: 2 is damage model
uint16 m_normalCull : 1;
uint16 m_wetRoadReflection : 1;
uint16 m_isDamaged : 1;
uint16 m_isBigBuilding : 1;
uint16 m_noFade : 1;
uint16 m_drawLast : 1;
uint16 m_additive : 1;
uint16 m_isSubway : 1;
uint16 m_ignoreLight : 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(ModelInfoType id) : CBaseModelInfo(id) {}

View file

@ -31,6 +31,10 @@
// Transition areas between zones
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,
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,
@ -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) },
{ 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) }
#endif
};
PedGroup CPopulation::ms_pPedGroups[NUMPEDGROUPS];
@ -109,7 +114,6 @@ CPopulation::Initialise()
ms_nTotalCivPeds = 0;
LoadPedGroups();
DealWithZoneChange(LEVEL_COMMERCIAL, LEVEL_INDUSTRIAL, true);
debug("CPopulation ready\n");
}
@ -335,49 +339,10 @@ CPopulation::ChooseGangOccupation(int gangId)
return firstGangModel;
}
//--MIAMI: done
void
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

View file

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

View file

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

View file

@ -708,11 +708,6 @@ CVisibilityPlugins::SetAtomicModelInfo(RpAtomic *atomic,
{
AtomicExt *ext = ATOMICEXT(atomic);
ext->modelInfo = modelInfo;
switch (modelInfo->GetModelType())
case MITYPE_SIMPLE:
case MITYPE_TIME:
if(modelInfo->m_normalCull)
SetAtomicRenderCallback(atomic, RenderObjNormalAtomic);
}
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;
if (MODELID_CRANE_1 == pEntity->GetModelIndex() ||
MODELID_CRANE_2 == pEntity->GetModelIndex() ||