Files
2025-09-29 00:52:08 +02:00

865 lines
25 KiB
Python
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//Compile out Title Update changes to header functions.
//Must be before includes.
//CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R.
USING "rage_builtins.sch"
USING "globals.sch"
USING "cutscene_public.sch"
USING "commands_cutscene.sch"
USING "commands_entity.sch"
USING "commands_script.sch"
USING "script_player.sch"
USING "randomChar_public.sch"
USING "CompletionPercentage_public.sch"
USING "email_public.sch"
USING "RC_Helper_Functions.sch"
USING "initial_scenes_Epsilon.sch"
USING "commands_recording.sch"
#IF IS_DEBUG_BUILD
USING "select_mission_stage.sch"
#ENDIF
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
//
// MISSION NAME : Epsilon1.sc
// AUTHOR : David Roberts
// DESCRIPTION : At dawn one morning, MICHAEL finds a RED TRUCK with a dent on
// its right FENDER in a pass in the countryside.
//
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
g_structRCScriptArgs sRCLauncherDataLocal
ENUM eRC_MainState
RC_INIT = 0,
RC_LEAD_IN,
RC_MEET_TOM,
RC_MICHAEL_PASS_OUT,
RC_MICHAEL_DUMPED,
RC_PASSED,
RC_STAGE_FAIL
ENDENUM
ENUM eRC_SubState
SS_SETUP = 0,
SS_UPDATE,
SS_CLEANUP
ENDENUM
ENUM GOON_AI
AI_FIGHT_INIT,
AI_FIGHTING,
AI_WAITING,
AI_WAIT_INIT
ENDENUM
STRUCT EpsilonGoon
PED_INDEX ped
BLIP_INDEX blip
GOON_AI AI
SEQUENCE_INDEX seqInd
ENDSTRUCT
ENUM CONV_STATE
CONV_WAITING,
CONV_DOLINE,
CONV_SPEAKING
ENDENUM
CONST_INT CP_AFTER_MOCAP 0 // Checkpoint
CONST_INT TOM 0
CONST_INT EPSILON_VEHICLE 0
CONST_INT MAX_GOONS 3
CONST_INT MAX_TAUNTS 4
// Mission state
eRC_MainState m_eState = RC_INIT
eRC_SubState m_eSubState = SS_SETUP
STRING sSceneHandleEpsilonVeh = "red_epsilon_truck"
PED_INDEX TomPed
MODEL_NAMES modelTom = CS_TOM
MODEL_NAMES modelVeh = BISON
VEHICLE_INDEX epsVeh
STRING sFailReason = "DEFAULT"
STRING sOnGroundDict = "GET_UP@DIRECTIONAL@TRANSITION@PRONE_TO_SEATED@STANDARD"
structPedsForConversation convStruct
VECTOR dumpCoords = <<1971.7144, 2870.0461, 48.9397>> // Coords for where Michael is dumped in his underpants
VECTOR tomLoc = <<1975.8699, 2865.3984, 49.1545>>
FLOAT epsVehSpeed = 15
BOOL bFading = FALSE
BOOL bTomConv = FALSE
BOOL bTriggeredMusic = FALSE
BOOL bTruckConv = FALSE
BOOL bAnimPlaying = FALSE
CAMERA_INDEX camDumped
CAMERA_INDEX camDumped1
#IF IS_DEBUG_BUILD
CONST_INT MAX_SKIP_MENU_LENGTH 2
MissionStageMenuTextStruct mSkipMenu[MAX_SKIP_MENU_LENGTH]
#ENDIF
/// PURPOSE:
/// Tells what side of a plane a point is on
/// PARAMS:
/// pNorm - plane normal
/// pOrg - plane origin
/// v - point we want to check
/// RETURNS:
/// Returns -1 if behind plane, +1 if in front and 0 if on plane
FUNC INT GET_PLANE_SIDE(VECTOR pNorm, VECTOR pOrg, VECTOR v)
FLOAT dot = DOT_PRODUCT(v - pOrg, pNorm)
IF (dot < 0)
RETURN -1 // it's behind the plane
ELIF (dot > 0)
RETURN 1 // it's in front of the plane
ENDIF
RETURN 0 // ON PLANE
ENDFUNC
// ===========================================================================================================
// Termination
// ===========================================================================================================
// -----------------------------------------------------------------------------------------------------------
// Script Cleanup
// -----------------------------------------------------------------------------------------------------------
/// PURPOSE:
/// Safely cleans up the script
PROC Script_Cleanup()
// Ensure launcher is cleaned up
RC_CLEANUP_LAUNCHER()
// If the mission was triggered then additional mission cleanup will be required.
IF (Random_Character_Cleanup_If_Triggered())
CPRINTLN(DEBUG_MISSION, "...Random Character Script was triggered so additional cleanup required")
SAFE_RELEASE_PED(TomPed)
SAFE_RELEASE_VEHICLE(epsVeh)
SET_MODEL_AS_NO_LONGER_NEEDED(modelVeh)
SET_MODEL_AS_NO_LONGER_NEEDED(modelTom)
CLEAR_PICKUP_REWARD_TYPE_SUPPRESSION(PICKUP_REWARD_TYPE_WEAPON)
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
CLEAR_PED_TASKS(PLAYER_PED_ID())
RESTORE_PLAYER_PED_WEAPONS(PLAYER_PED_ID())
ENDIF
IF IS_ENTITY_ALIVE(GET_PLAYERS_LAST_VEHICLE())
SET_VEHICLE_DOORS_LOCKED(GET_PLAYERS_LAST_VEHICLE(), VEHICLELOCK_UNLOCKED)
ENDIF
ENDIF
RC_END_CUTSCENE_MODE() // Return script systems to normal.
SET_WANTED_LEVEL_MULTIPLIER(1.0)
SAFE_RELEASE_PED(TomPed)
REMOVE_ANIM_DICT(sOnGroundDict)
// Cleanup scene entities created by the RC launcher
RC_CleanupSceneEntities(sRCLauncherDataLocal, TRUE)
DISABLE_CELLPHONE(FALSE)
TERMINATE_THIS_THREAD()
ENDPROC
/// PURPOSE:
/// Sets the new mission state and initialises the substate.
PROC SetState(eRC_MainState in)
m_eState = in
m_eSubState = SS_SETUP
ENDPROC
/// PURPOSE:
/// Sets the fail reason, and goes to the fail stage
/// PARAMS:
/// sFail - the fail reason
PROC SET_MISSION_FAILED(STRING sFail)
STOP_SCRIPTED_CONVERSATION(FALSE)
CLEAR_PRINTS()
sFailReason = sFail
SetState(RC_STAGE_FAIL)
ENDPROC
/// PURPOSE:
/// Fails and cleans up the mission correctly
PROC STATE_FAIL()
STOP_SCRIPTED_CONVERSATION(FALSE)
CLEAR_PRINTS()
SWITCH m_eSubState
CASE SS_SETUP
IF PREPARE_MUSIC_EVENT("EPS1_FAIL")
IF TRIGGER_MUSIC_EVENT("EPS1_FAIL")
CPRINTLN(DEBUG_MISSION, "Playing audio - EPS1_FAIL")
ENDIF
ENDIF
IF ARE_STRINGS_EQUAL(sFailReason,"DEFAULT")
Random_Character_Failed()
ELSE
Random_Character_Failed_With_Reason(sFailReason, TRUE)
ENDIF
m_eSubState = SS_UPDATE
BREAK
CASE SS_UPDATE
IF GET_MISSION_FLOW_SAFE_TO_CLEANUP()
Script_Cleanup() // script_cleanup should terminate the thread
ELSE
ENDIF
BREAK
ENDSWITCH
ENDPROC
// -----------------------------------------------------------------------------------------------------------
// Script Pass
// -----------------------------------------------------------------------------------------------------------
/// PURPOSE:
/// Adds needed contacts, completion %, cleans up and passes script.
PROC Script_Passed()
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
SET_PED_RESET_FLAG(PLAYER_PED_ID(),PRF_DisableDustOffAnims, TRUE)
ENDIF
IF PREPARE_MUSIC_EVENT("EPS1_STOP")
IF TRIGGER_MUSIC_EVENT("EPS1_STOP")
CPRINTLN(DEBUG_MISSION, "Playing audio - EPS1_STOP")
ENDIF
ENDIF
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
CLEAR_PLAYER_WANTED_LEVEL(GET_PLAYER_INDEX())
ENDIF
Random_Character_Passed(CP_RAND_C_EPS1)
// TODO: Move email into comms? We can reset donation in a code ID then...
WHILE NOT REGISTER_EMAIL_FROM_CHARACTER_TO_PLAYER(EMAIL_EPSILON1_DONATE, CT_AMBIENT, BIT_MICHAEL, CHAR_MARNIE, 15000, 10000)
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
SET_PED_RESET_FLAG(PLAYER_PED_ID(),PRF_DisableDustOffAnims, TRUE)
ENDIF
WAIT(0)
ENDWHILE
// Reset donations - pity the fool who has donated before this
CPRINTLN(DEBUG_RANDOM_CHAR, "Resetting donation to Epsilon Program for new mission request.")
g_savedGlobals.sRandomChars.g_iCurrentEpsilonPayment = 0
//Set epsilon step stat
INT iCurrent
STAT_GET_INT(NUM_EPSILON_STEP,iCurrent)
IF iCurrent < 2
STAT_SET_INT(NUM_EPSILON_STEP,2)
SET_ACHIEVEMENT_PROGRESS_SAFE(ENUM_TO_INT(ACH20),2)
CPRINTLN(debug_dan,"Epsilon progress:",2)
ENDIF
// Terminate script
Script_Cleanup()
ENDPROC
/// PURPOSE:
/// Creates Tom
PROC CREATE_TOM()
IF NOT DOES_ENTITY_EXIST(TomPed)
TomPed = CREATE_PED(PEDTYPE_MISSION, modelTom, tomLoc)
ENDIF
IF IS_ENTITY_ALIVE(TomPed)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(TomPed, TRUE)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(TomPed, TRUE)
SET_PED_KEEP_TASK(TomPed, TRUE)
ENDIF
ENDPROC
// ===========================================================================================================
// DEBUG FUNCTIONS
// ===========================================================================================================
#IF IS_DEBUG_BUILD
/// PURPOSE:
/// Sets Michael to look like he's in the fight again
PROC RESET_EPS1()
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), <<-1635.2100, 4204.3101, 83.0421>>)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
SAFE_DELETE_VEHICLE(epsVeh)
RESTORE_MISSION_START_OUTFIT()
DISABLE_CELLPHONE(FALSE)
//REMOVE_GOONS(FALSE)
//iGoonTaunt = 0
ENDPROC
PROC EPS1_DEBUG_SKIP_STATE(eRC_MainState eMissionStageToSkipTo)
RC_START_Z_SKIP()
STOP_SCRIPTED_CONVERSATION(FALSE)
CLEAR_PRINTS()
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
SET_ENTITY_HEALTH(PLAYER_PED_ID(), MAX_HEALTH_VALUE)
ENDIF
IF PREPARE_MUSIC_EVENT("EPS1_STOP")
IF TRIGGER_MUSIC_EVENT("EPS1_STOP")
CPRINTLN(DEBUG_MISSION, "Playing audio - EPS1_STOP")
ENDIF
ENDIF
SWITCH eMissionStageToSkipTo
CASE RC_MEET_TOM
RESET_EPS1()
RC_END_CUTSCENE_MODE()
RC_REQUEST_CUTSCENE("EP_1_RCM_Concat")
setState(eMissionStageToSkipTo)
BREAK
CASE RC_MICHAEL_PASS_OUT
RESET_EPS1()
setState(eMissionStageToSkipTo)
BREAK
CASE RC_MICHAEL_DUMPED
CREATE_TOM()
setState(eMissionStageToSkipTo)
BREAK
CASE RC_PASSED
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_OUTFIT, OUTFIT_P0_BED, FALSE)
ENDIF
DISABLE_CELLPHONE(FALSE)
setState(RC_PASSED)
BREAK
DEFAULT
CERRORLN(DEBUG_MISSION, " BARRY3_DEBUG_SKIP_STATE tried to skip to ", eMissionStageToSkipTo)
SCRIPT_ASSERT("Script cannot handle the given debug skip-to state")
BREAK
ENDSWITCH
RC_END_Z_SKIP()
ENDPROC
/// PURPOSE:
/// Check for Forced Pass or Fail
PROC DEBUG_Check_Debug_Keys()
// Check for Pass
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S))
WAIT_FOR_CUTSCENE_TO_STOP()
RC_END_Z_SKIP()
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID())
ENDIF
SetState(RC_PASSED)
ENDIF
// Check for Fail
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F))
WAIT_FOR_CUTSCENE_TO_STOP()
RC_END_Z_SKIP()
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID())
ENDIF
Random_Character_Failed()
Script_Cleanup()
TERMINATE_THIS_THREAD()
// Forward skip
ELIF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J))
RC_END_Z_SKIP()
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID())
ENDIF
SWITCH (m_eState)
CASE RC_INIT
CPRINTLN(DEBUG_MISSION, "Attempted j skip - you cannot skip initialisation")
BREAK
CASE RC_MEET_TOM
EPS1_DEBUG_SKIP_STATE(RC_MICHAEL_DUMPED)
BREAK
CASE RC_MICHAEL_PASS_OUT
EPS1_DEBUG_SKIP_STATE(RC_MICHAEL_DUMPED)
BREAK
CASE RC_MICHAEL_DUMPED
EPS1_DEBUG_SKIP_STATE(RC_PASSED)
BREAK
CASE RC_PASSED
CPRINTLN(DEBUG_MISSION, "Attempted j skip - you cannot skip mission pass")
BREAK
CASE RC_STAGE_FAIL
CPRINTLN(DEBUG_MISSION, "Attempted j skip - you cannot skip during fail")
BREAK
DEFAULT
CERRORLN(DEBUG_MISSION, " DEBUG_Check_Debug_Keys tried to j skip from ", m_eState)
SCRIPT_ASSERT("Unhandled j skip")
BREAK
ENDSWITCH
//back skip
ELIF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P)
SWITCH (m_eState)
CASE RC_INIT
CPRINTLN(DEBUG_MISSION, "Attempted p skip - there are no skippable stages before initialisation")
BREAK
CASE RC_MEET_TOM
CPRINTLN(DEBUG_MISSION, "Attempted p skip - there are no skippable stages before meeting barry cutscene")
BREAK
CASE RC_MICHAEL_PASS_OUT
EPS1_DEBUG_SKIP_STATE(RC_MEET_TOM)
BREAK
CASE RC_MICHAEL_DUMPED
EPS1_DEBUG_SKIP_STATE(RC_MEET_TOM)
BREAK
CASE RC_PASSED
CPRINTLN(DEBUG_MISSION, "Attempted p skip - you cannot skip mission pass")
BREAK
CASE RC_STAGE_FAIL
CPRINTLN(DEBUG_MISSION, "Attempted p skip - you cannot skip during fail")
BREAK
DEFAULT
CERRORLN(DEBUG_MISSION, " DEBUG_Check_Debug_Keys tried to p skip from ", m_eState)
SCRIPT_ASSERT("Unhandled p skip")
BREAK
ENDSWITCH
ENDIF
INT i_new_state
IF LAUNCH_MISSION_STAGE_MENU(mSkipMenu, i_new_state)
CPRINTLN(DEBUG_MISSION, "Z skip menu used so doing z skip ", i_new_state)
i_new_state+=2 //+2 because you can't skip to init or lead in which is 0 or 1 and you can't skip to mission passed this way
EPS1_DEBUG_SKIP_STATE(INT_TO_ENUM(eRC_MainState, i_new_state))
ENDIF
ENDPROC
#ENDIF
// ===========================================================================================================
// MISSION FUNCTIONS & PROCEDURES
// ===========================================================================================================
/// PURPOSE:
/// Initialises mission
PROC STATE_MISSION_INIT()
REQUEST_MODEL(modelVeh)
REQUEST_MODEL(modelTom)
REQUEST_ADDITIONAL_TEXT("EPS1",MISSION_TEXT_SLOT)
REQUEST_ANIM_DICT(sOnGroundDict)
WHILE NOT HAS_ANIM_DICT_LOADED(sOnGroundDict)
OR NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT)
OR NOT HAS_MODEL_LOADED(modelVeh)
OR NOT HAS_MODEL_LOADED(modelTom)
WAIT(0)
ENDWHILE
SET_WANTED_LEVEL_MULTIPLIER(0.1)
SUPPRESS_PICKUP_REWARD_TYPE(PICKUP_REWARD_TYPE_WEAPON)
ADD_PED_FOR_DIALOGUE(convStruct, 0, PLAYER_PED_ID(), "MICHAEL")
CPRINTLN(DEBUG_MISSION, "Added Michael to conv")
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
STORE_PLAYER_PED_WEAPONS(PLAYER_PED_ID())
REMOVE_ALL_PED_WEAPONS(PLAYER_PED_ID())
ENDIF
#IF IS_DEBUG_BUILD
mSkipMenu[0].sTxtLabel = "Intro"
mSkipMenu[1].sTxtLabel = "Michael dumped"
#ENDIF
SetState(RC_LEAD_IN)
ENDPROC
/// PURPOSE:
/// Michael comments about the car before the mocap
PROC STATE_RC_LEAD_IN()
RC_PLAYER_TRIGGER_SCENE_LOCK_IN()
SWITCH m_eSubState
CASE SS_SETUP
CPRINTLN(DEBUG_MISSION, "Init lead in")
//RC_END_CUTSCENE_MODE()
bTruckConv = FALSE
m_eSubState = SS_UPDATE
BREAK
CASE SS_UPDATE
IF NOT bTruckConv
bTruckConv = CREATE_CONVERSATION(convStruct, "EPS1AU", "EPS1_TRUCK", CONV_PRIORITY_HIGH)
CPRINTLN(DEBUG_MISSION, "Play lead-in truck conv")
ELSE
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF TIMERB() > 1000
m_eSubState = SS_CLEANUP
ENDIF
ELSE
SETTIMERB(0)
ENDIF
ENDIF
BREAK
CASE SS_CLEANUP
CPRINTLN(DEBUG_MISSION, "Cleaning up lead in")
SetState(RC_MEET_TOM)
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Triggers the mocap cutscene and creates goons once finished
PROC STATE_MeetTom()
RC_PLAYER_TRIGGER_SCENE_LOCK_IN()
SWITCH m_eSubState
CASE SS_SETUP
CPRINTLN(DEBUG_MISSION, "Init RC_MEET_TOM")
bFading = FALSE
bTriggeredMusic = FALSE
IF RC_IS_CUTSCENE_OK_TO_START()
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.vehID[EPSILON_VEHICLE])
//SAFE_TELEPORT_ENTITY(sRCLauncherDataLocal.vehID[EPSILON_VEHICLE], <<-1630.38, 4200.79, 83.01>>, 87.49)
REGISTER_ENTITY_FOR_CUTSCENE(sRCLauncherDataLocal.vehID[EPSILON_VEHICLE], sSceneHandleEpsilonVeh, CU_ANIMATE_EXISTING_SCRIPT_ENTITY, BISON)
ENDIF
// Cleanup launcher which will remove lead-in blip
RC_CLEANUP_LAUNCHER()
REPLAY_START_EVENT(REPLAY_IMPORTANCE_LOW)
START_CUTSCENE() // Start mocap scene
SET_CUTSCENE_FADE_VALUES()
WAIT(0)
STOP_GAMEPLAY_HINT()
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA(<<-1612.51282, 4201.78369, 82.21470>>, <<-1634.40173, 4205.39160, 83.02481>>, 12.0,
<< -1652.0852, 4207.4897, 83.1525 >>, 231.8747)
RC_START_CUTSCENE_MODE(<< -1630.38, 4200.79, 83.01 >>)
CLEAR_AREA_OF_VEHICLES(<< -1630.38, 4200.79, 83.01 >>, 70.0)
m_eSubState = SS_UPDATE // Monitor cutscene
ENDIF
BREAK
CASE SS_UPDATE
IF HAS_CUTSCENE_FINISHED()
IF IS_SCREEN_FADED_OUT()
m_eSubState = SS_CLEANUP
ENDIF
ELSE
IF NOT bTriggeredMusic
IF PREPARE_MUSIC_EVENT("EPS1_START")
IF TRIGGER_MUSIC_EVENT("EPS1_START")
CPRINTLN(DEBUG_MISSION, "Playing audio - EPS1_START")
bTriggeredMusic = TRUE
ENDIF
ENDIF
ENDIF
IF (GET_CUTSCENE_TIME() >= 25500)
IF NOT bFading
SAFE_FADE_SCREEN_OUT_TO_BLACK(500, TRUE)
bFading = TRUE
ENDIF
ELIF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED_WITH_DELAY()
WAIT_FOR_CUTSCENE_TO_STOP(FALSE, FALSE, FALSE)
CPRINTLN(DEBUG_MISSION, "Cutscene skipped")
m_eSubState = SS_CLEANUP
ENDIF
ENDIF
BREAK
CASE SS_CLEANUP
REPLAY_STOP_EVENT()
CPRINTLN(DEBUG_MISSION, "Cleaning up RC_MEET_TOM")
RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE)
SetState(RC_MICHAEL_PASS_OUT)
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Player passes out
PROC STATE_MICHAEL_PASS_OUT()
SWITCH m_eSubState
CASE SS_SETUP
CPRINTLN(DEBUG_MISSION, "Init RC_MICHAEL_PASS_OUT")
CREATE_TOM()
bTomConv = FALSE
m_eSubState = SS_UPDATE
BREAK
CASE SS_UPDATE
m_eSubState = SS_CLEANUP
BREAK
CASE SS_CLEANUP
CPRINTLN(DEBUG_MISSION, "Cleaning up RC_MICHAEL_PASS_OUT")
SetState(RC_MICHAEL_DUMPED)
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Player is dumped somewhere weird in only underpants. Pass script when vehicle drives away
PROC STATE_MICHAEL_DUMPED()
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
SET_PED_RESET_FLAG(PLAYER_PED_ID(),PRF_DisableDustOffAnims, TRUE)
ENDIF
SWITCH m_eSubState
CASE SS_SETUP
CPRINTLN(DEBUG_MISSION, "Init RC_MICHAEL_DUMPED")
bAnimPlaying = FALSE
DISABLE_CELLPHONE(TRUE)
CREATE_TOM() //just in case something happened to Tom
SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_OUTFIT, OUTFIT_P0_BED, FALSE)
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), dumpCoords, 201.2074)
IF NOT IS_NEW_LOAD_SCENE_ACTIVE()
NEW_LOAD_SCENE_START_SPHERE(dumpCoords, 100, NEWLOADSCENE_FLAG_REQUIRE_COLLISION)
ENDIF
IF NOT DOES_ENTITY_EXIST(epsVeh)
epsVeh = CREATE_VEHICLE(modelVeh, <<1970.3618, 2859.5945, 49.2307>>, 151.6095)//<<1989.4264, 2838.8040, 49.1869>>, 195.9715)
ENDIF
IF IS_ENTITY_ALIVE(TomPed)
SET_PED_CAN_BE_TARGETTED(TomPed, FALSE)
SET_PED_RELATIONSHIP_GROUP_HASH(TomPed, RELGROUPHASH_PLAYER)
SET_PED_KEEP_TASK(TomPed, TRUE)
IF IS_ENTITY_ALIVE(epsVeh)
SET_VEHICLE_COLOURS(epsVeh,0,0)
SET_VEHICLE_EXTRA_COLOURS(epsVeh,0,0)
SET_VEHICLE_ON_GROUND_PROPERLY(epsVeh)
SET_VEHICLE_NUMBER_PLATE_TEXT_INDEX(epsVeh, 0)
TASK_WARP_PED_INTO_VEHICLE(TomPed, epsVeh)
SET_VEHICLE_DOORS_LOCKED(epsVeh, VEHICLELOCK_LOCKOUT_PLAYER_ONLY)
SET_VEHICLE_ENGINE_ON(epsVeh, TRUE, TRUE)
ENDIF
ENDIF
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
TASK_PLAY_ANIM(PLAYER_PED_ID(), sOnGroundDict, "back_armsdown", INSTANT_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING)
FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID(), TRUE)
ENDIF
IF DOES_ENTITY_EXIST(TomPed)
ADD_PED_FOR_DIALOGUE(convStruct, 4, TomPed, "CRIS")
ENDIF
bTomConv = FALSE
m_eSubState = SS_UPDATE
BREAK
CASE SS_UPDATE
IF IS_NEW_LOAD_SCENE_ACTIVE()
IF IS_NEW_LOAD_SCENE_LOADED()
NEW_LOAD_SCENE_STOP()
camDumped = CREATE_CAMERA_WITH_PARAMS(CAMTYPE_SCRIPTED, <<1966.059448,2861.492920,50.106567>>,<<5.965983,0.000000,-30.250603>>,50.0)
SET_CAM_ACTIVE(camDumped, TRUE)
camDumped1 = CREATE_CAMERA_WITH_PARAMS(CAMTYPE_SCRIPTED, <<1970.628662,2872.504883,49.440811>>,<<5.712656,-0.000000,-160.952347>>,50.0)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
ELSE
CPRINTLN(DEBUG_MISSION, "Waiting for load scene to finish")
ENDIF
ELSE
IF IS_ENTITY_ALIVE(TomPed)
IF IS_ENTITY_ALIVE(epsVeh)
IF IS_PED_SITTING_IN_VEHICLE_SEAT(TomPed, epsVeh, VS_DRIVER)
IF bAnimPlaying
IF NOT bTomConv
bTomConv = CREATE_CONVERSATION(convStruct, "EPS1AU", "EPS1_CAR", CONV_PRIORITY_HIGH)
ELSE
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
TASK_VEHICLE_DRIVE_WANDER(TomPed, epsVeh, epsVehSpeed, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS)
MAKE_PED_DRUNK(PLAYER_PED_ID(), 30000)
STOP_RENDERING_SCRIPT_CAMS_USING_CATCH_UP()
SET_CAM_ACTIVE(camDumped1, FALSE)
DISABLE_CELLPHONE(FALSE)
m_eSubState = SS_CLEANUP
ELSE
IF TIMERA() > 10000
IF NOT IS_CAM_ACTIVE(camDumped1)
SET_CAM_ACTIVE(camDumped1, TRUE)
SET_CAM_ACTIVE(camDumped, FALSE)
SET_CAM_PARAMS(camDumped1,<<1970.766479,2872.220703,49.472328>>,<<5.712656,-0.000000,-160.952347>>, 50.0, 5000, GRAPH_TYPE_DECEL, GRAPH_TYPE_DECEL)
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
IF (GET_SCRIPT_TASK_STATUS(PLAYER_PED_ID(),SCRIPT_TASK_PLAY_ANIM) = PERFORMING_TASK)
CPRINTLN(DEBUG_MISSION, "Playing anim, set ragdoll now")
SET_PED_TO_RAGDOLL(PLAYER_PED_ID(), 16000, 16000, TASK_RELAX)
APPLY_FORCE_TO_ENTITY(PLAYER_PED_ID(), APPLY_TYPE_EXTERNAL_FORCE, <<0, -5, 2>>, <<0,0.5,0>>, ENUM_TO_INT(PED_COMP_TORSO), true, true, TRUE)
bAnimPlaying = TRUE
//SET_GAMEPLAY_CAM_RELATIVE_HEADING()
//SET_GAMEPLAY_CAM_RELATIVE_PITCH()
WAIT(1000)
SETTIMERA(0)
SAFE_FADE_SCREEN_IN_FROM_BLACK(2000, FALSE)
SET_CAM_PARAMS(camDumped, <<1966.352417,2861.772217,50.316555>>,<<4.433831,-0.000000,-30.380865>>, 50.0, 10000, GRAPH_TYPE_LINEAR, GRAPH_TYPE_LINEAR)
ENDIF
ENDIF
ENDIF
ELSE
TASK_WARP_PED_INTO_VEHICLE(TomPed, epsVeh)
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE SS_CLEANUP
REPLAY_RECORD_BACK_FOR_TIME(10.0, 0.0, REPLAY_IMPORTANCE_LOWEST)
CPRINTLN(DEBUG_MISSION, "Cleaning up RC_MICHAEL_DUMPED")
SetState(RC_PASSED)
BREAK
ENDSWITCH
ENDPROC
// ===========================================================================================================
// Script Loop
// ===========================================================================================================
SCRIPT(g_structRCScriptArgs sRCLauncherDataIn)
sRCLauncherDataLocal = sRCLauncherDataIn
RC_TakeEntityOwnership(sRCLauncherDataLocal)
SET_MISSION_FLAG(TRUE)
// Setup callback when player is killed, arrested or goes to multiplayer
IF (HAS_FORCE_CLEANUP_OCCURRED(DEFAULT_FORCE_CLEANUP_FLAGS|FORCE_CLEANUP_FLAG_DEBUG_MENU))
PRINT_LAUNCHER_DEBUG("Force cleanup [TERMINATING]")
IF PREPARE_MUSIC_EVENT("EPS1_FAIL")
IF TRIGGER_MUSIC_EVENT("EPS1_FAIL")
CPRINTLN(DEBUG_MISSION, "Playing audio - EPS1_FAIL")
ENDIF
ENDIF
Random_Character_Failed()
Script_Cleanup()
ENDIF
IF Is_Replay_In_Progress() // Set up the initial scene for replays
g_bSceneAutoTrigger = TRUE
eInitialSceneStage = IS_REQUEST_SCENE
WHILE NOT SetupScene_EPSILON_1(sRCLauncherDataLocal)
WAIT(0)
ENDWHILE
g_bSceneAutoTrigger = FALSE
ENDIF
// unlock the car
IF DOES_ENTITY_EXIST(sRCLauncherDataLocal.vehID[EPSILON_VEHICLE])
SET_VEHICLE_DOORS_LOCKED(sRCLauncherDataLocal.vehID[EPSILON_VEHICLE], VEHICLELOCK_UNLOCKED)
ENDIF
// Request mocap cutcene
RC_REQUEST_CUTSCENE("EP_1_RCM_Concat", TRUE)
// Loop within here until the mission passes or fails
WHILE(TRUE)
WAIT(0)
UPDATE_MISSION_NAME_DISPLAYING(sRCLauncherDataLocal.sIntroCutscene)
SWITCH(m_eState)
CASE RC_INIT
STATE_MISSION_INIT()
BREAK
CASE RC_LEAD_IN
STATE_RC_LEAD_IN()
BREAK
CASE RC_MEET_TOM
STATE_MeetTom()
BREAK
CASE RC_MICHAEL_PASS_OUT
STATE_MICHAEL_PASS_OUT()
BREAK
CASE RC_MICHAEL_DUMPED
STATE_MICHAEL_DUMPED()
BREAK
CASE RC_PASSED
Script_Passed()
BREAK
CASE RC_STAGE_FAIL
STATE_FAIL()
BREAK
ENDSWITCH
REPLAY_CHECK_FOR_EVENT_THIS_FRAME("SF_Epsilonism1")
// Check debug completion/failure
#IF IS_DEBUG_BUILD
DEBUG_Check_Debug_Keys()
#ENDIF
ENDWHILE
// Script should never reach here. Always terminate with cleanup function.
ENDSCRIPT