//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