4450 lines
147 KiB
Python
Executable File
4450 lines
147 KiB
Python
Executable File
|
|
//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 "dialogue_public.sch"
|
|
USING "script_player.sch"
|
|
USING "RC_launcher_public.sch"
|
|
USING "RC_Helper_Functions.sch"
|
|
USING "CompletionPercentage_public.sch"
|
|
USING "chase_hint_cam.sch" CHASE_HINT_CAM_STRUCT localChaseHintCamStruct
|
|
USING "replay_public.sch"
|
|
USING "initial_scenes_epsilon.sch"
|
|
USING "commands_recording.sch"
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
USING "select_mission_stage.sch"
|
|
#ENDIF
|
|
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
//
|
|
// MISSION NAME : Epsilon6.sc
|
|
// AUTHOR : Ian Gander
|
|
// DESCRIPTION : After wearing an Epsilon robe for 10 days, Jimmy texts Michael
|
|
// to ask him to steal a Plane for the organisation
|
|
//
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
// Enums
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
ENUM MISSION_STAGE
|
|
MS_INIT = 0,
|
|
MS_FLIGHT,
|
|
MS_LANDING,
|
|
MS_SEEJIMMY,
|
|
MS_ENDCUTSCENE,
|
|
MS_WAITFORJIMMY,
|
|
MS_FAILED
|
|
ENDENUM
|
|
|
|
ENUM SUB_STATE
|
|
SS_INIT,
|
|
SS_RUNNING,
|
|
SS_SHUTDOWN
|
|
ENDENUM
|
|
|
|
ENUM VEHICLE_STATE
|
|
VS_IDLE,
|
|
VS_GOTO,
|
|
VS_WANDER
|
|
ENDENUM
|
|
|
|
ENUM FAILED_REASON
|
|
FAILED_DEFAULT = 0,
|
|
FAILED_LEFT_PLANE,
|
|
FAILED_LEFT_DROPOFF,
|
|
FAILED_LEFT_PICKUP,
|
|
FAILED_DESTROYED,
|
|
FAILED_SPOOKED_JIMMY,
|
|
FAILED_ATTACKED_JIMMY,
|
|
FAILED_KILLED_JIMMY,
|
|
FAILED_HURT_JIMMY,
|
|
FAILED_KILLED_BUDDY,
|
|
FAILED_SPOOKED_BUDDY,
|
|
FAILED_HURT_BUDDY,
|
|
FAILED_STICKYBOMB
|
|
ENDENUM
|
|
|
|
ENUM JIMMY_CALL_STATE
|
|
CALL_WAITING,
|
|
CALL_BUFFERING,
|
|
CALL_PLAYING,
|
|
CALL_DONE
|
|
ENDENUM
|
|
|
|
ENUM ARMY_BACKUP_STATE
|
|
BACKUP_WAITING,
|
|
BACKUP_LOADING,
|
|
BACKUP_CREATION,
|
|
BACKUP_PLAYING,
|
|
BACKUP_DONE
|
|
ENDENUM
|
|
|
|
ENUM INTRO_STATE
|
|
INTRO_INIT = 0,
|
|
INTRO_SEENMIKE,
|
|
INTRO_INPLANE,
|
|
INTRO_INTERRUPTED
|
|
ENDENUM
|
|
|
|
ENUM EPS_STATE
|
|
EPS_INIT = 0,
|
|
EPS_INCAR = 1,
|
|
EPS_FOLLOW = 2,
|
|
EPS_HANDSUP = 3,
|
|
EPS_SAFE = 4,
|
|
EPS_WAIT = 5,
|
|
EPS_FLEEING = 6,
|
|
EPS_DEAD = 7
|
|
ENDENUM
|
|
|
|
ENUM EPS_MOVE
|
|
EPSMOVE_OK,
|
|
EPSMOVE_CHANGE,
|
|
EPSMOVE_MOVING
|
|
ENDENUM
|
|
|
|
ENUM EPS_ATTK
|
|
EPSATTK_OK,
|
|
EPSATTK_CHANGE,
|
|
EPSATTK_CHANGED
|
|
ENDENUM
|
|
|
|
ENUM ARMY_STATE
|
|
ARMY_WAITING = 0,
|
|
ARMY_LOADING = 1,
|
|
ARMY_CREATION = 2,
|
|
ARMY_DRIVING = 3,
|
|
ARMY_LEAVETRUCK = 4,
|
|
ARMY_AIMBOTH = 5,
|
|
ARMY_SHOOTEPS = 6,
|
|
ARMY_AIMPLAYER = 7,
|
|
ARMY_SHOOTPLAYER = 8,
|
|
ARMY_SHOOTALL = 9,
|
|
ARMY_DEAD = 10
|
|
ENDENUM
|
|
|
|
ENUM EPS6_WANDER_STATE
|
|
WANDER_INIT,
|
|
WANDER_GOTO,
|
|
WANDER_NOWGOINGTO,
|
|
WANDER_IDLEANIM,
|
|
WANDER_IDLEFINISH
|
|
ENDENUM
|
|
|
|
ENUM STATE_MODE
|
|
STATE_SETUP,
|
|
STATE_RUN
|
|
ENDENUM
|
|
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
// Structs
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
|
|
STRUCT MyVehicle // Custom vehicle struct
|
|
VEHICLE_INDEX VehIdx
|
|
MODEL_NAMES VehName
|
|
BLIP_INDEX biBlipIdx
|
|
Vector VehPos
|
|
Float Heading
|
|
ENDSTRUCT
|
|
|
|
STRUCT MySceneVehicle // Custom vehicle struct
|
|
VEHICLE_INDEX VehIdx
|
|
Vector VehPos
|
|
Float Heading
|
|
VEHICLE_STATE VehState
|
|
ENDSTRUCT
|
|
|
|
STRUCT MyPlaneCP // Struct to hold a vehicle destination
|
|
VECTOR vPointPos
|
|
BLIP_INDEX biBlipIdx
|
|
ENDSTRUCT
|
|
|
|
STRUCT MyPed // Custom ped struct
|
|
PED_INDEX piPedIdx
|
|
BLIP_INDEX biPedBlip
|
|
VECTOR vPos
|
|
FLOAT fHeading
|
|
STRING AnimDict
|
|
STRING AnimName
|
|
// BOOL bHasAttachments = FALSE
|
|
// MODEL_NAMES propModel
|
|
ENDSTRUCT
|
|
|
|
//STRUCT MyProp // Hold info for props I want for cover
|
|
// OBJECT_INDEX PropIdx
|
|
// MODEL_NAMES PropName
|
|
// VECTOR vPropPos
|
|
// VECTOR vPropRot
|
|
//ENDSTRUCT
|
|
//
|
|
//STRUCT Area // Non-AA struct for the zones for Gonz to advance through
|
|
// VECTOR vPos1
|
|
// VECTOR vPos2
|
|
// float fWidth
|
|
//ENDSTRUCT
|
|
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
// Consts
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
|
|
CONST_INT STUNT_PLANE_CHECKPOINT_SCALE 15
|
|
|
|
CONST_INT CP_START 0
|
|
CONST_INT CP_LANDING 1
|
|
CONST_INT CP_OUTRO 2
|
|
CONST_INT CP_JIMMY 3
|
|
CONST_INT CP_COMPLETE 4
|
|
|
|
CONST_INT Z_SKIP_INIT 0
|
|
CONST_INT Z_SKIP_FLIGHT 1
|
|
CONST_INT Z_SKIP_LANDING 2
|
|
CONST_INT Z_SKIP_SEEJIMMY 3
|
|
CONST_INT Z_SKIP_OUTRO 4
|
|
CONST_INT Z_SKIP_WAITJIMMY 5
|
|
CONST_INT Z_SKIP_COMPLETE 6
|
|
|
|
CONST_INT LENGTH_OF_CONVOY 5
|
|
|
|
CONST_INT ARMYDRIVER_ID 0
|
|
CONST_INT ARMYPASSENGER_ID 1
|
|
|
|
CONST_FLOAT MAX_WARNING_DISTANCE 300.0
|
|
CONST_FLOAT MAX_FAIL_DISTANCE 350.0
|
|
|
|
CONST_INT MAX_SECTIONS 4
|
|
CONST_INT TOP_LEFT 0
|
|
CONST_INT TOP_RIGHT 1
|
|
CONST_INT BOTTOM_LEFT 2
|
|
CONST_INT BOTTOM_RIGHT 3
|
|
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
// Globals
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
// Scene entities from mission launcher
|
|
g_structRCScriptArgs sRCLauncherDataLocal
|
|
|
|
MyVehicle mv_plane
|
|
MyVehicle mv_RewardCar
|
|
|
|
MyPlaneCP pcp_LandingGoal
|
|
|
|
MyPed mp_Jimmy
|
|
|
|
MyPed mp_Cultist
|
|
|
|
MISSION_STAGE missionStage = MS_INIT
|
|
SUB_STATE subState = SS_INIT
|
|
|
|
JIMMY_CALL_STATE CallState = CALL_WAITING
|
|
|
|
INTRO_STATE IntroState = INTRO_INIT
|
|
|
|
EPS_STATE EpsState = EPS_INIT
|
|
STATE_MODE EpsMode = STATE_SETUP
|
|
EPS_MOVE EpsMove = EPSMOVE_OK
|
|
|
|
EPS6_WANDER_STATE Eps6Wander = WANDER_INIT
|
|
INT iWanderStage = 0
|
|
VECTOR vTomCoords[3]
|
|
|
|
BOOL bHasSkipped = FALSE
|
|
BOOL bCompleteShitskip = FALSE
|
|
BOOL bShownGetInPlane = FALSE
|
|
BOOL bShownExitVehicle = FALSE
|
|
BOOL bShownLoseCops = FALSE
|
|
BOOL bAbandonment = FALSE
|
|
BOOL bPausedConv = FALSE
|
|
INT iPausedConvLn
|
|
INT iPausedConvTimer
|
|
TEXT_LABEL_23 tlPausedConvRoot
|
|
BOOL bPlaneTooCloseConv = FALSE
|
|
BOOL bShownGoToAirfield = FALSE
|
|
BOOL bShownLandAtAirfield = TRUE
|
|
BOOL bShownGoToJimmy = FALSE
|
|
BOOL bPlayerGoneTooFar = FALSE
|
|
BOOL bSetCP = FALSE
|
|
BOOL bSpawnJimmy = FALSE
|
|
//BOOL bCultistRagdoll = FALSE
|
|
BOOL bTomPushedOver = FALSE
|
|
BOOL bTomSaidPushedOver = FALSE
|
|
BOOL bTeleOnFail = FALSE
|
|
|
|
BOOL bCultistAimConv = FALSE
|
|
BOOL bCultistNoSubIntro = FALSE
|
|
|
|
INT iDetectorHumID = -1
|
|
INT iDetectorBeepID = -1
|
|
|
|
INT iCultistRoamStage = 0
|
|
INT iCultistHandsUpTimer
|
|
|
|
INT iJimmyCallTimer
|
|
INT iJimmyBeckonTimer
|
|
INT iJimmyPlaneWarningTimer
|
|
int iJimmyFlyStage
|
|
int iJimmyFlyGearTimer
|
|
BOOL bJimmyGearDone = FALSE
|
|
INT iCutsceneStage = 0
|
|
|
|
INT iCultistRoamTimer
|
|
INT iCultistConvDelayTimer
|
|
//INT g_iOutroTimer
|
|
INT iConvTimer
|
|
|
|
// Floats used for the shrinking abandonment values for the See Jimmy stage
|
|
FLOAT g_fJimmyWarningRange = MAX_WARNING_DISTANCE
|
|
FLOAT g_fJimmyFailRange = MAX_FAIL_DISTANCE
|
|
INT g_iAbandonCap = 5
|
|
|
|
// The area at the airfield the plane must be detected in
|
|
VECTOR vPlaneDetect1 = <<1720.961304,3254.950684, 42.5>>
|
|
VECTOR vPlaneDetect2 = <<1620.34, 3228.95, 37.650513>>
|
|
|
|
BOOL bDoneMusic = FALSE
|
|
|
|
STREAMVOL_ID cutsceneStreamvol
|
|
|
|
SEQUENCE_INDEX seq
|
|
|
|
//CAMERA_INDEX ciOutro
|
|
|
|
OBJECT_INDEX oiJimmyPhone
|
|
|
|
INT iNavBlockingObj = -1
|
|
|
|
FAILED_REASON FailedReason = FAILED_DEFAULT
|
|
|
|
structPedsForConversation s_conversation_cult
|
|
structPedsForConversation s_conversation_flight
|
|
structPedsForConversation s_conversation_outro
|
|
|
|
REL_GROUP_HASH relGroupPlayer
|
|
|
|
MODEL_NAMES vehModel = VELUM
|
|
MODEL_NAMES cultModel = IG_TOMEPSILON
|
|
|
|
// Replay stuff
|
|
BOOL bReplayTrackOn = FALSE
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
int i_debug_jump_stage
|
|
MissionStageMenuTextStruct s_skip_menu[6]
|
|
BOOL bDebug_PrintToTTY = TRUE
|
|
BOOL bDebugFlyingBuff = FALSE
|
|
WIDGET_GROUP_ID widgetGroup
|
|
#ENDIF
|
|
|
|
//PURPOSE: Print debug string to Rag.
|
|
//PARAMS: s - the string we want to print.
|
|
PROC DEBUG_PRINT(String s)
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_PrintToTTY
|
|
CPRINTLN(DEBUG_MISSION, "Epsilon 6: ", s)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
s = s
|
|
ENDPROC
|
|
|
|
//PURPOSE: Print debug string with float to Rag.
|
|
//PARAMS: s - the string we want to print. f - the float we want to print.
|
|
PROC DEBUG_PRINTFLOAT(String s, FLOAT f)
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_PrintToTTY
|
|
CPRINTLN(DEBUG_MISSION, "Epsilon 6: ", s, " ", f)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
s = s
|
|
f = f
|
|
ENDPROC
|
|
|
|
//PURPOSE: Print debug string with int to Rag.
|
|
//PARAMS: s - the string we want to print. i - the int we want to print.
|
|
PROC DEBUG_PRINTINT(String s, int i)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_PrintToTTY
|
|
CPRINTLN(DEBUG_MISSION, "Epsilon 6: ", s, ": ", i)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
s = s
|
|
i = i
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Print a state change notification for the Epsilonist
|
|
/// PARAMS:
|
|
/// newState - The state the Epsilonist's changed to
|
|
PROC EPS_STATE_PRINT(EPS_STATE newState)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_PrintToTTY
|
|
CPRINTLN(DEBUG_MISSION, "Epsilon 6: ","EPSILONIST: Changed state to ", INT_TO_ENUM(EPS_STATE, newState))
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
newState = newState
|
|
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Print a state change notification for the Army
|
|
/// PARAMS:
|
|
/// newState - The state the Epsilonist's changed to
|
|
PROC ARMY_STATE_PRINT(int iSoldierID, ARMY_STATE newState)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_PrintToTTY
|
|
CPRINTLN(DEBUG_MISSION, "Epsilon 6: ", "ARMY ID #", iSoldierID, ": Changed state to ", INT_TO_ENUM(ARMY_STATE, newState))
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
iSoldierID = iSoldierID
|
|
newState = newState
|
|
|
|
ENDPROC
|
|
|
|
//PURPOSE: Checks that a particular conversation root is currently playing.
|
|
//PARAMS: RootToCheck - The conversation root we want to check is playing.
|
|
//RETURNS: TRUE if the root is currently playing, FALSE otherwise.
|
|
FUNC BOOL IS_THIS_CONVERSATION_ROOT_PLAYING(STRING RootToCheck)
|
|
TEXT_LABEL_23 blah
|
|
blah = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT()
|
|
IF ARE_STRINGS_EQUAL(blah,RootToCheck)
|
|
RETURN TRUE
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Converts a debug cam rotation into a facing direction (for streamvol frustums) - shamelessly stolen from Chinese 2
|
|
/// PARAMS:
|
|
/// vRot - The rot we want to convert
|
|
/// RETURNS:
|
|
/// A direction vector
|
|
FUNC VECTOR CONVERT_ROTATION_TO_DIRECTION_VECTOR(VECTOR vRot)
|
|
RETURN <<-SIN(vRot.z) * COS(vRot.x), COS(vRot.z) * COS(vRot.x), SIN(vRot.x)>>
|
|
ENDFUNC
|
|
|
|
// ===========================================================================================================
|
|
// Termination
|
|
// ===========================================================================================================
|
|
|
|
//PURPOSE: Deletes (or alternatively releases) every entity in the mission.
|
|
//PARAMS: ReleaseInstead - if TRUE, release the entities rather than delete them outright.
|
|
PROC DeleteEverything(BOOL ReleaseInstead = FALSE)
|
|
|
|
// ReleaseInstead is used in Script_Cleanup(), where we don't want to see vehicles disappear in front of the player
|
|
IF ReleaseInstead
|
|
|
|
DEBUG_PRINT("DeleteEverything: Releasing entities")
|
|
|
|
// End-of-the-line cleanup - Jimmy probably won't exist at this point anyway
|
|
SAFE_RELEASE_PED(mp_Jimmy.piPedIdx)
|
|
|
|
SAFE_RELEASE_VEHICLE(mv_plane.VehIdx)
|
|
|
|
REMOVE_ANIM_DICT(mp_Jimmy.AnimDict)
|
|
|
|
SAFE_RELEASE_VEHICLE(mv_RewardCar.VehIdx)
|
|
|
|
// remove cultist from player's group, so he doesn't come with you for a replay
|
|
IF IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
IF IS_PED_IN_GROUP(mp_Cultist.piPedIdx)
|
|
REMOVE_PED_FROM_GROUP(mp_Cultist.piPedIdx)
|
|
ENDIF
|
|
ENDIF
|
|
SAFE_RELEASE_PED(mp_Cultist.piPedIdx)
|
|
ELSE
|
|
SAFE_DELETE_VEHICLE(mv_plane.VehIdx)
|
|
DEBUG_PRINT("Deleted Plane")
|
|
IF DOES_ENTITY_EXIST(mv_plane.VehIdx)
|
|
DEBUG_PRINT("Plane still exists!!")
|
|
ENDIF
|
|
|
|
REMOVE_ANIM_DICT(mp_Jimmy.AnimDict)
|
|
|
|
// End-of-the-line cleanup - Jimmy probably won't exist at this point anyway
|
|
SAFE_DELETE_PED(mp_Jimmy.piPedIdx)
|
|
|
|
SAFE_DELETE_VEHICLE(mv_RewardCar.VehIdx)
|
|
|
|
SAFE_DELETE_PED(mp_Cultist.piPedIdx)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
// Script Cleanup
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
|
|
//PURPOSE: Cleans up the script.
|
|
PROC Script_Cleanup()
|
|
|
|
// If the mission was triggered then additional mission cleanup will be required.
|
|
IF (Random_Character_Cleanup_If_Triggered())
|
|
DEBUG_PRINT("...Random Character Script was triggered so additional cleanup required")
|
|
ENDIF
|
|
|
|
DeleteEverything(TRUE)
|
|
|
|
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
|
|
|
|
ENABLE_DISPATCH_SERVICE(DT_POLICE_AUTOMOBILE, TRUE)
|
|
ENABLE_DISPATCH_SERVICE(DT_POLICE_HELICOPTER, TRUE)
|
|
ENABLE_DISPATCH_SERVICE(DT_FIRE_DEPARTMENT, TRUE)
|
|
ENABLE_DISPATCH_SERVICE(DT_AMBULANCE_DEPARTMENT, TRUE)
|
|
|
|
SET_MAX_WANTED_LEVEL(5)
|
|
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
|
|
ENDIF
|
|
|
|
if IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
|
|
IF HAS_CUTSCENE_LOADED()
|
|
REMOVE_CUTSCENE()
|
|
ENDIF
|
|
|
|
REMOVE_ANIM_DICT("rcm_epsilonism4")
|
|
|
|
IF DOES_SCENARIO_GROUP_EXIST("SANDY_PLANES")
|
|
IF NOT IS_SCENARIO_GROUP_ENABLED("SANDY_PLANES")
|
|
SET_SCENARIO_GROUP_ENABLED("SANDY_PLANES",TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Cleanup scene entities created by the RC launcher
|
|
RC_CleanupSceneEntities(sRCLauncherDataLocal, FALSE)
|
|
|
|
SET_ROADS_BACK_TO_ORIGINAL(<<-195.709671,1881.431641,196.157059>>, <<842.235168,2249.857178,48.501358>>)
|
|
SET_ROADS_BACK_TO_ORIGINAL(<<816.852661,2107.933838,63.374523>>, <<176.167633,2902.729980,46.615326>>)
|
|
SET_ROADS_BACK_TO_ORIGINAL(<<-36.251339,-465.831512,39.122559>>, <<25.801004,-287.171631,47.758629>>)
|
|
//SET_ROADS_BACK_TO_ORIGINAL(<<1542.315796,3767.182617,33.163731>>, <<1705.179199,3496.898926,36.706730>>)
|
|
|
|
DISABLE_CELLPHONE(FALSE)
|
|
|
|
TERMINATE_THIS_THREAD()
|
|
ENDPROC
|
|
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
// Script Pass
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
|
|
//PURPOSE: Passes the script.
|
|
PROC Script_Passed()
|
|
|
|
SET_VEHICLE_GEN_AVAILABLE(VEHGEN_EPSILON6_PLANE, FALSE)
|
|
Random_Character_Passed(CP_RAND_C_EPS6)
|
|
|
|
PRINTSTRING("******************* MISSION PASSED *********************")
|
|
PRINTNL()
|
|
|
|
CLEAR_PLAYER_WANTED_LEVEL( PLAYER_ID() )
|
|
//PRINT_NOW("EPS6_WIN", 7000, 1)
|
|
|
|
IF (IS_PLAYER_PLAYING(PLAYER_ID()))
|
|
// As a standard, holster the players gun on mission passed.
|
|
SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, FALSE)
|
|
|
|
// Clear the player's wanted level.
|
|
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0)
|
|
|
|
// Block contributions to the wanted level for 5 seconds.
|
|
START_FIRING_AMNESTY()
|
|
ENDIF
|
|
//Set epsilon step stat
|
|
INT iCurrent
|
|
STAT_GET_INT(NUM_EPSILON_STEP,iCurrent)
|
|
IF iCurrent < 17
|
|
STAT_SET_INT(NUM_EPSILON_STEP,17)
|
|
SET_ACHIEVEMENT_PROGRESS_SAFE(ENUM_TO_INT(ACH20),17)
|
|
CPRINTLN(debug_dan,"Epsilon progress:",17)
|
|
ENDIF
|
|
|
|
|
|
DEBUG_PRINT("Doing cleanup now")
|
|
Script_Cleanup()
|
|
|
|
ENDPROC
|
|
|
|
// ===========================================================================================================
|
|
// MISSION FUNCTIONS & PROCEDURES
|
|
// ===========================================================================================================
|
|
|
|
//PURPOSE: Sets the given ped into the given group, and updates the relationship of that group with the player
|
|
//PARAMS: pedindex - the ped we want to put into a group.
|
|
// BuddyGroup - the group hash that we want the ped to be added to.
|
|
// RelType - the relationship we want to set the given group hash to have with the player
|
|
PROC CREATE_SAFE_RELATIONSHIP(PED_INDEX &pedindex, REL_GROUP_HASH BuddyGroup, RELATIONSHIP_TYPE RelType)
|
|
IF IS_ENTITY_ALIVE(pedindex)
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(pedindex, BuddyGroup)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(RelType, BuddyGroup, RELGROUPHASH_PLAYER)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
//PURPOSE: Checks that the plane is OK and not stuck on its roof.
|
|
//RETURNS: TRUE if the plane is fine, FALSE if it's broken.
|
|
FUNC BOOL IsPlaneOK()
|
|
IF IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
IF GET_LANDING_GEAR_STATE(mv_plane.VehIdx) = LGS_BROKEN
|
|
DEBUG_PRINT("Detected plane landing gear is broken")
|
|
return FALSE
|
|
ELIF IS_VEHICLE_STUCK_ON_ROOF(mv_plane.VehIdx)
|
|
DEBUG_PRINT("Detected plane is stuck on roof")
|
|
return FALSE
|
|
ELIF GET_VEHICLE_ENGINE_HEALTH(mv_plane.VehIdx) <= 0
|
|
DEBUG_PRINT("Detected plane engine health is <= 0")
|
|
return FALSE
|
|
ELIF IS_VEHICLE_STUCK_TIMER_UP(mv_plane.VehIdx, VEH_STUCK_JAMMED, JAMMED_TIME)
|
|
DEBUG_PRINT("Detected plane IS_VEHICLE_STUCK_TIMER_UP > JAMMED_TIME")
|
|
return FALSE
|
|
ELSE
|
|
return TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
DEBUG_PRINT("The plane is broken!")
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
//PURPOSE: Checks whether the plane is moving so slowly that we might as well consider it "stopped".
|
|
//RETURNS: TRUE if the plane can be considered to have stopped, FALSE otherwise.
|
|
FUNC BOOL HAS_PLANE_ALMOST_STOPPED()
|
|
// The plane appears to never fully "stop" anymore for IS_VEHICLE_STOPPED to return true, so this will check the plane has slowed to such a speed that we can consider it so
|
|
IF IsPlaneOK()
|
|
FLOAT fTemp
|
|
fTemp = GET_ENTITY_SPEED(mv_plane.VehIdx)
|
|
IF (fTemp > -0.5)
|
|
AND (fTemp < 0.5)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
//PURPOSE: Checks whether the player has touched any of the flight controls.
|
|
//RETURNS: TRUE if any player flight input is detected, FALSE otherwise.
|
|
FUNC BOOL HAS_PLAYER_TOUCHED_FLYING_CONTROLS()
|
|
IF IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_MOVE_LR)
|
|
OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_MOVE_UD) // Leave old inputs, just in case
|
|
OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_FLY_ROLL_LR)
|
|
OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_FLY_PITCH_UD)
|
|
OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_FLY_UNDERCARRIAGE)
|
|
OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_FLY_ATTACK)
|
|
OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_FLY_THROTTLE_DOWN)
|
|
OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_FLY_THROTTLE_UP)
|
|
OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_FLY_YAW_LEFT)
|
|
OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_FLY_YAW_RIGHT)
|
|
DEBUG_PRINT("*** Player input detected")
|
|
RETURN TRUE
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
//PURPOSE: Releases plane control the player after a debug skip when the screen is faded in, if they have tried to move the plane in any way.
|
|
PROC HANDLE_SKIP_FLYING_CONTROLS()
|
|
IF IS_SCREEN_FADED_IN()
|
|
IF IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(mv_plane.VehIdx)
|
|
IF HAS_PLAYER_TOUCHED_FLYING_CONTROLS()
|
|
STOP_PLAYBACK_RECORDED_VEHICLE(mv_plane.VehIdx)
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
//PURPOSE: Loads and sets up some basic global resources that are needed during the mission at all times, called once at the start of the mission.
|
|
PROC LOAD_GLOBAL_RESOURCES()
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
s_skip_menu[0].sTxtLabel = "Start"
|
|
s_skip_menu[1].sTxtLabel = "Flight"
|
|
s_skip_menu[2].sTxtLabel = "Landing"
|
|
s_skip_menu[3].sTxtLabel = "Walk to Jimmy"
|
|
s_skip_menu[4].sTxtLabel = "Outro"
|
|
s_skip_menu[5].sTxtLabel = "Wait for Jimmy"
|
|
|
|
IF NOT DOES_WIDGET_GROUP_EXIST(widgetGroup)
|
|
widgetGroup = START_WIDGET_GROUP("Epsilon 6 widgets")
|
|
ADD_WIDGET_BOOL("TTY Toggle - Print Mission Debug Info", bDebug_PrintToTTY)
|
|
ADD_WIDGET_BOOL("Buff player flying stat", bDebugFlyingBuff)
|
|
STOP_WIDGET_GROUP()
|
|
ENDIF
|
|
|
|
#ENDIF
|
|
|
|
mv_RewardCar.Heading = 132.923
|
|
mv_RewardCar.VehName = f620
|
|
mv_RewardCar.VehPos = <<1692.160, 3271.055, 40.633>>
|
|
|
|
mv_plane.VehName = VELUM
|
|
|
|
mp_Jimmy.vPos = <<1687.51, 3278.35, 40.12>>
|
|
mp_Jimmy.fHeading = 212.0820
|
|
mp_Jimmy.AnimDict = "rcmepsilonism6"
|
|
mp_Jimmy.AnimName = "idle_a"
|
|
|
|
pcp_LandingGoal.vPointPos = <<1620.34, 3228.95, 39.71>>
|
|
|
|
ENABLE_DISPATCH_SERVICE(DT_POLICE_AUTOMOBILE, FALSE)
|
|
ENABLE_DISPATCH_SERVICE(DT_POLICE_HELICOPTER, FALSE)
|
|
ENABLE_DISPATCH_SERVICE(DT_FIRE_DEPARTMENT, FALSE)
|
|
ENABLE_DISPATCH_SERVICE(DT_AMBULANCE_DEPARTMENT, FALSE)
|
|
|
|
SET_MAX_WANTED_LEVEL(0)
|
|
|
|
ADD_CONTACT_TO_PHONEBOOK(CHAR_MARNIE, MICHAEL_BOOK, FALSE)
|
|
ADD_CONTACT_TO_PHONEBOOK(CHAR_JIMMY_BOSTON, MICHAEL_BOOK, FALSE)
|
|
|
|
REQUEST_ADDITIONAL_TEXT("EPS6", MISSION_TEXT_SLOT)
|
|
|
|
WHILE not HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT)
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
REGISTER_SCRIPT_WITH_AUDIO()
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Sets the player up in whatever starting state he should be in, at whatever stage the mission is currently at
|
|
PROC SETUP_PLAYER()
|
|
SWITCH missionStage
|
|
CASE MS_INIT
|
|
DEBUG_PRINT("*** Moving/realigning player...")
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), <<-2914.7070, 3234.6392, 9.7863>>, 215.2149)
|
|
ENDIF
|
|
|
|
BREAK
|
|
CASE MS_FLIGHT
|
|
// warp player into vehicle, turn engine on, move them
|
|
IF IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), <<-2892.93,3192.37,11.66>>)
|
|
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx)
|
|
ENDIF
|
|
BREAK
|
|
CASE MS_LANDING
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
AND IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx)
|
|
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx)
|
|
ENDIF
|
|
SET_PED_COORDS_KEEP_VEHICLE(PLAYER_PED_ID(), <<376.0205, 2886.5520, 171.3085>>)
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE MS_SEEJIMMY
|
|
FALLTHRU
|
|
|
|
CASE MS_ENDCUTSCENE
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), <<1681.54, 3259.38, 39.77>>, 298.33)
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE MS_WAITFORJIMMY
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), << 1688.45, 3277.15, 40.08 >>, 131.1749, TRUE)
|
|
ENDIF
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Sets the reward car up
|
|
PROC SETUP_CAR()
|
|
SWITCH missionStage
|
|
CASE MS_ENDCUTSCENE
|
|
FALLTHRU
|
|
CASE MS_WAITFORJIMMY
|
|
IF NOT IS_VEHICLE_OK(mv_RewardCar.VehIdx)
|
|
mv_RewardCar.VehIdx = CREATE_VEHICLE(mv_RewardCar.VehName, mv_RewardCar.VehPos, mv_RewardCar.Heading)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(mv_RewardCar.VehIdx)
|
|
SET_VEHICLE_HAS_BEEN_OWNED_BY_PLAYER(mv_RewardCar.VehIdx, TRUE)
|
|
SET_VEHICLE_DIRT_LEVEL(mv_RewardCar.VehIdx, 13)
|
|
SET_VEHICLE_COLOURS(mv_RewardCar.VehIdx, 157, 157)
|
|
SET_VEHICLE_EXTRA_COLOURS(mv_RewardCar.VehIdx, 157, 5)
|
|
ENDIF
|
|
BREAK
|
|
DEFAULT
|
|
IF NOT IS_VEHICLE_OK(mv_RewardCar.VehIdx)
|
|
mv_RewardCar.VehIdx = CREATE_VEHICLE(mv_RewardCar.VehName, mv_RewardCar.VehPos, mv_RewardCar.Heading)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(mv_RewardCar.VehIdx)
|
|
SET_VEHICLE_HAS_BEEN_OWNED_BY_PLAYER(mv_RewardCar.VehIdx, TRUE)
|
|
SET_VEHICLE_DOORS_LOCKED(mv_RewardCar.VehIdx, VEHICLELOCK_LOCKOUT_PLAYER_ONLY)
|
|
SET_VEHICLE_DIRT_LEVEL(mv_RewardCar.VehIdx, 13)
|
|
SET_VEHICLE_COLOURS(mv_RewardCar.VehIdx, 157, 157)
|
|
SET_VEHICLE_EXTRA_COLOURS(mv_RewardCar.VehIdx, 157, 5)
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
SET_VEHICLE_MODEL_IS_SUPPRESSED(mv_RewardCar.VehName, TRUE)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(mv_RewardCar.VehName)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Sets Jimmy Boston up in whatever starting state he should be in, at whatever stage the mission is currently at
|
|
PROC SETUP_JIMMY()
|
|
SWITCH missionStage
|
|
CASE MS_INIT
|
|
FALLTHRU // Same as MS_FLIGHT
|
|
|
|
CASE MS_FLIGHT
|
|
SAFE_DELETE_PED(mp_Jimmy.piPedIdx)
|
|
SAFE_REMOVE_BLIP(mp_Jimmy.biPedBlip)
|
|
BREAK
|
|
|
|
CASE MS_LANDING
|
|
FALLTHRU
|
|
|
|
CASE MS_SEEJIMMY
|
|
FALLTHRU
|
|
|
|
CASE MS_ENDCUTSCENE
|
|
IF NOT IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
WHILE NOT RC_CREATE_NPC_PED(mp_Jimmy.piPedIdx, CHAR_JIMMY_BOSTON, mp_Jimmy.vPos, mp_Jimmy.fHeading, "JimmyB")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mp_Jimmy.piPedIdx, TRUE)
|
|
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(mp_Jimmy.piPedIdx, FALSE)
|
|
SET_PED_CAN_BE_TARGETTED(mp_Jimmy.piPedIdx, FALSE)
|
|
SET_PED_CONFIG_FLAG(mp_Jimmy.piPedIdx, PCF_UseKinematicModeWhenStationary, TRUE)
|
|
SET_PED_PROP_INDEX(mp_Jimmy.piPedIdx, ANCHOR_EYES, 0, 0)
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(mp_Jimmy.piPedIdx, relGroupPlayer)
|
|
SET_PED_CONFIG_FLAG(mp_Jimmy.piPedIdx, PCF_KeepRelationshipGroupAfterCleanUp, TRUE)
|
|
TASK_PLAY_ANIM(mp_Jimmy.piPedIdx, mp_Jimmy.AnimDict, mp_Jimmy.AnimName, NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY | AF_LOOPING | AF_SECONDARY)
|
|
ELSE
|
|
SAFE_TELEPORT_ENTITY(mp_Jimmy.piPedIdx, mp_Jimmy.vPos, mp_Jimmy.fHeading)
|
|
IF IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
TASK_PLAY_ANIM(mp_Jimmy.piPedIdx, mp_Jimmy.AnimDict, mp_Jimmy.AnimName, NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY | AF_LOOPING | AF_SECONDARY)
|
|
SET_PED_PROP_INDEX(mp_Jimmy.piPedIdx, ANCHOR_EYES, 0, 0)
|
|
ENDIF
|
|
ENDIF
|
|
IF NOT DOES_ENTITY_EXIST(oiJimmyPhone)
|
|
oiJimmyPhone = CREATE_OBJECT(p_amb_phone_01, GET_ENTITY_COORDS(mp_Jimmy.piPedIdx))
|
|
ENDIF
|
|
IF NOT IS_ENTITY_ATTACHED(oiJimmyPhone)
|
|
ATTACH_ENTITY_TO_ENTITY(oiJimmyPhone, mp_Jimmy.piPedIdx, GET_PED_BONE_INDEX(mp_Jimmy.piPedIdx, BONETAG_PH_R_HAND), <<0,0,0>>, <<0,0,0>>, TRUE)
|
|
ENDIF
|
|
SET_NPC_PED_MODEL_AS_NO_LONGER_NEEDED(CHAR_JIMMY_BOSTON)
|
|
BREAK
|
|
|
|
CASE MS_WAITFORJIMMY
|
|
IF NOT bCompleteShitskip
|
|
IF NOT IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
WHILE NOT RC_CREATE_NPC_PED(mp_Jimmy.piPedIdx, CHAR_JIMMY_BOSTON, <<1683.76, 3270.74, 39.78>>, 168.3395 , "JimmyB")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mp_Jimmy.piPedIdx, TRUE)
|
|
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(mp_Jimmy.piPedIdx, FALSE)
|
|
SET_PED_CAN_BE_TARGETTED(mp_Jimmy.piPedIdx, FALSE)
|
|
SET_PED_CONFIG_FLAG(mp_Jimmy.piPedIdx, PCF_UseKinematicModeWhenStationary, TRUE)
|
|
SET_PED_PROP_INDEX(mp_Jimmy.piPedIdx, ANCHOR_EYES, 0, 0)
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(mp_Jimmy.piPedIdx, relGroupPlayer)
|
|
SET_PED_CONFIG_FLAG(mp_Jimmy.piPedIdx, PCF_KeepRelationshipGroupAfterCleanUp, TRUE)
|
|
IF NOT DOES_BLIP_EXIST(mp_Jimmy.biPedBlip)
|
|
mp_Jimmy.biPedBlip = CREATE_PED_BLIP(mp_Jimmy.piPedIdx, TRUE, TRUE, BLIPPRIORITY_HIGHEST)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
AND IsPlaneOK()
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, <<1682.44, 3258.81, 39.81>>, PEDMOVEBLENDRATIO_RUN, DEFAULT_TIME_BEFORE_WARP, 7.5, ENAV_NO_STOPPING)
|
|
TASK_ENTER_VEHICLE(NULL, mv_plane.VehIdx, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(mp_Jimmy.piPedIdx, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
FORCE_PED_AI_AND_ANIMATION_UPDATE(mp_Jimmy.piPedIdx, FALSE)
|
|
ELSE
|
|
SAFE_TELEPORT_ENTITY(mp_Jimmy.piPedIdx, <<1683.76, 3270.74, 39.78>>, 168.3395)
|
|
IF NOT DOES_BLIP_EXIST(mp_Jimmy.biPedBlip)
|
|
mp_Jimmy.biPedBlip = CREATE_PED_BLIP(mp_Jimmy.piPedIdx, TRUE, TRUE, BLIPPRIORITY_HIGHEST)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
AND IsPlaneOK()
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, <<1682.44, 3258.81, 39.81>>, PEDMOVEBLENDRATIO_RUN, DEFAULT_TIME_BEFORE_WARP, 7.5, ENAV_NO_STOPPING)
|
|
TASK_ENTER_VEHICLE(NULL, mv_plane.VehIdx, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(mp_Jimmy.piPedIdx, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
FORCE_PED_AI_AND_ANIMATION_UPDATE(mp_Jimmy.piPedIdx, TRUE)
|
|
ENDIF
|
|
SAFE_DELETE_OBJECT(oiJimmyPhone)
|
|
ELSE
|
|
SAFE_REMOVE_BLIP(mp_Jimmy.biPedBlip)
|
|
SAFE_DELETE_PED(mp_Jimmy.piPedIdx)
|
|
ENDIF
|
|
SET_NPC_PED_MODEL_AS_NO_LONGER_NEEDED(CHAR_JIMMY_BOSTON)
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Sets the plane up in whatever starting state it should be in, at whatever stage the mission is currently at
|
|
PROC SETUP_PLANE()
|
|
SWITCH missionStage
|
|
CASE MS_INIT
|
|
IF DOES_ENTITY_EXIST(mv_plane.VehIdx)
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx)
|
|
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), <<-2882.42, 3197.76, 10.74>>)
|
|
ENDIF
|
|
ENDIF
|
|
DELETE_VEHICLE(mv_plane.VehIdx)
|
|
ENDIF
|
|
mv_plane.VehIdx = CREATE_VEHICLE(vehModel,<<-2892.93,3192.37,11.66>>, -132.35, FALSE, FALSE)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(mv_plane.VehIdx)
|
|
ADD_VEHICLE_UPSIDEDOWN_CHECK(mv_plane.VehIdx)
|
|
SET_VEHICLE_COLOURS(mv_plane.VehIdx, 157, 157)
|
|
SET_VEHICLE_EXTRA_COLOURS(mv_plane.VehIdx, 157, 5)
|
|
SET_VEHICLE_LIVERY(mv_plane.VehIdx, 3)
|
|
SET_VEHICLE_ENGINE_CAN_DEGRADE(mv_plane.VehIdx, FALSE)
|
|
SET_VEHICLE_HAS_STRONG_AXLES(mv_plane.VehIdx, TRUE)
|
|
SET_VEHICLE_AS_RESTRICTED(mv_plane.VehIdx, 0)
|
|
DEBUG_PRINT("Creating plane in init skip...")
|
|
BREAK
|
|
CASE MS_FLIGHT
|
|
// Can't use SAFE_DELETE_VEHICLE here, in case the player is inside the plane at the time and we get duplicate planes!
|
|
IF DOES_ENTITY_EXIST(mv_plane.VehIdx)
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx)
|
|
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), <<-2882.42, 3197.76, 10.74>>)
|
|
ENDIF
|
|
ENDIF
|
|
DELETE_VEHICLE(mv_plane.VehIdx)
|
|
ENDIF
|
|
mv_plane.VehIdx = CREATE_VEHICLE(vehModel,<<-2892.93,3192.37,11.66>>, -132.35, FALSE, FALSE)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(mv_plane.VehIdx)
|
|
ADD_VEHICLE_UPSIDEDOWN_CHECK(mv_plane.VehIdx)
|
|
SET_VEHICLE_COLOURS(mv_plane.VehIdx, 157, 157)
|
|
SET_VEHICLE_EXTRA_COLOURS(mv_plane.VehIdx, 157, 5)
|
|
SET_VEHICLE_LIVERY(mv_plane.VehIdx, 3)
|
|
SET_VEHICLE_ENGINE_ON(mv_plane.VehIdx, TRUE, TRUE)
|
|
SET_VEHICLE_ENGINE_CAN_DEGRADE(mv_plane.VehIdx, FALSE)
|
|
SET_VEHICLE_HAS_STRONG_AXLES(mv_plane.VehIdx, TRUE)
|
|
SET_VEHICLE_AS_RESTRICTED(mv_plane.VehIdx, 0)
|
|
DEBUG_PRINT("Creating plane in Flight skip...")
|
|
BREAK
|
|
CASE MS_LANDING
|
|
IF IsPlaneOK()
|
|
SET_VEHICLE_DOORS_LOCKED(mv_plane.VehIdx, VEHICLELOCK_UNLOCKED)
|
|
SET_ENTITY_HEADING(mv_plane.VehIdx, 290.8230)
|
|
SET_VEHICLE_ENGINE_ON(mv_plane.VehIdx, TRUE, TRUE)
|
|
SET_VEHICLE_FORWARD_SPEED(mv_plane.VehIdx, 75)
|
|
SET_VEHICLE_ENGINE_CAN_DEGRADE(mv_plane.VehIdx, FALSE)
|
|
SET_VEHICLE_HAS_STRONG_AXLES(mv_plane.VehIdx, TRUE)
|
|
CONTROL_LANDING_GEAR(mv_plane.VehIdx, LGC_RETRACT_INSTANT)
|
|
FREEZE_ENTITY_POSITION(mv_plane.VehIdx, TRUE)
|
|
|
|
ELSE
|
|
mv_plane.VehIdx = CREATE_VEHICLE(vehModel, <<595.7562, 2926.4202, 173.2301>>, 283.3833, FALSE, FALSE)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(mv_plane.VehIdx)
|
|
ADD_VEHICLE_UPSIDEDOWN_CHECK(mv_plane.VehIdx)
|
|
SET_VEHICLE_COLOURS(mv_plane.VehIdx, 157, 157)
|
|
SET_VEHICLE_EXTRA_COLOURS(mv_plane.VehIdx, 157, 5)
|
|
SET_VEHICLE_LIVERY(mv_plane.VehIdx, 3)
|
|
SET_VEHICLE_ENGINE_ON(mv_plane.VehIdx, TRUE, TRUE)
|
|
SET_VEHICLE_ENGINE_CAN_DEGRADE(mv_plane.VehIdx, FALSE)
|
|
SET_VEHICLE_HAS_STRONG_AXLES(mv_plane.VehIdx, TRUE)
|
|
SET_VEHICLE_AS_RESTRICTED(mv_plane.VehIdx, 0)
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx)
|
|
ENDIF
|
|
CONTROL_LANDING_GEAR(mv_plane.VehIdx, LGC_RETRACT_INSTANT)
|
|
FREEZE_ENTITY_POSITION(mv_plane.VehIdx, TRUE)
|
|
DEBUG_PRINT("Creating plane for landing skip...")
|
|
|
|
ENDIF
|
|
BREAK
|
|
CASE MS_SEEJIMMY
|
|
FALLTHRU
|
|
|
|
CASE MS_ENDCUTSCENE
|
|
DEBUG_PRINT("Doing plane skip for SeeJimmy/EndCutscene")
|
|
IF IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(mv_plane.VehIdx)
|
|
STOP_PLAYBACK_RECORDED_VEHICLE(mv_plane.VehIdx)
|
|
ENDIF
|
|
SAFE_DELETE_VEHICLE(mv_plane.VehIdx)
|
|
ENDIF
|
|
mv_plane.VehIdx = CREATE_VEHICLE(mv_plane.VehName, <<1684.78, 3255.58, 41.78>>, 284.26)
|
|
IF IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(mv_plane.VehIdx)
|
|
ADD_VEHICLE_UPSIDEDOWN_CHECK(mv_plane.VehIdx)
|
|
SET_VEHICLE_DOORS_LOCKED(mv_plane.VehIdx, VEHICLELOCK_LOCKOUT_PLAYER_ONLY)
|
|
SET_VEHICLE_COLOURS(mv_plane.VehIdx, 157, 157)
|
|
SET_VEHICLE_EXTRA_COLOURS(mv_plane.VehIdx, 157, 5)
|
|
SET_VEHICLE_LIVERY(mv_plane.VehIdx, 3)
|
|
SET_VEHICLE_ENGINE_CAN_DEGRADE(mv_plane.VehIdx, FALSE)
|
|
SET_VEHICLE_HAS_STRONG_AXLES(mv_plane.VehIdx, TRUE)
|
|
SET_VEHICLE_AS_RESTRICTED(mv_plane.VehIdx, 0)
|
|
ENDIF
|
|
SAFE_REMOVE_BLIP(mv_plane.biBlipIdx)
|
|
BREAK
|
|
|
|
CASE MS_WAITFORJIMMY
|
|
DEBUG_PRINT("Doing plane skip for WaitForJimmy")
|
|
IF NOT bCompleteShitskip
|
|
IF IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(mv_plane.VehIdx)
|
|
STOP_PLAYBACK_RECORDED_VEHICLE(mv_plane.VehIdx)
|
|
ENDIF
|
|
SAFE_DELETE_VEHICLE(mv_plane.VehIdx)
|
|
ENDIF
|
|
mv_plane.VehIdx = CREATE_VEHICLE(mv_plane.VehName, <<1674.91, 3252.47, 41.69>>, 284.26)
|
|
IF IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(mv_plane.VehIdx)
|
|
ADD_VEHICLE_UPSIDEDOWN_CHECK(mv_plane.VehIdx)
|
|
SET_VEHICLE_DOORS_LOCKED(mv_plane.VehIdx, VEHICLELOCK_LOCKOUT_PLAYER_ONLY)
|
|
SET_VEHICLE_COLOURS(mv_plane.VehIdx, 157, 157)
|
|
SET_VEHICLE_EXTRA_COLOURS(mv_plane.VehIdx, 157, 5)
|
|
SET_VEHICLE_LIVERY(mv_plane.VehIdx, 3)
|
|
SET_VEHICLE_ENGINE_CAN_DEGRADE(mv_plane.VehIdx, FALSE)
|
|
SET_VEHICLE_HAS_STRONG_AXLES(mv_plane.VehIdx, TRUE)
|
|
SET_VEHICLE_AS_RESTRICTED(mv_plane.VehIdx, 0)
|
|
ENDIF
|
|
SAFE_REMOVE_BLIP(mv_plane.biBlipIdx)
|
|
IF NOT IS_PLAYBACK_GOING_ON_FOR_VEHICLE(mv_plane.VehIdx)
|
|
IF HAS_VEHICLE_RECORDING_BEEN_LOADED(501, "Eps6_Takeoff")
|
|
START_PLAYBACK_RECORDED_VEHICLE(mv_plane.VehIdx, 501, "Eps6_Takeoff")
|
|
FORCE_PLAYBACK_RECORDED_VEHICLE_UPDATE(mv_plane.VehIdx)
|
|
PAUSE_PLAYBACK_RECORDED_VEHICLE(mv_plane.VehIdx)
|
|
DEBUG_PRINT("Started/paused vehicle recording on plane (skip)")
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
SAFE_REMOVE_BLIP(mv_plane.biBlipIdx)
|
|
SAFE_DELETE_VEHICLE(mv_plane.VehIdx)
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
SET_VEHICLE_MODEL_IS_SUPPRESSED(mv_plane.VehName, TRUE)
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Give the cultist his default wandering-around task at the start of the mission
|
|
PROC CULTIST_GIVE_TASK()
|
|
GIVE_WEAPON_TO_PED(mp_Cultist.piPedIdx, WEAPONTYPE_DIGISCANNER, 0, TRUE)
|
|
SET_PED_CAN_SWITCH_WEAPON(mp_Cultist.piPedIdx, FALSE)
|
|
STOP_PED_SPEAKING(mp_Cultist.piPedIdx, TRUE)
|
|
// SET_PED_LEG_IK_MODE(mp_Cultist.piPedIdx, LEG_IK_PARTIAL)
|
|
SET_PED_DIES_WHEN_INJURED(mp_Cultist.piPedIdx, TRUE)
|
|
SET_PED_CAN_BE_TARGETTED(mp_Cultist.piPedIdx, FALSE)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_GO_TO_COORD_WHILE_AIMING_AT_COORD(NULL, <<-2887.95, 3194.88, 10.06>>, <<-2887.95, 3194.88, 10.06>>, 1.2, FALSE)
|
|
TASK_PLAY_ANIM(NULL, "rcmepsilonism6", "cultist_idle_a", REALLY_SLOW_BLEND_IN, REALLY_SLOW_BLEND_OUT)
|
|
TASK_GO_TO_COORD_WHILE_AIMING_AT_COORD(NULL, <<-2888.92, 3203.76, 10.60>>, <<-2888.92, 3203.76, 10.60>>, 1.2, FALSE)
|
|
TASK_PLAY_ANIM(NULL, "rcmepsilonism6", "cultist_idle_a", REALLY_SLOW_BLEND_IN, REALLY_SLOW_BLEND_OUT)
|
|
TASK_GO_TO_COORD_WHILE_AIMING_AT_COORD(NULL, <<-2895.37, 3199.37, 10.03>>, <<-2895.37, 3199.37, 10.03>>, 1.2, FALSE)
|
|
TASK_PLAY_ANIM(NULL, "rcmepsilonism6", "cultist_idle_a", REALLY_SLOW_BLEND_IN, REALLY_SLOW_BLEND_OUT)
|
|
SET_SEQUENCE_TO_REPEAT(seq, REPEAT_FOREVER)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(mp_Cultist.piPedIdx, seq)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Sets the Epsilonist up in whatever starting state he should be in, at whatever stage the mission is currently at
|
|
PROC SETUP_EPSILONIST()
|
|
|
|
SWITCH missionStage
|
|
CASE MS_INIT
|
|
IF IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
SET_ENTITY_HEADING(mp_Cultist.piPedIdx, 254.1723)
|
|
SET_ENTITY_COORDS(mp_Cultist.piPedIdx, << -2881.7554, 3188.1252, 10.1136 >>)
|
|
CLEAR_PED_TASKS(mp_Cultist.piPedIdx)
|
|
CULTIST_GIVE_TASK()
|
|
ELSE
|
|
SAFE_DELETE_PED(mp_Cultist.piPedIdx)
|
|
mp_Cultist.piPedIdx = CREATE_PED(PEDTYPE_MISSION, cultModel,<< -2881.7554, 3188.1252, 10.1136 >>, 254.1723)
|
|
SET_PED_DEFAULT_COMPONENT_VARIATION(mp_Cultist.piPedIdx)
|
|
CULTIST_GIVE_TASK()
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
SET_PED_MAX_MOVE_BLEND_RATIO(mp_Cultist.piPedIdx, 0)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mp_Cultist.piPedIdx, TRUE)
|
|
SET_PED_CONFIG_FLAG(mp_Cultist.piPedIdx,PCF_DontEnterVehiclesInPlayersGroup, TRUE)
|
|
STOP_PED_SPEAKING(mp_Cultist.piPedIdx, TRUE)
|
|
// SET_PED_LEG_IK_MODE(mp_Cultist.piPedIdx, LEG_IK_PARTIAL)
|
|
SET_PED_DIES_WHEN_INJURED(mp_Cultist.piPedIdx, TRUE)
|
|
SET_PED_CAN_BE_TARGETTED(mp_Cultist.piPedIdx, FALSE)
|
|
SET_PED_CONFIG_FLAG(mp_Cultist.piPedIdx, PCF_UseKinematicModeWhenStationary, TRUE)
|
|
SET_PED_CONFIG_FLAG(mp_Cultist.piPedIdx, PCF_DisableHurt, FALSE)
|
|
//SET_PED_CAN_RAGDOLL(mp_Cultist.piPedIdx, FALSE)
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(mp_Cultist.piPedIdx, relGroupPlayer)
|
|
SET_PED_CONFIG_FLAG(mp_Cultist.piPedIdx, PCF_KeepRelationshipGroupAfterCleanUp, TRUE)
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_cult, 4, mp_Cultist.piPedIdx, "TOM", TRUE)
|
|
ENDIF
|
|
BREAK
|
|
CASE MS_FLIGHT
|
|
IF IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
SET_ENTITY_HEADING(mp_Cultist.piPedIdx, 254.1723)
|
|
SET_ENTITY_COORDS(mp_Cultist.piPedIdx, << -2889.89, 3198.69, 10.11 >>)
|
|
CLEAR_PED_TASKS(mp_Cultist.piPedIdx)
|
|
ELSE
|
|
SAFE_DELETE_PED(mp_Cultist.piPedIdx)
|
|
mp_Cultist.piPedIdx = CREATE_PED(PEDTYPE_MISSION, cultModel,<<-2889.89, 3198.69, 10.11 >>, 254.1723)
|
|
SET_PED_DEFAULT_COMPONENT_VARIATION(mp_Cultist.piPedIdx)
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
SET_PED_MAX_MOVE_BLEND_RATIO(mp_Cultist.piPedIdx, 0)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mp_Cultist.piPedIdx, TRUE)
|
|
SET_PED_CONFIG_FLAG(mp_Cultist.piPedIdx,PCF_DontEnterVehiclesInPlayersGroup, TRUE)
|
|
STOP_PED_SPEAKING(mp_Cultist.piPedIdx, TRUE)
|
|
// SET_PED_LEG_IK_MODE(mp_Cultist.piPedIdx, LEG_IK_PARTIAL)
|
|
SET_PED_DIES_WHEN_INJURED(mp_Cultist.piPedIdx, TRUE)
|
|
SET_PED_CAN_BE_TARGETTED(mp_Cultist.piPedIdx, FALSE)
|
|
SET_PED_CONFIG_FLAG(mp_Cultist.piPedIdx, PCF_DisableHurt, FALSE)
|
|
SET_PED_CONFIG_FLAG(mp_Cultist.piPedIdx, PCF_UseKinematicModeWhenStationary, TRUE)
|
|
//SET_PED_CAN_RAGDOLL(mp_Cultist.piPedIdx, FALSE)
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(mp_Cultist.piPedIdx, relGroupPlayer)
|
|
SET_PED_CONFIG_FLAG(mp_Cultist.piPedIdx, PCF_KeepRelationshipGroupAfterCleanUp, TRUE)
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_cult, 4, mp_Cultist.piPedIdx, "TOM", TRUE)
|
|
ENDIF
|
|
BREAK
|
|
DEFAULT
|
|
IF IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
IF IS_PED_IN_GROUP(mp_Cultist.piPedIdx)
|
|
REMOVE_PED_FROM_GROUP(mp_Cultist.piPedIdx)
|
|
ENDIF
|
|
ENDIF
|
|
SAFE_REMOVE_BLIP(mp_Cultist.biPedBlip)
|
|
SAFE_DELETE_PED(mp_Cultist.piPedIdx)
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(cultModel)
|
|
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Loads and sets up whatever resources we need when going into a stage through a skip/checkpoint
|
|
PROC LoadSkip()
|
|
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
|
|
SWITCH missionStage
|
|
CASE MS_INIT
|
|
|
|
REQUEST_MODEL(cultModel)
|
|
REQUEST_MODEL(vehModel)
|
|
REQUEST_ANIM_DICT("rcm_epsilonism4")
|
|
|
|
WHILE NOT HAS_MODEL_LOADED(cultModel)
|
|
OR NOT HAS_MODEL_LOADED(vehModel)
|
|
OR NOT HAS_ANIM_DICT_LOADED("rcm_epsilonism4")
|
|
DEBUG_PRINT("WAITING FOR MS_INIT RESOURCES")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
bShownGetInPlane = FALSE
|
|
bShownGoToAirfield = FALSE
|
|
// bCultistRagdoll = FALSE
|
|
bCultistAimConv = FALSE
|
|
bDoneMusic = FALSE
|
|
bSpawnJimmy = FALSE
|
|
bSetCP = FALSE
|
|
bCultistNoSubIntro = FALSE
|
|
iCultistRoamStage = 0
|
|
|
|
IntroState = INTRO_INIT
|
|
EpsState = EPS_INIT
|
|
EpsMode = STATE_SETUP
|
|
|
|
SETUP_PLAYER()
|
|
SETUP_JIMMY()
|
|
SETUP_PLANE()
|
|
SETUP_EPSILONIST()
|
|
|
|
SAFE_REMOVE_BLIP(pcp_LandingGoal.biBlipIdx)
|
|
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(cultModel)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(vehModel)
|
|
|
|
SET_MAX_WANTED_LEVEL(0) // Because this won't be triggered by the phonecall in a skip
|
|
|
|
BREAK
|
|
CASE MS_FLIGHT
|
|
|
|
REQUEST_MODEL(vehModel)
|
|
REQUEST_MODEL(cultModel)
|
|
|
|
WHILE NOT HAS_MODEL_LOADED(vehModel)
|
|
OR NOT HAS_MODEL_LOADED(cultModel)
|
|
DEBUG_PRINT("WAITING FOR MS_FLIGHT RESOURCES")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
bShownGoToAirfield = FALSE
|
|
// bCultistRagdoll = FALSE
|
|
bCultistAimConv = FALSE
|
|
bSpawnJimmy = FALSE
|
|
bSetCP = FALSE
|
|
IntroState = INTRO_INPLANE
|
|
EpsState = EPS_SAFE
|
|
EpsMode = STATE_SETUP
|
|
|
|
SETUP_PLANE()
|
|
SETUP_JIMMY()
|
|
SETUP_PLAYER()
|
|
SETUP_EPSILONIST()
|
|
|
|
STOP_SOUND(iDetectorBeepID)
|
|
STOP_SOUND(iDetectorHumID)
|
|
|
|
TRIGGER_MUSIC_EVENT("EPS6_START")
|
|
|
|
SET_MAX_WANTED_LEVEL(0) // Because this won't be triggered by the phonecall in a skip
|
|
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(cultModel)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(vehModel)
|
|
|
|
BREAK
|
|
CASE MS_LANDING
|
|
|
|
REQUEST_MODEL(vehModel)
|
|
|
|
WHILE NOT HAS_MODEL_LOADED(vehModel)
|
|
DEBUG_PRINT("WAITING FOR MS_LANDING SKIP RESOURCES")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
IntroState = INTRO_INTERRUPTED
|
|
EpsState = EPS_FLEEING
|
|
|
|
bShownLandAtAirfield = FALSE
|
|
bShownGoToJimmy = FALSE
|
|
bSpawnJimmy = FALSE
|
|
|
|
SETUP_PLAYER()
|
|
SETUP_PLANE()
|
|
SETUP_EPSILONIST()
|
|
|
|
SAFE_REMOVE_BLIP(mp_Jimmy.biPedBlip)
|
|
|
|
STOP_SOUND(iDetectorBeepID)
|
|
STOP_SOUND(iDetectorHumID)
|
|
|
|
TRIGGER_MUSIC_EVENT("EPS6_START")
|
|
|
|
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_LANDING, "Landing stage") // Set the checkpoint now in case we've shitskipped
|
|
bSetCP = TRUE // Don't try to set this again now
|
|
|
|
SET_MAX_WANTED_LEVEL(5) // Because this won't be triggered by the phonecall in a skip
|
|
|
|
IF IsPlaneOK()
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
WAIT_FOR_WORLD_TO_LOAD(GET_ENTITY_COORDS(mv_plane.VehIdx), 200)
|
|
ENDIF
|
|
IF IsPlaneOK() // Since the first check is no longer valid after waiting for the world to load...
|
|
FREEZE_ENTITY_POSITION(mv_plane.VehIdx, FALSE)
|
|
if HAS_VEHICLE_RECORDING_BEEN_LOADED(500, "Eps6_LandingSkip")
|
|
IF NOT IS_PLAYBACK_GOING_ON_FOR_VEHICLE(mv_plane.VehIdx)
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
DEBUG_PRINT("Doing plane boost")
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
|
|
START_PLAYBACK_RECORDED_VEHICLE(mv_plane.VehIdx, 500, "Eps6_LandingSkip")
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(vehModel)
|
|
|
|
BREAK
|
|
CASE MS_SEEJIMMY
|
|
|
|
REQUEST_ANIM_DICT(mp_Jimmy.AnimDict)
|
|
REQUEST_MODEL(vehModel)
|
|
REQUEST_MODEL(mv_RewardCar.VehName)
|
|
REQUEST_NPC_PED_MODEL(CHAR_JIMMY_BOSTON)
|
|
|
|
WHILE NOT HAS_MODEL_LOADED(vehModel)
|
|
OR NOT HAS_MODEL_LOADED(mv_RewardCar.VehName)
|
|
OR NOT HAS_ANIM_DICT_LOADED(mp_Jimmy.AnimDict)
|
|
OR NOT HAS_NPC_PED_MODEL_LOADED(CHAR_JIMMY_BOSTON)
|
|
DEBUG_PRINT("WAITING FOR MS_SEEJIMMY RESOURCES")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
SETUP_PLAYER()
|
|
SETUP_PLANE()
|
|
SETUP_JIMMY()
|
|
SETUP_CAR()
|
|
SETUP_EPSILONIST()
|
|
|
|
SAFE_REMOVE_BLIP(pcp_LandingGoal.biBlipIdx)
|
|
SAFE_REMOVE_BLIP(mp_Cultist.biPedBlip)
|
|
|
|
STOP_SOUND(iDetectorBeepID)
|
|
STOP_SOUND(iDetectorHumID)
|
|
|
|
TRIGGER_MUSIC_EVENT("EPS6_START")
|
|
|
|
SET_MAX_WANTED_LEVEL(5) // Because this won't be triggered by the phonecall in a skip
|
|
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(vehModel)
|
|
|
|
IF iNavBlockingObj != -1
|
|
REMOVE_NAVMESH_BLOCKING_OBJECT(iNavBlockingObj)
|
|
DEBUG_PRINT("Navmesh blocking object removed")
|
|
iNavBlockingObj = -1
|
|
ENDIF
|
|
|
|
g_iAbandonCap = 5 // In case we've Z-skipped to the same stage (and effectively reset it), and need to reset the abandonment check
|
|
|
|
BREAK
|
|
|
|
CASE MS_ENDCUTSCENE
|
|
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
REQUEST_CUTSCENE("ep_6_rcm", CUTSCENE_REQUESTED_FROM_Z_SKIP)
|
|
ENDIF
|
|
REQUEST_MODEL(mv_RewardCar.VehName)
|
|
REQUEST_MODEL(mv_plane.VehName)
|
|
REQUEST_ANIM_DICT(mp_Jimmy.AnimDict)
|
|
REQUEST_VEHICLE_RECORDING(501, "Eps6_Takeoff")
|
|
REQUEST_NPC_PED_MODEL(CHAR_JIMMY_BOSTON)
|
|
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
WHILE NOT HAS_MODEL_LOADED(mv_RewardCar.VehName)
|
|
OR NOT HAS_CUTSCENE_LOADED()
|
|
OR NOT HAS_MODEL_LOADED(mv_plane.VehName)
|
|
OR NOT HAS_ANIM_DICT_LOADED(mp_Jimmy.AnimDict)
|
|
OR NOT HAS_VEHICLE_RECORDING_BEEN_LOADED(501, "Eps6_Takeoff")
|
|
OR NOT HAS_NPC_PED_MODEL_LOADED(CHAR_JIMMY_BOSTON)
|
|
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
|
|
SET_CUTSCENE_PED_PROP_VARIATION("Jimmy_Boston", ANCHOR_EYES, 0)
|
|
ENDIF
|
|
DEBUG_PRINT("WAITING FOR MS_ENDCUTSCENE RESOURCES")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
ELSE
|
|
WHILE NOT HAS_MODEL_LOADED(mv_RewardCar.VehName)
|
|
OR NOT HAS_MODEL_LOADED(mv_plane.VehName)
|
|
OR NOT HAS_ANIM_DICT_LOADED(mp_Jimmy.AnimDict)
|
|
OR NOT HAS_VEHICLE_RECORDING_BEEN_LOADED(501, "Eps6_Takeoff")
|
|
OR NOT HAS_NPC_PED_MODEL_LOADED(CHAR_JIMMY_BOSTON)
|
|
DEBUG_PRINT("WAITING FOR MS_ENDCUTSCENE RESOURCES")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
ENDIF
|
|
|
|
SAFE_REMOVE_BLIP(pcp_LandingGoal.biBlipIdx)
|
|
SAFE_REMOVE_BLIP(mp_Cultist.biPedBlip)
|
|
|
|
STOP_SOUND(iDetectorBeepID)
|
|
STOP_SOUND(iDetectorHumID)
|
|
|
|
SET_MAX_WANTED_LEVEL(5) // Because this won't be triggered by the phonecall in a skip
|
|
|
|
SETUP_CAR()
|
|
SETUP_PLANE()
|
|
SETUP_JIMMY()
|
|
SETUP_PLAYER()
|
|
SETUP_EPSILONIST()
|
|
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
IF IS_SCREEN_FADED_OUT()
|
|
WAIT(5000) // Do a wait if the screen is faded out to give the world some time to load in
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF iNavBlockingObj != -1
|
|
REMOVE_NAVMESH_BLOCKING_OBJECT(iNavBlockingObj)
|
|
DEBUG_PRINT("Navmesh blocking object removed")
|
|
iNavBlockingObj = -1
|
|
ENDIF
|
|
|
|
IF iNavBlockingObj = -1
|
|
iNavBlockingObj = ADD_NAVMESH_BLOCKING_OBJECT(<<1687.9539, 3277.7268, 40.2500>>, <<6,6,6>>, 0)
|
|
DEBUG_PRINT("Navmesh blocking object created")
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE MS_WAITFORJIMMY
|
|
|
|
REQUEST_ANIM_DICT(mp_Jimmy.AnimDict)
|
|
REQUEST_MODEL(mv_RewardCar.VehName)
|
|
REQUEST_MODEL(mv_plane.VehName)
|
|
REQUEST_VEHICLE_RECORDING(501, "Eps6_Takeoff")
|
|
REQUEST_NPC_PED_MODEL(CHAR_JIMMY_BOSTON)
|
|
|
|
WHILE NOT HAS_MODEL_LOADED(mv_RewardCar.VehName)
|
|
OR NOT HAS_MODEL_LOADED(mv_plane.VehName)
|
|
OR NOT HAS_ANIM_DICT_LOADED(mp_Jimmy.AnimDict)
|
|
OR NOT HAS_VEHICLE_RECORDING_BEEN_LOADED(501, "Eps6_Takeoff")
|
|
OR NOT HAS_NPC_PED_MODEL_LOADED(CHAR_JIMMY_BOSTON)
|
|
DEBUG_PRINT("WAITING FOR MS_WAITFORJIMMY RESOURCES")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
SAFE_REMOVE_BLIP(pcp_LandingGoal.biBlipIdx)
|
|
SAFE_REMOVE_BLIP(mp_Cultist.biPedBlip)
|
|
|
|
STOP_SOUND(iDetectorBeepID)
|
|
STOP_SOUND(iDetectorHumID)
|
|
|
|
SET_MAX_WANTED_LEVEL(5) // Because this won't be triggered by the phonecall in a skip
|
|
|
|
SETUP_PLAYER()
|
|
SETUP_PLANE()
|
|
SETUP_JIMMY()
|
|
SETUP_CAR()
|
|
SETUP_EPSILONIST()
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
///
|
|
/// RETURNS:
|
|
///
|
|
FUNC BOOL IS_PLAYER_IN_EPS_PLANE()
|
|
IF IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
AND IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID(), TRUE)
|
|
IF mv_plane.VehIdx = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), TRUE)
|
|
DEBUG_PRINT("Player is in plane...")
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
//PURPOSE: Makes Jimmy Boston flee the player.
|
|
PROC MAKE_JIMMY_FLEE()
|
|
IF IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
CLEAR_PED_TASKS(mp_Jimmy.piPedIdx)
|
|
SET_PED_KEEP_TASK(mp_Jimmy.piPedIdx, TRUE)
|
|
TASK_SMART_FLEE_PED(mp_Jimmy.piPedIdx, PLAYER_PED_ID(), 100, -1)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
//PURPOSE: Checks whether the player is attacking or shooting at, or near, Jimmy Boston and fails if so
|
|
PROC CHECK_JIMMY_AGGRO()
|
|
|
|
IF IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
IF HAS_PLAYER_THREATENED_PED(mp_Jimmy.piPedIdx, FALSE, DEFAULT, DEFAULT, TRUE)
|
|
OR IS_BULLET_IN_AREA(GET_ENTITY_COORDS(mp_Jimmy.piPedIdx), 3, TRUE)
|
|
IF missionStage <> MS_WAITFORJIMMY
|
|
AND missionStage <> MS_SEEJIMMY
|
|
bTeleOnFail = TRUE
|
|
ENDIF
|
|
FailedReason = FAILED_ATTACKED_JIMMY
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_outro, 3, mp_Jimmy.piPedIdx, "JIMMYBOSTON")
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_outro, ENUM_TO_INT(CHAR_MICHAEL), PLAYER_PED_ID(), "MICHAEL")
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(s_conversation_outro, "EPS6AUD", "EPS6_SHOT", CONV_PRIORITY_VERY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
|
|
ELSE
|
|
CREATE_CONVERSATION(s_conversation_outro, "EPS6AUD", "EPS6_SHOT", CONV_PRIORITY_VERY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
|
|
ENDIF
|
|
MAKE_JIMMY_FLEE()
|
|
ELIF HAS_PED_BUMPED_PED_WITH_VEHICLE(PLAYER_PED_ID(), mp_Jimmy.piPedIdx)
|
|
OR IS_BULLET_IN_AREA(GET_ENTITY_COORDS(mp_Jimmy.piPedIdx), 3, FALSE)
|
|
OR IS_PED_BEING_JACKED(mp_Jimmy.piPedIdx)
|
|
IF missionStage <> MS_WAITFORJIMMY
|
|
AND missionStage <> MS_SEEJIMMY
|
|
bTeleOnFail = TRUE
|
|
ENDIF
|
|
FailedReason = FAILED_SPOOKED_JIMMY
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_outro, 3, mp_Jimmy.piPedIdx, "JIMMYBOSTON")
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_outro, ENUM_TO_INT(CHAR_MICHAEL), PLAYER_PED_ID(), "MICHAEL")
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(s_conversation_outro, "EPS6AUD", "EPS6_SHOT", CONV_PRIORITY_VERY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
|
|
ELSE
|
|
CREATE_CONVERSATION(s_conversation_outro, "EPS6AUD", "EPS6_SHOT", CONV_PRIORITY_VERY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
|
|
ENDIF
|
|
MAKE_JIMMY_FLEE()
|
|
ELIF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mp_Jimmy.piPedIdx, PLAYER_PED_ID())
|
|
IF HAS_PED_BEEN_DAMAGED_BY_WEAPON(mp_Jimmy.piPedIdx, WEAPONTYPE_INVALID, GENERALWEAPON_TYPE_ANYWEAPON)
|
|
IF missionStage <> MS_WAITFORJIMMY
|
|
AND missionStage <> MS_SEEJIMMY
|
|
bTeleOnFail = TRUE
|
|
ENDIF
|
|
FailedReason = FAILED_HURT_JIMMY
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_outro, 3, mp_Jimmy.piPedIdx, "JIMMYBOSTON")
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_outro, ENUM_TO_INT(CHAR_MICHAEL), PLAYER_PED_ID(), "MICHAEL")
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(s_conversation_outro, "EPS6AUD", "EPS6_SHOT", CONV_PRIORITY_VERY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
|
|
ELSE
|
|
CREATE_CONVERSATION(s_conversation_outro, "EPS6AUD", "EPS6_SHOT", CONV_PRIORITY_VERY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
|
|
ENDIF
|
|
MAKE_JIMMY_FLEE()
|
|
ENDIF
|
|
ENDIF
|
|
ELSE // Jimmy is dead
|
|
IF bSpawnJimmy = TRUE // Only check this after we've spawned Jimmy!
|
|
IF missionStage <> MS_WAITFORJIMMY
|
|
AND missionStage <> MS_SEEJIMMY
|
|
bTeleOnFail = TRUE
|
|
ENDIF
|
|
FailedReason = FAILED_KILLED_JIMMY
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
//PURPOSE: Checks whether the player has flown the plane too close to Jimmy Boston, usually when trying to land it.
|
|
PROC CHECK_JIMMY_PLANE_FEAR()
|
|
IF IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
// Warning
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(mp_Jimmy.piPedIdx, mv_plane.VehIdx) < 17
|
|
IF NOT bPlaneTooCloseConv
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF CREATE_CONVERSATION(s_conversation_outro, "EPS6AUD", "EPS6_CLOSE", CONV_PRIORITY_VERY_HIGH)
|
|
bPlaneTooCloseConv = TRUE
|
|
iJimmyPlaneWarningTimer = GET_GAME_TIMER()
|
|
CLEAR_PED_TASKS(mp_Jimmy.piPedIdx)
|
|
TASK_LOOK_AT_ENTITY(mp_Jimmy.piPedIdx, PLAYER_PED_ID(), 10000, SLF_WIDEST_PITCH_LIMIT|SLF_WIDEST_YAW_LIMIT)
|
|
DEBUG_PRINT("*** Played diag EPS6_CLOSE")
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF (GET_GAME_TIMER() - iJimmyPlaneWarningTimer) > 10000
|
|
bPlaneTooCloseConv = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF NOT IS_ENTITY_PLAYING_ANIM(mp_Jimmy.piPedIdx, mp_Jimmy.AnimDict, mp_Jimmy.AnimName)
|
|
DEBUG_PRINT("*** Retasking Jimmy to play anim from plane fear check")
|
|
TASK_PLAY_ANIM(mp_Jimmy.piPedIdx, mp_Jimmy.AnimDict, mp_Jimmy.AnimName, NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY | AF_LOOPING | AF_SECONDARY)
|
|
ENDIF
|
|
ENDIF
|
|
// Actual fail
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(mp_Jimmy.piPedIdx, mv_plane.VehIdx) < 12
|
|
MAKE_JIMMY_FLEE()
|
|
FailedReason = FAILED_SPOOKED_JIMMY
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Removes the cultist from the player's group and makes the them flee the player
|
|
PROC MAKE_CULTIST_FLEE()
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
IF IS_PED_UNINJURED(mp_Cultist.piPedIdx)
|
|
CLEAR_PED_TASKS(mp_Cultist.piPedIdx)
|
|
IF IS_PED_IN_GROUP(mp_Cultist.piPedIdx)
|
|
REMOVE_PED_FROM_GROUP(mp_Cultist.piPedIdx)
|
|
ENDIF
|
|
TASK_SMART_FLEE_PED(mp_Cultist.piPedIdx, PLAYER_PED_ID(), 500, -1)
|
|
SAFE_REMOVE_BLIP(mp_Cultist.biPedBlip)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// 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
|
|
|
|
/// PURPOSE:
|
|
/// Switch the Cultist to a new state
|
|
/// PARAMS:
|
|
/// newState - The state we want to put the Cultist into
|
|
PROC SWITCH_CULTIST(EPS_STATE newState)
|
|
EPS_STATE_PRINT(newState)
|
|
EpsState = newState
|
|
EpsMode = STATE_SETUP
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Checks if the player damaged the plane as long as they're not in it
|
|
/// RETURNS:
|
|
/// TRUE if they damaged it, FALSE otherwise
|
|
FUNC BOOL DID_PLAYER_DAMAGE_PLANE()
|
|
if IsPlaneOK()
|
|
AND IS_ENTITY_ALIVE(mp_Cultist.piPedIdx) // Don't care if the player damages the plane when the cultist is already dead!
|
|
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx, TRUE)
|
|
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mv_plane.VehIdx, PLAYER_PED_ID())
|
|
DEBUG_PRINT("Player damaged plane")
|
|
CLEAR_ENTITY_LAST_DAMAGE_ENTITY(mv_plane.VehIdx)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
FUNC BOOL DID_PLAYER_PLACE_STICKY_BOMB_ON_PLANE()
|
|
|
|
if IsPlaneOK()
|
|
IF IS_PROJECTILE_TYPE_WITHIN_DISTANCE(GET_ENTITY_COORDS(mv_plane.VehIdx, FALSE), WEAPONTYPE_STICKYBOMB, 10)
|
|
DEBUG_PRINT("Sticky bomb in range of plane")
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
PROC STICKY_BOMB_FAIL()
|
|
|
|
IF IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
SWITCH_CULTIST(EPS_FLEEING)
|
|
ENDIF
|
|
FailedReason = FAILED_STICKYBOMB
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Fails the mission if the player has aggro'd or harmed the Cultist in any way
|
|
PROC CULTIST_AGGRO_FAIL()
|
|
|
|
IF IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
IF IS_PED_UNINJURED(mp_Cultist.piPedIdx)
|
|
IF NOT HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mp_Cultist.piPedIdx, PLAYER_PED_ID())
|
|
DEBUG_PRINT("EPSILONIST got scared by player, will never stop fleeing...")
|
|
SWITCH_CULTIST(EPS_FLEEING)
|
|
FailedReason = FAILED_SPOOKED_BUDDY
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ELSE
|
|
// Is injured but not dead - hurt?
|
|
DEBUG_PRINT("EPSILONIST got hurt by player - 2ND CHECK, NOT INJURED?")
|
|
SWITCH_CULTIST(EPS_FLEEING)
|
|
FailedReason = FAILED_HURT_BUDDY
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
ELSE
|
|
// Is injured but not dead - hurt?
|
|
DEBUG_PRINT("EPSILONIST got hurt by player...")
|
|
FailedReason = FAILED_HURT_BUDDY
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
ELSE
|
|
// if the ped is not alive at all, player must've killed him
|
|
DEBUG_PRINT("EPSILONIST got killed by player...")
|
|
FailedReason = FAILED_KILLED_BUDDY
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
|
|
IF IntroState <= INTRO_SEENMIKE
|
|
IntroState = INTRO_INTERRUPTED
|
|
ENDIF
|
|
|
|
// The aggro check doesn't always catch every instance of the ped getting killed
|
|
IF DOES_ENTITY_EXIST(mp_Cultist.piPedIdx)
|
|
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mp_Cultist.piPedIdx, PLAYER_PED_ID())
|
|
IF IS_ENTITY_DEAD(mp_Cultist.piPedIdx)
|
|
DEBUG_PRINT("EPSILONIST got killed by player - 2ND CHECK")
|
|
FailedReason = FAILED_KILLED_BUDDY
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// A kind of 'soft aggro' check against the Cultist that only checks for if the player outright damages him or shoots around him
|
|
/// This is being used for when the Cultist is doing his 'attacking' thing and the player has to be shooting around the guy,
|
|
/// because we don't want to scare him off when HAS_PLAYER_THREATENED_PED() would return true
|
|
/// RETURNS:
|
|
/// TRUE if the player damages the Cultist, FALSE otherwise.
|
|
FUNC BOOL CULTIST_CHECK_PLAYER_DAMAGE()
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
AND IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
if IS_PLAYER_SHOOTING_NEAR_PED(mp_Cultist.piPedIdx, FALSE)
|
|
DEBUG_PRINT("Player shot near cultist")
|
|
RETURN TRUE
|
|
ENDIF
|
|
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mp_Cultist.piPedIdx, PLAYER_PED_ID())
|
|
DEBUG_PRINT("Player damaged cultist")
|
|
RETURN TRUE
|
|
ENDIF
|
|
ELSE
|
|
IF DOES_ENTITY_EXIST(mp_Cultist.piPedIdx)
|
|
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(mp_Cultist.piPedIdx, PLAYER_PED_ID(), TRUE)
|
|
DEBUG_PRINT("Player damaged cultist (while he wasn't alive, so dead?)")
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Checks player aggro against the Cultist, and makes them flee.
|
|
/// RETURNS:
|
|
/// TRUE if the player aggros the Cultist, FALSE otherwise.
|
|
FUNC BOOL CULTIST_CHECK_AGGRO()
|
|
if HAS_PLAYER_THREATENED_PED(mp_Cultist.piPedIdx, FALSE)
|
|
OR HAS_PED_BUMPED_PED_WITH_VEHICLE(PLAYER_PED_ID(), mp_Cultist.piPedIdx, FALSE)
|
|
OR DID_PLAYER_DAMAGE_PLANE()
|
|
if HAS_PLAYER_THREATENED_PED(mp_Cultist.piPedIdx, FALSE)
|
|
DEBUG_PRINT("Player threatened cultist")
|
|
ENDIF
|
|
IF HAS_PED_BUMPED_PED_WITH_VEHICLE(PLAYER_PED_ID(), mp_Cultist.piPedIdx, FALSE)
|
|
DEBUG_PRINT("Player bumped cultist with vehicle")
|
|
ENDIF
|
|
iCultistRoamStage = 3 // To ensure combat isn't interrupted by roaming commands
|
|
IF IS_PED_UNINJURED(mp_Cultist.piPedIdx)
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(mp_Cultist.piPedIdx, "FIGHT_RUN", "TOM", SPEECH_PARAMS_FORCE_FRONTEND)
|
|
ENDIF
|
|
return true
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
VECTOR vTempPlayer
|
|
|
|
/// PURPOSE:
|
|
/// Manage where the cultist should stand during the intro sequence
|
|
PROC MANAGE_CULTISTS_POSITION()
|
|
IF EpsState = EPS_FOLLOW
|
|
SWITCH EpsMove
|
|
CASE EPSMOVE_OK
|
|
// Nothing to do!
|
|
BREAK
|
|
|
|
CASE EPSMOVE_CHANGE
|
|
IF IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
AND IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
CLEAR_PED_TASKS(mp_Cultist.piPedIdx)
|
|
vTempPlayer = GET_ENTITY_COORDS(PLAYER_PED_ID())
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, vTempPlayer, PEDMOVEBLENDRATIO_WALK)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(mp_Cultist.piPedIdx, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
EpsMove = EPSMOVE_MOVING
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE EPSMOVE_MOVING
|
|
IF IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
AND IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(mp_Cultist.piPedIdx, PLAYER_PED_ID()) < 5
|
|
OR GET_SCRIPT_TASK_STATUS(mp_Cultist.piPedIdx, SCRIPT_TASK_PERFORM_SEQUENCE) = FINISHED_TASK
|
|
CLEAR_PED_TASKS(mp_Cultist.piPedIdx)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(mp_Cultist.piPedIdx, PLAYER_PED_ID(), -1)
|
|
EpsMove = EPSMOVE_OK
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC DO_CULTIST_COMBAT_MOVEMENT(VECTOR vCoord, PED_INDEX target)
|
|
IF IS_PED_UNINJURED(mp_Cultist.piPedIdx)
|
|
AND IS_ENTITY_ALIVE(target)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_GO_TO_COORD_WHILE_AIMING_AT_ENTITY(NULL, vCoord, target, 1, FALSE, 0.5, 4, TRUE)
|
|
TASK_COMBAT_PED(NULL, target)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(mp_Cultist.piPedIdx, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Manage whether ragdoll is enabled for the Cultist or not depending on whether the player is in a vehicle
|
|
PROC MANAGE_CULTIST_RAGDOLL()
|
|
IF bTomSaidPushedOver = FALSE
|
|
IF IS_PED_UNINJURED(mp_Cultist.piPedIdx)
|
|
AND IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF bTomPushedOver = FALSE
|
|
IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), mp_Cultist.piPedIdx)
|
|
AND IS_PED_RAGDOLL(mp_Cultist.piPedIdx)
|
|
KILL_ANY_CONVERSATION()
|
|
DEBUG_PRINT("Player knocked Tom over!")
|
|
bTomPushedOver = TRUE
|
|
ENDIF
|
|
ELSE
|
|
IF IS_PED_UNINJURED(mp_Cultist.piPedIdx)
|
|
IF IS_PED_GETTING_UP(mp_Cultist.piPedIdx)
|
|
OR IS_PED_ON_FOOT(mp_Cultist.piPedIdx)
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
IF CREATE_CONVERSATION(s_conversation_cult, "EPS6AUD", "EPS6_PUSHED", CONV_PRIORITY_HIGH)
|
|
bTomPushedOver = FALSE
|
|
bTomSaidPushedOver = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// State machine to handle Tom wandering around at the start of Eps 6
|
|
PROC DO_DETECTOR_WANDER()
|
|
IF IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
SWITCH Eps6Wander
|
|
CASE WANDER_INIT
|
|
iWanderStage = 0
|
|
vTomCoords[0] = <<-2887.15, 3197.88, 10.17>>
|
|
vTomCoords[1] = <<-2888.92, 3203.76, 10.60>>
|
|
vTomCoords[2] = <<-2895.37, 3199.37, 10.03>>
|
|
REQUEST_ANIM_DICT("rcmepsilonism6")
|
|
IF HAS_ANIM_DICT_LOADED("rcmepsilonism6")
|
|
AND NOT IS_ENTITY_PLAYING_ANIM(mp_Cultist.piPedIdx, "rcmepsilonism6", "cultist_idle_a") // Don't interrupt this anim if it's ongoing
|
|
TASK_PLAY_ANIM(mp_Cultist.piPedIdx, "rcmepsilonism6", "cultist_upperstatic", DEFAULT, DEFAULT, -1, AF_UPPERBODY|AF_SECONDARY|AF_LOOPING)
|
|
Eps6Wander = WANDER_GOTO
|
|
DEBUG_PRINT("Initialised Eps 6 Tom state machine")
|
|
ENDIF
|
|
BREAK
|
|
CASE WANDER_GOTO
|
|
IF NOT IsPedPerformingTask(mp_Cultist.piPedIdx, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(mp_Cultist.piPedIdx, vTomCoords[iWanderStage], PEDMOVEBLENDRATIO_WALK, DEFAULT_TIME_BEFORE_WARP)
|
|
DEBUG_PRINT("Eps 6: Nav tasking Tom...")
|
|
Eps6Wander = WANDER_NOWGOINGTO
|
|
ENDIF
|
|
BREAK
|
|
CASE WANDER_NOWGOINGTO
|
|
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(mp_Cultist.piPedIdx, vTomCoords[iWanderStage]) <= 1.2
|
|
Eps6Wander = WANDER_IDLEANIM
|
|
DEBUG_PRINT("Eps 6: Tom at coord; do idle anim")
|
|
ENDIF
|
|
BREAK
|
|
CASE WANDER_IDLEANIM
|
|
CLEAR_PED_TASKS(mp_Cultist.piPedIdx)
|
|
TASK_PLAY_ANIM(mp_Cultist.piPedIdx, "rcmepsilonism6", "cultist_idle_a", FAST_BLEND_IN, REALLY_SLOW_BLEND_OUT, -1, AF_FORCE_START)
|
|
FORCE_PED_AI_AND_ANIMATION_UPDATE(mp_Cultist.piPedIdx)
|
|
Eps6Wander = WANDER_IDLEFINISH
|
|
DEBUG_PRINT("Eps 6: Done Tom idle anim")
|
|
BREAK
|
|
CASE WANDER_IDLEFINISH
|
|
IF IS_ENTITY_PLAYING_ANIM(mp_Cultist.piPedIdx, "rcmepsilonism6", "cultist_idle_a")
|
|
IF GET_ENTITY_ANIM_CURRENT_TIME(mp_Cultist.piPedIdx, "rcmepsilonism6", "cultist_idle_a") >=0.98
|
|
IF iWanderStage >= 2
|
|
iWanderStage = 0
|
|
ELSE
|
|
iWanderStage++
|
|
ENDIF
|
|
TASK_PLAY_ANIM(mp_Cultist.piPedIdx, "rcmepsilonism6", "cultist_upperstatic", FAST_BLEND_IN, DEFAULT, -1, AF_UPPERBODY|AF_SECONDARY|AF_LOOPING)
|
|
FORCE_PED_AI_AND_ANIMATION_UPDATE(mp_Cultist.piPedIdx)
|
|
Eps6Wander = WANDER_GOTO
|
|
DEBUG_PRINT("Eps 6: Tom idle anim >0.98")
|
|
ENDIF
|
|
ELSE
|
|
IF iWanderStage >= 2
|
|
iWanderStage = 0
|
|
ELSE
|
|
iWanderStage++
|
|
ENDIF
|
|
TASK_PLAY_ANIM(mp_Cultist.piPedIdx, "rcmepsilonism6", "cultist_upperstatic", DEFAULT, DEFAULT, -1, AF_UPPERBODY|AF_SECONDARY|AF_LOOPING)
|
|
Eps6Wander = WANDER_GOTO
|
|
DEBUG_PRINT("Eps 6: Tom idle anim not playing")
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Update the actions of the Cultist during the intro.
|
|
PROC UPDATE_CULTIST()
|
|
|
|
MANAGE_CULTIST_RAGDOLL()
|
|
|
|
IF EpsState = EPS_INIT
|
|
OR EpsState = EPS_INCAR
|
|
IF CULTIST_CHECK_AGGRO()
|
|
CULTIST_AGGRO_FAIL()
|
|
ENDIF
|
|
ELSE
|
|
IF CULTIST_CHECK_PLAYER_DAMAGE()
|
|
CULTIST_AGGRO_FAIL()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SWITCH EpsState
|
|
CASE EPS_INIT
|
|
IF EpsMode = STATE_SETUP
|
|
IF IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
EpsMode = STATE_RUN
|
|
ENDIF
|
|
|
|
ELIF EpsMode = STATE_RUN
|
|
DO_DETECTOR_WANDER()
|
|
SWITCH iCultistRoamStage
|
|
CASE 0
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), mp_Cultist.piPedIdx) < 50
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
OR GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0
|
|
iCultistRoamStage++
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE 1
|
|
IF CREATE_CONVERSATION(s_conversation_cult, "EPS6AUD", "EPS6_CULT", CONV_PRIORITY_HIGH)
|
|
iCultistRoamStage++
|
|
iCultistRoamTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
BREAK
|
|
CASE 2
|
|
IF (GET_GAME_TIMER() - iCultistRoamTimer) > 12000
|
|
iCultistRoamStage = 0
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) AND IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), mp_Cultist.piPedIdx) < 10
|
|
OR GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), mv_plane.VehIdx) < 10
|
|
IF NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-2915.730469,3195.935791,7.803610>>, <<-2897.806885,3171.756348,12.604198>>, 16.000000)
|
|
// This area is the sandy slope to the right of the plane - we want the Cultist to ignore the player if they're in here,
|
|
// because this is an awkward area for him to run to and the scene would look crap if he stood around here
|
|
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
SWITCH_CULTIST(EPS_FOLLOW)
|
|
IntroState = INTRO_SEENMIKE
|
|
ELSE
|
|
SWITCH_CULTIST(EPS_INCAR)
|
|
// if the Cultist goes into this state, he hasn't 'recognised' Michael yet, so don't trigger the rest of the scene
|
|
ENDIF
|
|
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
SWITCH_CULTIST(EPS_FOLLOW)
|
|
IntroState = INTRO_SEENMIKE
|
|
ELSE
|
|
SWITCH_CULTIST(EPS_INCAR)
|
|
// if the Cultist goes into this state, he hasn't 'recognised' Michael yet as he's in his car, so don't trigger the rest of the scene
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NOT IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
SWITCH_CULTIST(EPS_DEAD)
|
|
ENDIF
|
|
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE EPS_INCAR
|
|
IF EpsMode = STATE_SETUP
|
|
IF IS_PED_UNINJURED(mp_Cultist.piPedIdx)
|
|
CLEAR_PED_TASKS(mp_Cultist.piPedIdx)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(mp_Cultist.piPedIdx, PLAYER_PED_ID())
|
|
IF IS_MESSAGE_BEING_DISPLAYED()
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_FACE_TO_FACE_CONVERSATION()
|
|
ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(s_conversation_cult, "EPS6AUD", "EPS6_INCAR", CONV_PRIORITY_MEDIUM)
|
|
ELSE
|
|
CREATE_CONVERSATION(s_conversation_cult, "EPS6AUD", "EPS6_INCAR", CONV_PRIORITY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
|
|
ENDIF
|
|
ELSE
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(s_conversation_cult, "EPS6AUD", "EPS6_INCAR", CONV_PRIORITY_HIGH)
|
|
ELSE
|
|
CREATE_CONVERSATION(s_conversation_cult, "EPS6AUD", "EPS6_INCAR", CONV_PRIORITY_HIGH)
|
|
ENDIF
|
|
ENDIF
|
|
EpsMode = STATE_RUN
|
|
ENDIF
|
|
|
|
ELIF EpsMode = STATE_RUN
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
AND IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
AND IS_PED_UNINJURED(mp_Cultist.piPedIdx)
|
|
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), mp_Cultist.piPedIdx) < 15
|
|
OR GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), mv_plane.VehIdx) < 10
|
|
IF NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-2915.730469,3195.935791,7.803610>>, <<-2897.806885,3171.756348,12.604198>>, 16.000000)
|
|
// This area is the sandy slope to the right of the plane - we want the Cultist to ignore the player if they're in here,
|
|
// because this is an awkward area for him to run to and the scene would look crap if he stood around here
|
|
SWITCH_CULTIST(EPS_FOLLOW)
|
|
IntroState = INTRO_SEENMIKE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE EPS_FOLLOW
|
|
IF EpsMode = STATE_SETUP
|
|
IF IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
CLEAR_PED_TASKS(mp_Cultist.piPedIdx)
|
|
EpsMove = EPSMOVE_CHANGE
|
|
MANAGE_CULTISTS_POSITION()
|
|
STOP_SOUND(iDetectorBeepID)
|
|
STOP_SOUND(iDetectorHumID)
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
|
|
// If the player runs up before the God text disappears, we need to do a bunch of weird shit to make the conversation play in a timely manner
|
|
// (for LB B*1342750)
|
|
// If this happens, we play the first line of EPS6_SPOT only, with no subs, and set bCultistNoSubIntro
|
|
// Then in the run loop, if that's happened, we wait for that single line to finish and the God text to go, and then
|
|
// play the rest of the conversation starting from the second line, WITH subtitles
|
|
// If there's no God text when you run up to the Epsilonist, then we don't bother with any of this and play the conv straight with subs
|
|
IF IS_MESSAGE_BEING_DISPLAYED()
|
|
|
|
PLAY_SINGLE_LINE_FROM_CONVERSATION(s_conversation_cult, "EPS6AUD", "EPS6_SPOT", "EPS6_SPOT_1", CONV_PRIORITY_HIGH, DO_NOT_DISPLAY_SUBTITLES)
|
|
iCultistConvDelayTimer = 0
|
|
bCultistNoSubIntro = TRUE
|
|
DEBUG_PRINT("EPSILONIST: Play single line with subs")
|
|
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), mp_Cultist.piPedIdx, -1)
|
|
TASK_LOOK_AT_ENTITY(mp_Cultist.piPedIdx, PLAYER_PED_ID(), -1)
|
|
REPLAY_RECORD_BACK_FOR_TIME(3.0, 10.0, REPLAY_IMPORTANCE_LOW)
|
|
EpsMode = STATE_RUN
|
|
ELSE
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
// I think this is almost guaranteed to fire as the cultist should be looping "EPS6_CULT"...
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ADD_NON_CRITICAL_STANDARD_CONVERSATION_TO_BUFFER(s_conversation_cult, "EPS6AUD", "EPS6_SPOT", CONV_PRIORITY_HIGH)
|
|
iCultistConvDelayTimer = GET_GAME_TIMER()
|
|
DEBUG_PRINT("EPSILONIST: Play full convo as add to buffer")
|
|
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), mp_Cultist.piPedIdx, -1)
|
|
TASK_LOOK_AT_ENTITY(mp_Cultist.piPedIdx, PLAYER_PED_ID(), -1)
|
|
REPLAY_RECORD_BACK_FOR_TIME(3.0, 10.0, REPLAY_IMPORTANCE_LOW)
|
|
EpsMode = STATE_RUN
|
|
ELSE
|
|
IF CREATE_CONVERSATION(s_conversation_cult, "EPS6AUD", "EPS6_SPOT", CONV_PRIORITY_HIGH)
|
|
iCultistConvDelayTimer = 0
|
|
DEBUG_PRINT("EPSILONIST: Play full convo normally")
|
|
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), mp_Cultist.piPedIdx, -1)
|
|
TASK_LOOK_AT_ENTITY(mp_Cultist.piPedIdx, PLAYER_PED_ID(), -1)
|
|
REPLAY_RECORD_BACK_FOR_TIME(3.0, 10.0, REPLAY_IMPORTANCE_LOW)
|
|
EpsMode = STATE_RUN
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELSE
|
|
SWITCH_CULTIST(EPS_DEAD)
|
|
ENDIF
|
|
|
|
ELIF EpsMode = STATE_RUN
|
|
IF NOT IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
SWITCH_CULTIST(EPS_DEAD)
|
|
ENDIF
|
|
|
|
MANAGE_CULTISTS_POSITION()
|
|
|
|
IF DID_PLAYER_DAMAGE_PLANE()
|
|
IF CREATE_CONVERSATION(s_conversation_cult, "EPS6AUD", "EPS6_SHPLNE", CONV_PRIORITY_HIGH)
|
|
bCultistAimConv = TRUE // So we don't get the normal "you aimed at me" conv
|
|
SWITCH_CULTIST(EPS_HANDSUP)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_PLAYER_VISIBLY_TARGETTING_PED(mp_Cultist.piPedIdx)
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
SWITCH_CULTIST(EPS_HANDSUP)
|
|
ENDIF
|
|
|
|
// See above - handles firing "EPS6_SPOT" again if we played the first line with no subs
|
|
IF bCultistNoSubIntro = TRUE
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF NOT bTomSaidPushedOver
|
|
IF CREATE_CONVERSATION_FROM_SPECIFIC_LINE(s_conversation_cult, "EPS6AUD", "EPS6_SPOT", "EPS6_SPOT_3", CONV_PRIORITY_HIGH)
|
|
bCultistNoSubIntro = FALSE
|
|
DEBUG_PRINT("EPSILONIST: Play rest of EPS6_SPOT")
|
|
ENDIF
|
|
ELSE
|
|
bCultistNoSubIntro = FALSE // Just skip this if we've pushed Tom over
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
|
|
IF (GET_GAME_TIMER() - iCultistConvDelayTimer) > 1000
|
|
OR iCultistConvDelayTimer = 0
|
|
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
DEBUG_PRINT("No conversation is ongoing at all...")
|
|
ELSE
|
|
DEBUG_PRINT("A conversation is playing!")
|
|
ENDIF
|
|
|
|
// Do actions while EPS6_SPOT is playing
|
|
IF IS_THIS_CONVERSATION_ROOT_PLAYING("EPS6_SPOT")
|
|
DEBUG_PRINT("EPS6_SPOT is playing...")
|
|
IF GET_CURRENT_SCRIPTED_CONVERSATION_LINE() >= 5
|
|
SAFE_REMOVE_BLIP(mp_Cultist.biPedBlip)
|
|
IF NOT DOES_BLIP_EXIST(mv_plane.biBlipIdx)
|
|
mv_plane.biBlipIdx = CREATE_VEHICLE_BLIP(mv_plane.VehIdx)
|
|
ENDIF
|
|
IF bDoneMusic = FALSE
|
|
TRIGGER_MUSIC_EVENT("EPS6_START")
|
|
bDoneMusic = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Only do the "too far" check after the first line to give the Cultist time to get close to Michael
|
|
IF GET_CURRENT_SCRIPTED_CONVERSATION_LINE() >= 3
|
|
IF GET_DISTANCE_BETWEEN_PEDS(mp_Cultist.piPedIdx, PLAYER_PED_ID()) > 10
|
|
KILL_ANY_CONVERSATION() // Interrupt the convo
|
|
bPlayerGoneTooFar = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
DEBUG_PRINT("EPSILONIST: EPS6_SPOT not playing")
|
|
SAFE_REMOVE_BLIP(mp_Cultist.biPedBlip)
|
|
IF NOT DOES_BLIP_EXIST(mv_plane.biBlipIdx)
|
|
mv_plane.biBlipIdx = CREATE_VEHICLE_BLIP(mv_plane.VehIdx)
|
|
ENDIF
|
|
SWITCH_CULTIST(EPS_SAFE) // Switch him to 'safe' so he walks away if we've got here (pushed Tom over?)
|
|
ENDIF
|
|
ELSE
|
|
DEBUG_PRINT("EPS6_SPOT delay timer...")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Player has gone too far from the plane (as above), so progress like this
|
|
IF bPlayerGoneTooFar
|
|
IF CREATE_CONVERSATION(s_conversation_cult, "EPS6AUD", "EPS6_TOOFAR", CONV_PRIORITY_HIGH)
|
|
SWITCH_CULTIST(EPS_WAIT)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// If the player rushes into the plane or pushes the Epsilonist over, stop the ongoing convo, play a single line and progress
|
|
IF IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
AND IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx, TRUE)
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
DEBUG_PRINT("Kill convo as player getting into plane (1)")
|
|
ENDIF
|
|
WHILE NOT CREATE_CONVERSATION(s_conversation_cult, "EPS6AUD", "EPS6_LEAVE", CONV_PRIORITY_HIGH)
|
|
WAIT(0)
|
|
ENDWHILE
|
|
SWITCH_CULTIST(EPS_SAFE)
|
|
IntroState = INTRO_INPLANE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE EPS_HANDSUP
|
|
IF EpsMode = STATE_SETUP
|
|
DEBUG_PRINT("EPSILONIST: In EPS_HANDSUP")
|
|
IF bCultistAimConv = FALSE
|
|
//IF CREATE_CONVERSATION(s_conversation_cult, "EPS6AUD", "EPS6_AIMING", CONV_PRIORITY_HIGH)
|
|
PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(mp_Cultist.piPedIdx, "AIMED_AT_BY_PLAYER", "TOM", SPEECH_PARAMS_FORCE_FRONTEND)
|
|
IF NOT IsPedPerformingTask(mp_Cultist.piPedIdx, SCRIPT_TASK_HANDS_UP)
|
|
CLEAR_PED_TASKS(mp_Cultist.piPedIdx)
|
|
TASK_HANDS_UP(mp_Cultist.piPedIdx, -1, PLAYER_PED_ID(), -1, HANDS_UP_STRAIGHT_TO_LOOP)
|
|
ENDIF
|
|
iCultistHandsUpTimer = -1
|
|
EpsMode = STATE_RUN
|
|
//ENDIF
|
|
ELSE
|
|
IF NOT IsPedPerformingTask(mp_Cultist.piPedIdx, SCRIPT_TASK_HANDS_UP)
|
|
CLEAR_PED_TASKS(mp_Cultist.piPedIdx)
|
|
TASK_HANDS_UP(mp_Cultist.piPedIdx, -1, PLAYER_PED_ID(), -1, HANDS_UP_STRAIGHT_TO_LOOP)
|
|
ENDIF
|
|
iCultistHandsUpTimer = -1
|
|
EpsMode = STATE_RUN
|
|
ENDIF
|
|
ELIF EpsMode = STATE_RUN
|
|
|
|
IF NOT IS_PLAYER_VISIBLY_TARGETTING_PED(mp_Cultist.piPedIdx)
|
|
IF iCultistHandsUpTimer = -1
|
|
iCultistHandsUpTimer = GET_GAME_TIMER()
|
|
ELSE // Makes the cultist keep his hands up for just over a second after the player puts their gun down
|
|
IF (GET_GAME_TIMER() - iCultistHandsUpTimer) > 1200
|
|
CLEAR_PED_TASKS(mp_Cultist.piPedIdx)
|
|
TASK_LOOK_AT_ENTITY(mp_Cultist.piPedIdx, PLAYER_PED_ID(), -1)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(mp_Cultist.piPedIdx, PLAYER_PED_ID())
|
|
IF bCultistAimConv = FALSE
|
|
IF CREATE_CONVERSATION(s_conversation_cult, "EPS6AUD", "EPS6_LEAVE", CONV_PRIORITY_HIGH)
|
|
bCultistAimConv = TRUE
|
|
SWITCH_CULTIST(EPS_SAFE)
|
|
ENDIF
|
|
ELSE
|
|
SWITCH_CULTIST(EPS_SAFE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
iCultistHandsUpTimer = -1
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE EPS_WAIT
|
|
IF EpsMode = STATE_SETUP
|
|
DEBUG_PRINT("EPSILONIST: In EPS_WAIT")
|
|
TASK_TURN_PED_TO_FACE_ENTITY(mp_Cultist.piPedIdx, PLAYER_PED_ID(), -1)
|
|
EpsMode = STATE_RUN
|
|
ELIF EpsMode = STATE_RUN
|
|
IF bShownGetInPlane = FALSE
|
|
IF NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx, TRUE)
|
|
|
|
REPLAY_RECORD_BACK_FOR_TIME(3.0, 10.0, REPLAY_IMPORTANCE_LOW)
|
|
|
|
PRINT("EPS6_GETIN", DEFAULT_GOD_TEXT_TIME, 1)
|
|
DEBUG_PRINT("Printed EPS6_GETIN from EPS_WAIT")
|
|
bShownGetInPlane = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
IF IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
AND IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx, TRUE)
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
DEBUG_PRINT("Kill convo as player getting into plane (2)")
|
|
ENDIF
|
|
IF CREATE_CONVERSATION(s_conversation_cult, "EPS6AUD", "EPS6_LEAVE", CONV_PRIORITY_HIGH)
|
|
SWITCH_CULTIST(EPS_SAFE)
|
|
IntroState = INTRO_INPLANE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
IF DID_PLAYER_DAMAGE_PLANE()
|
|
IF CREATE_CONVERSATION(s_conversation_cult, "EPS6AUD", "EPS6_SHPLNE", CONV_PRIORITY_HIGH)
|
|
bCultistAimConv = TRUE // No "you aimed at me" conv
|
|
SWITCH_CULTIST(EPS_HANDSUP)
|
|
ENDIF
|
|
ENDIF
|
|
IF IS_PLAYER_VISIBLY_TARGETTING_PED(mp_Cultist.piPedIdx)
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
SWITCH_CULTIST(EPS_HANDSUP)
|
|
ENDIF
|
|
IF NOT IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
SWITCH_CULTIST(EPS_DEAD)
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE EPS_SAFE
|
|
IF EpsMode = STATE_SETUP
|
|
IF IS_PED_UNINJURED(mp_Cultist.piPedIdx)
|
|
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(mp_Cultist.piPedIdx, <<-2884.9338, 3200.1558, 10.7036>>) > 2.0
|
|
// Only do this if the Cultist isn't already at the coords (in case we come back here after aiming at him)
|
|
CLEAR_PED_TASKS(mp_Cultist.piPedIdx)
|
|
TASK_CLEAR_LOOK_AT(mp_Cultist.piPedIdx)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), -1)
|
|
TASK_PLAY_ANIM(NULL, "gestures@m@standing@casual", "gesture_bye_soft")
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, <<-2884.9338, 3200.1558, 10.7036>>, PEDMOVE_WALK, DEFAULT_TIME_BEFORE_WARP)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(NULL, PLAYER_PED_ID(), -1)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(mp_Cultist.piPedIdx, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
EpsMode = STATE_RUN
|
|
ENDIF
|
|
IF NOT IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
SWITCH_CULTIST(EPS_DEAD)
|
|
ENDIF
|
|
ELIF EpsMode = STATE_RUN
|
|
// IF missionStage = MS_FLIGHT
|
|
// SWITCH_CULTIST(EPS_WAIT)
|
|
// ENDIF
|
|
IF missionStage = MS_INIT
|
|
IF bShownGetInPlane = FALSE
|
|
IF NOT IS_THIS_CONVERSATION_ROOT_PLAYING("EPS6_SPOT")
|
|
AND NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx, TRUE)
|
|
AND NOT IS_PED_GETTING_INTO_A_VEHICLE(PLAYER_PED_ID())
|
|
PRINT("EPS6_GETIN", DEFAULT_GOD_TEXT_TIME, 1)
|
|
DEBUG_PRINT("Printed EPS6_GETIN from EPS_SAFE")
|
|
bShownGetInPlane = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
IF DID_PLAYER_DAMAGE_PLANE()
|
|
IF CREATE_CONVERSATION(s_conversation_cult, "EPS6AUD", "EPS6_SHPLNE", CONV_PRIORITY_HIGH)
|
|
bCultistAimConv = TRUE // No "you aimed at me" conv
|
|
SWITCH_CULTIST(EPS_HANDSUP)
|
|
ENDIF
|
|
ENDIF
|
|
IF IS_PLAYER_VISIBLY_TARGETTING_PED(mp_Cultist.piPedIdx)
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
SWITCH_CULTIST(EPS_HANDSUP)
|
|
ENDIF
|
|
IF NOT IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
SWITCH_CULTIST(EPS_DEAD)
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE EPS_FLEEING
|
|
IF EpsMode = STATE_SETUP
|
|
MAKE_CULTIST_FLEE()
|
|
IF NOT DOES_BLIP_EXIST(mv_plane.biBlipIdx)
|
|
mv_plane.biBlipIdx = CREATE_VEHICLE_BLIP(mv_plane.VehIdx)
|
|
ENDIF
|
|
EpsMode = STATE_RUN
|
|
ELIF EpsMode = STATE_RUN
|
|
IF NOT IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
SWITCH_CULTIST(EPS_DEAD)
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE EPS_DEAD
|
|
IF EpsMode = STATE_SETUP
|
|
DEBUG_PRINT("EPSILONIST: Dead!?")
|
|
SAFE_REMOVE_BLIP(mp_Cultist.biPedBlip)
|
|
EpsMode = STATE_RUN
|
|
ELIF EpsMode = STATE_RUN
|
|
// Nothing to do!
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
//PURPOSE: The main process to control what happens around the player near the Army base.
|
|
PROC INTRO_SCENE_CONTROLLER()
|
|
|
|
IF missionStage < MS_LANDING
|
|
SWITCH IntroState
|
|
CASE INTRO_INIT
|
|
UPDATE_CULTIST()
|
|
BREAK
|
|
CASE INTRO_SEENMIKE
|
|
UPDATE_CULTIST()
|
|
BREAK
|
|
CASE INTRO_INPLANE
|
|
UPDATE_CULTIST()
|
|
BREAK
|
|
CASE INTRO_INTERRUPTED
|
|
UPDATE_CULTIST()
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
|
|
// Checking a couple of things when we're in the plane
|
|
IF missionStage >= MS_FLIGHT
|
|
VECTOR vTempCheck = <<-2896.33, 3201.92, 10.01>>
|
|
|
|
// If we're flying away in the plane, kill the convo between the Epsilonist and Army peds when we get too far away
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF IS_THIS_CONVERSATION_ROOT_PLAYING("EPS6_ARMY")
|
|
OR IS_THIS_CONVERSATION_ROOT_PLAYING("EPS6_LEAVE")
|
|
OR IS_THIS_CONVERSATION_ROOT_PLAYING("EPS6_SAFE")
|
|
OR IS_THIS_CONVERSATION_ROOT_PLAYING("EPS6_PUSHED")
|
|
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), vTempCheck) > 35
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
DEBUG_PRINT("*** Killing an intro conversation because player is too far away")
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), vTempCheck) > 450
|
|
SAFE_RELEASE_PED(mp_Cultist.piPedIdx)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
//PURPOSE: Handles the initial phone call from Jimmy after you have just stolen back the plane to trigger at the appropriate moment.
|
|
PROC HANDLE_JIMMY_PHONECALL()
|
|
|
|
VECTOR vPlanePos
|
|
|
|
SWITCH CallState
|
|
CASE CALL_WAITING
|
|
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 0
|
|
IF IsPlaneOK()
|
|
vPlanePos = GET_ENTITY_COORDS(mv_plane.VehIdx)
|
|
if vPlanePos.z > 15.0
|
|
DEBUG_PRINT("vPlanePos.z is > 15.0")
|
|
iJimmyCallTimer = GET_GAME_TIMER()
|
|
SAFE_RELEASE_PED(mp_Cultist.piPedIdx, TRUE)
|
|
DEBUG_PRINT("RELEASING CULTIST PED VIA JIMMY PHONECALL")
|
|
//CREATE_ARMY_CONVOY()
|
|
CallState = CALL_BUFFERING
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE CALL_BUFFERING
|
|
IF (GET_GAME_TIMER() - iJimmyCallTimer) > 12000
|
|
CallState = CALL_PLAYING
|
|
ENDIF
|
|
BREAK
|
|
CASE CALL_PLAYING
|
|
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 0
|
|
IF PLAYER_CALL_CHAR_CELLPHONE(s_conversation_flight, CHAR_JIMMY_BOSTON, "EPS6AUD", "EPS6_FLIGHT", CONV_PRIORITY_CELLPHONE)
|
|
SET_MAX_WANTED_LEVEL(5) // It's safe to change the wanted level to normal now
|
|
|
|
REPLAY_RECORD_BACK_FOR_TIME(3.0, 10.0, REPLAY_IMPORTANCE_LOW)
|
|
|
|
CallState = CALL_DONE
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE CALL_DONE
|
|
// Played the call, do nothing
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
//PURPOSE: Handle Jimmy's beckon lines when the player has handled at the air field.
|
|
PROC HANDLE_JIMMY_BECKON_LINES()
|
|
|
|
IF IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), mp_Jimmy.piPedIdx) <= 15
|
|
IF NOT IS_PED_HEADTRACKING_PED(mp_Jimmy.piPedIdx, PLAYER_PED_ID())
|
|
DEBUG_PRINT("Jimmy headlooking")
|
|
TASK_LOOK_AT_ENTITY(mp_Jimmy.piPedIdx, PLAYER_PED_ID(), -1, SLF_WHILE_NOT_IN_FOV|SLF_WIDEST_PITCH_LIMIT|SLF_WIDEST_YAW_LIMIT)
|
|
ENDIF
|
|
ELIF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), mp_Jimmy.piPedIdx) <= 25
|
|
AND IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF NOT IS_PED_HEADTRACKING_PED(mp_Jimmy.piPedIdx, PLAYER_PED_ID())
|
|
DEBUG_PRINT("Jimmy headlooking (during conv)")
|
|
TASK_LOOK_AT_ENTITY(mp_Jimmy.piPedIdx, PLAYER_PED_ID(), -1, SLF_WHILE_NOT_IN_FOV|SLF_WIDEST_PITCH_LIMIT|SLF_WIDEST_YAW_LIMIT)
|
|
ENDIF
|
|
ELSE
|
|
IF IS_PED_HEADTRACKING_PED(mp_Jimmy.piPedIdx, PLAYER_PED_ID())
|
|
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
DEBUG_PRINT("Clear Jimmy headlook")
|
|
TASK_CLEAR_LOOK_AT(mp_Jimmy.piPedIdx)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
IF IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
AND IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), mp_Jimmy.piPedIdx, 25.0)
|
|
IF (GET_GAME_TIMER() - iJimmyBeckonTimer) > 15000
|
|
IF CREATE_CONVERSATION(s_conversation_outro, "EPS6AUD", "EPS6_BECKON", CONV_PRIORITY_HIGH)
|
|
iJimmyBeckonTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Check for the player flying under one of the Raton Canyon River bridges for the stat
|
|
PROC TRACK_UNDER_BRIDGE_STAT()
|
|
IF IsPlaneOK()
|
|
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx)
|
|
if IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-2611.599121,2953.921875,10.794971>>, <<-2698.713135,2367.250000,-0.336048>>, 3.000000) // Long highway bridge by airbase
|
|
OR IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-1506.538086,2717.231201,15.289821>>, <<-1377.952515,2609.015137,0.028772>>, 3.000000) // Bridge to airbase entrance
|
|
OR IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-395.950104,2960.713867,23.473852>>, <<-426.353912,2966.561035,14.004027>>, 3.000000) // Small covered road bridge
|
|
IF NOT bReplayTrackOn
|
|
bReplayTrackOn = TRUE
|
|
ENDIF
|
|
INFORM_STAT_SYSTEM_OF_BOOL_STAT_HAPPENED(EP6_UNDER_BRIDGE)
|
|
ELSE
|
|
// Once the player has hit one of the under-bridge areas, we track the previous 3 seconds once they've exited out of it
|
|
IF bReplayTrackOn = TRUE
|
|
REPLAY_RECORD_BACK_FOR_TIME(3.0)
|
|
bReplayTrackOn = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Check whether the player is 'in the air' by seeing if they're more than 5m above the ground Z of their current coord
|
|
/// RETURNS:
|
|
/// TRUE if they're in the air, FALSE otherwise
|
|
FUNC BOOL IS_PLAYER_IN_AIR()
|
|
|
|
VECTOR vPlayerPos
|
|
FLOAT fReturnZ
|
|
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID())
|
|
GET_GROUND_Z_FOR_3D_COORD(vPlayerPos, fReturnZ)
|
|
IF vPlayerPos.Z > fReturnZ + 5.0 // if the player's Z coord is more than 5m above the ground Z of their coord, we consider them 'in the air'
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
|
|
//PURPOSE: Checks the player's current wanted level - if 0, make sure the flight can process. If >0, make the player lose the cops before trying to land.
|
|
PROC CHECK_FOR_WANTED_LEVEL()
|
|
// If player has a wanted level, tell them to lose the cops before giving them the next objective
|
|
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0
|
|
if not bShownLoseCops
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
PRINT_NOW("EPS6_COPS", DEFAULT_GOD_TEXT_TIME, 1) //Lose the cops.
|
|
bShownLoseCops = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SAFE_REMOVE_BLIP(pcp_LandingGoal.biBlipIdx)
|
|
|
|
ELSE // *** Reset check - clear prints, recreate checkpoints and blips
|
|
IF bShownLoseCops
|
|
CLEAR_PRINTS()
|
|
bShownLoseCops = FALSE
|
|
ENDIF
|
|
IF NOT DOES_BLIP_EXIST(pcp_LandingGoal.biBlipIdx)
|
|
pcp_LandingGoal.biBlipIdx = CREATE_COORD_BLIP(pcp_LandingGoal.vPointPos)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
//PURPOSE: Handle and gradually shrink the mission abandonment range when the player is close to Jimmy
|
|
PROC HANDLE_JIMMY_ABANDONMENT()
|
|
|
|
FLOAT fCurrentDistance
|
|
|
|
// Every frame, grab the distance between the player and Jimmy
|
|
IF IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
AND IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
fCurrentDistance = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(mp_Jimmy.piPedIdx))
|
|
ENDIF
|
|
|
|
// Then incrementally check each distance - the closer we get, the smaller the warning and fail ranges become
|
|
// The AbandonCap incrementally decreases, and prevents larger distances from resetting the warning/fail ranges if we've moved closer to Jimmy
|
|
IF fCurrentDistance < 50
|
|
g_fJimmyWarningRange = 100
|
|
g_fJimmyFailRange = 150
|
|
g_iAbandonCap = 1
|
|
//DEBUG_PRINT("Setting g_iAbandonCap = 1")
|
|
ELIF fCurrentDistance < 100
|
|
IF g_iAbandonCap > 1
|
|
g_fJimmyWarningRange = 150
|
|
g_fJimmyFailRange = 200
|
|
g_iAbandonCap = 2
|
|
//DEBUG_PRINT("Setting g_iAbandonCap = 2")
|
|
ENDIF
|
|
ELIF fCurrentDistance < 150
|
|
IF g_iAbandonCap > 2
|
|
g_fJimmyWarningRange = 200
|
|
g_fJimmyFailRange = 250
|
|
g_iAbandonCap = 3
|
|
//DEBUG_PRINT("Setting g_iAbandonCap = 3")
|
|
ENDIF
|
|
ELIF fCurrentDistance < 200
|
|
IF g_iAbandonCap > 3
|
|
g_fJimmyWarningRange = 250
|
|
g_fJimmyFailRange = 300
|
|
g_iAbandonCap = 4
|
|
//DEBUG_PRINT("Setting g_iAbandonCap = 4")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(mp_Jimmy.piPedIdx)) > g_fJimmyWarningRange)
|
|
// Check to make sure the player hasn't run too far away from Jimmy
|
|
IF NOT bAbandonment
|
|
PRINT_NOW("EPS6_GOBACK", DEFAULT_GOD_TEXT_TIME, 1) // Return to ~b~Jimmy Boston.
|
|
bAbandonment = TRUE // Uh oh, player is >warning range away from Jimmy, are they abandoning the mission?
|
|
ELIF (GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(mp_Jimmy.piPedIdx)) > g_fJimmyFailRange)
|
|
FailedReason = FAILED_LEFT_DROPOFF
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
ELSE
|
|
IF bAbandonment
|
|
bAbandonment = false //Less than warning range away from Jimmy, player isn't abandoning the mission
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
FUNC BOOL DO_MICHAEL_EXIT()
|
|
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Michael")
|
|
FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_IDLE, FALSE, FAUS_CUTSCENE_EXIT)
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), mp_Jimmy.piPedIdx, -1)
|
|
DEBUG_PRINT("Do Michael exit")
|
|
SAFE_TELEPORT_ENTITY(mv_RewardCar.VehIdx, mv_RewardCar.VehPos, mv_RewardCar.Heading, TRUE) // Move the reward car back to the player
|
|
IF IS_VEHICLE_OK(mv_RewardCar.VehIdx)
|
|
SET_VEHICLE_DOORS_LOCKED(mv_RewardCar.VehIdx, VEHICLELOCK_UNLOCKED)
|
|
ENDIF
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
|
|
PROC DO_JIMMY_EXIT()
|
|
|
|
IF IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Jimmy_Boston")
|
|
DEBUG_PRINT("Doing Jimmy exit state")
|
|
IF IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
AND IsPlaneOK()
|
|
SAFE_TELEPORT_ENTITY(mp_Jimmy.piPedIdx, <<1682.13, 3268.65, 39.75>>, 183.3768)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, <<1682.44, 3258.81, 39.81>>, PEDMOVEBLENDRATIO_RUN, DEFAULT_TIME_BEFORE_WARP, 7.5, ENAV_NO_STOPPING)
|
|
TASK_ENTER_VEHICLE(NULL, mv_plane.VehIdx, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(mp_Jimmy.piPedIdx, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
ENDIF
|
|
FORCE_PED_MOTION_STATE(mp_Jimmy.piPedIdx, MS_ON_FOOT_RUN, FALSE, FAUS_CUTSCENE_EXIT)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
PROC DO_PLANE_EXIT()
|
|
|
|
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("ep_plane")
|
|
DEBUG_PRINT("Doing plane exit state")
|
|
If IsPlaneOK()
|
|
SET_ENTITY_COORDS (mv_plane.VehIdx, <<1684.78, 3255.58, 41.78>>)
|
|
SET_ENTITY_HEADING (mv_plane.VehIdx, 284.26)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(mv_plane.VehIdx)
|
|
ELSE
|
|
SAFE_DELETE_VEHICLE(mv_plane.VehIdx)
|
|
mv_plane.VehIdx = CREATE_VEHICLE(mv_plane.VehName, <<1684.78, 3255.58, 41.78>>, 284.26)
|
|
SET_VEHICLE_AS_RESTRICTED(mv_plane.VehIdx, 0)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(mv_plane.VehIdx)
|
|
ENDIF
|
|
IF NOT IS_PLAYBACK_GOING_ON_FOR_VEHICLE(mv_plane.VehIdx)
|
|
IF HAS_VEHICLE_RECORDING_BEEN_LOADED(501, "Eps6_Takeoff")
|
|
START_PLAYBACK_RECORDED_VEHICLE(mv_plane.VehIdx, 501, "Eps6_Takeoff")
|
|
FORCE_PLAYBACK_RECORDED_VEHICLE_UPDATE(mv_plane.VehIdx)
|
|
PAUSE_PLAYBACK_RECORDED_VEHICLE(mv_plane.VehIdx)
|
|
DEBUG_PRINT("Started/paused vehicle recording on plane")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Handles creating or removing the streamvol depending on distance from the player to Jimmy
|
|
PROC HANDLE_STREAMVOL_SETUP()
|
|
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), mp_Jimmy.piPedIdx) <= 15
|
|
IF NOT IS_STREAMVOL_ACTIVE()
|
|
IF NOT STREAMVOL_HAS_LOADED(cutsceneStreamvol)
|
|
DEBUG_PRINT("Loading streamvol")
|
|
cutsceneStreamvol = STREAMVOL_CREATE_FRUSTUM(<<1684.85, 3276.16, 39.93>>, CONVERT_ROTATION_TO_DIRECTION_VECTOR(<<-2.1719, 0.0000, -78.5672>>), 50, FLAG_MAPDATA)
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF IS_STREAMVOL_ACTIVE()
|
|
DEBUG_PRINT("Removing streamvol")
|
|
STREAMVOL_DELETE(cutsceneStreamvol)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
//PURPOSE: Main mission state process forthe start of the mission.
|
|
PROC m_pInit()
|
|
|
|
SWITCH subState
|
|
|
|
CASE SS_INIT
|
|
|
|
DEBUG_PRINT("*** Doing Init initialisation")
|
|
|
|
IF bHasSkipped = TRUE
|
|
|
|
LoadSkip()
|
|
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
RC_END_Z_SKIP()
|
|
ENDIF
|
|
|
|
bHasSkipped = FALSE
|
|
|
|
ENDIF
|
|
|
|
REQUEST_ANIM_DICT("rcmepsilonism6")
|
|
REQUEST_ANIM_DICT("gestures@m@standing@casual")
|
|
|
|
WHILE NOT HAS_ANIM_DICT_LOADED("rcmepsilonism6")
|
|
OR NOT HAS_ANIM_DICT_LOADED("gestures@m@standing@casual")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_cult, ENUM_TO_INT(CHAR_MICHAEL), PLAYER_PED_ID(), "MICHAEL")
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(mp_Cultist.piPedIdx)
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_cult, 4, mp_Cultist.piPedIdx, "TOM", TRUE)
|
|
STOP_PED_SPEAKING(mp_Cultist.piPedIdx, TRUE)
|
|
// SET_PED_LEG_IK_MODE(mp_Cultist.piPedIdx, LEG_IK_PARTIAL)
|
|
SET_PED_DIES_WHEN_INJURED(mp_Cultist.piPedIdx, TRUE)
|
|
SET_PED_CAN_BE_TARGETTED(mp_Cultist.piPedIdx, FALSE)
|
|
SET_PED_CONFIG_FLAG(mp_Cultist.piPedIdx,PCF_DontEnterVehiclesInPlayersGroup, TRUE)
|
|
SET_PED_CONFIG_FLAG(mp_Cultist.piPedIdx, PCF_UseKinematicModeWhenStationary, TRUE)
|
|
// SET_PED_CAN_RAGDOLL(mp_Cultist.piPedIdx, FALSE)
|
|
SET_PED_CAN_SWITCH_WEAPON(mp_Cultist.piPedIdx, FALSE)
|
|
// Play hum sound
|
|
iDetectorHumID = GET_SOUND_ID()
|
|
iDetectorBeepID = GET_SOUND_ID()
|
|
PLAY_SOUND_FROM_ENTITY(iDetectorHumID, "DEVICE", GET_CURRENT_PED_WEAPON_ENTITY_INDEX(mp_Cultist.piPedIdx), "EPSILONISM_04_SOUNDSET")
|
|
PLAY_SOUND_FROM_ENTITY(iDetectorBeepID, "IDLE_BEEP_NPC", GET_CURRENT_PED_WEAPON_ENTITY_INDEX(mp_Cultist.piPedIdx), "EPSILONISM_04_SOUNDSET")
|
|
ENDIF
|
|
|
|
IF NOT DOES_BLIP_EXIST(mp_Cultist.biPedBlip)
|
|
mp_Cultist.biPedBlip = CREATE_PED_BLIP(mp_Cultist.piPedIdx, TRUE, TRUE)
|
|
ENDIF
|
|
|
|
//CREATE_BOAT()
|
|
|
|
IF IsPlaneOK()
|
|
DEBUG_PRINTINT("*** Plane 'entity' health: ", GET_ENTITY_HEALTH(mv_plane.VehIdx))
|
|
DEBUG_PRINTFLOAT("*** Plane engine health: ", GET_VEHICLE_ENGINE_HEALTH(mv_plane.VehIdx))
|
|
DEBUG_PRINTFLOAT("*** Plane petrol tank health: ", GET_VEHICLE_PETROL_TANK_HEALTH(mv_plane.VehIdx))
|
|
ENDIF
|
|
|
|
IF Is_Replay_In_Progress()
|
|
IF IS_REPLAY_BEING_SET_UP()
|
|
END_REPLAY_SETUP()
|
|
ENDIF
|
|
RC_END_Z_SKIP()
|
|
ENDIF
|
|
|
|
REPLAY_RECORD_BACK_FOR_TIME(0.0, 15.0, REPLAY_IMPORTANCE_LOW)
|
|
|
|
DEBUG_PRINT("*** Epsilon 6 initialised, now running")
|
|
|
|
bTomSaidPushedOver = FALSE
|
|
bPlayerGoneTooFar = FALSE
|
|
bAbandonment = FALSE // Reset abandonment check
|
|
iCultistRoamStage = 0
|
|
|
|
PRINT_NOW("EPS6_01", DEFAULT_GOD_TEXT_TIME, 1) //Meet the ~b~Epsilonist.
|
|
|
|
iCultistRoamTimer = GET_GAME_TIMER()
|
|
|
|
DEBUG_PRINT("*** Going into Init running state")
|
|
|
|
subState = SS_RUNNING
|
|
BREAK
|
|
|
|
CASE SS_RUNNING
|
|
|
|
IF DID_PLAYER_PLACE_STICKY_BOMB_ON_PLANE()
|
|
STICKY_BOMB_FAIL()
|
|
ENDIF
|
|
|
|
INTRO_SCENE_CONTROLLER()
|
|
|
|
IF NOT IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
// Plane has been destroyed somehow, fail the mission
|
|
DEBUG_PRINT("*** FAILED: Plane destroyed")
|
|
FailedReason = FAILED_DESTROYED
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ELSE // Do abandonment checks
|
|
|
|
IF (GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(mv_plane.VehIdx)) > 50)
|
|
// Check to make sure the player hasn't run too far away from the plane
|
|
IF NOT bAbandonment
|
|
IF IS_SCRIPTED_CONVERSATION_ONGOING()
|
|
iPausedConvLn = GET_CURRENT_SCRIPTED_CONVERSATION_LINE()
|
|
tlPausedConvRoot = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT()
|
|
KILL_ANY_CONVERSATION()
|
|
bPausedConv = TRUE
|
|
iPausedConvTimer = GET_GAME_TIMER() - DEFAULT_GOD_TEXT_TIME
|
|
ENDIF
|
|
PRINT_NOW("EPS6_BACKPL", DEFAULT_GOD_TEXT_TIME, 1) //Return to the ~b~plane.
|
|
bAbandonment = TRUE // Uh oh, player is >100m away from the plane, are they abandoning the mission?
|
|
ELSE
|
|
IF (GET_GAME_TIMER() - iPausedConvTimer) > DEFAULT_GOD_TEXT_TIME
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
IF CREATE_CONVERSATION(s_conversation_cult, "EPS6AUD", "EPS6_RUNAWAY", CONV_PRIORITY_HIGH)
|
|
iPausedConvTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(mv_plane.VehIdx)) > 100)
|
|
FailedReason = FAILED_LEFT_PLANE
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ELSE
|
|
IF bAbandonment
|
|
IF bPausedConv
|
|
TEXT_LABEL_23 tlNew
|
|
tlNew += tlPausedConvRoot
|
|
tlNew += "_"
|
|
tlNew += iPausedConvLn
|
|
IF CREATE_CONVERSATION_FROM_SPECIFIC_LINE(s_conversation_cult, "EPS6AUD", tlPausedConvRoot, tlNew, CONV_PRIORITY_HIGH)
|
|
bPausedConv = FALSE
|
|
bAbandonment = false //Less than 100m away from the plane, player isn't abandoning the mission
|
|
ENDIF
|
|
ELSE
|
|
bAbandonment = false //Less than 100m away from the plane, player isn't abandoning the mission
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) AND IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx)
|
|
subState = SS_SHUTDOWN
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE SS_SHUTDOWN
|
|
|
|
DEBUG_PRINT("*** Doing Init cleanup")
|
|
|
|
SAFE_REMOVE_BLIP(mp_Cultist.biPedBlip)
|
|
SAFE_REMOVE_BLIP(mv_plane.biBlipIdx)
|
|
|
|
missionStage = MS_FLIGHT
|
|
subState = SS_INIT
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
//PURPOSE: Main mission state process for when the player has entered and is flying the plane.
|
|
PROC m_pFlight()
|
|
|
|
SWITCH subState
|
|
|
|
CASE SS_INIT
|
|
|
|
DEBUG_PRINT("*** Doing Flight init")
|
|
|
|
IF bHasSkipped = TRUE
|
|
|
|
LoadSkip()
|
|
|
|
RC_END_Z_SKIP()
|
|
|
|
bHasSkipped = FALSE
|
|
|
|
ENDIF
|
|
|
|
SET_ROADS_IN_ANGLED_AREA(<<-36.251339,-465.831512,39.122559>>, <<25.801004,-287.171631,47.758629>>, 59.500000, false, false)
|
|
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_flight, 3, NULL, "JIMMYBOSTON")
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_flight, ENUM_TO_INT(CHAR_MICHAEL), PLAYER_PED_ID(), "MICHAEL")
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_cult, ENUM_TO_INT(CHAR_MICHAEL), PLAYER_PED_ID(), "MICHAEL")
|
|
|
|
// IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
// KILL_ANY_CONVERSATION()
|
|
// ENDIF
|
|
|
|
TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
|
|
|
|
IF IntroState <= INTRO_INIT
|
|
CREATE_CONVERSATION(s_conversation_cult, "EPS6AUD", "EPS6_LEAVE", CONV_PRIORITY_HIGH)
|
|
ENDIF
|
|
|
|
IF IsPlaneOK()
|
|
DEBUG_PRINTINT("*** Plane 'entity' health: ", GET_ENTITY_HEALTH(mv_plane.VehIdx))
|
|
DEBUG_PRINTFLOAT("*** Plane engine health: ", GET_VEHICLE_ENGINE_HEALTH(mv_plane.VehIdx))
|
|
DEBUG_PRINTFLOAT("*** Plane petrol tank health: ", GET_VEHICLE_PETROL_TANK_HEALTH(mv_plane.VehIdx))
|
|
ENDIF
|
|
|
|
IF bDoneMusic = FALSE
|
|
TRIGGER_MUSIC_EVENT("EPS6_START")
|
|
bDoneMusic = TRUE
|
|
ENDIF
|
|
|
|
bAbandonment = FALSE
|
|
CallState = CALL_WAITING
|
|
|
|
DEBUG_PRINT("*** Going into Flight running state")
|
|
|
|
subState = SS_RUNNING
|
|
BREAK
|
|
|
|
CASE SS_RUNNING
|
|
|
|
INTRO_SCENE_CONTROLLER()
|
|
//HANDLE_ARMY_CONVOY() // These aren't created immediately - only when the phonecall is given
|
|
//HANDLE_DUMPING_SCENE() // same as above
|
|
//HANDLE_BOAT()
|
|
TRACK_UNDER_BRIDGE_STAT()
|
|
HANDLE_JIMMY_PHONECALL()
|
|
|
|
IF DID_PLAYER_PLACE_STICKY_BOMB_ON_PLANE()
|
|
STICKY_BOMB_FAIL()
|
|
ENDIF
|
|
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF bShownGoToAirfield = FALSE
|
|
PRINT_NOW("EPS6_02", DEFAULT_GOD_TEXT_TIME, 1) //Deliver the plane to the ~y~airfield.
|
|
bShownGoToAirfield = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IsPlaneOK()
|
|
|
|
if IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx)
|
|
|
|
CHECK_FOR_WANTED_LEVEL()
|
|
|
|
SAFE_REMOVE_BLIP(mv_plane.biBlipIdx)
|
|
|
|
// Keep the military base runway strobe component turned off
|
|
SET_MINIMAP_COMPONENT(MINIMAP_COMPONENT_RUNWAY_4, FALSE)
|
|
|
|
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 0
|
|
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), pcp_LandingGoal.vPointPos, FALSE) < 2300
|
|
subState = SS_SHUTDOWN
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF NOT DOES_BLIP_EXIST(mv_plane.biBlipIdx)
|
|
mv_plane.biBlipIdx = CREATE_VEHICLE_BLIP(mv_plane.VehIdx)
|
|
DEBUG_PRINT("***** GET BACK IN PLANE")
|
|
if not bShownExitVehicle
|
|
PRINT_NOW("EPS6_03", DEFAULT_GOD_TEXT_TIME, 1) //Get back in the ~b~plane.
|
|
bShownExitVehicle = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF bShownLoseCops
|
|
bShownLoseCops = FALSE
|
|
ENDIF
|
|
|
|
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF IS_THIS_CONVERSATION_ROOT_PLAYING("EPS6_ARMY")
|
|
OR IS_THIS_CONVERSATION_ROOT_PLAYING("EPS6_LEAVE")
|
|
OR IS_THIS_CONVERSATION_ROOT_PLAYING("EPS6_SAFE")
|
|
OR IS_THIS_CONVERSATION_ROOT_PLAYING("EPS6_PUSHED")
|
|
OR IS_THIS_CONVERSATION_ROOT_PLAYING("EPS6_FLIGHT")
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SAFE_REMOVE_BLIP(pcp_LandingGoal.biBlipIdx)
|
|
|
|
IF (GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(mv_plane.VehIdx)) > 80)
|
|
// Check to make sure the player hasn't run too far away from the plane
|
|
IF NOT bAbandonment
|
|
PRINT_NOW("EPS6_BACKPL", DEFAULT_GOD_TEXT_TIME, 1) //Return to the ~b~plane.
|
|
bAbandonment = TRUE // Uh oh, player is >80m away from the plane, are they abandoning the mission?
|
|
ELIF (GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(mv_plane.VehIdx)) > 120)
|
|
if IS_PLAYER_IN_AIR()
|
|
bTeleOnFail = TRUE
|
|
ENDIF
|
|
FailedReason = FAILED_LEFT_PLANE
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
ELSE
|
|
IF bAbandonment
|
|
bAbandonment = false //Less than 80m away from the plane, player isn't abandoning the mission
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELSE
|
|
// Something's gone wrong with the plane here, so fail the mission
|
|
FailedReason = FAILED_DESTROYED
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
bTeleOnFail = TRUE
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE SS_SHUTDOWN
|
|
|
|
DEBUG_PRINT("*** Doing Flight cleanup")
|
|
|
|
missionStage = MS_LANDING
|
|
subState = SS_INIT
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
//PURPOSE: main mission state process for when the player is coming in to land at the air field.
|
|
PROC m_pLanding()
|
|
|
|
SWITCH subState
|
|
|
|
CASE SS_INIT
|
|
|
|
DEBUG_PRINT("*** Doing Landing init")
|
|
|
|
REMOVE_ANIM_DICT("gestures@m@standing@casual")
|
|
|
|
|
|
|
|
// If we've used a skip, we need this vehicle recording to keep the plane in the air while the fade-in occurs and everything is loading
|
|
if bHasSkipped
|
|
REQUEST_VEHICLE_RECORDING(500, "Eps6_LandingSkip")
|
|
ENDIF
|
|
|
|
DEBUG_PRINT("Landing resources loaded!")
|
|
|
|
// As above - but we can't IF check a bool in the middle of a WHILE, so we have to do it separately here
|
|
if bHasSkipped
|
|
WHILE NOT HAS_VEHICLE_RECORDING_BEEN_LOADED(500, "Eps6_LandingSkip")
|
|
DEBUG_PRINT("WAITING FOR LANDING SKIP RECORDING")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
DEBUG_PRINT("Landing skip loaded!")
|
|
ENDIF
|
|
|
|
g_iAbandonCap = 5
|
|
|
|
SAFE_RELEASE_PED(mp_Cultist.piPedIdx)
|
|
|
|
bAbandonment = FALSE
|
|
bSetCP = FALSE
|
|
|
|
IF bHasSkipped = TRUE
|
|
|
|
LoadSkip()
|
|
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
RC_END_Z_SKIP()
|
|
ENDIF
|
|
|
|
bHasSkipped = FALSE
|
|
ENDIF
|
|
|
|
// Check around the wrecked bus on the airfield for any ambient vehicles stuck inside and clear them (#709593)
|
|
CLEAR_ANGLED_AREA_OF_VEHICLES(<<1727.441895,3288.314697,39.406002>>, <<1706.909058,3280.668945,45.132561>>, 14.250000)
|
|
|
|
IF Is_Replay_In_Progress()
|
|
IF IS_REPLAY_BEING_SET_UP()
|
|
END_REPLAY_SETUP(mv_plane.VehIdx)
|
|
IF IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
START_PLAYBACK_RECORDED_VEHICLE(mv_plane.VehIdx, 500, "Eps6_LandingSkip")
|
|
ENDIF
|
|
WAIT(750)
|
|
ENDIF
|
|
RC_END_Z_SKIP()
|
|
ENDIF
|
|
|
|
// Double check for the skip handling - just in case we're hanging out in the init here for whatever reason
|
|
HANDLE_SKIP_FLYING_CONTROLS()
|
|
|
|
DEBUG_PRINT("*** Going into Landing running state")
|
|
|
|
subState = SS_RUNNING
|
|
|
|
BREAK
|
|
|
|
CASE SS_RUNNING
|
|
|
|
INTRO_SCENE_CONTROLLER()
|
|
TRACK_UNDER_BRIDGE_STAT()
|
|
//HANDLE_ARMY_CONVOY() // Will release the convoy vehicles when it hits this point
|
|
//HANDLE_DUMPING_SCENE()
|
|
//HANDLE_BOAT()
|
|
|
|
// IF NOT bShownLandAtAirfield
|
|
// CLEAR_PRINTS()
|
|
// PRINT("EPS6_02", DEFAULT_GOD_TEXT_TIME, 1) //Deliver the plane to the ~y~airfield.
|
|
// bShownLandAtAirfield = TRUE
|
|
// ENDIF
|
|
|
|
CHECK_JIMMY_AGGRO()
|
|
|
|
IF DID_PLAYER_PLACE_STICKY_BOMB_ON_PLANE()
|
|
STICKY_BOMB_FAIL()
|
|
ENDIF
|
|
|
|
IF IsPlaneOK()
|
|
|
|
IF bSetCP = FALSE
|
|
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(mv_plane.VehIdx, pcp_LandingGoal.vPointPos) < 1100
|
|
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_LANDING, "Landing stage")
|
|
bSetCP = TRUE
|
|
DEBUG_PRINT("Landing checkpoint set")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF bSpawnJimmy = FALSE
|
|
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(mv_plane.VehIdx, pcp_LandingGoal.vPointPos) < 350
|
|
REQUEST_MODEL(mv_RewardCar.VehName)
|
|
REQUEST_NPC_PED_MODEL(CHAR_JIMMY_BOSTON)
|
|
REQUEST_ANIM_DICT(mp_Jimmy.AnimDict)
|
|
REQUEST_MODEL(p_amb_phone_01)
|
|
DEBUG_PRINT("Requesting Jimmy resources...")
|
|
|
|
IF HAS_MODEL_LOADED(mv_RewardCar.VehName)
|
|
AND HAS_NPC_PED_MODEL_LOADED(CHAR_JIMMY_BOSTON)
|
|
AND HAS_ANIM_DICT_LOADED(mp_Jimmy.AnimDict)
|
|
AND HAS_MODEL_LOADED(p_amb_phone_01)
|
|
SETUP_JIMMY()
|
|
SETUP_CAR()
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_outro, 3, mp_Jimmy.piPedIdx, "JIMMYBOSTON")
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_outro, ENUM_TO_INT(CHAR_MICHAEL), PLAYER_PED_ID(), "MICHAEL")
|
|
bSpawnJimmy = TRUE
|
|
DEBUG_PRINT("Jimmy created")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
if IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx)
|
|
|
|
// Skip handling
|
|
HANDLE_SKIP_FLYING_CONTROLS()
|
|
|
|
CHECK_FOR_WANTED_LEVEL()
|
|
|
|
CHECK_JIMMY_PLANE_FEAR()
|
|
|
|
// Keep the military base runway strobe component turned off - must be called every frame
|
|
SET_MINIMAP_COMPONENT(MINIMAP_COMPONENT_RUNWAY_4, FALSE)
|
|
|
|
// *** Never show the plane blip when we're inside it
|
|
SAFE_REMOVE_BLIP(mv_plane.biBlipIdx)
|
|
|
|
SAFE_REMOVE_BLIP(mp_Jimmy.biPedBlip)
|
|
|
|
// ***********
|
|
// PLANE IN LANDING AREA CHECK
|
|
// ***********
|
|
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 0 // Only progress if the player does not have a wanted level
|
|
IF IS_ENTITY_IN_ANGLED_AREA(mv_plane.VehIdx, vPlaneDetect1, vPlaneDetect2,
|
|
33.250000, FALSE, TRUE, TM_IN_VEHICLE)
|
|
DEBUG_PRINT("Plane detected")
|
|
DEBUG_PRINT("*** Entering Landing cleanup")
|
|
subState = SS_SHUTDOWN
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELSE // *** The player is NOT in the plane and they need to get back in
|
|
|
|
// *** Reblip the plane and keep it blipped
|
|
IF NOT DOES_BLIP_EXIST(mv_plane.biBlipIdx)
|
|
mv_plane.biBlipIdx = CREATE_VEHICLE_BLIP(mv_plane.VehIdx)
|
|
DEBUG_PRINT("***** GET BACK IN PLANE")
|
|
if not bShownExitVehicle
|
|
PRINT_NOW("EPS6_03", 7500, 1) //Get back in the ~b~plane.
|
|
bShownExitVehicle = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// *** If we've shown "Lose the cops" already, we can show it again if the player gets a wanted level while on foot
|
|
IF bShownLoseCops
|
|
bShownLoseCops = FALSE
|
|
ENDIF
|
|
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF IS_THIS_CONVERSATION_ROOT_PLAYING("EPS6_ARMY")
|
|
OR IS_THIS_CONVERSATION_ROOT_PLAYING("EPS6_LEAVE")
|
|
OR IS_THIS_CONVERSATION_ROOT_PLAYING("EPS6_SAFE")
|
|
OR IS_THIS_CONVERSATION_ROOT_PLAYING("EPS6_PUSHED")
|
|
OR IS_THIS_CONVERSATION_ROOT_PLAYING("EPS6_FLIGHT")
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// *** Keep the landing goal blip gone while out of the plane
|
|
SAFE_REMOVE_BLIP(pcp_LandingGoal.biBlipIdx)
|
|
|
|
// *** If you get any more than 120m away from the plane, you fail the mission
|
|
IF (GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(mv_plane.VehIdx)) > 80)
|
|
// Check to make sure the player hasn't run too far away from the plane
|
|
// If the player's left the plane within about 50m of Jimmy, increase the range of abandonment
|
|
// (this is so if they roll it into the area at high speed and bail,
|
|
// the mission won't automatically fail if the plane exits the locate on the other side)
|
|
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(mv_plane.VehIdx, <<1654.72, 3239.21, 39.55>>) >= 50
|
|
IF NOT bAbandonment
|
|
PRINT_NOW("EPS6_BACKPL", DEFAULT_GOD_TEXT_TIME, 1) //Return to the ~b~plane.
|
|
bAbandonment = TRUE // Uh oh, player is >80m away from the plane, are they abandoning the mission?
|
|
ELIF (GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(mv_plane.VehIdx)) > 150)
|
|
if IS_PLAYER_IN_AIR()
|
|
bTeleOnFail = TRUE
|
|
ENDIF
|
|
FailedReason = FAILED_LEFT_PLANE
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
ELSE
|
|
IF NOT bAbandonment
|
|
PRINT_NOW("EPS6_BACKPL", DEFAULT_GOD_TEXT_TIME, 1) //Return to the ~b~plane.
|
|
bAbandonment = TRUE // Uh oh, player is >80m away from the plane, are they abandoning the mission?
|
|
ELIF (GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(mv_plane.VehIdx)) > 250)
|
|
if IS_PLAYER_IN_AIR()
|
|
bTeleOnFail = TRUE
|
|
ENDIF
|
|
FailedReason = FAILED_LEFT_PLANE
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF bAbandonment
|
|
bAbandonment = false //Less than 80m away from the plane, player isn't abandoning the mission
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// ***********
|
|
// PLANE IN LANDING AREA CHECK
|
|
// ***********
|
|
// The player may have bailed from the plane and rolled it into the landing area, so check for this (B*1162916)
|
|
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 0 // Only progress if the player does not have a wanted level
|
|
IF IS_ENTITY_IN_ANGLED_AREA(mv_plane.VehIdx, vPlaneDetect1, vPlaneDetect2,
|
|
33.250000, FALSE, TRUE, TM_IN_VEHICLE)
|
|
DEBUG_PRINT("Plane detected")
|
|
DEBUG_PRINT("*** Entering Landing cleanup")
|
|
subState = SS_SHUTDOWN
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// // *** If the player's in the plane, make Jimmy do his anim - otherwise keep him looking at the player
|
|
// IF IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
// IF IS_PED_IN_ANY_PLANE(PLAYER_PED_ID())
|
|
// if not IS_ENTITY_PLAYING_ANIM(mp_Jimmy.piPedIdx, mp_Jimmy.AnimDict, mp_Jimmy.AnimName)
|
|
// TASK_TURN_PED_TO_FACE_ENTITY(mp_Jimmy.piPedIdx, mv_plane.VehIdx)
|
|
// TASK_PLAY_ANIM(mp_Jimmy.piPedIdx, mp_Jimmy.AnimDict, mp_Jimmy.AnimName, NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY | AF_LOOPING | AF_SECONDARY)
|
|
// ENDIF
|
|
// ELSE
|
|
// if NOT IS_PED_FACING_PED(mp_Jimmy.piPedIdx, PLAYER_PED_ID(), 45)
|
|
// TASK_TURN_PED_TO_FACE_ENTITY(mp_Jimmy.piPedIdx, mv_plane.VehIdx)
|
|
// TASK_STAND_STILL(mp_Jimmy.piPedIdx, -1)
|
|
// ENDIF
|
|
// ENDIF
|
|
// ENDIF
|
|
|
|
CHECK_JIMMY_AGGRO()
|
|
|
|
ENDIF
|
|
ELSE
|
|
// Something's gone wrong with the plane here, so fail the mission
|
|
FailedReason = FAILED_DESTROYED
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
bTeleOnFail = TRUE
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
|
|
IF bSpawnJimmy = TRUE // Don't check this until we've set the checkpoint and spawned Jimmy
|
|
IF NOT IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
FailedReason = FAILED_KILLED_JIMMY
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE SS_SHUTDOWN
|
|
|
|
If IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
IF IS_ENTITY_IN_ANGLED_AREA(mv_plane.VehIdx, vPlaneDetect1, vPlaneDetect2,
|
|
33.250000, FALSE, TRUE, TM_IN_VEHICLE)
|
|
|
|
SAFE_REMOVE_BLIP(mv_plane.biBlipIdx)
|
|
|
|
IF GET_LANDING_GEAR_STATE(mv_plane.VehIdx) = LGS_LOCKED_DOWN
|
|
OR GET_LANDING_GEAR_STATE(mv_plane.VehIdx) = LGS_DEPLOYING
|
|
// Blip Jimmy, remove landing spot blip
|
|
IF NOT DOES_BLIP_EXIST(mp_Jimmy.biPedBlip)
|
|
mp_Jimmy.biPedBlip = CREATE_PED_BLIP(mp_Jimmy.piPedIdx, TRUE, TRUE, BLIPPRIORITY_HIGHEST)
|
|
ENDIF
|
|
SAFE_REMOVE_BLIP(pcp_LandingGoal.biBlipIdx)
|
|
IF bShownLandAtAirfield
|
|
// Only clear prints once, then God Text loop will stop this
|
|
CLEAR_PRINTS()
|
|
ENDIF
|
|
IF NOT bShownGoToJimmy
|
|
REPLAY_RECORD_BACK_FOR_TIME(15.0, 5.0, REPLAY_IMPORTANCE_LOW)
|
|
PRINT_NOW("EPS6_LEAVE", DEFAULT_GOD_TEXT_TIME, 1) // Go to ~b~Jimmy Boston.
|
|
bShownGoToJimmy = TRUE
|
|
bShownLandAtAirfield = FALSE // Set this to FALSE so if the player flies out of the area, it will give them the god text again
|
|
ENDIF
|
|
|
|
IF HAS_PLANE_ALMOST_STOPPED()
|
|
AND NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx)
|
|
DEBUG_PRINT("*** Finishing Landing cleanup")
|
|
DEBUG_PRINTINT("*** Plane 'entity' health: ", GET_ENTITY_HEALTH(mv_plane.VehIdx))
|
|
DEBUG_PRINTFLOAT("*** Plane engine health: ", GET_VEHICLE_ENGINE_HEALTH(mv_plane.VehIdx))
|
|
DEBUG_PRINTFLOAT("*** Plane petrol tank health: ", GET_VEHICLE_PETROL_TANK_HEALTH(mv_plane.VehIdx))
|
|
|
|
IF GET_ENTITY_HEALTH(mv_plane.VehIdx) = 1000
|
|
AND GET_VEHICLE_ENGINE_HEALTH(mv_plane.VehIdx) = 1000.0
|
|
AND GET_VEHICLE_PETROL_TANK_HEALTH(mv_plane.VehIdx) = 1000.0
|
|
INFORM_STAT_SYSTEM_OF_BOOL_STAT_HAPPENED(EP6_PERFECT_LANDING)
|
|
ENDIF
|
|
|
|
SAFE_REMOVE_BLIP(pcp_LandingGoal.biBlipIdx)
|
|
missionStage = MS_SEEJIMMY
|
|
subState = SS_INIT
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
IF GET_LANDING_GEAR_STATE(mv_plane.VehIdx) = LGS_RETRACTING
|
|
OR GET_LANDING_GEAR_STATE(mv_plane.VehIdx) = LGS_LOCKED_UP
|
|
OR GET_LANDING_GEAR_STATE(mv_plane.VehIdx) = LGS_BROKEN
|
|
// The player has fucked up the landing gear on the plane
|
|
DEBUG_PRINT("In the landing area and landing gear is retracting, locked up or broken")
|
|
FailedReason = FAILED_DESTROYED
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
|
|
ELSE
|
|
DEBUG_PRINT("*** Plane out of delivery area, reverting back to Landing running state")
|
|
SET_VEHICLE_ENGINE_ON(mv_plane.VehIdx, TRUE, FALSE)
|
|
SET_VEHICLE_DOORS_LOCKED(mv_plane.VehIdx, VEHICLELOCK_UNLOCKED)
|
|
subState = SS_RUNNING
|
|
ENDIF
|
|
ELSE
|
|
// The player has fucked up the plane
|
|
DEBUG_PRINT("Plane not OK in landing cleanup")
|
|
FailedReason = FAILED_DESTROYED
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
VECTOR vTempJimmy
|
|
|
|
//PURPOSE: Main mission state process for the player to go and walk to Jimmy by the air field.
|
|
PROC m_pSeeJimmy()
|
|
SWITCH subState
|
|
case SS_INIT
|
|
|
|
DEBUG_PRINT("*** Doing See Jimmy init")
|
|
|
|
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_LANDING, "See Jimmy stage") // Just in case we've skipped straight to here
|
|
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
|
|
REQUEST_NPC_PED_MODEL(CHAR_JIMMY_BOSTON)
|
|
REQUEST_ANIM_DICT(mp_Jimmy.AnimDict)
|
|
REQUEST_MODEL(mv_RewardCar.VehName)
|
|
REQUEST_MODEL(p_amb_phone_01)
|
|
REQUEST_VEHICLE_RECORDING(501, "Eps6_Takeoff")
|
|
|
|
WHILE NOT HAS_NPC_PED_MODEL_LOADED(CHAR_JIMMY_BOSTON)
|
|
OR NOT HAS_ANIM_DICT_LOADED(mp_Jimmy.AnimDict)
|
|
OR NOT HAS_MODEL_LOADED(mv_RewardCar.VehName)
|
|
OR NOT HAS_MODEL_LOADED(p_amb_phone_01)
|
|
OR NOT HAS_VEHICLE_RECORDING_BEEN_LOADED(501, "Eps6_Takeoff")
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
IF bHasSkipped
|
|
|
|
LoadSkip()
|
|
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
RC_END_Z_SKIP()
|
|
ENDIF
|
|
|
|
bHasSkipped = FALSE
|
|
ENDIF
|
|
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_outro, 3, mp_Jimmy.piPedIdx, "JIMMYBOSTON")
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_outro, ENUM_TO_INT(CHAR_MICHAEL), PLAYER_PED_ID(), "MICHAEL")
|
|
|
|
IF IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
TASK_PLAY_ANIM(mp_Jimmy.piPedIdx, mp_Jimmy.AnimDict, mp_Jimmy.AnimName, NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY | AF_LOOPING | AF_SECONDARY) // temp animation
|
|
ENDIF
|
|
|
|
// Wait for the player to be fully out of the plane before showing the God text and progressing the mission
|
|
IF IsPlaneOK()
|
|
SET_VEHICLE_ENGINE_ON(mv_plane.VehIdx, false, false)
|
|
ENDIF
|
|
|
|
// Blip Jimmy, remove landing spot blip
|
|
IF NOT DOES_BLIP_EXIST(mp_Jimmy.biPedBlip)
|
|
mp_Jimmy.biPedBlip = CREATE_PED_BLIP(mp_Jimmy.piPedIdx, TRUE, TRUE, BLIPPRIORITY_HIGHEST)
|
|
ENDIF
|
|
|
|
IF Is_Replay_In_Progress()
|
|
IF IS_REPLAY_BEING_SET_UP()
|
|
END_REPLAY_SETUP()
|
|
ENDIF
|
|
RC_END_Z_SKIP()
|
|
ENDIF
|
|
|
|
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
|
|
DEBUG_PRINT("Trying to set player component variation (init)")
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED_SAFE("Michael", PLAYER_PED_ID())
|
|
ENDIF
|
|
SET_CUTSCENE_PED_PROP_VARIATION("Jimmy_Boston", ANCHOR_EYES, 0)
|
|
ENDIF
|
|
|
|
IF iNavBlockingObj = -1
|
|
iNavBlockingObj = ADD_NAVMESH_BLOCKING_OBJECT(<<1687.9539, 3277.7268, 40.2500>>, <<6,6,6>>, 0)
|
|
DEBUG_PRINT("Navmesh blocking object created")
|
|
ENDIF
|
|
|
|
iJimmyBeckonTimer = GET_GAME_TIMER() - 10000
|
|
|
|
bAbandonment = false // Reset abandonment check
|
|
|
|
//PRINT_NOW("EPS6_GOTO", DEFAULT_GOD_TEXT_TIME, 1)
|
|
|
|
DEBUG_PRINT("*** Going into See Jimmy running state")
|
|
|
|
subState = SS_RUNNING
|
|
BREAK
|
|
|
|
CASE SS_RUNNING
|
|
|
|
IF DID_PLAYER_PLACE_STICKY_BOMB_ON_PLANE()
|
|
STICKY_BOMB_FAIL()
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), mp_Jimmy.piPedIdx) < DEFAULT_CUTSCENE_LOAD_DIST
|
|
IF NOT HAS_CUTSCENE_LOADED()
|
|
REQUEST_CUTSCENE("ep_6_rcm")
|
|
DEBUG_PRINT("Requesting cutscene now")
|
|
ENDIF
|
|
ELIF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), mp_Jimmy.piPedIdx) > DEFAULT_CUTSCENE_UNLOAD_DIST
|
|
IF HAS_CUTSCENE_LOADED()
|
|
DEBUG_PRINT("Player moved away - unloading midtro")
|
|
REMOVE_CUTSCENE()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
|
|
DEBUG_PRINT("Trying to set player component variation (running)")
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED_SAFE("Michael", PLAYER_PED_ID())
|
|
ENDIF
|
|
SET_CUTSCENE_PED_PROP_VARIATION("Jimmy_Boston", ANCHOR_EYES, 0)
|
|
ENDIF
|
|
|
|
//HANDLE_DUMPING_SCENE() // Should release everything when it hits this point
|
|
HANDLE_JIMMY_BECKON_LINES()
|
|
HANDLE_JIMMY_ABANDONMENT()
|
|
HANDLE_STREAMVOL_SETUP()
|
|
|
|
IF IsPlaneOK()
|
|
//SET_VEHICLE_ENGINE_ON(mv_plane.VehIdx, false, false) // Keep plane engine off
|
|
CHECK_JIMMY_AGGRO() // Make sure the mission fails if the player starts shooting at Jimmy
|
|
|
|
// If the player's in a vehicle, play the outro when ~13m away after getting out of the car
|
|
// If on foot, do it ~5m away
|
|
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
// If the player has got back into the plane, punt them back to the Landing stage
|
|
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx)
|
|
subState = SS_SHUTDOWN
|
|
missionStage = MS_LANDING
|
|
ENDIF
|
|
IF IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), mp_Jimmy.piPedIdx, 13)
|
|
IF NOT IS_VEHICLE_STOPPED(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()))
|
|
BRING_VEHICLE_TO_HALT(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), 2, -1)
|
|
ELSE
|
|
TASK_LEAVE_ANY_VEHICLE(PLAYER_PED_ID())
|
|
WHILE IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
WAIT(0)
|
|
ENDWHILE
|
|
subState = SS_SHUTDOWN
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), mp_Jimmy.piPedIdx, 5)
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) AND IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
vTempPlayer = GET_ENTITY_COORDS(PLAYER_PED_ID())
|
|
vTempJimmy = GET_ENTITY_COORDS(mp_Jimmy.piPedIdx)
|
|
IF (vTempPlayer.z - vTempJimmy.z) < 1.5
|
|
AND NOT IS_PED_FALLING(PLAYER_PED_ID())
|
|
AND NOT IS_PED_RAGDOLL(PLAYER_PED_ID())
|
|
subState = SS_SHUTDOWN
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
// Something's gone wrong with the plane here, so fail the mission
|
|
FailedReason = FAILED_DESTROYED
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
BREAK
|
|
CASE SS_SHUTDOWN
|
|
|
|
DEBUG_PRINT("*** Doing See Jimmy cleanup")
|
|
|
|
missionStage = MS_ENDCUTSCENE
|
|
subState = SS_INIT
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
//PURPOSE: Main mission state process for the ending mocap and scripted cutscene.
|
|
PROC m_pEndCutscene()
|
|
|
|
SWITCH subState
|
|
|
|
case SS_INIT
|
|
|
|
DEBUG_PRINT("*** Doing End Cutscene init")
|
|
|
|
if bHasSkipped = TRUE
|
|
|
|
LoadSkip()
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
RC_END_Z_SKIP()
|
|
ENDIF
|
|
bHasSkipped = FALSE
|
|
ENDIF
|
|
|
|
IF NOT DOES_BLIP_EXIST(mp_Jimmy.biPedBlip)
|
|
mp_Jimmy.biPedBlip = CREATE_PED_BLIP(mp_Jimmy.piPedIdx, TRUE, TRUE, BLIPPRIORITY_HIGHEST)
|
|
ENDIF
|
|
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_outro, 3, mp_Jimmy.piPedIdx, "JIMMYBOSTON")
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_outro, ENUM_TO_INT(CHAR_MICHAEL), PLAYER_PED_ID(), "MICHAEL")
|
|
|
|
IF Is_Replay_In_Progress()
|
|
IF IS_REPLAY_BEING_SET_UP()
|
|
END_REPLAY_SETUP()
|
|
REQUEST_CUTSCENE("ep_6_rcm")
|
|
DEBUG_PRINT("Requested cutscene for replay skip")
|
|
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
|
|
SET_CUTSCENE_PED_PROP_VARIATION("Jimmy_Boston", ANCHOR_EYES, 0)
|
|
ENDIF
|
|
WHILE NOT HAS_CUTSCENE_LOADED()
|
|
DEBUG_PRINT("Waiting for cutscene to load in replay skip...")
|
|
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
|
|
SET_CUTSCENE_PED_PROP_VARIATION("Jimmy_Boston", ANCHOR_EYES, 0)
|
|
ENDIF
|
|
WAIT(0)
|
|
ENDWHILE
|
|
RC_END_Z_SKIP(FALSE, FALSE, FALSE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF RC_IS_CUTSCENE_OK_TO_START()
|
|
|
|
SET_ROADS_IN_ANGLED_AREA(<<1775.157349,3373.424805,37.246861>>, <<1893.735107,3203.022217,48.487232>>, 96.5, FALSE, FALSE)
|
|
|
|
SAFE_REMOVE_BLIP(mv_plane.biBlipIdx) // Just in case
|
|
//SAFE_REMOVE_BLIP(mp_Jimmy.biBlipIdx)
|
|
|
|
If IsPlaneOK()
|
|
SET_ENTITY_COORDS (mv_plane.VehIdx, <<1674.91, 3252.47, 41.69>>)
|
|
SET_ENTITY_HEADING (mv_plane.VehIdx, 284.26)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(mv_plane.VehIdx)
|
|
ELSE
|
|
SAFE_DELETE_VEHICLE(mv_plane.VehIdx)
|
|
mv_plane.VehIdx = CREATE_VEHICLE(mv_plane.VehName, <<1674.91, 3252.47, 41.69>>, 284.26)
|
|
SET_VEHICLE_AS_RESTRICTED(mv_plane.VehIdx, 0)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(mv_plane.VehIdx)
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(mp_Jimmy.piPedIdx)
|
|
REGISTER_ENTITY_FOR_CUTSCENE(mp_Jimmy.piPedIdx, "Jimmy_Boston", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
REGISTER_ENTITY_FOR_CUTSCENE(PLAYER_PED_ID(), "Michael", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(mv_plane.VehIdx)
|
|
REGISTER_ENTITY_FOR_CUTSCENE(mv_plane.VehIdx, "ep_plane", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
|
|
// iCutsceneStage = 0
|
|
|
|
REPLAY_START_EVENT(REPLAY_IMPORTANCE_LOW)
|
|
|
|
TRIGGER_MUSIC_EVENT("EPS6_STOP")
|
|
START_CUTSCENE()
|
|
WAIT(0)
|
|
IF Is_Replay_In_Progress()
|
|
SAFE_FADE_SCREEN_IN_FROM_BLACK(DEFAULT, FALSE)
|
|
ENDIF
|
|
SAFE_DELETE_OBJECT(oiJimmyPhone)
|
|
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA_WITH_SIZE_LIMIT(<<1679.916748,3270.734619,39.344662>>, <<1697.998535,3281.171631,44.149509>>, 7.75,
|
|
<< 1530.8623, 3767.0510, 33.0489 >>, 304.28, GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR())
|
|
RC_START_CUTSCENE_MODE(<< 1525.0846, 3772.6855, 33.5119 >>, TRUE, FALSE, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT)
|
|
|
|
DEBUG_PRINT("*** Going into End Cutscene running state")
|
|
|
|
subState = SS_RUNNING
|
|
|
|
ENDIF
|
|
|
|
CHECK_JIMMY_AGGRO()
|
|
|
|
BREAK
|
|
|
|
CASE SS_RUNNING
|
|
|
|
IF iCutsceneStage = 0
|
|
|
|
//SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
//SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
|
|
// While the mocap is going on, prepare for the scripted cutscene and set this all up
|
|
IF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED_WITH_DELAY()
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
iCutsceneStage = 1
|
|
ENDIF
|
|
|
|
IF CAN_SET_EXIT_STATE_FOR_CAMERA()
|
|
// SAFE_TELEPORT_ENTITY(mv_RewardCar.VehIdx, mv_RewardCar.VehPos, mv_RewardCar.Heading, TRUE) // Move the reward car back to the player
|
|
// IF IS_VEHICLE_OK(mv_RewardCar.VehIdx)
|
|
// SET_VEHICLE_DOORS_LOCKED(mv_RewardCar.VehIdx, VEHICLELOCK_UNLOCKED)
|
|
// ENDIF
|
|
ENDIF
|
|
|
|
IF DO_MICHAEL_EXIT()
|
|
iCutsceneStage = 1
|
|
ENDIF
|
|
|
|
DO_JIMMY_EXIT()
|
|
|
|
DO_PLANE_EXIT()
|
|
|
|
ELIF iCutsceneStage = 1
|
|
|
|
DO_JIMMY_EXIT()
|
|
|
|
DO_MICHAEL_EXIT()
|
|
|
|
DO_PLANE_EXIT()
|
|
|
|
IF WAS_CUTSCENE_SKIPPED()
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
ENDIF
|
|
|
|
IF CAN_SET_EXIT_STATE_FOR_CAMERA()
|
|
REPLAY_STOP_EVENT()
|
|
// SAFE_TELEPORT_ENTITY(mv_RewardCar.VehIdx, mv_RewardCar.VehPos, mv_RewardCar.Heading, TRUE) // Move the reward car back to the player
|
|
// IF IS_VEHICLE_OK(mv_RewardCar.VehIdx)
|
|
// SET_VEHICLE_DOORS_LOCKED(mv_RewardCar.VehIdx, VEHICLELOCK_UNLOCKED)
|
|
// ENDIF
|
|
ENDIF
|
|
|
|
IF NOT IS_CUTSCENE_ACTIVE()
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
subState = SS_SHUTDOWN
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
|
|
CASE SS_SHUTDOWN
|
|
|
|
DEBUG_PRINT("*** Doing End Cutscene cleanup")
|
|
|
|
// SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), <<1629.8502, 3252.1289, 39.8499>>, 106.52, TRUE)
|
|
|
|
// We need to do a teleport here so we can reset the game camera, otherwise it won't work!
|
|
//SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), << 1688.45, 3277.15, 40.08 >>, 131.1749, TRUE)
|
|
|
|
IF IS_VEHICLE_OK(mv_RewardCar.VehIdx)
|
|
SET_VEHICLE_DOORS_LOCKED(mv_plane.VehIdx, VEHICLELOCK_LOCKOUT_PLAYER_ONLY)
|
|
ENDIF
|
|
|
|
SAFE_TELEPORT_ENTITY(mv_plane.VehIdx, <<1684.78, 3255.58, 41.78>>, 284.26)
|
|
|
|
IF IS_STREAMVOL_ACTIVE()
|
|
STREAMVOL_DELETE(cutsceneStreamvol)
|
|
ENDIF
|
|
|
|
SET_ROADS_BACK_TO_ORIGINAL_IN_ANGLED_AREA(<<1775.157349,3373.424805,37.246861>>, <<1893.735107,3203.022217,48.487232>>, 96.5)
|
|
|
|
RC_END_CUTSCENE_MODE()
|
|
|
|
missionStage = MS_WAITFORJIMMY
|
|
subState = SS_INIT
|
|
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Main process to wait for Jimmy to get in the plane and fly away after the mocap
|
|
PROC m_pWaitForJimmy()
|
|
|
|
SWITCH subState
|
|
case SS_INIT
|
|
|
|
DEBUG_PRINT("*** Doing Wait for Jimmy init")
|
|
|
|
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_JIMMY, "Wait For Jimmy stage") // Just in case we've skipped straight to here
|
|
|
|
if bHasSkipped = TRUE
|
|
|
|
LoadSkip()
|
|
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
RC_END_Z_SKIP()
|
|
ENDIF
|
|
bHasSkipped = FALSE
|
|
ENDIF
|
|
|
|
REQUEST_VEHICLE_RECORDING(501, "Eps6_Takeoff")
|
|
|
|
iJimmyFlyStage = 0
|
|
bJimmyGearDone = FALSE
|
|
|
|
IF Is_Replay_In_Progress()
|
|
IF IS_REPLAY_BEING_SET_UP()
|
|
END_REPLAY_SETUP()
|
|
ENDIF
|
|
RC_END_Z_SKIP()
|
|
ENDIF
|
|
|
|
IF IS_VEHICLE_OK(mv_RewardCar.VehIdx)
|
|
SET_VEHICLE_DOORS_LOCKED(mv_RewardCar.VehIdx, VEHICLELOCK_UNLOCKED)
|
|
ENDIF
|
|
|
|
IF iNavBlockingObj != -1
|
|
REMOVE_NAVMESH_BLOCKING_OBJECT(iNavBlockingObj)
|
|
DEBUG_PRINT("Navmesh blocking object removed")
|
|
ENDIF
|
|
|
|
iConvTimer = GET_GAME_TIMER() - 6000
|
|
|
|
DEBUG_PRINT("*** Going into Wait for Jimmy loop")
|
|
|
|
subState = SS_RUNNING
|
|
|
|
BREAK
|
|
|
|
case SS_RUNNING
|
|
|
|
IF DID_PLAYER_PLACE_STICKY_BOMB_ON_PLANE()
|
|
STICKY_BOMB_FAIL()
|
|
ENDIF
|
|
|
|
IF bCompleteShitskip // Skip the wait for Jimmy stage if the player keeps being a dick and shooting at him and causing a shitskip
|
|
subState = SS_SHUTDOWN
|
|
ELSE
|
|
CHECK_JIMMY_AGGRO()
|
|
|
|
IF IsPlaneOK()
|
|
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), mv_plane.VehIdx) > 300
|
|
AND NOT IS_ENTITY_ON_SCREEN(mv_plane.VehIdx)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_PLANE_MISSION(NULL, mv_plane.VehIdx, NULL, NULL, <<3891.4780, 2298.5537, 301.6707>>, MISSION_GOTO, 40, 10, -1, 300, 30)
|
|
TASK_PLANE_MISSION(NULL, mv_plane.VehIdx, NULL, NULL, <<1562.0986, 2167.6770, 329.9366>>, MISSION_GOTO, 40, 10, -1, 300, 100)
|
|
SET_SEQUENCE_TO_REPEAT(seq, REPEAT_FOREVER)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(mp_Jimmy.piPedIdx, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
subState = SS_SHUTDOWN // If the player drives away before Jimmy flies away, end the mission when far enough away
|
|
ENDIF
|
|
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND NOT IS_PED_FLEEING(mp_Jimmy.piPedIdx)
|
|
AND NOT IS_PED_RAGDOLL(mp_Jimmy.piPedIdx)
|
|
AND NOT IS_PED_PRONE(mp_Jimmy.piPedIdx)
|
|
AND NOT IS_PED_INJURED(mp_Jimmy.piPedIdx)
|
|
AND NOT IS_PED_IN_ANY_VEHICLE(mp_Jimmy.piPedIdx)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(mp_Jimmy.piPedIdx, PLAYER_PED_ID()) <= 2.3
|
|
IF (GET_GAME_TIMER() - iConvTimer) > 8000
|
|
IF CREATE_CONVERSATION(s_conversation_outro, "EPS6AUD", "EPS6_FOLLOW", CONV_PRIORITY_MEDIUM)
|
|
iConvTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
switch iJimmyFlyStage
|
|
CASE 0
|
|
IF IS_PED_SITTING_IN_VEHICLE(mp_Jimmy.piPedIdx, mv_plane.VehIdx)
|
|
iJimmyFlyStage++
|
|
ENDIF
|
|
BREAK
|
|
CASE 1
|
|
IF NOT IS_PLAYBACK_GOING_ON_FOR_VEHICLE(mv_plane.VehIdx)
|
|
IF HAS_VEHICLE_RECORDING_BEEN_LOADED(501, "Eps6_Takeoff")
|
|
START_PLAYBACK_RECORDED_VEHICLE(mv_plane.VehIdx, 501, "Eps6_Takeoff")
|
|
FORCE_PLAYBACK_RECORDED_VEHICLE_UPDATE(mv_plane.VehIdx)
|
|
DEBUG_PRINT("Started vehicle recording on plane #2")
|
|
iJimmyFlyStage++
|
|
iJimmyFlyGearTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ELSE
|
|
DEBUG_PRINT("Unpaused vehicle recording on plane")
|
|
UNPAUSE_PLAYBACK_RECORDED_VEHICLE(mv_plane.VehIdx)
|
|
SET_HELI_BLADES_SPEED(mv_plane.VehIdx, 1.0)
|
|
iJimmyFlyStage++
|
|
iJimmyFlyGearTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
BREAK
|
|
CASE 2
|
|
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(mv_plane.VehIdx)
|
|
SET_HELI_BLADES_SPEED(mv_plane.VehIdx, 1.0)
|
|
IF bJimmyGearDone = FALSE
|
|
IF (GET_GAME_TIMER() - iJimmyFlyGearTimer) > 23000
|
|
DEBUG_PRINT(" Retracting Jimmy's landing gear")
|
|
CONTROL_LANDING_GEAR(mv_plane.VehIdx, LGC_RETRACT)
|
|
bJimmyGearDone = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_PLANE_MISSION(NULL, mv_plane.VehIdx, NULL, NULL, <<3891.4780, 2298.5537, 301.6707>>, MISSION_GOTO, 40, 10, -1, 300, 30)
|
|
TASK_PLANE_MISSION(NULL, mv_plane.VehIdx, NULL, NULL, <<1562.0986, 2167.6770, 329.9366>>, MISSION_GOTO, 40, 10, -1, 300, 100)
|
|
SET_SEQUENCE_TO_REPEAT(seq, REPEAT_FOREVER)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(mp_Jimmy.piPedIdx, seq)
|
|
IF IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
SET_VEHICLE_ENGINE_ON(mv_plane.VehIdx, TRUE, TRUE)
|
|
ENDIF
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
iJimmyFlyStage++
|
|
ENDIF
|
|
BREAK
|
|
CASE 3
|
|
//IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), mv_plane.VehIdx) > 300
|
|
//AND NOT IS_ENTITY_ON_SCREEN(mv_plane.VehIdx)
|
|
subState = SS_SHUTDOWN
|
|
//ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ELSE
|
|
// Something's gone wrong with the plane here, so fail the mission
|
|
FailedReason = FAILED_DESTROYED
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), mv_plane.VehIdx)
|
|
bTeleOnFail = TRUE
|
|
ENDIF
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE SS_SHUTDOWN
|
|
|
|
DEBUG_PRINT("*** Doing Wait for Jimmy cleanup")
|
|
|
|
IF NOT bCompleteShitskip
|
|
IF IsPlaneOK()
|
|
IF GET_LANDING_GEAR_STATE(mv_plane.VehIdx) != LGS_LOCKED_UP
|
|
OR GET_LANDING_GEAR_STATE(mv_plane.VehIdx) != LGS_RETRACTING
|
|
DEBUG_PRINT(" Retracting Jimmy's landing gear (cleanup)")
|
|
CONTROL_LANDING_GEAR(mv_plane.VehIdx, LGC_RETRACT)
|
|
ENDIF
|
|
ENDIF
|
|
SAFE_RELEASE_PED(mp_Jimmy.piPedIdx)
|
|
SAFE_RELEASE_VEHICLE(mv_plane.VehIdx)
|
|
ELSE
|
|
SAFE_DELETE_PED(mp_Jimmy.piPedIdx)
|
|
SAFE_DELETE_VEHICLE(mv_plane.VehIdx)
|
|
ENDIF
|
|
|
|
SCRIPT_PASSED()
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
//******************************************
|
|
// Skip functionality
|
|
//******************************************
|
|
|
|
//PURPOSE: Skip back a stage in the mission.
|
|
PROC SkipBack()
|
|
RC_START_Z_SKIP()
|
|
IF IS_CUTSCENE_ACTIVE()
|
|
STOP_CUTSCENE_IMMEDIATELY()
|
|
RC_END_CUTSCENE_MODE()
|
|
ENDIF
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
switch missionStage
|
|
|
|
CASE MS_INIT
|
|
subState = SS_INIT
|
|
BREAK
|
|
|
|
CASE MS_FLIGHT
|
|
|
|
SAFE_REMOVE_BLIP(mv_plane.biBlipIdx)
|
|
|
|
SAFE_RELEASE_PED(mp_Jimmy.piPedIdx)
|
|
|
|
SAFE_DELETE_VEHICLE(mv_RewardCar.VehIdx)
|
|
|
|
missionStage = MS_INIT
|
|
subState = SS_INIT
|
|
BREAK
|
|
|
|
CASE MS_LANDING
|
|
IF IS_VEHICLE_OK(mv_plane.VehIdx)
|
|
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(mv_plane.VehIdx, pcp_LandingGoal.vPointPos) < 1300
|
|
// Fake-skip back to the start of the Landing stage if within 1300m of the landing spot, so the player can attempt the landing again
|
|
subState = SS_INIT
|
|
ELSE
|
|
missionStage = MS_FLIGHT
|
|
subState = SS_INIT
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE MS_SEEJIMMY
|
|
missionStage = MS_LANDING
|
|
subState = SS_INIT
|
|
BREAK
|
|
CASE MS_ENDCUTSCENE
|
|
missionStage = MS_SEEJIMMY
|
|
subState = SS_INIT
|
|
BREAK
|
|
CASE MS_WAITFORJIMMY
|
|
missionStage = MS_ENDCUTSCENE
|
|
subState = SS_INIT
|
|
BREAK
|
|
DEFAULT
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
//PURPOSE: Skip forward a stage in the mission.
|
|
PROC SkipForward()
|
|
RC_START_Z_SKIP()
|
|
IF IS_CUTSCENE_ACTIVE()
|
|
STOP_CUTSCENE_IMMEDIATELY()
|
|
RC_END_CUTSCENE_MODE()
|
|
ENDIF
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
switch missionStage
|
|
CASE MS_INIT
|
|
missionStage = MS_FLIGHT
|
|
subState = SS_INIT
|
|
BREAK
|
|
CASE MS_FLIGHT
|
|
missionStage = MS_LANDING
|
|
subState = SS_INIT
|
|
BREAK
|
|
CASE MS_LANDING
|
|
missionStage = MS_SEEJIMMY
|
|
subState = SS_INIT
|
|
BREAK
|
|
CASE MS_SEEJIMMY
|
|
missionStage = MS_ENDCUTSCENE
|
|
subState = SS_INIT
|
|
BREAK
|
|
CASE MS_ENDCUTSCENE
|
|
missionStage = MS_WAITFORJIMMY
|
|
subState = SS_INIT
|
|
BREAK
|
|
DEFAULT
|
|
RC_END_Z_SKIP()
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
//PURPOSE: Jump directly to a stage in the mission.
|
|
PROC JUMP_TO_STAGE(int iStage)
|
|
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
RC_START_Z_SKIP()
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
bHasSkipped = TRUE
|
|
|
|
SWITCH iStage
|
|
CASE Z_SKIP_INIT
|
|
MissionStage = MS_INIT
|
|
SubState = SS_INIT
|
|
BREAK
|
|
CASE Z_SKIP_FLIGHT
|
|
MissionStage = MS_FLIGHT
|
|
SubState = SS_INIT
|
|
BREAK
|
|
CASE Z_SKIP_LANDING
|
|
MissionStage = MS_LANDING
|
|
SubState = SS_INIT
|
|
BREAK
|
|
CASE Z_SKIP_SEEJIMMY
|
|
MissionStage = MS_SEEJIMMY
|
|
SubState = SS_INIT
|
|
BREAK
|
|
CASE Z_SKIP_OUTRO
|
|
MissionStage = MS_ENDCUTSCENE
|
|
SubState = SS_INIT
|
|
BREAK
|
|
CASE Z_SKIP_WAITJIMMY
|
|
MissionStage = MS_WAITFORJIMMY
|
|
SubState = SS_INIT
|
|
BREAK
|
|
CASE Z_SKIP_COMPLETE
|
|
MissionStage = MS_WAITFORJIMMY
|
|
SubState = SS_INIT
|
|
bCompleteShitskip = TRUE
|
|
BREAK
|
|
DEFAULT
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Check for Forced Pass or Fail
|
|
PROC DEBUG_Check_Debug_Keys()
|
|
#IF IS_DEBUG_BUILD
|
|
IF missionStage <> MS_FAILED
|
|
// Skip forward
|
|
if IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J)
|
|
bHasSkipped = TRUE
|
|
SkipForward()
|
|
ENDIF
|
|
|
|
// Skip back
|
|
if IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P)
|
|
bHasSkipped = TRUE
|
|
SkipBack()
|
|
ENDIF
|
|
|
|
// Mission success
|
|
if IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S)
|
|
bHasSkipped = TRUE
|
|
CLEAR_PRINTS()
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
TRIGGER_MUSIC_EVENT("EPS6_STOP")
|
|
Script_Passed()
|
|
ENDIF
|
|
|
|
// Mission fail
|
|
if IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F)
|
|
bHasSkipped = TRUE
|
|
CLEAR_PRINTS()
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
FailedReason = FAILED_DEFAULT
|
|
subState = SS_INIT
|
|
missionStage = MS_FAILED
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
ENDIF
|
|
|
|
IF LAUNCH_MISSION_STAGE_MENU(s_skip_menu, i_debug_jump_stage)
|
|
JUMP_TO_STAGE(i_debug_jump_stage)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Handle flying buff here
|
|
IF bDebugFlyingBuff
|
|
INT iStatValue
|
|
IF STAT_GET_INT(GET_SP_PLAYER_STAT_ENUM(GET_CURRENT_PLAYER_PED_ENUM(), PS_FLYING_ABILITY), iStatValue)
|
|
IF iStatValue < 70
|
|
STAT_SET_INT(GET_SP_PLAYER_STAT_ENUM(GET_CURRENT_PLAYER_PED_ENUM(), PS_FLYING_ABILITY), 70)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
#ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
//PURPOSE: Main mission failed state while the fade is ongoing.
|
|
PROC m_pFailed()
|
|
|
|
SWITCH subState
|
|
CASE SS_INIT
|
|
DEBUG_PRINT("******************* MISSION FAILED *********************")
|
|
CLEAR_PRINTS()
|
|
CLEAR_HELP()
|
|
|
|
IF FailedReason <> FAILED_HURT_JIMMY
|
|
and FailedReason <> FAILED_SPOOKED_JIMMY
|
|
AND FailedReason <> FAILED_SPOOKED_BUDDY
|
|
AND FailedReason <> FAILED_HURT_BUDDY
|
|
WHILE IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
DEBUG_PRINT("*** Failed() kill conversation")
|
|
KILL_ANY_CONVERSATION()
|
|
WAIT(0)
|
|
ENDWHILE
|
|
ENDIF
|
|
|
|
SET_VEHICLE_GEN_AVAILABLE(VEHGEN_EPSILON6_PLANE, TRUE)
|
|
|
|
SAFE_REMOVE_BLIP(mv_plane.biBlipIdx)
|
|
SAFE_REMOVE_BLIP(mp_Jimmy.biPedBlip)
|
|
SAFE_REMOVE_BLIP(pcp_LandingGoal.biBlipIdx)
|
|
|
|
IF bPlaneTooCloseConv
|
|
// We've failed the mission by getting too close to Jimmy while in the plane, need to set up the reaction dialogue
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_outro, 3, mp_Jimmy.piPedIdx, "JIMMYBOSTON")
|
|
ADD_PED_FOR_DIALOGUE(s_conversation_outro, ENUM_TO_INT(CHAR_MICHAEL), PLAYER_PED_ID(), "MICHAEL")
|
|
ENDIF
|
|
|
|
// set fail string
|
|
STRING FailedString
|
|
SWITCH FailedReason
|
|
CASE FAILED_DESTROYED
|
|
FailedString = "EPS6_FAIL"
|
|
BREAK
|
|
|
|
CASE FAILED_KILLED_JIMMY
|
|
FailedString = "EPS6_DEAD"
|
|
BREAK
|
|
|
|
CASE FAILED_HURT_JIMMY
|
|
FailedString = "EPS6_HURT"
|
|
BREAK
|
|
|
|
CASE FAILED_SPOOKED_JIMMY
|
|
FailedString = "EPS6_SPOOK"
|
|
BREAK
|
|
|
|
CASE FAILED_ATTACKED_JIMMY
|
|
FailedString = "EPS6_ATTACK"
|
|
BREAK
|
|
|
|
CASE FAILED_LEFT_PLANE
|
|
FailedString = "EPS6_04"
|
|
BREAK
|
|
|
|
CASE FAILED_LEFT_DROPOFF
|
|
FailedString = "EPS6_LEFT"
|
|
BREAK
|
|
|
|
CASE FAILED_LEFT_PICKUP
|
|
FailedString = "EPS6_ABAND"
|
|
BREAK
|
|
|
|
CASE FAILED_KILLED_BUDDY
|
|
FailedString = "EPS6_BUDDYDEAD"
|
|
BREAK
|
|
|
|
CASE FAILED_SPOOKED_BUDDY
|
|
FailedString = "EPS6_BUDDYSPOOK"
|
|
BREAK
|
|
|
|
CASE FAILED_HURT_BUDDY
|
|
FailedString = "EPS6_BUDDYHURT"
|
|
BREAK
|
|
|
|
CASE FAILED_STICKYBOMB
|
|
FailedString = "EPS6_STICKYB"
|
|
BREAK
|
|
|
|
DEFAULT
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
IF FailedReason = FAILED_DEFAULT
|
|
Random_Character_Failed()
|
|
ELSE
|
|
Random_Character_Failed_With_Reason(FailedString)
|
|
ENDIF
|
|
|
|
|
|
subState = SS_RUNNING
|
|
BREAK
|
|
|
|
CASE SS_RUNNING
|
|
IF GET_MISSION_FLOW_SAFE_TO_CLEANUP()
|
|
// Call RemovePlayerFromRestrictedVehicle() here if you need to
|
|
|
|
// Do a check here to see if we need to warp the player at all
|
|
// (only set the fail warp locations if we can't leave the player where he was)
|
|
IF bTeleOnFail
|
|
// Only set the player back here (near the army base) if they failed the mission before reaching Jimmy Boston
|
|
MISSION_FLOW_SET_FAIL_WARP_LOCATION(<< -2932.7339, 3241.3037, 9.4520 >>, 228.8328)
|
|
SET_REPLAY_DECLINED_VEHICLE_WARP_LOCATION(<< -2932.7339, 3241.3037, 9.4520 >>, 228.8328)
|
|
ENDIF
|
|
|
|
DeleteEverything()
|
|
|
|
Script_Cleanup() // script_cleanup should terminate the thread
|
|
|
|
ELSE
|
|
// not finished fading out
|
|
// you may want to handle dialogue etc here.
|
|
IF bPlaneTooCloseConv
|
|
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
// ===========================================================================================================
|
|
// Script Loop
|
|
// ===========================================================================================================
|
|
|
|
SCRIPT(g_structRCScriptArgs sRCLauncherDataIn)
|
|
|
|
DEBUG_PRINT("*** Epsilon 6 is now running")
|
|
|
|
sRCLauncherDataLocal = sRCLauncherDataIn
|
|
RC_TakeEntityOwnership(sRCLauncherDataLocal)
|
|
RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE)
|
|
RC_CLEANUP_LAUNCHER()
|
|
|
|
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]")
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
Random_Character_Failed()
|
|
Script_Cleanup()
|
|
ENDIF
|
|
|
|
IF NOT Is_Replay_In_Progress()
|
|
IF NOT IS_CUTSCENE_ACTIVE()
|
|
REQUEST_CUTSCENE("ep_6_rcm")
|
|
DEBUG_PRINT("Requesting cutscene now")
|
|
ENDIF
|
|
ELSE // Set up the initial scene for replays
|
|
IF Get_Replay_Mid_Mission_Stage() = CP_START
|
|
g_bSceneAutoTrigger = TRUE
|
|
eInitialSceneStage = IS_REQUEST_SCENE
|
|
WHILE NOT SetupScene_EPSILON_6(sRCLauncherDataLocal)
|
|
WAIT(0)
|
|
ENDWHILE
|
|
g_bSceneAutoTrigger = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Assign vehicle handle to the one used by this script
|
|
IF IS_VEHICLE_OK(sRCLauncherDataLocal.vehID[0])
|
|
mv_plane.VehIdx = sRCLauncherDataLocal.vehID[0]
|
|
SET_VEHICLE_AS_RESTRICTED(mv_plane.VehIdx, 0)
|
|
SET_VEHICLE_HAS_STRONG_AXLES(mv_plane.VehIdx, TRUE)
|
|
SET_VEHICLE_DOORS_LOCKED(mv_plane.VehIdx, VEHICLELOCK_UNLOCKED)
|
|
ENDIF
|
|
|
|
IF IS_PED_UNINJURED(PLAYER_PED_ID())
|
|
relGroupPlayer = GET_PED_RELATIONSHIP_GROUP_HASH(PLAYER_PED_ID())
|
|
ENDIF
|
|
|
|
// Assign initial scene peds to script handles
|
|
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[0]) // The player may have killed the Cultist by this point, so do this check
|
|
mp_Cultist.piPedIdx = sRCLauncherDataLocal.pedID[0]
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(mp_Cultist.piPedIdx, TRUE)
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(mp_Cultist.piPedIdx, relGroupPlayer)
|
|
SET_PED_CONFIG_FLAG(mp_Cultist.piPedIdx, PCF_KeepRelationshipGroupAfterCleanUp, TRUE)
|
|
ENDIF
|
|
|
|
LOAD_GLOBAL_RESOURCES()
|
|
|
|
DEBUG_PRINT("*** Epsilon 6 is now in loop")
|
|
|
|
IF Is_Replay_In_Progress()
|
|
DEBUG_PRINT("*** Replay detected! Skipping to appropriate stage!")
|
|
|
|
INT iReplayStage = Get_Replay_Mid_Mission_Stage()
|
|
|
|
IF g_bShitskipAccepted = TRUE
|
|
iReplayStage++ // player is skipping this stage
|
|
ENDIF
|
|
|
|
SWITCH iReplayStage
|
|
CASE CP_START
|
|
START_REPLAY_SETUP(<<-2907.2898, 3215.9097, 9.8660>>, 215.2019)
|
|
// Do nothing - mission will start as normal
|
|
BREAK
|
|
CASE CP_LANDING
|
|
START_REPLAY_SETUP(<<376.0205, 2886.5520, 171.3085>>, -132.35)
|
|
JUMP_TO_STAGE(Z_SKIP_LANDING) // Go to MS_LANDING
|
|
BREAK
|
|
CASE CP_OUTRO
|
|
START_REPLAY_SETUP(<<1681.54, 3259.38, 39.77>>, 298.33)
|
|
JUMP_TO_STAGE(Z_SKIP_OUTRO) // Go to MS_OUTRO (if the player screws up the landing 3 times and shitskips it)
|
|
BREAK
|
|
CASE CP_JIMMY
|
|
START_REPLAY_SETUP(<< 1688.45, 3277.15, 40.08 >>, 131.1749)
|
|
JUMP_TO_STAGE(Z_SKIP_WAITJIMMY) // Go to MS_WAITFORJIMMY
|
|
BREAK
|
|
CASE CP_COMPLETE
|
|
START_REPLAY_SETUP(<< 1688.45, 3277.15, 40.08 >>, 131.1749)
|
|
JUMP_TO_STAGE(Z_SKIP_COMPLETE) // Go to MS_WAITFORJIMMY with special bool (shitskip only)
|
|
BREAK
|
|
DEFAULT
|
|
SCRIPT_ASSERT("Replay in progress: Unknown checkpoint selected?")
|
|
BREAK
|
|
ENDSWITCH
|
|
ELSE
|
|
RC_END_Z_SKIP(FALSE)
|
|
ENDIF
|
|
|
|
// Loop within here until the mission passes or fails
|
|
WHILE(TRUE)
|
|
|
|
REPLAY_CHECK_FOR_EVENT_THIS_FRAME("SF_Epsilon6")
|
|
|
|
WAIT(0)
|
|
|
|
UPDATE_MISSION_NAME_DISPLAYING(sRCLauncherDataLocal.sIntroCutscene)
|
|
|
|
// Keep searching for this, as the group has to be loaded in for it to actually disable the group
|
|
IF DOES_SCENARIO_GROUP_EXIST("SANDY_PLANES")
|
|
IF IS_SCENARIO_GROUP_ENABLED("SANDY_PLANES")
|
|
SET_SCENARIO_GROUP_ENABLED("SANDY_PLANES",FALSE)
|
|
DEBUG_PRINT("Disabled Sandy planes")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SWITCH missionStage
|
|
|
|
CASE MS_INIT
|
|
m_pInit()
|
|
BREAK
|
|
|
|
CASE MS_FLIGHT
|
|
m_pFlight()
|
|
BREAK
|
|
|
|
CASE MS_LANDING
|
|
m_pLanding()
|
|
BREAK
|
|
|
|
CASE MS_SEEJIMMY
|
|
m_pSeeJimmy()
|
|
BREAK
|
|
|
|
CASE MS_ENDCUTSCENE
|
|
m_pEndCutscene()
|
|
BREAK
|
|
|
|
CASE MS_WAITFORJIMMY
|
|
m_pWaitForJimmy()
|
|
BREAK
|
|
|
|
CASE MS_FAILED
|
|
m_pFailed()
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
// Check debug completion/failure
|
|
DEBUG_Check_Debug_Keys()
|
|
|
|
ENDWHILE
|
|
|
|
// Script should never reach here. Always terminate with cleanup function.
|
|
ENDSCRIPT
|
|
|