summaryrefslogtreecommitdiffstats
path: root/src/control/Script.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/control/Script.cpp151
1 files changed, 149 insertions, 2 deletions
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index bfc778ba..d238f276 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -29,6 +29,9 @@
#include "GameLogic.h"
#include "Garages.h"
#include "General.h"
+#ifdef MISSION_REPLAY
+#include "GenericGameStorage.h"
+#endif
#include "HandlingMgr.h"
#include "Heli.h"
#include "Hud.h"
@@ -130,6 +133,38 @@ uint16 CTheScripts::NumberOfExclusiveMissionScripts;
bool CTheScripts::bPlayerHasMetDebbieHarry;
bool CTheScripts::bPlayerIsInTheStatium;
+#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
@@ -768,6 +803,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();
@@ -1340,6 +1410,17 @@ int8 CRunningScript::ProcessCommands0To99(int32 command)
RemoveScriptFromList(&CTheScripts::pActiveScripts);
AddScriptToList(&CTheScripts::pIdleScripts);
m_bIsActive = false;
+#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:
{
@@ -2265,7 +2346,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:
@@ -2335,6 +2423,10 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
case COMMAND_PRINT_BIG:
{
wchar* key = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+#ifdef MISSION_REPLAY
+ if (strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "M_FAIL") == 0 && CanAllowMissionReplay())
+ AllowMissionReplay = 1;
+#endif
CollectParameters(&m_nIp, 2);
CMessages::AddBigMessage(key, ScriptParams[0], ScriptParams[1] - 1);
return 0;
@@ -8778,6 +8870,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);
@@ -9020,6 +9116,11 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
CollectParameters(&m_nIp, 1);
if (CTheScripts::NumberOfExclusiveMissionScripts > 0 && ScriptParams[0] <= UINT16_MAX - 2)
return 0;
+#ifdef MISSION_REPLAY
+ missionRetryScriptIndex = ScriptParams[0];
+ if (missionRetryScriptIndex == 19)
+ CStats::LastMissionPassedName[0] = '\0';
+#endif
CTimer::Suspend();
int offset = CTheScripts::MultiScriptArray[ScriptParams[0]];
#ifdef USE_DEBUG_SCRIPT_LOADER
@@ -12781,8 +12882,8 @@ void CRunningScript::LocateCharCarCommand(int32 command, uint32* pIp)
case COMMAND_LOCATE_CHAR_ON_FOOT_CAR_3D:
result = !pPed->bInVehicle;
break;
- case COMMAND_LOCATE_CHAR_IN_CAR_CHAR_2D:
- case COMMAND_LOCATE_CHAR_IN_CAR_CHAR_3D:
+ case COMMAND_LOCATE_CHAR_IN_CAR_CAR_2D:
+ case COMMAND_LOCATE_CHAR_IN_CAR_CAR_3D:
result = pPed->bInVehicle;
break;
default:
@@ -13597,6 +13698,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;
@@ -14243,3 +14350,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