summaryrefslogtreecommitdiff
path: root/src/control/Script.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/control/Script.cpp')
-rw-r--r--src/control/Script.cpp147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index 1ea970c4..c8dfd93a 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -28,6 +28,9 @@
#include "Gangs.h"
#include "Garages.h"
#include "General.h"
+#ifdef MISSION_REPLAY
+#include "GenericGameStorage.h"
+#endif
#include "HandlingMgr.h"
#include "Heli.h"
#include "Hud.h"
@@ -128,6 +131,38 @@ uint16 CTheScripts::CommandsExecuted;
uint16 CTheScripts::ScriptsUpdated;
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 =
#ifdef COMPATIBLE_SAVES
@@ -666,6 +701,41 @@ void CTheScripts::Process()
if (UseTextCommands == 1)
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;
while (script != nil){
CRunningScript* next = script->GetNext();
@@ -1239,6 +1309,17 @@ int8 CRunningScript::ProcessCommands0To99(int32 command)
CTheScripts::bAlreadyRunningAMissionScript = false;
RemoveScriptFromList(&CTheScripts::pActiveScripts);
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;
case COMMAND_START_NEW_SCRIPT:
{
@@ -2149,7 +2230,14 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
CollectParameters(&m_nIp, 2);
CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
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);
+#endif
return 0;
}
case COMMAND_SET_CAR_DRIVING_STYLE:
@@ -2219,6 +2307,10 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
case COMMAND_PRINT_BIG:
{
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;
CollectParameters(&m_nIp, 2);
CMessages::AddBigMessage(key, ScriptParams[0], ScriptParams[1] - 1);
@@ -8479,6 +8571,10 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
case COMMAND_MAKE_PLAYER_SAFE_FOR_CUTSCENE:
{
CollectParameters(&m_nIp, 1);
+#ifdef MISSION_REPLAY
+ AllowMissionReplay = 0;
+ SaveGameForPause(3);
+#endif
CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
CPad::GetPad(ScriptParams[0])->DisablePlayerControls |= PLAYERCONTROL_DISABLED_80;
pPlayerInfo->MakePlayerSafe(true);
@@ -8685,6 +8781,11 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
case COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL:
{
CollectParameters(&m_nIp, 1);
+#ifdef MISSION_REPLAY
+ missionRetryScriptIndex = ScriptParams[0];
+ if (missionRetryScriptIndex == 19)
+ CStats::LastMissionPassedName[0] = '\0';
+#endif
CTimer::Suspend();
int offset = CTheScripts::MultiScriptArray[ScriptParams[0]];
CFileMgr::ChangeDir("\\");
@@ -11074,6 +11175,12 @@ void CRunningScript::DoDeatharrestCheck()
CPlayerInfo* pPlayer = &CWorld::Players[CWorld::PlayerInFocus];
if (!pPlayer->IsRestartingAfterDeath() && !pPlayer->IsRestartingAfterArrest() && !CTheScripts::UpsideDownCars.AreAnyCarsUpsideDown())
return;
+#ifdef MISSION_REPLAY
+ if (AllowMissionReplay != 0)
+ return;
+ if (CanAllowMissionReplay())
+ AllowMissionReplay = 1;
+#endif
assert(m_nStackPointer > 0);
while (m_nStackPointer > 1)
--m_nStackPointer;
@@ -11755,3 +11862,43 @@ void CRunningScript::Load(uint8*& buf)
prev = p;
#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