mirror of
https://github.com/halpz/re3.git
synced 2025-07-12 16:18:08 +00:00
Merge remote-tracking branch 'upstream/miami' into miami
This commit is contained in:
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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++) {
|
||||
|
Reference in New Issue
Block a user