Merge branch 'master' of https://github.com/GTAmodding/re3 into erorcun

This commit is contained in:
eray orçunus 2020-05-28 11:40:56 +03:00
commit 98fec63ca7
11 changed files with 325 additions and 5 deletions

View File

@ -83,12 +83,20 @@ CGameLogic::Update()
} }
break; break;
case WBSTATE_WASTED: case WBSTATE_WASTED:
#ifdef MISSION_REPLAY
if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > AddExtraDeathDelay() + 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= AddExtraDeathDelay() + 0x800)) {
#else
if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) { if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) {
#endif
TheCamera.SetFadeColour(200, 200, 200); TheCamera.SetFadeColour(200, 200, 200);
TheCamera.Fade(2.0f, FADE_OUT); TheCamera.Fade(2.0f, FADE_OUT);
} }
#ifdef MISSION_REPLAY
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= AddExtraDeathDelay() + 0x1000) {
#else
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) { if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) {
#endif
pPlayerInfo.m_WBState = WBSTATE_PLAYING; pPlayerInfo.m_WBState = WBSTATE_PLAYING;
if (pPlayerInfo.m_bGetOutOfHospitalFree) { if (pPlayerInfo.m_bGetOutOfHospitalFree) {
pPlayerInfo.m_bGetOutOfHospitalFree = false; pPlayerInfo.m_bGetOutOfHospitalFree = false;
@ -131,11 +139,19 @@ CGameLogic::Update()
} }
break; break;
case WBSTATE_BUSTED: case WBSTATE_BUSTED:
#ifdef MISSION_REPLAY
if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > AddExtraDeathDelay() + 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= AddExtraDeathDelay() + 0x800)) {
#else
if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) { if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) {
#endif
TheCamera.SetFadeColour(0, 0, 0); TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(2.0f, FADE_OUT); TheCamera.Fade(2.0f, FADE_OUT);
} }
#ifdef MISSION_REPLAY
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= AddExtraDeathDelay() + 0x1000) {
#else
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) { if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) {
#endif
pPlayerInfo.m_WBState = WBSTATE_PLAYING; pPlayerInfo.m_WBState = WBSTATE_PLAYING;
int takeMoney; int takeMoney;
@ -203,11 +219,19 @@ CGameLogic::Update()
} }
break; break;
case WBSTATE_FAILED_CRITICAL_MISSION: case WBSTATE_FAILED_CRITICAL_MISSION:
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800 && CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800) { #ifdef MISSION_REPLAY
if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > AddExtraDeathDelay() + 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= AddExtraDeathDelay() + 0x800)) {
#else
if ((CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime > 0x800) && (CTimer::GetPreviousTimeInMilliseconds() - pPlayerInfo.m_nWBTime <= 0x800)) {
#endif
TheCamera.SetFadeColour(0, 0, 0); TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(2.0f, FADE_OUT); TheCamera.Fade(2.0f, FADE_OUT);
} }
#ifdef MISSION_REPLAY
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= AddExtraDeathDelay() + 0x1000) {
#else
if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) { if (CTimer::GetTimeInMilliseconds() - pPlayerInfo.m_nWBTime >= 0x1000) {
#endif
pPlayerInfo.m_WBState = WBSTATE_PLAYING; pPlayerInfo.m_WBState = WBSTATE_PLAYING;
if (pPlayerInfo.m_pPed->bInVehicle) { if (pPlayerInfo.m_pPed->bInVehicle) {
CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle; CVehicle *pVehicle = pPlayerInfo.m_pPed->m_pMyVehicle;

View File

@ -27,6 +27,9 @@
#include "Gangs.h" #include "Gangs.h"
#include "Garages.h" #include "Garages.h"
#include "General.h" #include "General.h"
#ifdef MISSION_REPLAY
#include "GenericGameStorage.h"
#endif
#include "HandlingMgr.h" #include "HandlingMgr.h"
#include "Heli.h" #include "Heli.h"
#include "Hud.h" #include "Hud.h"
@ -127,6 +130,38 @@ uint16 CTheScripts::CommandsExecuted;
uint16 CTheScripts::ScriptsUpdated; uint16 CTheScripts::ScriptsUpdated;
int32 ScriptParams[32]; int32 ScriptParams[32];
#ifdef MISSION_REPLAY
static const char* nonMissionScripts[] = {
"copcar",
"ambulan",
"taxi",
"firetru",
"rampage",
"t4x4_1",
"t4x4_2",
"t4x4_3",
"rc1",
"rc2",
"rc3",
"rc4",
"hj",
"usj",
"mayhem"
};
int AllowMissionReplay;
uint32 NextMissionDelay;
uint32 MissionStartTime;
uint32 WaitForMissionActivate;
uint32 WaitForSave;
float oldTargetX;
float oldTargetY;
int missionRetryScriptIndex;
bool doingMissionRetry;
#endif
const uint32 CRunningScript::nSaveStructSize = const uint32 CRunningScript::nSaveStructSize =
#ifdef COMPATIBLE_SAVES #ifdef COMPATIBLE_SAVES
@ -677,6 +712,41 @@ void CTheScripts::Process()
if (UseTextCommands == 1) if (UseTextCommands == 1)
UseTextCommands = 0; UseTextCommands = 0;
} }
#ifdef MISSION_REPLAY
static uint32 TimeToWaitTill;
switch (AllowMissionReplay) {
case 2:
AllowMissionReplay = 3;
TimeToWaitTill = CTimer::GetTimeInMilliseconds() + (AddExtraDeathDelay() > 1000 ? 4000 : 2500);
break;
case 3:
if (TimeToWaitTill < CTimer::GetTimeInMilliseconds())
AllowMissionReplay = 4;
break;
case 4:
AllowMissionReplay = 5;
RetryMission(0, 0);
case 6:
AllowMissionReplay = 7;
TimeToWaitTill = CTimer::GetTimeInMilliseconds() + 500;
case 7:
if (TimeToWaitTill < CTimer::GetTimeInMilliseconds()) {
AllowMissionReplay = 0;
return;
}
break;
}
if (WaitForMissionActivate) {
if (WaitForMissionActivate > CTimer::GetTimeInMilliseconds())
return;
WaitForMissionActivate = 0;
WaitForSave = CTimer::GetTimeInMilliseconds() + 3000;
}
if (WaitForSave && WaitForSave > CTimer::GetTimeInMilliseconds())
WaitForSave = 0;
#endif
CRunningScript* script = pActiveScripts; CRunningScript* script = pActiveScripts;
while (script != nil){ while (script != nil){
CRunningScript* next = script->GetNext(); CRunningScript* next = script->GetNext();
@ -1250,6 +1320,17 @@ int8 CRunningScript::ProcessCommands0To99(int32 command)
CTheScripts::bAlreadyRunningAMissionScript = false; CTheScripts::bAlreadyRunningAMissionScript = false;
RemoveScriptFromList(&CTheScripts::pActiveScripts); RemoveScriptFromList(&CTheScripts::pActiveScripts);
AddScriptToList(&CTheScripts::pIdleScripts); AddScriptToList(&CTheScripts::pIdleScripts);
#ifdef MISSION_REPLAY
if (m_bMissionFlag) {
CPlayerInfo* pPlayerInfo = &CWorld::Players[CWorld::PlayerInFocus];
if (pPlayerInfo->m_pPed->GetPedState() != PED_DEAD && pPlayerInfo->m_WBState == WBSTATE_PLAYING && !m_bDeatharrestExecuted)
SaveGameForPause(1);
oldTargetX = oldTargetY = 0.0f;
if (AllowMissionReplay == 1)
AllowMissionReplay = 2;
// I am fairly sure they forgot to set return value here
}
#endif
return 1; return 1;
case COMMAND_START_NEW_SCRIPT: case COMMAND_START_NEW_SCRIPT:
{ {
@ -2160,7 +2241,14 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
CollectParameters(&m_nIp, 2); CollectParameters(&m_nIp, 2);
CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
assert(car); assert(car);
#if defined MISSION_REPLAY && defined SIMPLIER_MISSIONS
car->AutoPilot.m_nCruiseSpeed = *(float*)&ScriptParams[1];
if (missionRetryScriptIndex == 40 && car->GetModelIndex() == MI_CHEETAH) // Turismo
car->AutoPilot.m_nCruiseSpeed = 8 * car->AutoPilot.m_nCruiseSpeed / 10;
car->AutoPilot.m_nCruiseSpeed = Min(car->AutoPilot.m_nCruiseSpeed, 60.0f * car->pHandling->Transmission.fUnkMaxVelocity);
#else
car->AutoPilot.m_nCruiseSpeed = Min(*(float*)&ScriptParams[1], 60.0f * car->pHandling->Transmission.fUnkMaxVelocity); car->AutoPilot.m_nCruiseSpeed = Min(*(float*)&ScriptParams[1], 60.0f * car->pHandling->Transmission.fUnkMaxVelocity);
#endif
return 0; return 0;
} }
case COMMAND_SET_CAR_DRIVING_STYLE: case COMMAND_SET_CAR_DRIVING_STYLE:
@ -2230,6 +2318,10 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
case COMMAND_PRINT_BIG: case COMMAND_PRINT_BIG:
{ {
wchar* key = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); wchar* key = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]);
#ifdef MISSION_REPLAY
if (strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "M_FAIL") == 0 && CanAllowMissionReplay())
AllowMissionReplay = 1;
#endif
m_nIp += KEY_LENGTH_IN_SCRIPT; m_nIp += KEY_LENGTH_IN_SCRIPT;
CollectParameters(&m_nIp, 2); CollectParameters(&m_nIp, 2);
CMessages::AddBigMessage(key, ScriptParams[0], ScriptParams[1] - 1); CMessages::AddBigMessage(key, ScriptParams[0], ScriptParams[1] - 1);
@ -8490,6 +8582,10 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
case COMMAND_MAKE_PLAYER_SAFE_FOR_CUTSCENE: case COMMAND_MAKE_PLAYER_SAFE_FOR_CUTSCENE:
{ {
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
#ifdef MISSION_REPLAY
AllowMissionReplay = 0;
SaveGameForPause(3);
#endif
CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]]; CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
CPad::GetPad(ScriptParams[0])->DisablePlayerControls |= PLAYERCONTROL_DISABLED_80; CPad::GetPad(ScriptParams[0])->DisablePlayerControls |= PLAYERCONTROL_DISABLED_80;
pPlayerInfo->MakePlayerSafe(true); pPlayerInfo->MakePlayerSafe(true);
@ -8696,6 +8792,11 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
case COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL: case COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL:
{ {
CollectParameters(&m_nIp, 1); CollectParameters(&m_nIp, 1);
#ifdef MISSION_REPLAY
missionRetryScriptIndex = ScriptParams[0];
if (missionRetryScriptIndex == 19)
CStats::LastMissionPassedName[0] = '\0';
#endif
CTimer::Suspend(); CTimer::Suspend();
int offset = CTheScripts::MultiScriptArray[ScriptParams[0]]; int offset = CTheScripts::MultiScriptArray[ScriptParams[0]];
CFileMgr::ChangeDir("\\"); CFileMgr::ChangeDir("\\");
@ -11085,6 +11186,12 @@ void CRunningScript::DoDeatharrestCheck()
CPlayerInfo* pPlayer = &CWorld::Players[CWorld::PlayerInFocus]; CPlayerInfo* pPlayer = &CWorld::Players[CWorld::PlayerInFocus];
if (!pPlayer->IsRestartingAfterDeath() && !pPlayer->IsRestartingAfterArrest() && !CTheScripts::UpsideDownCars.AreAnyCarsUpsideDown()) if (!pPlayer->IsRestartingAfterDeath() && !pPlayer->IsRestartingAfterArrest() && !CTheScripts::UpsideDownCars.AreAnyCarsUpsideDown())
return; return;
#ifdef MISSION_REPLAY
if (AllowMissionReplay != 0)
return;
if (CanAllowMissionReplay())
AllowMissionReplay = 1;
#endif
assert(m_nStackPointer > 0); assert(m_nStackPointer > 0);
while (m_nStackPointer > 1) while (m_nStackPointer > 1)
--m_nStackPointer; --m_nStackPointer;
@ -11766,3 +11873,43 @@ void CRunningScript::Load(uint8*& buf)
prev = p; prev = p;
#endif #endif
} }
#ifdef MISSION_REPLAY
bool CRunningScript::CanAllowMissionReplay()
{
if (AllowMissionReplay)
return false;
if (CStats::LastMissionPassedName[0] == '\0')
return false;
for (int i = 0; i < ARRAY_SIZE(nonMissionScripts); i++) {
if (strcmp(m_abScriptName, nonMissionScripts[i]) == 0)
return false;
}
return true;
}
uint32 AddExtraDeathDelay()
{
if (missionRetryScriptIndex == 63)
return 7000;
if (missionRetryScriptIndex == 64)
return 4000;
return 1000;
}
void RetryMission(int type, int unk)
{
if (type == 0) {
doingMissionRetry = true;
FrontEndMenuManager.m_nCurrScreen = MENUPAGE_MISSION_RETRY;
FrontEndMenuManager.RequestFrontEndStartUp();
}
else if (type == 2) {
doingMissionRetry = false;
AllowMissionReplay = 6;
CTheScripts::MissionCleanup.Process();
}
}
#endif

View File

@ -372,6 +372,9 @@ private:
friend class CRunningScript; friend class CRunningScript;
friend class CHud; friend class CHud;
friend void CMissionCleanup::Process(); friend void CMissionCleanup::Process();
#ifdef FIX_BUGS
friend void RetryMission(int, int);
#endif
}; };
@ -479,6 +482,10 @@ private:
void CharInAreaCheckCommand(int32, uint32*); void CharInAreaCheckCommand(int32, uint32*);
void CarInAreaCheckCommand(int32, uint32*); void CarInAreaCheckCommand(int32, uint32*);
#ifdef MISSION_REPLAY
bool CanAllowMissionReplay();
#endif
float LimitAngleOnCircle(float angle) { return angle < 0.0f ? angle + 360.0f : angle; } float LimitAngleOnCircle(float angle) { return angle < 0.0f ? angle + 360.0f : angle; }
bool ThisIsAValidRandomPed(uint32 pedtype) { bool ThisIsAValidRandomPed(uint32 pedtype) {
@ -502,3 +509,15 @@ private:
} }
} }
}; };
#ifdef MISSION_REPLAY
extern int AllowMissionReplay;
extern uint32 WaitForMissionActivate;
extern uint32 WaitForSave;
extern uint32 MissionStartTime;
extern int missionRetryScriptIndex;
extern bool doingMissionRetry;
uint32 AddExtraDeathDelay();
void RetryMission(int, int);
#endif

