1395 lines
52 KiB
Python
Executable File
1395 lines
52 KiB
Python
Executable File
// *****************************************************************************************
|
|
//
|
|
// SCRIPT NAME : replay_controller.sc
|
|
// AUTHOR : Andy Minghella
|
|
// DESCRIPTION : Controls the setting up and activation of mission replays.
|
|
//
|
|
// *****************************************************************************************
|
|
|
|
|
|
//Compile out Title Update changes to header functions.
|
|
//Must be before includes.
|
|
//CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R.
|
|
|
|
|
|
USING "commands_brains.sch"
|
|
USING "replay_public.sch"
|
|
USING "shop_public.sch"
|
|
USING "RC_Launcher_public.sch"
|
|
USING "script_misc.sch"
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
USING "replay_debug.sch"
|
|
USING "flow_debug_GAME.sch"
|
|
USING "debug_channels_structs.sch"
|
|
USING "commands_debug.sch"
|
|
BOOL bWaitingForFlowToStart = FALSE // Used to avoid replays being setup just before flow setup begins after using debug menu
|
|
#ENDIF
|
|
|
|
BOOL bForceSkipReplayScreen = FALSE // Used for callbacks since they don't all terminate the script
|
|
BOOL bCallbacksSetup = FALSE
|
|
BOOL bFadeInOnSkipReplayScreen = FALSE
|
|
|
|
INT iButtonNumber = 0 // used to display the button prompts in correct order
|
|
BOOL bScreenAlreadyFading = FALSE // used in special cases like start of FBI 1
|
|
BOOL bSetSystemTime = FALSE //Used to set the scaleform to use the system timer, see B* 2036584
|
|
|
|
// variables used for handling replay warps
|
|
INT iReplayWarpTimer
|
|
|
|
ENUM REPLAY_SCREEN_BUTTONS
|
|
RSB_NONE,
|
|
RSB_OK,
|
|
RSB_YES,
|
|
RSB_RETRY,
|
|
RSB_NO,
|
|
RSB_EXIT,
|
|
RSB_RESTART,
|
|
RSB_FORCE_RESTART,
|
|
RSB_SKIP_SECTION,
|
|
RSB_SKIP_MISSION
|
|
ENDENUM
|
|
|
|
// ===========================================================================================================
|
|
// Cleanup
|
|
// ===========================================================================================================
|
|
|
|
/// PURPOSE:
|
|
/// Ensures that the script gets a chance to cleanup under specific circumstances (ie: moving from SP to MP)
|
|
PROC Script_Cleanup()
|
|
CPRINTLN(DEBUG_REPLAY, "Replay controller cleaning up.")
|
|
|
|
#IF IS_DEBUG_BUILD Delete_Replay_Debug_Widgets() #ENDIF
|
|
|
|
Cleanup_Replay_Controller()
|
|
|
|
CPRINTLN(DEBUG_REPLAY, "Replay controller thread terminating now.")
|
|
g_replay.replayStageID = RS_NOT_RUNNING
|
|
TERMINATE_THIS_THREAD()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Used to skip over the replay screen, and reset any changes made.
|
|
PROC SkipReplayScreen(BOOL bFadeIn #IF IS_DEBUG_BUILD , BOOL bDebugMenuCleanup #ENDIF)
|
|
CPRINTLN(DEBUG_REPLAY, "Replay screen was skipped- J/F skip or debug menu cleanup.")
|
|
IF bFadeIn
|
|
DO_SCREEN_FADE_IN(0)
|
|
ENDIF
|
|
SET_SCRIPT_GFX_DRAW_ORDER(GFX_ORDER_AFTER_HUD)
|
|
ResetCommonReplayChanges()
|
|
|
|
// If we were part way through setting up a replay we need to handle it as rejected
|
|
IF IS_REPLAY_BEING_PROCESSED()
|
|
|
|
// set state to one which passes GET_MISSION_FLOW_SAFE_TO_CLEANUP + wait for cleanup
|
|
g_replay.replayStageID = RS_REJECTING
|
|
Wait_For_Mission_To_Cleanup()
|
|
CLEAR_TIMECYCLE_MODIFIER()
|
|
|
|
// then handle it as rejected
|
|
CPRINTLN(DEBUG_REPLAY, "SkipReplayScreen: Mission script terminated, treating as rejected", g_replay.replayScriptName)
|
|
|
|
RESET_MISSION_STATS_SYSTEM()
|
|
TERMINATE_STAT_WATCHER() //B* 2194192
|
|
|
|
Replay_RejectionCleanup()
|
|
ELSE
|
|
#IF IS_DEBUG_BUILD
|
|
// replay isn't being processed,
|
|
// need to enter the waiting for flow state
|
|
// to avoid trying to setup a replay just as the gameflow setup begins
|
|
IF bDebugMenuCleanup = TRUE
|
|
IF g_savedGlobals.sFlow.isGameflowActive = TRUE // don't need this in debug mode
|
|
bWaitingForFlowToStart = TRUE
|
|
g_replay.replayStageID = RS_WAITING_FOR_FLOW
|
|
CPRINTLN(DEBUG_REPLAY, "Entering RS_WAITING_FOR_FLOW.")
|
|
ENDIF
|
|
ENDIF
|
|
#ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Draws the chosen button prompt as the next button in the current list
|
|
/// PARAMS:
|
|
/// eButton - the replay button propt (ok, yes, no, restart etc)
|
|
PROC DrawButtonPrompt(REPLAY_SCREEN_BUTTONS eButton)
|
|
|
|
STRING eButtonIcon
|
|
STRING sButtonString
|
|
CONTROL_ACTION eButtonClickInput = MAX_INPUTS
|
|
|
|
SWITCH eButton
|
|
CASE RSB_OK
|
|
eButtonIcon = GET_CONTROL_INSTRUCTIONAL_BUTTONS_STRING(FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT)
|
|
sButtonString = "REPLAY_OK"
|
|
eButtonClickInput = INPUT_FRONTEND_ACCEPT
|
|
BREAK
|
|
CASE RSB_YES
|
|
eButtonIcon = GET_CONTROL_INSTRUCTIONAL_BUTTONS_STRING(FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT)
|
|
sButtonString = "REPLAY_YES"
|
|
eButtonClickInput = INPUT_FRONTEND_ACCEPT
|
|
BREAK
|
|
CASE RSB_RETRY
|
|
eButtonIcon = GET_CONTROL_INSTRUCTIONAL_BUTTONS_STRING(FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT)
|
|
sButtonString = "REPLAY_RETRY"
|
|
eButtonClickInput = INPUT_FRONTEND_ACCEPT
|
|
BREAK
|
|
CASE RSB_NO
|
|
eButtonIcon = GET_CONTROL_INSTRUCTIONAL_BUTTONS_STRING(FRONTEND_CONTROL, INPUT_FRONTEND_CANCEL)
|
|
sButtonString = "REPLAY_NO"
|
|
eButtonClickInput = INPUT_FRONTEND_CANCEL
|
|
BREAK
|
|
CASE RSB_EXIT
|
|
eButtonIcon = GET_CONTROL_INSTRUCTIONAL_BUTTONS_STRING(FRONTEND_CONTROL, INPUT_FRONTEND_CANCEL)
|
|
sButtonString = "REPLAY_EXIT"
|
|
eButtonClickInput = INPUT_FRONTEND_CANCEL
|
|
BREAK
|
|
CASE RSB_RESTART
|
|
eButtonIcon = GET_CONTROL_INSTRUCTIONAL_BUTTONS_STRING(FRONTEND_CONTROL, INPUT_FRONTEND_Y)
|
|
sButtonString = "REPLAY_RESTART"
|
|
eButtonClickInput = INPUT_FRONTEND_Y
|
|
BREAK
|
|
CASE RSB_FORCE_RESTART
|
|
eButtonIcon = GET_CONTROL_INSTRUCTIONAL_BUTTONS_STRING(FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT)
|
|
sButtonString = "REPLAY_RESTART"
|
|
eButtonClickInput = INPUT_FRONTEND_ACCEPT
|
|
BREAK
|
|
CASE RSB_SKIP_SECTION
|
|
eButtonIcon = GET_CONTROL_INSTRUCTIONAL_BUTTONS_STRING(FRONTEND_CONTROL, INPUT_FRONTEND_X)
|
|
sButtonString = "REPLAY_SKIP_S"
|
|
eButtonClickInput = INPUT_FRONTEND_X
|
|
BREAK
|
|
CASE RSB_SKIP_MISSION
|
|
eButtonIcon = GET_CONTROL_INSTRUCTIONAL_BUTTONS_STRING(FRONTEND_CONTROL, INPUT_FRONTEND_X)
|
|
sButtonString = "REPLAY_SKIP_M"
|
|
eButtonClickInput = INPUT_FRONTEND_X
|
|
BREAK
|
|
DEFAULT // no button, exit
|
|
EXIT
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
// set data slot info for this button
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(g_replay.mFailButtonsScaleform, "SET_DATA_SLOT")
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(iButtonNumber)
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INSTRUCTIONAL_BUTTONS(eButtonIcon)
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(sButtonString)
|
|
|
|
// Add clickable input [PC platform only]
|
|
IF IS_PC_VERSION()
|
|
IF eButtonClickInput = MAX_INPUTS
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_BOOL(FALSE)
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(ENUM_TO_INT(MAX_INPUTS))
|
|
ELSE
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_BOOL(TRUE)
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(ENUM_TO_INT(eButtonClickInput))
|
|
ENDIF
|
|
ENDIF
|
|
END_SCALEFORM_MOVIE_METHOD()
|
|
|
|
CPRINTLN(DEBUG_REPLAY, "button prompt set up for button: ", iButtonNumber)
|
|
iButtonNumber++
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Checks if we are currently handling shitskips
|
|
/// (Shitskips not handled during restart confirmation screens)
|
|
/// RETURNS:
|
|
/// True if we are handling shitskips
|
|
FUNC BOOL HandleShitskips()
|
|
IF g_bShitskipOffered = TRUE
|
|
AND g_replay.replayStageID <> RS_SCREEN_RESTART_CONFIRMATION // don't show shitskip on confirmation screen
|
|
RETURN TRUE
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Checks whether shitskips are allowed for this mission type
|
|
/// And whether this mission has been failed enough for a shitskip
|
|
/// If so it displays the correct button prompt (skip section / mission)
|
|
/// PARAMS:
|
|
/// bShitskipsAllowed - is this type of replay screen allowed to show the "skip" option?
|
|
PROC DrawShitskipButtonPrompts(BOOL bShitskipsAllowed = TRUE)
|
|
IF bShitskipsAllowed = TRUE
|
|
IF HandleShitskips()
|
|
IF g_bShitskipToEnd = TRUE
|
|
DrawButtonPrompt(RSB_SKIP_MISSION)
|
|
ELSE
|
|
DrawButtonPrompt(RSB_SKIP_SECTION)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Returns whether the button prompts scaleform movie has loaded
|
|
/// This needs to be checked before setting up any button prompts
|
|
/// RETURNS:
|
|
/// TRUE if scaleform has loaded, FALSE otherwise
|
|
FUNC BOOL HasButtonsScaleformLoaded()
|
|
RETURN HAS_SCALEFORM_MOVIE_LOADED(g_replay.mFailButtonsScaleform)
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Requests the fail screen scaleform
|
|
PROC RequestScaleform()
|
|
|
|
// main scaleform
|
|
IF g_replay.mFailTextScaleform = NULL
|
|
g_replay.mFailTextScaleform = REQUEST_SCALEFORM_MOVIE("MP_BIG_MESSAGE_FREEMODE")
|
|
bSetSystemTime = FALSE
|
|
ELSE
|
|
IF NOT HAS_SCALEFORM_MOVIE_LOADED(g_replay.mFailTextScaleform)
|
|
g_replay.mFailTextScaleform = REQUEST_SCALEFORM_MOVIE("MP_BIG_MESSAGE_FREEMODE")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// instructional buttons
|
|
IF g_replay.mFailButtonsScaleform = NULL
|
|
g_replay.mFailButtonsScaleform = REQUEST_SCALEFORM_MOVIE("INSTRUCTIONAL_BUTTONS")
|
|
ELSE
|
|
IF NOT HAS_SCALEFORM_MOVIE_LOADED(g_replay.mFailButtonsScaleform)
|
|
g_replay.mFailButtonsScaleform = REQUEST_SCALEFORM_MOVIE("INSTRUCTIONAL_BUTTONS")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Draws button prompts for 2 buttons
|
|
/// Then handles the shitskip button prompts
|
|
/// (This ensures that the skip options are always the last button prompts)
|
|
/// PARAMS:
|
|
/// eButton1 - 1st button to display
|
|
/// eButton2 - 2nd button to display
|
|
PROC DrawButtonPrompts(REPLAY_SCREEN_BUTTONS eButton1, REPLAY_SCREEN_BUTTONS eButton2, BOOL bAllowShitskips = TRUE)
|
|
|
|
// check if player has switched between mouse/joypad
|
|
IF IS_PC_VERSION()
|
|
IF HAVE_CONTROLS_CHANGED(FRONTEND_CONTROL)
|
|
CLEAR_BIT(g_replay.iReplayBits, ENUM_TO_INT(RB_BUTTONS_SETUP))
|
|
ENDIF
|
|
|
|
IF IS_USING_KEYBOARD_AND_MOUSE(FRONTEND_CONTROL)
|
|
SET_MOUSE_CURSOR_THIS_FRAME()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NOT IS_BIT_SET(g_replay.iReplayBits, ENUM_TO_INT(RB_BUTTONS_SETUP))
|
|
|
|
IF HasButtonsScaleformLoaded()
|
|
// only do the setup once the scaleform has loaded
|
|
// reset the button number (so buttons get displayed in correct order)
|
|
iButtonNumber = 0
|
|
|
|
// clear all
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(g_replay.mFailButtonsScaleform, "CLEAR_ALL")
|
|
END_SCALEFORM_MOVIE_METHOD()
|
|
|
|
// clear space
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(g_replay.mFailButtonsScaleform, "SET_CLEAR_SPACE")
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(200)
|
|
END_SCALEFORM_MOVIE_METHOD()
|
|
|
|
// set background colour
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(g_replay.mFailButtonsScaleform, "SET_BACKGROUND_COLOUR")
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(0)
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(0)
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(0)
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(80)
|
|
END_SCALEFORM_MOVIE_METHOD()
|
|
|
|
// enable clickable input [PC platform only]
|
|
IF IS_PC_VERSION()
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(g_replay.mFailButtonsScaleform, "TOGGLE_MOUSE_BUTTONS")
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_BOOL(TRUE)
|
|
END_SCALEFORM_MOVIE_METHOD()
|
|
ENDIF
|
|
|
|
// Set up each button
|
|
DrawButtonPrompt(eButton1)
|
|
DrawButtonPrompt(eButton2)
|
|
DrawShitskipButtonPrompts(bAllowShitskips)
|
|
|
|
CPRINTLN(DEBUG_REPLAY, "Replay button prompts have been setup.")
|
|
SET_BIT(g_replay.iReplayBits, ENUM_TO_INT(RB_BUTTONS_SETUP))
|
|
|
|
// draw the buttons
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(g_replay.mFailButtonsScaleform, "DRAW_INSTRUCTIONAL_BUTTONS")
|
|
END_SCALEFORM_MOVIE_METHOD()
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Displays the question text if we have any, otherwise the fail reason
|
|
/// PARAMS:
|
|
/// sQuestionText - text label of the question text to use
|
|
PROC HANDLE_SECONDARY_FAIL_TEXT(STRING sQuestionText)
|
|
IF NOT IS_STRING_NULL_OR_EMPTY(sQuestionText)
|
|
// if we have question text, display it
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(sQuestionText)
|
|
ELSE
|
|
// otherwise show fail reason
|
|
#IF IS_DEBUG_BUILD
|
|
// show a debug fail reason if we don't have one set
|
|
IF IS_STRING_NULL_OR_EMPTY(g_txtMissionFailReason)
|
|
g_txtMissionFailReason= "REPLAY_NFR"
|
|
CPRINTLN(DEBUG_REPLAY, "Setting fail reason to debug fail.")
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// handle string insertions
|
|
IF IS_STRING_NULL_OR_EMPTY(g_txtMissionFailAddText)
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(g_txtMissionFailReason)
|
|
ELSE
|
|
BEGIN_TEXT_COMMAND_SCALEFORM_STRING(g_txtMissionFailReason)
|
|
ADD_TEXT_COMPONENT_SUBSTRING_TEXT_LABEL(g_txtMissionFailAddText)
|
|
END_TEXT_COMMAND_SCALEFORM_STRING()
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Draws the replay screen
|
|
/// PARAMS:
|
|
/// sQuestionText - the question text to be displayed
|
|
/// bButtonPrompts - display the button prompts
|
|
/// bShowFailReason- If true we show the fail reason, otherwise we show the question text.
|
|
/// bDoAudio - only true while we need to play the failed audio (before screen faded out)
|
|
PROC DrawReplayScreen(STRING sQuestionText, BOOL bButtonPrompts = TRUE, BOOL bDoAudio = FALSE)
|
|
|
|
RequestScaleform()
|
|
|
|
SET_SCRIPT_GFX_DRAW_ORDER(GFX_ORDER_AFTER_FADE)
|
|
|
|
// fail screen scaleforms
|
|
IF NOT IS_BIT_SET(g_replay.iReplayBits, ENUM_TO_INT(RB_TEXT_SCALE_LOADED))
|
|
IF HAS_SCALEFORM_MOVIE_LOADED(g_replay.mFailTextScaleform)
|
|
// set bit once scaleform has loaded
|
|
IF NOT IS_BIT_SET(g_replay.iReplayBits, ENUM_TO_INT(RB_TEXT_SCALE_LOADED))
|
|
SET_BIT(g_replay.iReplayBits, ENUM_TO_INT(RB_TEXT_SCALE_LOADED))
|
|
// set transition time
|
|
g_replay.fTextTransitionTime = GET_GAME_TIMER() + (FAIL_TRANSITION_DELAY * FAIL_OUT_EFFECT_SLO_MO)
|
|
ENDIF
|
|
//Set scaleform to use system timer
|
|
IF NOT bSetSystemTime
|
|
CPRINTLN(debug_replay,"Setting scaleform to use system timer")
|
|
SET_SCALEFORM_MOVIE_TO_USE_SYSTEM_TIME(g_replay.mFailTextScaleform,TRUE)
|
|
bSetSystemTime = true
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_REPLAY, "Loading replay scaleform movie, mFailTextScaleform.")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// only do the fail text if scaleform has loaded
|
|
IF HAS_SCALEFORM_MOVIE_LOADED(g_replay.mFailTextScaleform)
|
|
// draw the scaleform
|
|
DRAW_SCALEFORM_MOVIE_FULLSCREEN(g_replay.mFailTextScaleform,255,255,255,0)
|
|
|
|
//#2053591 - Don't record footage for the Rockstar Editor while drawing a fail screen.
|
|
REPLAY_PREVENT_RECORDING_AND_UI_THIS_FRAME()
|
|
|
|
IF NOT IS_BIT_SET(g_replay.iReplayBits, ENUM_TO_INT(RB_QUESTION_SETUP))
|
|
// set info for fail text
|
|
CPRINTLN(DEBUG_REPLAY, "Updating info for scaleform, mFailTextScaleform.")
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(g_replay.mFailTextScaleform, "SHOW_SHARD_CENTERED_MP_MESSAGE_LARGE")
|
|
|
|
IF g_replay.replayType = REPLAY_TYPE_MINIGAME
|
|
OR IS_REPLAY_MISSION_A_RAMPAGE()
|
|
// minigames, bail bonds + rampages just say failed
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING("REPLAY_TMG")
|
|
ELSE
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING("REPLAY_T") // mission failed
|
|
ENDIF
|
|
|
|
HANDLE_SECONDARY_FAIL_TEXT(sQuestionText)
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(0)
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(100.0)
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_BOOL(TRUE)
|
|
END_SCALEFORM_MOVIE_METHOD()
|
|
SET_BIT(g_replay.iReplayBits, ENUM_TO_INT(RB_QUESTION_SETUP))
|
|
SET_BIT(g_replay.iReplayBits, ENUM_TO_INT(RB_2ND_TEXT_SETUP))
|
|
CPRINTLN(DEBUG_REPLAY, "Updated Fail text with '",sQuestionText)
|
|
ENDIF
|
|
|
|
// handle the secondary text (fail reason / question)
|
|
IF NOT IS_BIT_SET(g_replay.iReplayBits, ENUM_TO_INT(RB_2ND_TEXT_SETUP))
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(g_replay.mFailTextScaleform, "UPDATE_MESSAGE")
|
|
HANDLE_SECONDARY_FAIL_TEXT(sQuestionText)
|
|
END_SCALEFORM_MOVIE_METHOD_RETURN_VALUE()
|
|
CPRINTLN(DEBUG_REPLAY, "Updating secondary text now with '",sQuestionText)
|
|
SET_BIT(g_replay.iReplayBits, ENUM_TO_INT(RB_2ND_TEXT_SETUP))
|
|
ENDIF
|
|
|
|
// transition the fail message up the screen
|
|
IF NOT IS_BIT_SET(g_replay.iReplayBits, ENUM_TO_INT(RB_DONE_TRANSITION))
|
|
|
|
// if we've paused before transition has finished- unpause
|
|
Replay_Pause_Game(FALSE)
|
|
|
|
IF NOT IS_BIT_SET(g_replay.iReplayBits, ENUM_TO_INT(RB_STARTED_TRANSITION))
|
|
CDEBUG1LN(debug_replay,"Started transition bit not set: ",GET_GAME_TIMER(),"/",g_replay.fTextTransitionTime)
|
|
|
|
// transition hasn't started yet, is it time?
|
|
IF GET_GAME_TIMER() > g_replay.fTextTransitionTime
|
|
CDEBUG1LN(debug_replay,"Starting transition")
|
|
// start the transition now
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(g_replay.mFailTextScaleform, "TRANSITION_UP")
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(0.15 * FAIL_OUT_EFFECT_SLO_MO)
|
|
END_SCALEFORM_MOVIE_METHOD_RETURN_VALUE()
|
|
SET_BIT(g_replay.iReplayBits, ENUM_TO_INT(RB_STARTED_TRANSITION))
|
|
|
|
// set the time that the transition will be complete
|
|
g_replay.fTextTransitionTime = GET_GAME_TIMER() + (150 * FAIL_OUT_EFFECT_SLO_MO)
|
|
CPRINTLN(DEBUG_REPLAY, "Triggering text transition now 1")
|
|
ELSE
|
|
CPRINTLN(DEBUG_REPLAY, "Waiting to do text transition: ", GET_GAME_TIMER())
|
|
ENDIF
|
|
ENDIF
|
|
//Bug 1926954: If the fade-out is hurried up, make sure the RB_DONE_TRANSITION bit is set in the same frame
|
|
IF IS_BIT_SET(g_replay.iReplayBits, ENUM_TO_INT(RB_STARTED_TRANSITION))
|
|
CDEBUG1LN(debug_replay,"Checking if transition finished:", GET_GAME_TIMER(),"/",g_replay.fTextTransitionTime)
|
|
// transition has been started, has it finished?
|
|
IF GET_GAME_TIMER() > g_replay.fTextTransitionTime
|
|
CPRINTLN(DEBUG_REPLAY, "Text transition finished")
|
|
SET_BIT(g_replay.iReplayBits, ENUM_TO_INT(RB_DONE_TRANSITION))
|
|
IF bButtonPrompts = TRUE
|
|
// if we're not paused after started showing button prompts, pause now
|
|
CPRINTLN(DEBUG_REPLAY, "Pausing as transition done, as we're showing button prompts")
|
|
Replay_Pause_Game(TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF bDoAudio = TRUE
|
|
// play the audio as the text appears
|
|
IF IS_BIT_SET(g_replay.iReplayBits, ENUM_TO_INT(RB_AUDIO_LOADED))
|
|
// don't try to play audio after we've faded out
|
|
IF IS_SCREEN_FADED_OUT()
|
|
AND IS_BIT_SET(g_replay.iReplayBits, ENUM_TO_INT(RB_DONE_TRANSITION))
|
|
// already faded out, don't do audio
|
|
CPRINTLN(DEBUG_REPLAY, "Already faded and done transition. Don't do Texthit audio")
|
|
ELSE
|
|
IF g_replay.iFailSoundID = -1
|
|
g_replay.iFailSoundID = GET_SOUND_ID()
|
|
PLAY_SOUND_FRONTEND(g_replay.iFailSoundID, "TextHit", "MissionFailedSounds")
|
|
CPRINTLN(DEBUG_REPLAY, "Playing fail audio now. TextHit")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF bButtonPrompts = TRUE
|
|
IF iButtonNumber > 0
|
|
// button prompts (only do this if we've set a button to display)
|
|
IF NOT HasButtonsScaleformLoaded()
|
|
CPRINTLN(DEBUG_REPLAY, "Loading replay scaleform movie, mFailButtonsScaleform.")
|
|
EXIT
|
|
ENDIF
|
|
DRAW_SCALEFORM_MOVIE_FULLSCREEN(g_replay.mFailButtonsScaleform, 255,255,255,0)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Resets scaleform setup variables as we need to change text / button prompts
|
|
/// Updates state to go to correct screen
|
|
PROC ChangeReplayScreen(g_eReplayStages eStage)
|
|
CPRINTLN(DEBUG_REPLAY, "Changing replay screen to ", eStage)
|
|
ResetScaleformSetupVariables()
|
|
g_replay.replayStageID = eStage
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Sets the replay stage to show correct fail screen based on which replay type we are processing
|
|
PROC SetReplayScreenType()
|
|
|
|
SWITCH g_replay.replayType
|
|
CASE REPLAY_TYPE_MISSION_FORCE_RESTART
|
|
IF IS_REPEAT_PLAY_ACTIVE()
|
|
// in repeat play, just use the default screen for this mission
|
|
ChangeReplayScreen(RS_SCREEN_DEFAULT)
|
|
ELSE
|
|
ChangeReplayScreen(RS_SCREEN_FORCE_RESTART)
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE REPLAY_TYPE_FAIL_SCREEN_ONLY
|
|
ChangeReplayScreen(RS_SCREEN_FAIL_ONLY)
|
|
BREAK
|
|
|
|
DEFAULT
|
|
ChangeReplayScreen(RS_SCREEN_DEFAULT)
|
|
// this currently covers these replay types:
|
|
// REPLAY_TYPE_MISSION, REPLAY_TYPE_RANDOM_CHARACTER, REPLAY_TYPE_MINIGAME
|
|
// REPLAY_TYPE_MICHAEL_EVENT, REPLAY_TYPE_PHONECALL_TRIGGER
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
// ===========================================================================================================
|
|
// Replay Progression Control Functions
|
|
// ===========================================================================================================
|
|
|
|
/// PURPOSE:
|
|
/// Shows the fail reason and triggers fail effects
|
|
/// If the player was killed / arrested it waits for code to fade the screen out
|
|
/// Moves on to RS_SCREEN_FORCE_RESTART, RS_SCREEN_FAIL_ONLY or RS_SCREEN_DEFAULT
|
|
PROC Replay_Do_Blur()
|
|
|
|
// TimerA is reset when fail effect is triggered
|
|
// and is used to time triggering of fail out effect
|
|
// TimerB is reset when failOut effect is triggered
|
|
// and is used to time when to fade out
|
|
|
|
// debug stuff
|
|
#IF IS_DEBUG_BUILD
|
|
IF g_bDebugDisableFailScreen
|
|
//Replay screens blocked. Cancel replay.
|
|
Reset_All_Replay_Variables()
|
|
EXIT
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// Trigger the death fail effect here
|
|
IF NOT IS_BIT_SET(g_replay.iReplayBits, ENUM_TO_INT(RB_FAIL_EFFECT_TRIGGERED))
|
|
AND NOT IS_BIT_SET(g_replay.iReplayBits, ENUM_TO_INT(RB_FAIL_OUT_EFFECT_TRIGGERED))
|
|
|
|
IF IS_SCREEN_FADED_OUT()
|
|
// if we're already faded out, skip to showing the fail reason
|
|
// special case for FBI 1 fail cut-scene
|
|
CPRINTLN(DEBUG_REPLAY, "Skipping initial fail effect as screen is faded out")
|
|
SET_BIT(g_replay.iReplayBits, ENUM_TO_INT(RB_FAIL_EFFECT_TRIGGERED))
|
|
SETTIMERA(CEIL(FAIL_EFFECT_TIME * FAIL_EFFECT_SLO_MO))
|
|
Replay_Control_Slow_Motion(TRUE, 1)
|
|
ELSE
|
|
// not started fail effect, do it now
|
|
Replay_Control_Fail_Effect(TRUE)
|
|
PLAY_SOUND_FRONTEND(-1, "ScreenFlash", "MissionFailedSounds")
|
|
CPRINTLN(DEBUG_REPLAY, "Playing fail audio now. ScreenFlash")
|
|
SETTIMERA(0)
|
|
ENDIF
|
|
|
|
// start audio scene as effect appears
|
|
Replay_Control_Audio_Scene(TRUE)
|
|
|
|
// ------------other stuff that only needs to be done once--------------
|
|
|
|
DISABLE_CELLPHONE(TRUE) //Added for bug 1591786
|
|
|
|
// block the death jingle, so we don't get 2 fail sounds played
|
|
// if the player dies during the fail screen
|
|
Replay_Block_Death_Jingle(TRUE)
|
|
Replay_Block_Damage_Overlay(TRUE)
|
|
|
|
// clear stunt jump display
|
|
CANCEL_STUNT_JUMP()
|
|
|
|
Replay_Block_Load_Screen(TRUE)
|
|
|
|
// check if screen is already fading out (used for special cases like start of FBI1)
|
|
IF IS_SCREEN_FADING_OUT()
|
|
OR IS_SCREEN_FADED_OUT()
|
|
bScreenAlreadyFading = TRUE
|
|
// block load screen so failed screen displays correctly (needs to be done as close to fade out as possible)
|
|
ELSE
|
|
bScreenAlreadyFading = FALSE
|
|
ENDIF
|
|
|
|
// B*1575302 - We need to clear the mission title during a fail
|
|
MISSION_FLOW_CLEAR_DISPLAY_MISSION_TITLE()
|
|
|
|
// kill chase hint cam effects
|
|
IF IS_GAMEPLAY_HINT_ACTIVE()
|
|
CPRINTLN(DEBUG_REPLAY, "Stopping hint effects")
|
|
ANIMPOSTFX_STOP("FocusIn")
|
|
ANIMPOSTFX_PLAY("FocusOut",0,false)
|
|
STOP_GAMEPLAY_HINT()
|
|
ENDIF
|
|
|
|
//Unblock the respawn controller
|
|
CPRINTLN(DEBUG_REPLAY,"Unblocking the respawn controller")
|
|
CLEAR_BIT(g_replay.iReplayBits,ENUM_TO_INT(RB_BLOCK_RESPAWN))
|
|
ENDIF
|
|
|
|
// things we need to block every frame
|
|
// remove any god text / subtitles
|
|
IF NOT IS_CUTSCENE_PLAYING()
|
|
CLEAR_PRINTS()
|
|
ELSE
|
|
// block load screen so failed screen displays correctly
|
|
// (needs to be done as close to fade out as possible)
|
|
Replay_Block_Load_Screen(TRUE)
|
|
ENDIF
|
|
|
|
// hide the feed
|
|
THEFEED_HIDE_THIS_FRAME()
|
|
|
|
// disable the pause menu during fail screen
|
|
DISABLE_CONTROL_ACTION(FRONTEND_CONTROL, INPUT_FRONTEND_PAUSE)
|
|
|
|
// block aggresive cop clean-up
|
|
SUPPRESS_AMBIENT_PED_AGGRESSIVE_CLEANUP_THIS_FRAME()
|
|
|
|
//#2067723 - Ensure the game is in 3rd person view on all fail screens.
|
|
DISABLE_CONTROL_ACTION(FRONTEND_CONTROL, INPUT_NEXT_CAMERA)
|
|
DISABLE_ON_FOOT_FIRST_PERSON_VIEW_THIS_UPDATE()
|
|
|
|
// stop player from being able to right upside down vehicles
|
|
IF IS_BIT_SET(g_replay.iReplayBits, ENUM_TO_INT(RB_DISABLED_VEH_CONT))
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_MOVE_LR)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_MOVE_UD)
|
|
ENDIF
|
|
|
|
// don't let the player use the sniper scope (since HUD needs to be hidden)
|
|
IF DOES_ENTITY_EXIST(PLAYER_PED_ID())
|
|
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
|
|
WEAPON_TYPE mCurrentWeapon
|
|
GET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), mCurrentWeapon)
|
|
IF mCurrentWeapon = WEAPONTYPE_SNIPERRIFLE
|
|
OR mCurrentWeapon = WEAPONTYPE_HEAVYSNIPER
|
|
OR mCurrentWeapon = WEAPONTYPE_REMOTESNIPER
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_AIM)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// disable weapon switching
|
|
Disable_Weapon_Select(TRUE)
|
|
|
|
// load the fail screen audio + play sound as soon as loaded
|
|
IF Load_Replay_Audio()
|
|
IF NOT IS_SCREEN_FADED_OUT()
|
|
IF g_replay.iFailBedSoundID = -1
|
|
g_replay.iFailBedSoundID = GET_SOUND_ID()
|
|
PLAY_SOUND_FRONTEND(g_replay.iFailBedSoundID, "Bed", "MissionFailedSounds")
|
|
CPRINTLN(DEBUG_REPLAY, "Playing fail audio now. Bed")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// check if it is time to start showing fail text
|
|
CDEBUG1LN(debug_replay,"Show fail text time: ",TIMERA(),"/",FAIL_EFFECT_TIME * FAIL_EFFECT_SLO_MO)
|
|
IF TIMERA() > FAIL_EFFECT_TIME * FAIL_EFFECT_SLO_MO
|
|
|
|
// Display the mission failed text
|
|
DrawReplayScreen("", FALSE, TRUE)
|
|
|
|
// Trigger the Death Fail Out Effect here
|
|
IF NOT IS_BIT_SET(g_replay.iReplayBits, ENUM_TO_INT(RB_FAIL_OUT_EFFECT_TRIGGERED))
|
|
// not started fail out effect, do it now + pause the game
|
|
|
|
Replay_Block_Load_Screen(TRUE) //Block the load screen early
|
|
|
|
Replay_Control_Fail_Out_Effect(TRUE)
|
|
SETTIMERB(0)
|
|
ELSE
|
|
// we are waiting for the fail out effect to finish
|
|
|
|
// check if effect has finished
|
|
CDEBUG1LN(debug_replay,"---Check if effect has finished: ",TIMERB(),"/",FAIL_OUT_EFFECT_TIME * FAIL_OUT_EFFECT_SLO_MO)
|
|
IF TIMERB() > FAIL_OUT_EFFECT_TIME * FAIL_OUT_EFFECT_SLO_MO
|
|
OR (IS_SCREEN_FADED_OUT() // used for skipping fail cut-scenes
|
|
AND bScreenAlreadyFading = FALSE) // if screen was already fading out for a special case, wait as normal
|
|
|
|
CDEBUG1LN(debug_replay,"Finished fadeout effect")
|
|
// --------finished fail out effect ------------------------------
|
|
// start fading out
|
|
IF NOT IS_SCREEN_FADED_OUT()
|
|
IF NOT IS_SCREEN_FADING_OUT()
|
|
AND NOT IS_CUTSCENE_PLAYING()
|
|
SET_SCRIPT_GFX_DRAW_ORDER(GFX_ORDER_AFTER_FADE)
|
|
DO_SCREEN_FADE_OUT(FAIL_FADE_OUT_TIME)
|
|
// block load screen so failed screen displays correctly (needs to be done as close to fade out as possible)
|
|
Replay_Block_Load_Screen(TRUE)
|
|
ENDIF
|
|
ELSE
|
|
// -------------screen has faded out--------------------------
|
|
// Do necessary setup, and then move on to showing the replay screen
|
|
CPRINTLN(DEBUG_REPLAY, "\nFail effect for script [", GET_THIS_SCRIPT_NAME(), "] completed.")
|
|
|
|
// disable player control
|
|
IF IS_PLAYER_PLAYING(PLAYER_ID())
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
|
|
ENDIF
|
|
|
|
// stuff that needs to be set after fade
|
|
SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE)
|
|
DISABLE_CELLPHONE(TRUE)
|
|
SET_FRONTEND_ACTIVE(FALSE)
|
|
SET_PAUSE_MENU_ACTIVE(FALSE)
|
|
CLEAR_HELP()
|
|
CLEAR_PRINTS()
|
|
Replay_Control_Audio_Scene(FALSE)
|
|
RESET_RETICULE_VALUES()
|
|
IF IS_GAMEPLAY_CAM_SHAKING()
|
|
STOP_GAMEPLAY_CAM_SHAKING(TRUE)
|
|
ENDIF
|
|
KILL_ANY_CONVERSATION()
|
|
IF IS_PLAYER_SWITCH_IN_PROGRESS()
|
|
STOP_PLAYER_SWITCH()
|
|
CPRINTLN(DEBUG_REPLAY, "Stopping current player switch")
|
|
ENDIF
|
|
STOP_ALL_ALARMS(TRUE)
|
|
|
|
// ------Wait here for a short time before updating the fail text---------
|
|
|
|
// brief delay before showing the button prompts
|
|
//DrawReplayScreen("", FALSE)
|
|
FLOAT fDelayTimer = GET_GAME_TIMER() + (FAIL_PROMPT_DELAY *FAIL_OUT_EFFECT_SLO_MO)
|
|
WHILE GET_GAME_TIMER() < fDelayTimer
|
|
//B*1926954: Keep waiting until the text transition finishes
|
|
OR GET_GAME_TIMER() < g_replay.fTextTransitionTime
|
|
WAIT(0)
|
|
DrawReplayScreen("", FALSE)
|
|
ENDWHILE
|
|
// store vehicle's velocity before pause
|
|
IF DOES_ENTITY_EXIST(PLAYER_PED_ID())
|
|
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
|
|
VEHICLE_INDEX mPlayerVehicle = GET_PLAYERS_LAST_VEHICLE()
|
|
IF DOES_ENTITY_EXIST(mPlayerVehicle)
|
|
IF IS_VEHICLE_DRIVEABLE(mPlayerVehicle)
|
|
g_replay.vVehicleVelocity = GET_ENTITY_VELOCITY(mPlayerVehicle)
|
|
CPRINTLN(DEBUG_REPLAY, "Stored velocity as g_replay.vVehicleVelocity x= ", g_replay.vVehicleVelocity.x, " y= ", g_replay.vVehicleVelocity.y, " z= ", g_replay.vVehicleVelocity.z)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// pause the game (only if we've done the text transition)
|
|
IF IS_BIT_SET(g_replay.iReplayBits, ENUM_TO_INT(RB_DONE_TRANSITION))
|
|
Replay_Pause_Game(TRUE)
|
|
ENDIF
|
|
|
|
// set which state we're moving on to
|
|
// based on which replay type we are configuring
|
|
SetReplayScreenType()
|
|
ENDIF
|
|
ELSE
|
|
CDEBUG1LN(DEBUG_REPLAY, "Accepting input, TimerB = .", TIMERB())
|
|
// Allow player to skip to the retry options
|
|
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT)
|
|
AND (TIMERB()<CEIL(FAIL_OUT_EFFECT_TIME * FAIL_OUT_EFFECT_SLO_MO*0.7))
|
|
SETTIMERB(CEIL(FAIL_OUT_EFFECT_TIME * FAIL_OUT_EFFECT_SLO_MO*0.7))
|
|
CPRINTLN(DEBUG_REPLAY, "Skipping to the retry prompts.")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
//CPRINTLN(DEBUG_REPLAY, "TimerA = .", TIMERA())
|
|
|
|
// not drawing fail screen yet, request scaleform (DrawReplayScreen also does this)
|
|
RequestScaleform()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Called every frame while a replay screen is on
|
|
/// Hides loading, disables pause menu etc.
|
|
PROC DoCommonReplayScreenSetup()
|
|
CLEAR_PRINTS() // remove any god text / subtitles
|
|
SET_CONTROL_SHAKE(PLAYER_CONTROL, 0, 0) // stop pad vibrating
|
|
DISABLE_CONTROL_ACTION(FRONTEND_CONTROL, INPUT_FRONTEND_PAUSE) // disable pause menu
|
|
HIDE_LOADING_ON_FADE_THIS_FRAME()
|
|
|
|
//Has this replay screen been requested to be skipped by debug routines?
|
|
#IF IS_DEBUG_BUILD
|
|
IF g_bDebugSkipReplayScreen
|
|
g_bDebugSkipReplayScreen = FALSE
|
|
Replay_Player_Has_Accepted(FALSE)
|
|
ENDIF
|
|
#ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Draws the default mission replay screen and waits for the player to respond
|
|
/// REPLAY_PREPARE_ACTIVATION (player has accepted replay)
|
|
/// RS_SCREEN_REJECT_CONFIRMATION (player rejected replay on a story / flow mission)
|
|
PROC Display_RS_SCREEN_DEFAULT()
|
|
STRING sQuestionText
|
|
|
|
DoCommonReplayScreenSetup()
|
|
sQuestionText = ""
|
|
DrawButtonPrompts(RSB_RETRY, RSB_EXIT) // fail reason + A:RETRY B:EXIT
|
|
DrawReplayScreen(sQuestionText)
|
|
|
|
//-----------Wait for selection button press--------------------------------------------
|
|
IF HandleShitskips()
|
|
AND IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_X)
|
|
PLAY_SOUND_FRONTEND(-1, "SKIP", "HUD_FRONTEND_DEFAULT_SOUNDSET")
|
|
ChangeReplayScreen(RS_SCREEN_SKIP_CONFIRMATION)
|
|
ELSE
|
|
// not shit skipping- do other options
|
|
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT)
|
|
PLAY_SOUND_FRONTEND(-1, "RETRY", "HUD_FRONTEND_DEFAULT_SOUNDSET")
|
|
Replay_Player_Has_Accepted(FALSE)
|
|
ELSE
|
|
// handle player rejecting replay
|
|
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_CANCEL)
|
|
PLAY_SOUND_FRONTEND(-1, "EXIT", "HUD_FRONTEND_DEFAULT_SOUNDSET")
|
|
ChangeReplayScreen(RS_SCREEN_REJECT_CONFIRMATION)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Draws the Force Restart mission reaply screen and waits for the player to respond
|
|
/// Moves on to one of these:
|
|
/// REPLAY_PREPARE_ACTIVATION (player chose to restart from checkpoint)
|
|
/// RS_SCREEN_RESTART_CONFIRMATION (player chose to restart from beginning)
|
|
PROC Display_RS_SCREEN_FORCE_RESTART()
|
|
STRING sQuestionText
|
|
|
|
DoCommonReplayScreenSetup()
|
|
|
|
IF g_replay.replayStageReadOnly > 0
|
|
sQuestionText = ""
|
|
DrawButtonPrompts(RSB_RETRY, RSB_RESTART) // Fail reason + A: RETRY Y: RESTART
|
|
ELSE
|
|
sQuestionText = ""
|
|
DrawButtonPrompts(RSB_FORCE_RESTART, RSB_NONE) // Fail reason + A: RESTART
|
|
ENDIF
|
|
|
|
DrawReplayScreen(sQuestionText)
|
|
|
|
//-----------Wait for selection button press--------------------------------------------
|
|
IF HandleShitskips()
|
|
AND IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_X)
|
|
PLAY_SOUND_FRONTEND(-1, "SKIP", "HUD_FRONTEND_DEFAULT_SOUNDSET")
|
|
ChangeReplayScreen(RS_SCREEN_SKIP_CONFIRMATION)
|
|
ELSE
|
|
// not shitskipping- handle other options
|
|
|
|
IF g_replay.replayStageReadOnly > 0
|
|
// retry from checkpoint, or restart
|
|
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT)
|
|
PLAY_SOUND_FRONTEND(-1, "RETRY", "HUD_FRONTEND_DEFAULT_SOUNDSET")
|
|
Replay_Player_Has_Accepted(FALSE)
|
|
ELSE
|
|
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_Y)
|
|
PLAY_SOUND_FRONTEND(-1, "RESTART", "HUD_FRONTEND_DEFAULT_SOUNDSET")
|
|
// player is choosing restart over checkpoint- give confirmation screen
|
|
ChangeReplayScreen(RS_SCREEN_RESTART_CONFIRMATION)
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT)
|
|
PLAY_SOUND_FRONTEND(-1, "RESTART", "HUD_FRONTEND_DEFAULT_SOUNDSET")
|
|
// player is choosing to restart, when he has made no progress, same as accepting replay
|
|
Replay_Player_Has_Accepted(FALSE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Draws the restart confirmation screen and waits for the player to respond
|
|
/// Moves on to one of these:
|
|
/// REPLAY_PREPARE_ACTIVATION (player has accepted restarting from the beginning)
|
|
/// RS_SCREEN_FORCE_RESTART (player has cancelled restarting from begininng, back to previous screen)
|
|
PROC Display_RS_SCREEN_RESTART_CONFIRMATION()
|
|
DoCommonReplayScreenSetup()
|
|
|
|
DrawButtonPrompts(RSB_YES,RSB_NO, FALSE) // Restarting the mission will result in losing checkpoint progress. Are you sure you want to restart? A: YES B: NO
|
|
DrawReplayScreen("REPLAY_AYS")
|
|
|
|
//-----------Wait for selection button press--------------------------------------------
|
|
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT)
|
|
PLAY_SOUND_FRONTEND(-1, "YES", "HUD_FRONTEND_DEFAULT_SOUNDSET")
|
|
Replay_Player_Has_Accepted(TRUE)
|
|
ELSE
|
|
// handle player rejecting replay
|
|
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_CANCEL)
|
|
PLAY_SOUND_FRONTEND(-1, "NO", "HUD_FRONTEND_DEFAULT_SOUNDSET")
|
|
// rejecting a restart confirmation screen takes you back to the force restart screen
|
|
ChangeReplayScreen(RS_SCREEN_FORCE_RESTART)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Draws the replay rejection confirmation screen and waits for the player to respond
|
|
/// Moves on to one of these:
|
|
/// RS_NOT_REQUIRED (player has confirmed rejecting the non story / flow mission)
|
|
/// RS_REJECTED (player has confirmed rejecting the story / flow mission)
|
|
/// PREVIOUS SCREEN: If player cancels rejection we return to one of the other fail screens
|
|
/// Currently if cancelled this always goes back to RS_SCREEN_DEFAULT as it is only one that offers replay rejection
|
|
PROC Display_RS_SCREEN_REJECT_CONFIRMATION()
|
|
DoCommonReplayScreenSetup()
|
|
|
|
DrawButtonPrompts(RSB_YES,RSB_NO, FALSE) // Exiting the mission will result in losing mission progress. Are you sure you want to exit? A: YES B: NO
|
|
DrawReplayScreen("REPLAY_REJ")
|
|
|
|
//-----------Wait for selection button press--------------------------------------------
|
|
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT)
|
|
PLAY_SOUND_FRONTEND(-1, "YES", "HUD_FRONTEND_DEFAULT_SOUNDSET")
|
|
CPRINTLN(DEBUG_REPLAY, "Player rejected replay")
|
|
Replay_Player_Has_Rejected()
|
|
ELSE
|
|
// handle player rejecting replay
|
|
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_CANCEL)
|
|
PLAY_SOUND_FRONTEND(-1, "NO", "HUD_FRONTEND_DEFAULT_SOUNDSET")
|
|
// rejecting a restart confirmation screen takes you back to the previous replay screen
|
|
CPRINTLN(DEBUG_REPLAY, "Player rejected reject confirmation screen, going back to previous screen")
|
|
SetReplayScreenType()
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Draws the shitskip confirmation screen and waits for the player to respond
|
|
/// Moves on to one of these:
|
|
/// REPLAY_PREPARE_ACTIVATION (player has accepted the shitskip)
|
|
/// PREVIOUS SCREEN: If player cancels the shitskip we return to one of the other fail screens
|
|
PROC Display_RS_SCREEN_SKIP_CONFIRMATION()
|
|
DoCommonReplayScreenSetup()
|
|
|
|
DrawButtonPrompts(RSB_YES,RSB_NO, FALSE)
|
|
IF g_bShitskipToEnd = TRUE
|
|
DrawReplayScreen("REPLAY_SKIPM") // Are you sure you want to skip this mission? A: YES B: NO
|
|
ELSE
|
|
DrawReplayScreen("REPLAY_SKIPS") // Are you sure you want to skip this section? A: YES B: NO
|
|
ENDIF
|
|
|
|
//-----------Wait for selection button press--------------------------------------------
|
|
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT)
|
|
PLAY_SOUND_FRONTEND(-1, "YES", "HUD_FRONTEND_DEFAULT_SOUNDSET")
|
|
CPRINTLN(DEBUG_REPLAY, "Player accepted shitskip")
|
|
g_bShitskipAccepted = TRUE
|
|
INFORM_MISSION_STATS_SYSTEM_OF_SHITSKIP()
|
|
|
|
//Update the profile stat tracking how many times this player has skipped a checkpoint.
|
|
INT iTimesSkipped
|
|
STAT_GET_INT(TIMES_MISSION_SKIPPED, iTimesSkipped)
|
|
STAT_SET_INT(TIMES_MISSION_SKIPPED, iTimesSkipped+1)
|
|
SET_BIT(g_replay.iReplayBits, ENUM_TO_INT(RB_DID_WE_EVER_SHITSKIP))
|
|
|
|
Replay_Player_Has_Accepted(FALSE)
|
|
ELSE
|
|
// handle player rejecting shitskip
|
|
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_CANCEL)
|
|
PLAY_SOUND_FRONTEND(-1, "NO", "HUD_FRONTEND_DEFAULT_SOUNDSET")
|
|
// rejecting a shitskip confirmation screen takes you back to the previous replay screen
|
|
CPRINTLN(DEBUG_REPLAY, "Player rejected shitskip confirmation screen, going back to previous screen")
|
|
SetReplayScreenType()
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Draws the Fail Only mission reaply screen and waits for the player to respond
|
|
/// Moves on to one of these:
|
|
/// RS_NOT_REQUIRED (player rejected non story / flow mission)
|
|
/// RS_REJECTED (player rejected replay on a story / flow mission)
|
|
PROC Display_RS_SCREEN_FAIL_ONLY()
|
|
DoCommonReplayScreenSetup()
|
|
|
|
DrawButtonPrompts(RSB_OK, RSB_NONE, FALSE) // fail reason + A: OK
|
|
DrawReplayScreen(" ")
|
|
|
|
//-----------Wait for selection button press--------------------------------------------
|
|
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT)
|
|
PLAY_SOUND_FRONTEND(-1, "OK", "HUD_FRONTEND_DEFAULT_SOUNDSET")
|
|
CPRINTLN(DEBUG_REPLAY, "Player rejected replay- fail only")
|
|
Replay_Player_Has_Rejected()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Sets the bit that lets the mission know it is being replayed
|
|
PROC Setup_Mission_Specific_Replay_State()
|
|
CPRINTLN(DEBUG_REPLAY, "Setting up Mission replay state.")
|
|
|
|
// Stop the flow from prestreaming intro mocaps for replayed missions.
|
|
g_eMissionIDToLoadCutscene = SP_MISSION_NONE
|
|
g_bFlowLoadIntroCutscene = FALSE
|
|
g_bFlowLoadRequestStarted = FALSE
|
|
g_bFlowCleanupIntroCutscene = TRUE
|
|
g_bFlowLoadingIntroCutscene = FALSE
|
|
|
|
IF IsThisAPrepMission()
|
|
CPRINTLN(DEBUG_REPLAY, "Accepted replay for prep mission")
|
|
// set replay as rejected for prep missions
|
|
// as we don't want them to retrigger (just re-blip)
|
|
// also need to clear the candidate ID as the mission needs to be able to retrigger normally
|
|
Replay_RejectionCleanup()
|
|
ELSE
|
|
SET_BIT(g_availableMissions[Get_Available_Mission_Index_For_Stored_Mission(g_replay.replayCoreVarsIndex)].bitflags, BITS_AVAILABLE_MISSION_BEING_REPLAYED)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Flag a global flag to inform all minigame launchers that a minigame replay is ready to be processed.
|
|
PROC Setup_Minigame_Specific_Replay_State()
|
|
CPRINTLN(DEBUG_REPLAY, "Setting up Minigame replay state.")
|
|
g_bLaunchMinigameReplay = TRUE
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Sets up any requirements for an RC mission to trigger its replay
|
|
/// then waits until the replay activates
|
|
PROC Setup_Random_Character_Specific_Replay_State()
|
|
CPRINTLN(DEBUG_REPLAY, "Setting up Random Character replay state. for ", g_replay.replayScriptName)
|
|
|
|
//Get RC mission data.
|
|
g_eRC_MissionIDs eRCMissionID = Get_RC_MissionID_For_Script(g_replay.replayScriptName)
|
|
g_structRCMissionsStatic sRCMissionDetails
|
|
Retrieve_Random_Character_Static_Mission_Details(eRCMissionID, sRCMissionDetails)
|
|
|
|
// Unpause the game here, so we can do the warp / reactivate properly
|
|
Replay_Pause_Game(FALSE)
|
|
|
|
g_structRCScriptArgs sRCLauncherData // Scene information to pass to mission script
|
|
RC_Reset_LauncherData(sRCLauncherData)
|
|
sRCLauncherData.sScriptName = g_replay.replayScriptName
|
|
sRCLauncherData.eMissionID = eRCMissionID
|
|
|
|
INFORM_MISSION_STATS_SYSTEM_OF_RESTART()
|
|
|
|
WHILE NOT LAUNCH_RC_MISSION(sRCLauncherData)
|
|
WAIT(0)
|
|
CPRINTLN(DEBUG_REPLAY, "Waiting for RC mission to relaunch.")
|
|
ENDWHILE
|
|
CPRINTLN(DEBUG_REPLAY, "RC mission has relaunched.")
|
|
SET_RC_AS_RUNNING(eRCMissionID)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Waits for player to respawn, sets him to have at least a decent amount of health
|
|
/// Sets up any specific requirements for this replay type then resets common replay changes (enables phone etc)
|
|
/// Moves on to RS_ACTIVE
|
|
PROC ReplayActivate()
|
|
BOOL bDoFade = TRUE
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
bDoFade = bFadeOut // skip the fade?
|
|
#ENDIF
|
|
|
|
// DO NOT CHECK THIS IN!! DEBUG ONLY!
|
|
//#IF IS_DEBUG_BUILD BREAK_ON_NATIVE_COMMAND("NEW_LOAD_SCENE_START_SPHERE", FALSE) #ENDIF
|
|
//#IF IS_DEBUG_BUILD BREAK_ON_NATIVE_COMMAND("SET_GAMEPLAY_CAM_RELATIVE_HEADING", FALSE) #ENDIF
|
|
//#IF IS_DEBUG_BUILD BREAK_ON_NATIVE_COMMAND("SET_GAMEPLAY_CAM_RELATIVE_PITCH", FALSE) #ENDIF
|
|
|
|
|
|
IF DOES_MISSION_USE_NEW_REPLAY_SYSTEM()
|
|
IF IsThisAPrepMission() = FALSE
|
|
// for normal replays, don't let the replay controller get paused
|
|
// so it can handle the teleport whilst the mission sets up
|
|
CPRINTLN(DEBUG_REPLAY, "Using new replay warp system for this mission.")
|
|
SET_THIS_SCRIPT_CAN_BE_PAUSED(FALSE)
|
|
g_eReplayWarpStage = RWS_WAIT
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Fade out if needed
|
|
IF bDoFade = TRUE
|
|
AND NOT IS_SCREEN_FADED_OUT()
|
|
AND NOT IS_SCREEN_FADING_OUT()
|
|
DO_SCREEN_FADE_OUT(0)
|
|
ENDIF
|
|
|
|
// Ensure player health is at a minimum level (ensure this is after the player swap).
|
|
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
|
|
INT iPlayerHealth = GET_ENTITY_HEALTH(PLAYER_PED_ID())
|
|
CPRINTLN(DEBUG_REPLAY, "Current Player Health: ", iPlayerHealth)
|
|
IF (iPlayerHealth < MINIMUM_REPLAY_HEALTH)
|
|
CPRINTLN(DEBUG_REPLAY, "Health for Replay too low. Being boosted to ", MINIMUM_REPLAY_HEALTH, ".")
|
|
SET_ENTITY_HEALTH(PLAYER_PED_ID(), MINIMUM_REPLAY_HEALTH)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// launcher setup
|
|
IF DoesThisReplayTypeUseStoryMissionLauncher()
|
|
Setup_Mission_Specific_Replay_State()
|
|
ELSE
|
|
SWITCH g_replay.replayType
|
|
CASE REPLAY_TYPE_MINIGAME
|
|
Setup_Minigame_Specific_Replay_State()
|
|
BREAK
|
|
CASE REPLAY_TYPE_RANDOM_CHARACTER
|
|
Setup_Random_Character_Specific_Replay_State()
|
|
BREAK
|
|
DEFAULT
|
|
SCRIPT_ASSERT("Replay_Controller: Wrong replay type in Maintain_Wait_Until_Replay_Ready_To_Launch()")
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
|
|
IF IsThisAPrepMission() = FALSE
|
|
// prep missions handle this stuff via the rejection cleanup
|
|
// as they don't actually launch the mission again
|
|
|
|
//TODO, add check here for invalidation type relating to bug 536824
|
|
IF GET_REPLAY_MID_MISSION_STAGE()!= 0
|
|
INFORM_MISSION_STATS_SYSTEM_OF_RESTART()
|
|
ENDIF
|
|
//ELSE
|
|
// INFORM_MISSION_STATS_SYSTEM_OF_RESTART(TRUE)
|
|
//ENDIF
|
|
|
|
// reset necessary replay variables
|
|
Reset_Fail_Warp_Location()
|
|
ResetFailReasons()
|
|
ENDIF
|
|
|
|
ResetCommonReplayChanges()
|
|
|
|
WAIT(0) // wait needed as we are unpausing
|
|
|
|
IF IsThisAPrepMission() = FALSE
|
|
// prep missions handle this stuff via the rejection cleanup
|
|
// as they don't actually launch the mission again
|
|
// Replay now active - mission flow should take over now and re-launch the script.
|
|
g_replay.replayStageID = RS_ACTIVE
|
|
ELSE
|
|
// slight delay before fading back in so we don't see repopulated area peds not having anims
|
|
WAIT(500)
|
|
CPRINTLN(DEBUG_REPLAY, "Fading screen back in for prep mission.")
|
|
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// ===========================================================================================================
|
|
// Script Loop
|
|
// ===========================================================================================================
|
|
SCRIPT
|
|
CPRINTLN(DEBUG_REPLAY, "Replay_controller.sc is now being launched.")
|
|
|
|
#IF IS_DEBUG_BUILD Initialise_Replay_Debug_Widgets() #ENDIF
|
|
|
|
WHILE (TRUE)
|
|
// ----------------------Handle debug menu callback --------------------------
|
|
IF bCallbacksSetup = FALSE
|
|
CPRINTLN(DEBUG_REPLAY, "bCallbacksSetup = false.")
|
|
|
|
bCallbacksSetup = TRUE
|
|
bForceSkipReplayScreen = FALSE
|
|
bFadeInOnSkipReplayScreen = FALSE
|
|
CPRINTLN(DEBUG_REPLAY, "SETTING UP CALLBACKS.")
|
|
IF HAS_FORCE_CLEANUP_OCCURRED(FORCE_CLEANUP_FLAG_DEBUG_MENU | FORCE_CLEANUP_FLAG_SP_TO_MP | FORCE_CLEANUP_FLAG_MAGDEMO | FORCE_CLEANUP_FLAG_REPEAT_PLAY)
|
|
SWITCH GET_CAUSE_OF_MOST_RECENT_FORCE_CLEANUP()
|
|
|
|
CASE FORCE_CLEANUP_FLAG_DEBUG_MENU
|
|
CPRINTLN(DEBUG_REPLAY, "Replay_controller.sc skipping replay: DebugMenu force cleanup.")
|
|
bForceSkipReplayScreen = TRUE
|
|
bFadeInOnSkipReplayScreen = TRUE
|
|
bCallbacksSetup = FALSE
|
|
BREAK
|
|
|
|
CASE FORCE_CLEANUP_FLAG_REPEAT_PLAY
|
|
CPRINTLN(DEBUG_REPLAY, "Replay_controller.sc skipping replay: Repeat Play force cleanup.")
|
|
bForceSkipReplayScreen = TRUE
|
|
bFadeInOnSkipReplayScreen = FALSE
|
|
bCallbacksSetup = FALSE
|
|
BREAK
|
|
|
|
CASE FORCE_CLEANUP_FLAG_SP_TO_MP
|
|
CPRINTLN(DEBUG_REPLAY, "Replay_controller.sc has been forced to cleanup SP to MP.")
|
|
Script_Cleanup()
|
|
BREAK
|
|
|
|
CASE FORCE_CLEANUP_FLAG_MAGDEMO
|
|
CPRINTLN(DEBUG_REPLAY, "Replay_controller.sc has been forced to cleanup Magdemo.")
|
|
Script_Cleanup()
|
|
BREAK
|
|
|
|
DEFAULT
|
|
// other force cleanups are ignored
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
ENDIF
|
|
|
|
If bForceSkipReplayScreen = TRUE
|
|
CPRINTLN(DEBUG_REPLAY, "Skipping replay screen caused by debug menu force cleanup.")
|
|
SkipReplayScreen(bFadeInOnSkipReplayScreen #IF IS_DEBUG_BUILD ,TRUE #ENDIF)
|
|
ELSE
|
|
// -----------------------Debug stuff--------------------------------
|
|
#IF IS_DEBUG_BUILD
|
|
Maintain_Replay_Debug_Widgets()
|
|
|
|
//Allow us to F / J skip replays. (J skip is used by missionTester / autoplaythrough)
|
|
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F)
|
|
OR IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J)
|
|
IF IsReplayWaitingForReplayScreen()
|
|
SkipReplayScreen(TRUE #IF IS_DEBUG_BUILD ,FALSE #ENDIF)
|
|
ENDIF
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
BOOL bCheckState = TRUE
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
// only check replay stage if gameflow isn't being setup
|
|
// or we're in the RS_WAITING_FOR_FLOW stage
|
|
IF g_flowUnsaved.bUpdatingGameflow = FALSE
|
|
OR g_replay.replayStageID = RS_WAITING_FOR_FLOW
|
|
bCheckState = TRUE
|
|
ELSE
|
|
bCheckState = FALSE
|
|
// Gameflow is updating, so don't try to set up a new replay
|
|
//CPRINTLN(DEBUG_REPLAY, "Gameflow is busy, so pausing replay controller.")
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// ------------Main Replay Flow ------------------------------------------
|
|
IF bCheckState = TRUE
|
|
SWITCH (g_replay.replayStageID)
|
|
|
|
// If replay controller loads up in this state move straight into not required
|
|
CASE RS_NOT_RUNNING
|
|
g_replay.replayStageID = RS_NOT_REQUIRED
|
|
BREAK
|
|
|
|
// show fail reason, wait if necessary then fade out
|
|
CASE RS_DO_BLUR
|
|
Replay_Do_Blur()
|
|
BREAK
|
|
|
|
// Replay screen for normal missions.
|
|
CASE RS_SCREEN_DEFAULT
|
|
Display_RS_SCREEN_DEFAULT()
|
|
BREAK
|
|
|
|
// Replay screen for force restart missions.
|
|
CASE RS_SCREEN_FORCE_RESTART
|
|
Display_RS_SCREEN_FORCE_RESTART()
|
|
BREAK
|
|
|
|
// Replay screen for force restart missions.
|
|
CASE RS_SCREEN_RESTART_CONFIRMATION
|
|
Display_RS_SCREEN_RESTART_CONFIRMATION()
|
|
BREAK
|
|
|
|
// Replay screen for confirming the player wants to exit the mission.
|
|
CASE RS_SCREEN_REJECT_CONFIRMATION
|
|
Display_RS_SCREEN_REJECT_CONFIRMATION()
|
|
BREAK
|
|
|
|
// Replay screen for confirming the player wants to skip forwards in the mission.
|
|
CASE RS_SCREEN_SKIP_CONFIRMATION
|
|
Display_RS_SCREEN_SKIP_CONFIRMATION()
|
|
BREAK
|
|
|
|
// Replay screen for fail screen only missions. No replay options.
|
|
CASE RS_SCREEN_FAIL_ONLY
|
|
Display_RS_SCREEN_FAIL_ONLY()
|
|
BREAK
|
|
|
|
// Does some setup and terminates the mission thread
|
|
CASE RS_ACCEPTING
|
|
// This is handled in Replay_Player_Has_Accepted in replay private
|
|
// as it needs to run in same frame as player accepting the replay
|
|
BREAK
|
|
|
|
// Does some setup and terminates the mission thread
|
|
CASE RS_REJECTING
|
|
// This is handled in Replay_Player_Has_Accepted in replay private
|
|
// as it needs to run in same frame as player rejecting the replay
|
|
BREAK
|
|
|
|
// Waiting for the replay preparations to finish ready to start the replay
|
|
CASE RS_ACTIVATE
|
|
ReplayActivate()
|
|
BREAK
|
|
|
|
// The replay is now active - control has been handed over to the replaying activity
|
|
CASE RS_ACTIVE
|
|
|
|
IF DOES_MISSION_USE_NEW_REPLAY_SYSTEM()
|
|
// Handle warping the player into position
|
|
// Clearing + repopulating area
|
|
IF g_eReplayWarpStage <> RWS_DONE
|
|
IF REPLAY_WARP_PLAYER(iReplayWarpTimer)
|
|
SET_THIS_SCRIPT_CAN_BE_PAUSED(TRUE)
|
|
ELSE
|
|
/*
|
|
#IF IS_DEBUG_BUILD
|
|
// do not check in!
|
|
IF g_eReplayWarpStage > RWS_START
|
|
AND g_eReplayWarpStage < RWS_DONE
|
|
// warp ongoing, check for player and camera movement
|
|
VECTOR vPos
|
|
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
|
|
vPos = GET_ENTITY_COORDS(PLAYER_PED_ID())
|
|
IF GET_DISTANCE_BETWEEN_COORDS(vPos, g_eReplayWarpPos) > 30
|
|
SCRIPT_ASSERT("ReplayWarp: Player moved too far from g_eReplayWarpPos!")
|
|
ENDIF
|
|
vPos = GET_GAMEPLAY_CAM_COORD()
|
|
IF GET_DISTANCE_BETWEEN_COORDS(vPos, g_eReplayWarpPos) > 30
|
|
SCRIPT_ASSERT("ReplayWarp: Camera moved too far from g_eReplayWarpPos!")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
#ENDIF
|
|
*/
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
// The player has rejected the replay, and we have done the teleport etc (story / flow only)
|
|
CASE RS_REJECTED
|
|
// This is currently only used by story missions to get the mission flow to work correctly
|
|
// Flow waits for replay to finish processing,
|
|
// Then if it was rejected, cleans up + moves on, otherwise it relaunches mission
|
|
BREAK
|
|
|
|
// Not currently processing a replay and a replay is not being played
|
|
CASE RS_NOT_REQUIRED
|
|
IF NOT(IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY)
|
|
OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY_FRIENDS)
|
|
OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY_PREP)
|
|
OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_RANDOM_CHAR)
|
|
OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME)
|
|
OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME_FRIENDS))
|
|
CPRINTLN(DEBUG_REPLAY, "Cleaning up replay controller as there are no missions running to service.")
|
|
Script_Cleanup()
|
|
ENDIF
|
|
BREAK
|
|
|
|
// debug only states
|
|
#IF IS_DEBUG_BUILD
|
|
// A debug menu force cleanup was triggred
|
|
// Now wait in this state until flow setup is done
|
|
// So a replay can't be offered just before flow setup begins
|
|
CASE RS_WAITING_FOR_FLOW
|
|
IF bWaitingForFlowToStart = TRUE
|
|
IF g_flowUnsaved.bUpdatingGameflow = FALSE
|
|
//CPRINTLN(DEBUG_REPLAY, "Waiting for flow setup to begin.")
|
|
ELSE
|
|
bWaitingForFlowToStart = FALSE
|
|
//CPRINTLN(DEBUG_REPLAY, "Flow setup has started.")
|
|
ENDIF
|
|
ELSE
|
|
IF g_flowUnsaved.bUpdatingGameflow = FALSE
|
|
//CPRINTLN(DEBUG_REPLAY, "Exiting RS_WAITING_FOR_FLOW.")
|
|
g_replay.replayStageID = RS_NOT_REQUIRED
|
|
// Can also get out of this state by calling CleanupReplayController
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
#ENDIF
|
|
|
|
DEFAULT
|
|
SCRIPT_ASSERT("Replay_Controller: Unknown Replay Stage ID")
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
ENDIF
|
|
|
|
WAIT (0)
|
|
ENDWHILE
|
|
|
|
// Script should never reach here. Always terminate with cleanup function.
|
|
ENDSCRIPT
|