View File

@ -3560,6 +3560,13 @@ CMenuManager::Process(void)
SaveLoadFileError_SetUpErrorScreen(); SaveLoadFileError_SetUpErrorScreen();
} }
if (m_nCurrScreen == MENUPAGE_LOADING_IN_PROGRESS) { if (m_nCurrScreen == MENUPAGE_LOADING_IN_PROGRESS) {
#ifdef MISSION_REPLAY
if (doingMissionRetry) {
RetryMission(2, 0);
m_nCurrSaveSlot = SLOT_COUNT;
doingMissionRetry = false;
}
#endif
if (CheckSlotDataValid(m_nCurrSaveSlot)) { if (CheckSlotDataValid(m_nCurrSaveSlot)) {
TheCamera.m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD; TheCamera.m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD;
if (m_PrefsVsyncDisp != m_PrefsVsync) if (m_PrefsVsyncDisp != m_PrefsVsync)
@ -4694,6 +4701,18 @@ CMenuManager::ProcessButtonPresses(void)
DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1); DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
OutputDebugString("STARTED PLAYING FRONTEND AUDIO TRACK"); OutputDebugString("STARTED PLAYING FRONTEND AUDIO TRACK");
break; break;
#ifdef MISSION_REPLAY
case MENUACTION_REJECT_RETRY:
doingMissionRetry = false;
AllowMissionReplay = 0;
RequestFrontEndShutDown();
break;
case MENUACTION_UNK114:
doingMissionRetry = false;
RequestFrontEndShutDown();
RetryMission(2, 0);
return;
#endif
#ifdef CUSTOM_FRONTEND_OPTIONS #ifdef CUSTOM_FRONTEND_OPTIONS
case MENUACTION_TRIGGERFUNC: case MENUACTION_TRIGGERFUNC:
FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu]; FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu];

View File

@ -245,7 +245,7 @@ enum eMenuScreen
MENUPAGE_SKIN_SELECT = 54, MENUPAGE_SKIN_SELECT = 54,
MENUPAGE_KEYBOARD_CONTROLS = 55, MENUPAGE_KEYBOARD_CONTROLS = 55,
MENUPAGE_MOUSE_CONTROLS = 56, MENUPAGE_MOUSE_CONTROLS = 56,
MENUPAGE_57 = 57, // mission failed, wanna restart page in mobile MENUPAGE_MISSION_RETRY = 57,
MENUPAGE_58 = 58, MENUPAGE_58 = 58,
#ifdef MENU_MAP #ifdef MENU_MAP
MENUPAGE_MAP = 59, MENUPAGE_MAP = 59,
@ -366,6 +366,10 @@ enum eMenuAction
MENUACTION_UNK108, MENUACTION_UNK108,
MENUACTION_UNK109, MENUACTION_UNK109,
MENUACTION_UNK110, MENUACTION_UNK110,
MENUACTION_UNK111,
MENUACTION_UNK112,
MENUACTION_REJECT_RETRY,
MENUACTION_UNK114,
#ifdef CUSTOM_FRONTEND_OPTIONS #ifdef CUSTOM_FRONTEND_OPTIONS
MENUACTION_TRIGGERFUNC MENUACTION_TRIGGERFUNC
#endif #endif

View File

@ -417,11 +417,19 @@ CMenuScreen aScreens[] = {
MENUACTION_MOUSESTEER, "FET_MST", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS, MENUACTION_MOUSESTEER, "FET_MST", SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS,
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
}, },
// MENUPAGE_MISSION_RETRY = 57
#ifdef MISSION_REPLAY
// MENUPAGE_57 = 57 { "M_FAIL", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
MENUACTION_LABEL, "FESZ_RM", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CHANGEMENU, "FEM_YES", SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS,
MENUACTION_REJECT_RETRY, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE
},
#else
{ "", 0, MENUPAGE_NONE, MENUPAGE_NONE, 0, 0, { "", 0, MENUPAGE_NONE, MENUPAGE_NONE, 0, 0,
// mission failed, wanna restart page in mobile // mission failed, wanna restart page in mobile
}, },
#endif
// MENUPAGE_58 = 58 // MENUPAGE_58 = 58
{ "", 0, MENUPAGE_NONE, MENUPAGE_NONE, 0, 0, { "", 0, MENUPAGE_NONE, MENUPAGE_NONE, 0, 0,

View File

@ -4,6 +4,9 @@
#include "Boat.h" #include "Boat.h"
#include "CarCtrl.h" #include "CarCtrl.h"
#ifdef MISSION_REPLAY
#include "GenericGameStorage.h"
#endif
#include "Population.h" #include "Population.h"
#include "ProjectileInfo.h" #include "ProjectileInfo.h"
#include "Streaming.h" #include "Streaming.h"
@ -206,11 +209,24 @@ INITSAVEBUF
if (pVehicle->pPassengers[j]) if (pVehicle->pPassengers[j])
bHasPassenger = true; bHasPassenger = true;
} }
#ifdef MISSION_REPLAY
bool bForceSaving = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pMyVehicle == pVehicle && IsQuickSave;
#ifdef FIX_BUGS
if ((!pVehicle->pDriver && !bHasPassenger) || bForceSaving) {
#else
if (!pVehicle->pDriver && !bHasPassenger) {
#endif
if (pVehicle->IsCar() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving))
++nNumCars;
if (pVehicle->IsBoat() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving))
++nNumBoats;
#else
if (!pVehicle->pDriver && !bHasPassenger) { if (!pVehicle->pDriver && !bHasPassenger) {
if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE)
++nNumCars; ++nNumCars;
if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE)
++nNumBoats; ++nNumBoats;
#endif
} }
} }
*size = nNumCars * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CAutomobile::nSaveStructSize) + sizeof(int) + *size = nNumCars * (sizeof(uint32) + sizeof(int16) + sizeof(int32) + CAutomobile::nSaveStructSize) + sizeof(int) +
@ -226,23 +242,42 @@ INITSAVEBUF
if (pVehicle->pPassengers[j]) if (pVehicle->pPassengers[j])
bHasPassenger = true; bHasPassenger = true;
} }
#ifdef MISSION_REPLAY
bool bForceSaving = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pMyVehicle == pVehicle && IsQuickSave;
#endif
#if defined FIX_BUGS && defined MISSION_REPLAY
if ((!pVehicle->pDriver && !bHasPassenger) || bForceSaving) {
#else
if (!pVehicle->pDriver && !bHasPassenger) { if (!pVehicle->pDriver && !bHasPassenger) {
#endif
#ifdef COMPATIBLE_SAVES #ifdef COMPATIBLE_SAVES
#ifdef MISSION_REPLAY
if ((pVehicle->IsCar() || pVehicle->IsBoat()) && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) {
#else
if ((pVehicle->IsCar() || pVehicle->IsBoat()) && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { if ((pVehicle->IsCar() || pVehicle->IsBoat()) && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
#endif
WriteSaveBuf<uint32>(buf, pVehicle->m_vehType); WriteSaveBuf<uint32>(buf, pVehicle->m_vehType);
WriteSaveBuf<int16>(buf, pVehicle->GetModelIndex()); WriteSaveBuf<int16>(buf, pVehicle->GetModelIndex());
WriteSaveBuf<int32>(buf, GetVehicleRef(pVehicle)); WriteSaveBuf<int32>(buf, GetVehicleRef(pVehicle));
pVehicle->Save(buf); pVehicle->Save(buf);
} }
#else
#ifdef MISSION_REPLAY
if (pVehicle->IsCar() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) {
#else #else
if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { if (pVehicle->IsCar() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
#endif
WriteSaveBuf(buf, (uint32)pVehicle->m_vehType); WriteSaveBuf(buf, (uint32)pVehicle->m_vehType);
WriteSaveBuf(buf, pVehicle->GetModelIndex()); WriteSaveBuf(buf, pVehicle->GetModelIndex());
WriteSaveBuf(buf, GetVehicleRef(pVehicle)); WriteSaveBuf(buf, GetVehicleRef(pVehicle));
memcpy(buf, pVehicle, sizeof(CAutomobile)); memcpy(buf, pVehicle, sizeof(CAutomobile));
SkipSaveBuf(buf, sizeof(CAutomobile)); SkipSaveBuf(buf, sizeof(CAutomobile));
} }
#ifdef MISSION_REPLAY
if (pVehicle->IsBoat() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving)) {
#else
if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) { if (pVehicle->IsBoat() && pVehicle->VehicleCreatedBy == MISSION_VEHICLE) {
#endif
WriteSaveBuf(buf, (uint32)pVehicle->m_vehType); WriteSaveBuf(buf, (uint32)pVehicle->m_vehType);
WriteSaveBuf(buf, pVehicle->GetModelIndex()); WriteSaveBuf(buf, pVehicle->GetModelIndex());
WriteSaveBuf(buf, GetVehicleRef(pVehicle)); WriteSaveBuf(buf, GetVehicleRef(pVehicle));
@ -400,7 +435,11 @@ INITSAVEBUF
CPed* pPed = GetPedPool()->GetSlot(i); CPed* pPed = GetPedPool()->GetSlot(i);
if (!pPed) if (!pPed)
continue; continue;
#ifdef MISSION_REPLAY
if ((!pPed->bInVehicle || (pPed == CWorld::Players[CWorld::PlayerInFocus].m_pPed && IsQuickSave)) && pPed->m_nPedType == PEDTYPE_PLAYER1)
#else
if (!pPed->bInVehicle && pPed->m_nPedType == PEDTYPE_PLAYER1) if (!pPed->bInVehicle && pPed->m_nPedType == PEDTYPE_PLAYER1)
#endif
nNumPeds++; nNumPeds++;
} }
*size = sizeof(int) + nNumPeds * (sizeof(uint32) + sizeof(int16) + sizeof(int) + CPlayerPed::nSaveStructSize + *size = sizeof(int) + nNumPeds * (sizeof(uint32) + sizeof(int16) + sizeof(int) + CPlayerPed::nSaveStructSize +
@ -410,7 +449,11 @@ INITSAVEBUF
CPed* pPed = GetPedPool()->GetSlot(i); CPed* pPed = GetPedPool()->GetSlot(i);
if (!pPed) if (!pPed)
continue; continue;
#ifdef MISSION_REPLAY
if ((!pPed->bInVehicle || (pPed == CWorld::Players[CWorld::PlayerInFocus].m_pPed && IsQuickSave)) && pPed->m_nPedType == PEDTYPE_PLAYER1) {
#else
if (!pPed->bInVehicle && pPed->m_nPedType == PEDTYPE_PLAYER1) { if (!pPed->bInVehicle && pPed->m_nPedType == PEDTYPE_PLAYER1) {
#endif
CopyToBuf(buf, pPed->m_nPedType); CopyToBuf(buf, pPed->m_nPedType);
CopyToBuf(buf, pPed->m_modelIndex); CopyToBuf(buf, pPed->m_modelIndex);
int32 ref = GetPedRef(pPed); int32 ref = GetPedRef(pPed);

View File

@ -228,6 +228,8 @@ enum Config {
#define USE_DEBUG_SCRIPT_LOADER // makes game load main_freeroam.scm by default #define USE_DEBUG_SCRIPT_LOADER // makes game load main_freeroam.scm by default
#define USE_MEASUREMENTS_IN_METERS // makes game use meters instead of feet in script #define USE_MEASUREMENTS_IN_METERS // makes game use meters instead of feet in script
#define USE_PRECISE_MEASUREMENT_CONVERTION // makes game convert feet to meeters more precisely #define USE_PRECISE_MEASUREMENT_CONVERTION // makes game convert feet to meeters more precisely
#define MISSION_REPLAY // mobile feature
//#define SIMPLIER_MISSIONS // apply simplifications from mobile
#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible #define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible

View File

@ -42,6 +42,11 @@
const uint32 SIZE_OF_ONE_GAME_IN_BYTES = 201729; const uint32 SIZE_OF_ONE_GAME_IN_BYTES = 201729;
#ifdef MISSION_REPLAY
int8 IsQuickSave;
const int PAUSE_SAVE_SLOT = SLOT_COUNT;
#endif
char DefaultPCSaveFileName[260]; char DefaultPCSaveFileName[260];
char ValidSaveName[260]; char ValidSaveName[260];
char LoadFileName[256]; char LoadFileName[256];
@ -134,7 +139,12 @@ GenericSave(int file)
WriteDataToBufferPointer(buf, saveName); WriteDataToBufferPointer(buf, saveName);
GetLocalTime(&saveTime); GetLocalTime(&saveTime);
WriteDataToBufferPointer(buf, saveTime); WriteDataToBufferPointer(buf, saveTime);
#ifdef MISSION_REPLAY
int32 data = IsQuickSave << 24 | SIZE_OF_ONE_GAME_IN_BYTES;
WriteDataToBufferPointer(buf, data);
#else
WriteDataToBufferPointer(buf, SIZE_OF_ONE_GAME_IN_BYTES); WriteDataToBufferPointer(buf, SIZE_OF_ONE_GAME_IN_BYTES);
#endif
WriteDataToBufferPointer(buf, CGame::currLevel); WriteDataToBufferPointer(buf, CGame::currLevel);
WriteDataToBufferPointer(buf, TheCamera.GetPosition().x); WriteDataToBufferPointer(buf, TheCamera.GetPosition().x);
WriteDataToBufferPointer(buf, TheCamera.GetPosition().y); WriteDataToBufferPointer(buf, TheCamera.GetPosition().y);
@ -240,6 +250,9 @@ GenericLoad()
uint8 *buf; uint8 *buf;
int32 file; int32 file;
uint32 size; uint32 size;
#ifdef MISSION_REPLAY
int8 qs;
#endif
int32 saveSize; int32 saveSize;
CPad *currPad; CPad *currPad;
@ -254,6 +267,9 @@ GenericLoad()
ReadDataFromFile(file, work_buff, size); ReadDataFromFile(file, work_buff, size);
buf = (work_buff + 0x40); buf = (work_buff + 0x40);
ReadDataFromBufferPointer(buf, saveSize); ReadDataFromBufferPointer(buf, saveSize);
#ifdef MISSION_REPLAY // a hack to keep compatibility but get new data from save
qs = saveSize >> 24;
#endif
ReadDataFromBufferPointer(buf, CGame::currLevel); ReadDataFromBufferPointer(buf, CGame::currLevel);
ReadDataFromBufferPointer(buf, TheCamera.GetMatrix().GetPosition().x); ReadDataFromBufferPointer(buf, TheCamera.GetMatrix().GetPosition().x);
ReadDataFromBufferPointer(buf, TheCamera.GetMatrix().GetPosition().y); ReadDataFromBufferPointer(buf, TheCamera.GetMatrix().GetPosition().y);
@ -296,6 +312,11 @@ GenericLoad()
ReadDataFromBufferPointer(buf, TheCamera.PedZoomIndicator); ReadDataFromBufferPointer(buf, TheCamera.PedZoomIndicator);
#endif #endif
assert(buf - work_buff == SIZE_OF_SIMPLEVARS); assert(buf - work_buff == SIZE_OF_SIMPLEVARS);
#ifdef MISSION_REPLAY
WaitForSave = 0;
if (FrontEndMenuManager.m_nCurrSaveSlot == PAUSE_SAVE_SLOT && qs == 3)
WaitForMissionActivate = CTimer::GetTimeInMilliseconds() + 2000;
#endif
ReadDataFromBlock("Loading Scripts \n", CTheScripts::LoadAllScripts); ReadDataFromBlock("Loading Scripts \n", CTheScripts::LoadAllScripts);
// Load the rest // Load the rest
@ -563,3 +584,27 @@ align4bytes(int32 size)
{ {
return (size + 3) & 0xFFFFFFFC; return (size + 3) & 0xFFFFFFFC;
} }
#ifdef MISSION_REPLAY
void DisplaySaveResult(int unk, char* name)
{}
bool SaveGameForPause(int type)
{
if (AllowMissionReplay != 0 || type != 3 && WaitForSave > CTimer::GetTimeInMilliseconds())
return false;
WaitForSave = 0;
if (gGameState != GS_PLAYING_GAME || CTheScripts::IsPlayerOnAMission() || CStats::LastMissionPassedName[0] == '\0') {
DisplaySaveResult(3, CStats::LastMissionPassedName);
return false;
}
IsQuickSave = type;
MissionStartTime = 0;
int res = PcSaveHelper.SaveSlot(PAUSE_SAVE_SLOT);
PcSaveHelper.PopulateSlotInfo();
IsQuickSave = 0;
DisplaySaveResult(res, CStats::LastMissionPassedName);
return true;
}
#endif

View File

@ -41,3 +41,9 @@ extern uint32 TimeToStayFadedBeforeFadeOut;
extern char SaveFileNameJustSaved[260]; // 8F2570 extern char SaveFileNameJustSaved[260]; // 8F2570
const char TopLineEmptyFile[] = "THIS FILE IS NOT VALID YET"; const char TopLineEmptyFile[] = "THIS FILE IS NOT VALID YET";
#ifdef MISSION_REPLAY
extern int8 IsQuickSave; // originally int
bool SaveGameForPause(int);
#endif

View File

@ -41,7 +41,10 @@ C_PcSave::SaveSlot(int32 slot)
_psGetUserFilesFolder(); _psGetUserFilesFolder();
int file = CFileMgr::OpenFile(ValidSaveName, "wb"); int file = CFileMgr::OpenFile(ValidSaveName, "wb");
if (file != 0) { if (file != 0) {
DoGameSpecificStuffBeforeSave(); #ifdef MISSION_REPLAY
if (!IsQuickSave)
#endif
DoGameSpecificStuffBeforeSave();
if (GenericSave(file)) { if (GenericSave(file)) {
if (!!CFileMgr::CloseFile(file)) if (!!CFileMgr::CloseFile(file))
nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE; nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE;