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

17415 lines
556 KiB
Python
Executable File

// _________________________________________________________________________________________
// ___
// ___ Author: Rob Bray
// ___ Date: 09/01/2012
// _________________________________________________________________________________________
// ___
// ___ Finale 1B - Save Michael and Trevor
// ___
// ___ Take out the remaining story enemies at separate locations
// ___
// _________________________________________________________________________________________
//Compile out Title Update changes to header functions.
//Must be before includes.
//CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R.
// ____________________________________ INCLUDES ___________________________________________
USING "rage_builtins.sch"
USING "globals.sch"
USING "commands_misc.sch"
USING "commands_pad.sch"
USING "commands_script.sch"
USING "commands_player.sch"
USING "commands_streaming.sch"
USING "commands_vehicle.sch"
USING "commands_camera.sch"
USING "commands_path.sch"
USING "commands_fire.sch"
USING "commands_object.sch"
USING "commands_graphics.sch"
USING "commands_cutscene.sch"
USING "commands_physics.sch"
USING "script_maths.sch"
USING "script_player.sch"
USING "streamed_scripts.sch"
USING "model_enums.sch"
USING "selector_public.sch"
USING "dialogue_public.sch"
USING "chase_hint_cam.sch" CHASE_HINT_CAM_STRUCT localChaseHintCamStruct
USING "flow_public_core_override.sch"
USING "script_blips.sch"
USING "script_buttons.sch"
USING "script_ped.sch"
USING "select_mission_stage.sch"
USING "replay_public.sch"
USING "cutscene_public.sch"
USING "mission_stat_public.sch"
USING "area_checks.sch"
USING "rappel_public.sch"
USING "clearMissionArea.sch"
USING "CompletionPercentage_public.sch"
USING "locates_public.sch"
USING "building_control_public.sch"
USING "achievement_public.sch"
USING "spline_cam_edit.sch"
USING "commands_recording.sch"
USING "script_misc.sch"
// Enums
ENUM MISSION_INIT_STAGE_ENUM
MISSION_INIT_PRE_INTRO = 0,
MISSION_INIT_REQUEST_INTRO,
MISSION_INIT_WAIT_FOR_INTRO,
MISSION_INIT_PLAY_INTRO,
MISSION_INIT_DONE
ENDENUM
ENUM MISSION_STAGE_ENUM
STAGE_GET_TO_HIT = 0,
STAGE_TREVOR_HIT,
STAGE_MICHAEL_HIT,
STAGE_FRANKLIN_HIT,
STAGE_PICKUP_DEVIN,
STAGE_DEVINS_HOUSE,
STAGE_GET_TO_CLIFF
ENDENUM
ENUM FAIL_REASON_ENUM
FAIL_MICHAEL_DEAD = 0,
FAIL_FRANKLIN_DEAD,
FAIL_TREVOR_DEAD,
FAIL_DEVIN_DEAD,
FAIL_DEVIN_CAR_DESTROYED,
FAIL_DEVIN_CAR_ABANDONED,
FAIL_DEVIN_CAR_STUCK,
FAIL_MICHAEL_CAR_DESTROYED,
FAIL_MICHAEL_CAR_ABANDONED,
FAIL_MICHAEL_CAR_STUCK,
FAIL_TREVOR_CAR_DESTROYED,
FAIL_TREVOR_CAR_ABANDONED,
FAIL_TREVOR_CAR_STUCK,
FAIL_FRANKLIN_BIKE_DESTROYED,
FAIL_FRANKLIN_BIKE_ABANDONED,
FAIL_FRANKLIN_BIKE_STUCK,
FAIL_STEVE_TOO_LONG,
FAIL_STEVE_SPOOKED,
//FAIL_TRIADS_EARLY,
FAIL_WRONG_STEVE,
FAIL_WRONG_STRETCH,
FAIL_WRONG_TRIADS,
FAIL_WRONG_STEVE_DEAD,
FAIL_WRONG_STRETCH_DEAD,
FAIL_WRONG_TRIADS_DEAD,
FAIL_ABANDONED_STEVE,
FAIL_LOST_STRETCH,
FAIL_LOST_CHENG,
FAIL_SPOOKED_DEVIN,
FAIL_NOT_DISPOSED_DEVIN,
FAIL_ABANDONED_DEVIN,
FAIL_POLICE_DEVIN
ENDENUM
ENUM MISSION_FAIL_STATE_ENUM
MISSION_FAIL_STATE_NOT_FAILED = 0,
MISSION_FAIL_STATE_WAIT_FOR_FADE,
MISSION_FAIL_STATE_DONE
ENDENUM
ENUM MOCAP_STREAMING_STAGE_ENUM
MOCAP_STREAMING_STAGE_REQUEST = 0,
MOCAP_STREAMING_STAGE_WAIT,
MOCAP_STREAMING_STAGE_COMPLETE
ENDENUM
ENUM MISSION_HOTSWAP_STAGE_ENUM
MISSION_HOTSWAP_STAGE_SELECT_CHARACTER = 0,
MISSION_HOTSWAP_STAGE_DO_SPLINE_CAM,
MISSION_HOTSWAP_STAGE_DONE
ENDENUM
ENUM HOTSWAP_CAM_ENUM
HOTSWAP_CAM_DEFAULT = 0,
HOTSWAP_CAM_FREE_HOTSWAP_SPLINE
ENDENUM
ENUM MISSION_STREAMING_STAGE_ENUM
MISSION_STREAMING_STAGE_REQUEST = 0,
MISSION_STREAMING_STAGE_WAIT,
MISSION_STREAMING_STAGE_COMPLETE
ENDENUM
ENUM FINALE_MODEL_ENUM
FM_MICHAEL = 0,
FM_FRANKLIN,
FM_TREVOR,
FM_DEVIN,
FM_MICHAEL_CAR,
FM_FRANKLIN_BIKE,
FM_TREVOR_CAR,
FM_DEVIN_CAR,
//FM_STRETCH_CAR,
FM_CHENG_SR,
FM_CHENG_JR,
FM_TRIAD,
FM_TRIAD_BOSS_CAR,
FM_TRIAD_ESCORT_CAR,
FM_GANGSTER_CAR,
FM_STEVE,
FM_CAMERAMAN,
FM_BYSTANDER,
FM_CAMERA,
FM_STRETCH,
FM_GANGSTER,
FM_COP,
FM_MERRYWEATHER,
FM_STRETCH_PHONE,
FM_BASKETBALL,
FM_FERRIS_WHEEL,
FM_GONDOLA,
FM_BOX,
FM_BOX_COLLISION,
FM_TABLET
//FM_BULLDOZER
ENDENUM
ENUM FINALE_VECTOR_ENUM
FINVEC_PLAYER_INIT = 0,
FINVEC_TREVOR_INIT,
FINVEC_MICHAEL_INIT,
FINVEC_FRANKLIN_BIKE_INIT,
FINVEC_TREVOR_CAR_INIT,
FINVEC_MICHAEL_CAR_INIT,
FINVEC_FRANKLIN_BIKE_AT_CLUB,
FINVEC_TREVOR_CAR_AT_PIER,
FINVEC_TREVOR_CAR_AT_PICKUP,
FINVEC_TREVOR_CAR_DRIVE_TO_PICKUP,
FINVEC_MICHAEL_CAR_AT_REC,
FINVEC_DEVIN_CAR_INIT,
FINVEC_TREVOR_AT_PIER,
FINVEC_REC,
FINVEC_PIER,
FINVEC_CLUB,
FINVEC_PICKUP,
FINVEC_CLIFF,
FINVEC_GONDOLA,
FINVEC_DEVIN_INIT,
FINVEC_WHEEL
ENDENUM
ENUM FINALE_SHOT_DETAILS_ENUM
FIN_SHOT_SNIPER = 0,
FIN_SHOT_STEVE,
FIN_SHOT_TRIADS,
FIN_SHOT_STRETCH,
FIN_SHOT_KIDNAP,
FIN_SHOT_KIDNAP2,
FIN_SHOT_CLIFF,
FIN_SHOT_SNIPE,
FIN_SHOT_GANGSTERS,
FIN_SHOT_HOUSE_1,
FIN_SHOT_HOUSE_1B,
FIN_SHOT_HOUSE_2,
FIN_SHOT_HOUSE_2B,
FIN_SHOT_HOUSE_3,
FIN_SHOT_HOUSE_3B,
FIN_SHOT_CLIFFS,
FIN_SHOT_CLIFFSB
ENDENUM
ENUM FINALE_VEHICLE_ENUM
FV_FRANKLIN_CAR = 0,
FV_TREVOR_CAR,
FV_MICHAEL_CAR,
FV_DEVIN_CAR
ENDENUM
ENUM FINALE_ANIM_DICT_ENUM
F_ANIM_DICT_STEVE_FILMING = 0,
F_ANIM_DICT_CAMERAMAN_REACT,
F_ANIM_DICT_STEVE_REACT,
F_ANIM_DICT_STEVE_SPEECH,
F_ANIM_DICT_STEVE_DEATH,
F_ANIM_DICT_WHEEL_BYSTANDERS,
//F_ANIM_DICT_DEVIN_CHECK_OUT_GIRL,
//F_ANIM_DICT_GANGSTERS_BBALL,
F_ANIM_DICT_GANGSTERS,
F_ANIM_DICT_GANGSTERS_PHONE,
F_ANIM_DICT_TRIADS_INTO_CARS,
//F_ANIM_DICT_TRIADS_IDLE,
F_ANIM_DICT_PUSH_CAR,
//F_ANIM_DICT_CLIFF_CAM,
F_ANIM_DICT_REACT_INTRO,
F_ANIM_DICT_REACT_FLEE,
F_ANIM_DICT_DEVIN_AND_BOX
ENDENUM
ENUM FINALE_WEAPON_ENUM
F_WEAPON_SNIPER = 0,
F_WEAPON_PISTOL,
F_WEAPON_TRIAD_SMG,
F_WEAPON_STICKY_BOMB,
F_WEAPON_MERRYWEATHER_RIFLE,
F_WEAPON_MERRYWEATHER_SHOTGUN
ENDENUM
ENUM FINALE_PTFX_ENUM
F_PTFX_SCRIPT = 0
ENDENUM
ENUM FINALE_SFX_ENUM
F_SFX_DEVIN_BANGING = 0,
F_SFX_STEVE_DEATH
ENDENUM
ENUM FINALE_MISC_ASSET_ENUM
F_MISC_ASSET_ALL_PATH_NODES = 0
ENDENUM
ENUM FINALE_CUTSCENE_STAGE_ENUM
F_CUT_STAGE_INIT = 0,
F_CUT_STAGE_RUNNING,
F_CUT_STAGE_CLEANUP
ENDENUM
ENUM FREE_HOTSWAP_STATE_ENUM
FREE_HOTSWAP_STATE_SELECTING = 0,
FREE_HOTSWAP_STATE_IN_PROGRESS
ENDENUM
ENUM CUTSCENE_ENUM
CUTSCENE_STEVE = 0,
CUTSCENE_STRETCH,
CUTSCENE_TRIADS
ENDENUM
ENUM STEVE_ENUM
STEVE_TARGET = 0,
STEVE_CAMERAMAN
ENDENUM
ENUM GANGSTER_ENUM
// stretch's crew
GANGSTER_STRETCH = 0,
GANGSTER_L,
GANGSTER_M,
GANGSTER_R,
// bystanders
GANGSTER_GROUP_CHAT_1,
GANGSTER_GROUP_CHAT_2,
GANGSTER_GROUP_CHAT_3,
GANGSTER_DRINKING_1,
// in cars
GANGSTER_CAR_ROAD_DRIVER,
GANGSTER_CAR_ROAD_PASSENGER
//GANGSTER_CAR_COURT_DRIVER,
//GANGSTER_CAR_CAR_PARK_DRIVER
ENDENUM
ENUM TRIAD_ENUM
TRIAD_CHENG_SR = 0,
TRIAD_CHENG_JR,
TRIAD_BOSSES_DRIVER,
TRIAD_BOSSES_FR,
TRIAD_ESCORT_FRONT_DRIVER,
TRIAD_ESCORT_FRONT_FR,
TRIAD_ESCORT_FRONT_BL,
TRIAD_ESCORT_REAR_DRIVER,
TRIAD_ESCORT_REAR_FR,
TRIAD_ESCORT_REAR_BL
ENDENUM
ENUM MERRYWEATHER_ENUM
MERRYWEATHER_IN_GARAGE = 0,
MERRYWEATHER_DRIVE,
MERRYWEATHER_WALKWAY_1,
MERRYWEATHER_WALKWAY_2,
MERRYWEATHER_OVERLOOK_POOL,
MERRYWEATHER_OVERLOOK_SEA,
MERRYWEATHER_VIEWING_PLATFORM,
MERRYWEATHER_PATROL_COURTYARD
ENDENUM
ENUM TRIAD_VEHICLE_ENUM
TRIAD_VEHICLE_BOSSES = 0,
TRIAD_VEHICLE_ESCORT_FRONT,
TRIAD_VEHICLE_ESCORT_REAR
ENDENUM
ENUM CLIFF_STAGE_ENUM
CLIFF_STAGE_PAN_UP = 0,
CLIFF_STAGE_ARRIVE,
CLIFF_STAGE_PUSH_CAR,
CLIFF_STAGE_AFTERMATH,
CLIFF_STAGE_BEGIN_CREDITS
ENDENUM
ENUM CREATE_HIT_STAGE_ENUM
CREATE_HIT_STAGE_NOT_STARTED = 0,
CREATE_HIT_STAGE_WAITING,
CREATE_HIT_STAGE_DONE
ENDENUM
ENUM CREATE_DEVIN_HOUSE_STAGE_ENUM
CREATE_DEVIN_HOUSE_STAGE_NOT_STARTED = 0,
CREATE_DEVIN_HOUSE_STAGE_WAITING,
CREATE_DEVIN_HOUSE_STAGE_DONE
ENDENUM
ENUM STEVE_STATE_ENUM
STEVE_STATE_FILMING = 0,
STEVE_STATE_END_FILMING,
STEVE_STATE_SPEECH,
STEVE_STATE_IDLE,
STEVE_STATE_REACT,
STEVE_STATE_COWER,
STEVE_STATE_DEAD
ENDENUM
ENUM GANGSTER_STATE_ENUM
GANGSTER_STATE_BBALL = 0,
GANGSTER_STATE_GATHER_AT_PHONE,
GANGSTER_STATE_IDLE,
GANGSTER_STATE_TO_ACTION_FAST,
GANGSTER_STATE_TO_ACTION_SLOW,
GANGSTER_STATE_COMBAT,
GANGSTER_STATE_ENTERING_FLEE,
GANGSTER_STATE_FLEE
ENDENUM
ENUM GANGSTER_AGGRO_ENUM
GANGSTER_AGGRO_NOT_AGGROED = 0,
GANGSTER_AGGRO_DANGER,
GANGSTER_AGGRO_SUSPICION
ENDENUM
ENUM TRIAD_STATE_ENUM
TRIAD_STATE_IDLE = 0,
TRIAD_STATE_SLAP,
TRIAD_STATE_ENTER_CARS,
TRIAD_STATE_DRIVING_LEAVE_CLUB,
TRIAD_STATE_DRIVING_WANDER,
TRIAD_STATE_DRIVING_ESCAPE,
TRIAD_STATE_CHASE_DOWN_PLAYER
//TRIAD_STATE_COMBAT
ENDENUM
ENUM TREVOR_DRIVING_TO_PICKUP_STAGE_ENUM
TREVOR_DRIVING_TO_PICKUP_NOT_STARTED = 0,
TREVOR_DRIVING_TO_PICKUP_WAITING,
TREVOR_DRIVING_TO_PICKUP_DRIVING
ENDENUM
ENUM DRIVE_TO_HIT_STATE_ENUM
DRIVE_TO_HIT_STATE_AI = 0,
DRIVE_TO_HIT_STATE_DONE
ENDENUM
ENUM OCCUPIED_GONDOLA_STATE_ENUM
OCCUPIED_GONDOLA_NOT_CREATED = 0,
OCCUPIED_GONDOLA_UNALERTED,
OCCUPIED_GONDOLA_PRE_REACT,
OCCUPIED_GONDOLA_REACT,
OCCUPIED_GONDOLA_COWERING
ENDENUM
ENUM FINALE_AUDIO_SCENE_ENUM
FINALE_AUDIO_SCENE_FRANKLIN_DRIVE = 0,
FINALE_AUDIO_SCENE_FRANKLIN_ON_FOOT,
FINALE_AUDIO_SCENE_FRANKLIN_KILL_CHENG,
FINALE_AUDIO_SCENE_MICHAEL_DRIVE,
FINALE_AUDIO_SCENE_MICHAEL_ON_FOOT,
FINALE_AUDIO_SCENE_MICHAEL_KILL_STRETCH,
FINALE_AUDIO_SCENE_TREVOR_DRIVE,
FINALE_AUDIO_SCENE_TREVOR_ON_FOOT,
FINALE_AUDIO_SCENE_TREVOR_KILL_STEVE,
FINALE_AUDIO_SCENE_DRIVE_TO_DEVIN,
FINALE_AUDIO_SCENE_DRIVE_TO_OCEAN,
FINALE_AUDIO_SCENE_PUSH_CAR,
// SECOND LOT
FINALE_AUDIO_SCENE_FRANKLIN_ESCAPE_TRIADS,
FINALE_AUDIO_SCENE_MICHAEL_KILL_BALLAS,
FINALE_AUDIO_SCENE_MICHAEL_ENEMY_CAR_ARRIVES,
FINALE_AUDIO_SCENE_TREVOR_FOCUS_ON_WHEEL,
FINALE_AUDIO_SCENE_TREVOR_WATCH_STEVE_CAMERA,
FINALE_AUDIO_SCENE_TREVOR_KILL_CAM,
FINALE_AUDIO_SCENE_DEVINS_HOUSE_OVERVIEW,
FINALE_AUDIO_SCENE_KIDNAP_DEVIN_STEALTH,
FINALE_AUDIO_SCENE_KIDNAP_DEVIN_ALERT
ENDENUM
ENUM DEVIN_BOOT_SPEECH_STATE_ENUM
DEVIN_BOOT_SPEECH_STATE_WAKE_UP = 0,
DEVIN_BOOT_SPEECH_STATE_LET_ME_OUT,
DEVIN_BOOT_SPEECH_STATE_SHUT_UP,
DEVIN_BOOT_SPEECH_STATE_BANTER,
DEVIN_BOOT_SPEECH_STATE_YOU_DEAD,
DEVIN_BOOT_SPEECH_STATE_WAITING,
DEVIN_BOOT_SPEECH_STATE_THREAT,
DEVIN_BOOT_SPEECH_STATE_REPLY
ENDENUM
ENUM CREATE_WHEEL_STATE_ENUM
WHEEL_CREATE_STATE_NOT_STARTED = 0,
WHEEL_CREATE_STATE_WAITING,
WHEEL_CREATE_STATE_DONE
ENDENUM
ENUM MERRYWEATHER_AI_STATE_ENUM
MERRYWEATHER_AI_STATIC = 0,
MERRYWEATHER_AI_PATROL,
MERRYWEATHER_AI_COMBAT
ENDENUM
ENUM MERRYWEATHER_PATROL_STATE_ENUM
MERRYWEATHER_PATROL_WAIT_1,
MERRYWEATHER_PATROL_ROUTE_1,
MERRYWEATHER_PATROL_WAIT_2,
MERRYWEATHER_PATROL_ROUTE_2
ENDENUM
ENUM DEVIN_INTO_BOX_STATE_ENUM
DEVIN_INTO_BOX_STATE_NOT_STARTED = 0,
DEVIN_INTO_BOX_STATE_RUNNING,
DEVIN_INTO_BOX_STATE_DONE
ENDENUM
ENUM HOUSE_OVERVIEW_SHOT_ENUM
HOUSE_OVERVIEW_SHOT_1 = 0,
HOUSE_OVERVIEW_SHOT_2,
HOUSE_OVERVIEW_SHOT_3
ENDENUM
ENUM STEVE_SPEECH_STATE_ENUM
STEVE_SPEECH_STATE_NOT_STARTED = 0,
STEVE_SPEECH_STATE_PREPARING,
STEVE_SPEECH_STATE_DONE
ENDENUM
ENUM DEVIN_HIDE_REASON_ENUM
DEVIN_HIDE_REASON_NONE = 0,
DEVIN_HIDE_REASON_SEE_TREVOR,
DEVIN_HIDE_REASON_SEE_VEHICLE,
DEVIN_HIDE_REASON_EXPLOSION,
DEVIN_HIDE_REASON_GUARD_SHOT
ENDENUM
// Consts
CONST_INT NUMBER_MODEL_REQUEST_SLOTS COUNT_OF(FINALE_MODEL_ENUM)
CONST_INT NUMBER_RECORDING_REQUEST_SLOTS 10
CONST_INT NUMBER_WAYPOINT_REQUEST_SLOTS 18
CONST_INT NUMBER_SPLINE_CAMS 20
CONST_INT NUMBER_GONDOLAS 16
CONST_INT NUMBER_OCCUPIED_GONDOLAS 5
CONST_INT NUMBER_PIER_COPS 2
CONST_INT NUMBER_STRETCH_CREW 4
CONST_INT NUMBER_GANGSTER_VEHICLES 1
CONST_INT STEVE_GONDOLA 3
CONST_INT MIN_RANDOM_SPEECH_TIME 7000
CONST_INT MAX_RANDOM_SPEECH_TIME 12000
CONST_INT BIG_EVENT_TIME_SPACING 10000
CONST_INT MAX_SKIP_MENU_LENGTH 12
CONST_INT SKIP_FADE_WAIT_TIME 200
CONST_FLOAT PLAYER_INIT_ROT -166.9
CONST_FLOAT TREVOR_INIT_ROT 57.04
CONST_FLOAT MICHAEL_INIT_ROT 14.7
CONST_FLOAT FRANKLIN_INIT_ROT2 121.14
CONST_FLOAT TREVOR_INIT_ROT2 57.04
CONST_FLOAT MICHAEL_INIT_ROT2 63.41
CONST_FLOAT FRANKLIN_BIKE_INIT_ROT 144.89
CONST_FLOAT TREVOR_CAR_INIT_ROT 86.1
CONST_FLOAT MICHAEL_CAR_INIT_ROT 88.6
CONST_FLOAT FRANKLIN_BIKE_AT_CLUB_ROT 139.04
CONST_FLOAT TREVOR_CAR_AT_PIER_ROT 226.07
CONST_FLOAT TREVOR_CAR_AT_PICKUP_ROT 71.08
CONST_FLOAT TREVOR_CAR_DRIVE_TO_PICKUP_ROT -24.33
CONST_FLOAT MICHAEL_CAR_AT_REC_ROT 139.38
CONST_FLOAT DEVIN_CAR_INIT_ROT -106.61
CONST_FLOAT TREVOR_AT_PIER_ROT 136.8
CONST_FLOAT POST_SWITCH_SPEED 12.0
CONST_FLOAT CRANE_TARGET_HEIGHT 32.7
CONST_FLOAT CLEAR_POS_RADIUS 3.2
CONST_FLOAT MIN_PUSH_CAR_FORCE 9.0
CONST_FLOAT MAX_PUSH_CAR_FORCE 14.0//20.0
CONST_FLOAT DEFAULT_TRAVEL_DISTANCE 50.0
CONST_FLOAT INIT_WHEEL_ROTATION 0.0
CONST_FLOAT GONDOLA_RADIUS 15.3
CONST_FLOAT GONDOLA_SCENE_ROT 0.0//300.0
CONST_FLOAT CITY_PATHS_MIN_X -4000.0
CONST_FLOAT CITY_PATHS_MIN_Y -4000.0
CONST_FLOAT CITY_PATHS_MAX_X 4000.0
CONST_FLOAT CITY_PATHS_MAX_Y 1400.0//200.0
CONST_FLOAT DRIVE_TO_TARGET_SPEED 18.0
CONST_FLOAT OFF_PISTE_DISTANCE 1000.0
CONST_FLOAT MIN_SWITCH_DIST 400.0
STRUCT FREE_HOTSWAP_DATA
SELECTOR_SLOTS_ENUM swapTarget
FREE_HOTSWAP_STATE_ENUM state
ENDSTRUCT
STRUCT OCCUPIED_GONDOLA
PED_INDEX ped[2]
OCCUPIED_GONDOLA_STATE_ENUM state
ENDSTRUCT
STRUCT MERRYWEATHER_PED
PED_INDEX ped
AI_BLIP_STRUCT blipStruct
BOOL bIsAlerted
BOOL bDoneCharge
MERRYWEATHER_AI_STATE_ENUM aiState
MERRYWEATHER_PATROL_STATE_ENUM patrolState
INT iNextPatrolTime
INT iSeenTime
FLOAT fToChargeTimer
ENDSTRUCT
STRUCT GANGSTER_PED
PED_INDEX ped
AI_BLIP_STRUCT blipStruct
GANGSTER_STATE_ENUM state
BOOL bRegisteredDead
BOOL bToCombat
BOOL bAllowLeaveCar
INT iToCombatTIme
ENDSTRUCT
STRUCT TRIAD_PED
PED_INDEX ped
AI_BLIP_STRUCT blipStruct
BOOL bInCombat
BOOL bRegisteredDead
BOOL bSetHeadshotEntity
INT iDrivebyTime
FLOAT fInStoppedVehicleTime
ENDSTRUCT
// Script-specific variables
MISSION_INIT_STAGE_ENUM missionInitStage = MISSION_INIT_PRE_INTRO
MISSION_FAIL_STATE_ENUM missionFailState = MISSION_FAIL_STATE_NOT_FAILED
MISSION_STAGE_ENUM currentMissionStage
FAIL_REASON_ENUM savedFailReason
MISSION_HOTSWAP_STAGE_ENUM hotswapStage
MISSION_STREAMING_STAGE_ENUM streamingStage
MOCAP_STREAMING_STAGE_ENUM mocapStreamingStage
FINALE_CUTSCENE_STAGE_ENUM cutsceneStage
SELECTOR_PED_STRUCT sSelectorPeds
SELECTOR_CAM_STRUCT sCamDetails
FREE_HOTSWAP_DATA freeHotswapData
CLIFF_STAGE_ENUM cliffStage
CREATE_HIT_STAGE_ENUM createHitStage[3]
CREATE_DEVIN_HOUSE_STAGE_ENUM createDevinHouseStage
STEVE_STATE_ENUM steveState[COUNT_OF(STEVE_ENUM)]
GANGSTER_PED gangsterPed[COUNT_OF(GANGSTER_ENUM)]
TRIAD_PED triadPed[COUNT_OF(TRIAD_ENUM)]
MERRYWEATHER_PED merryweatherPed[COUNT_OF(MERRYWEATHER_ENUM)]
TRIAD_STATE_ENUM triadState
GANGSTER_AGGRO_ENUM gangsterAggro
TREVOR_DRIVING_TO_PICKUP_STAGE_ENUM trevorDrivingToPickupStage
DRIVE_TO_HIT_STATE_ENUM driveToHitState[3]
OCCUPIED_GONDOLA occupiedGondola[NUMBER_OCCUPIED_GONDOLAS]
DEVIN_BOOT_SPEECH_STATE_ENUM devinBootSpeechState
CREATE_WHEEL_STATE_ENUM wheelCreateState
DEVIN_INTO_BOX_STATE_ENUM devinIntoBoxState
HOUSE_OVERVIEW_SHOT_ENUM houseOverviewShot
STEVE_SPEECH_STATE_ENUM steveSpeechState
STREAMVOL_ID trevorVolume
STREAMVOL_ID devinVolume
DEVIN_HIDE_REASON_ENUM devinHideReason
DRIVINGMODE triadDrivingMode = DF_StopForCars|DF_SteerAroundObjects|DF_SteerAroundStationaryCars|DF_StopAtLights|DF_UseShortCutLinks|DF_ChangeLanesAroundObstructions
// Peds
PED_INDEX devinPed
PED_INDEX girlPed
PED_INDEX stevePed[COUNT_OF(STEVE_ENUM)]
PED_INDEX copPed[NUMBER_PIER_COPS]
// Vehicles
VEHICLE_INDEX finaleVehicle[COUNT_OF(FINALE_VEHICLE_ENUM)]
VEHICLE_INDEX triadVehicle[COUNT_OF(TRIAD_VEHICLE_ENUM)]
VEHICLE_INDEX gangsterVehicle[NUMBER_GANGSTER_VEHICLES]
VEHICLE_INDEX hitCutsceneVehicle
// Objects
OBJECT_INDEX gondolaObject[NUMBER_GONDOLAS]
OBJECT_INDEX cameraObject
OBJECT_INDEX stretchPhoneObject
OBJECT_INDEX basketballObject
OBJECT_INDEX wheelObject
OBJECT_INDEX boxObject
OBJECT_INDEX boxCollisionObject
OBJECT_INDEX tabletObject
// Blips
BLIP_INDEX gotoBlip
BLIP_INDEX vehicleBlip
BLIP_INDEX devinBlip
BLIP_INDEX buddyBlip[3]
BLIP_INDEX steveBlip[COUNT_OF(STEVE_ENUM)]
BLIP_INDEX stretchBlip
BLIP_INDEX chengBlip
BLIP_INDEX gangsterVehicleBlip[NUMBER_GANGSTER_VEHICLES]
BLIP_INDEX triadVehicleBlip[COUNT_OF(TRIAD_VEHICLE_ENUM)]
// Cameras
CAMERA_INDEX staticCam
CAMERA_INDEX interpCam
CAMERA_INDEX animCam
CAMERA_INDEX reactionCam
CAMERA_INDEX splineCam[NUMBER_SPLINE_CAMS]
//CAMERA_INDEX timeLapseCam
structTimelapse sTimelapse
// Bools
BOOL bModelRequestTracker[COUNT_OF(FINALE_MODEL_ENUM)]
BOOL bVehicleRecordingRequestTracker[NUMBER_RECORDING_REQUEST_SLOTS]
BOOL bWaypointRequestTracker[NUMBER_WAYPOINT_REQUEST_SLOTS]
BOOL bAnimDictRequestTracker[COUNT_OF(FINALE_ANIM_DICT_ENUM)]
BOOL bWeaponRequestTracker[COUNT_OF(FINALE_WEAPON_ENUM)]
BOOL bPTFXRequestTracker[COUNT_OF(FINALE_PTFX_ENUM)]
BOOL bSFXRequestTracker[COUNT_OF(FINALE_SFX_ENUM)]
BOOL bMiscAssetRequestTracker[COUNT_OF(FINALE_MISC_ASSET_ENUM)]
BOOL bThoroughCleanup
BOOL bForcePassOnShitskip
BOOL bRunningCutscene
BOOL bSkippedCutscene
BOOL bClearedForCutscene
BOOL bCutsceneWaitStarted
BOOL bShownGodText
BOOL bShownGotoText[3]
BOOL bShownDoHitText[3]
BOOL bDoneReadySpeech[3]
BOOL bDoneHitSuccessfulSpeech[3]
BOOL bEscapedArea[3]
BOOL bShownEscapePrompt[3]
BOOL bUnblockedGPS[3]
BOOL bIsOffPiste[3]
BOOL bDoneWhoNextQuestionSpeech
BOOL bDoneWhoNextAnswerSpeech
BOOL bJumpedAheadToTrevorHit
BOOL bJumpedAheadToMichaelHit
BOOL bJumpedAheadToFranklinHit
BOOL bShownSwitchPrompt
BOOL bShouldDoGetInText
BOOL bDoneGotoSpeech
BOOL bSavedBanter
BOOL bRemovedBlipsForWanted
BOOL bShownLoseWantedPrompt
BOOL bLockSelector
BOOL bSteveInGondola
BOOL bDoneCameramanSpeech
BOOL bCacheChengInCar
BOOL bCacheStretchInCar
BOOL bRemovedStretchPhone
BOOL bDetachedBasketball
BOOL bGivenGun
BOOL bAggroedTriads
BOOL bRemovedTrevorCar
BOOL bDoneChengLeaveSpeech
BOOL bDoneChengEscapeSpeech
BOOL bResetAIDrive
BOOL bStoppedSwitchToVehicle
BOOL bRepositionedPreviousCharacter
BOOL bDoneOnlyYourTargetSpeech
BOOL bDoneOnlyYourTargetReplySpeech
BOOL bDoneFranklinCallLamar
BOOL bDoneTrevorCallRon
BOOL bDoneHailStretchSpeech
BOOL bDoneStretchToCombatSpeech
BOOL bDoneCowardlySpeech
BOOL bDoneDisloyalSpeech
BOOL bDoneStretchThreatenSpeech
BOOL bDoneStretchOrderSpeech
BOOL bRestoredVehicleDensity
BOOL bRestoredTriadHealth
BOOL bStartedWheel
BOOL bUsingWheelCam
BOOL bDoneWheelCamHelp
BOOL bDoingDriveAudioScene
BOOL bDoingOnFootAudioScene
BOOL bPlayerShootingInArea
BOOL bSteveDead[COUNT_OF(STEVE_ENUM)]
BOOL bDoFadeInOnHitCreation
BOOL bIsNaturalSkipToGetToHits
BOOL bDoneRevengeForStretchSpeech
BOOL bGotRevengeForStretchSpeaker
BOOL bDonePhoneIntroSpeech
BOOL bKilledSpeechForHail
//BOOL bDoRecognizeSpeech
//BOOL bDoneRecognizeSpeech
BOOL bDoneKillConversationForAttack
BOOL bGangstersFrozen
BOOL bTriadsFrozen
BOOL bGeneralMerryweatherAlert
BOOL bDoneKidnapDevinText
BOOL bRepeatedKidnapDevinText
BOOL bDoneKillGuardsText
BOOL bPlayerNearDeck
BOOL bDoneDevinHideSpeech
BOOL bTrespassing
BOOL bDoneInstanceHintShooting
BOOL bNearGangster
BOOL bNearTriad
BOOL bGangstersHostileFromAggro
BOOL bTriadsMustChasePlayer
BOOL bDoneDevinToGuardSpeech
BOOL bShownSteveIntro
BOOL bDoShotSteveCutscene
BOOL bGangsterVehicleOnGo[NUMBER_GANGSTER_VEHICLES]
BOOL bDoneGotChengSpeech
BOOL bDoneSpookedSpeech
BOOL bDoSpookedSpeech
BOOL bDoSeenSpeech
BOOL bResetCopAccuracy
BOOL bDoneTriadsWander
BOOL bBeenCloseToSteve
BOOL bDoneFrontCarFollow
BOOL bStoppedWheel
BOOL bLockedOutOfWheelCam
BOOL bReleasedCamButton
BOOL bLockIntoWheelCam
BOOL bShouldDoCamView
BOOL bCamViewTurnedOn
BOOL bSuppressFutureReplaySetups
BOOL bDoneSecondAIDrive
BOOL bAllowDescent
BOOL bDamagedGangster
BOOL bDoneAlertedCue
BOOL bDoneKilledAllCue
BOOL bSetTornadoOutOfCut
BOOL bAwardedAchievement
BOOL bDoneDontGetCloseHelp
BOOL bBlockedDevinRagdoll
BOOL bStoppedTabletAnim
//BOOL bWasInVehicle
//BOOL bCheckedInVehicle
//BOOL bKilledHintCamForLeaveVehicle
BOOL bDoneNearlyThereSpeech
BOOL bTriggeredDevinDamageReaction
BOOL bClearedLookAtForKilledStretch
BOOL bRecreatedDevinVolume
BOOL bDoneCarArriveAudioScene
BOOL bDoneMySonDeadSpeech
BOOL bDonePushCarSound
BOOL bSetMerryweatherSpeaker1
BOOL bSetMerryweatherSpeaker2
BOOL bDoneMerryweatherCombatSpeech1
BOOL bDoneMerryweatherCombatSpeech2
BOOL bDoneMerryweatherCombatSpeech3
BOOL bDoSpottedSpeech
BOOL bFlipMerryweatherDialogue
BOOL bDoneAttackStretchMusic
BOOL bDoneAttackChengMusic
BOOL bDoDevinBangOnTrunk
BOOL bDoDevinAdditionalBangOnTrunk
BOOL bWaitForGangsterVariations
BOOL bWaitForTriadVariations
BOOL bForceRelativeCamReset
BOOL bTaskedCopsToWander
BOOL bAllowWheelTopSpeed
BOOL bFailedOut
BOOL bSetDevinRadio
BOOL bSuppressShotCutscene
BOOL bStartedCreditsRoll
BOOL bSuppressBulletCam
BOOL bSetDoBulletCam
BOOL bRecordAdvance //Ross W
BOOL bDoneFlash
BOOL bDoneBulletCamFlash
INT iMerryweatherSpeaker1
INT iMerryweatherSpeaker2
INT iAssignedSpeakerTime
INT iMerryweatherCombatSpeechTime
INT iBulletCamTime
// Vectors
//VECTOR vWheelPos = <<-1663.9, -1126.7, 15.1>>
VECTOR vGangsterVehicleWarpTarget[NUMBER_GANGSTER_VEHICLES]
VECTOR vGangsterVehicleLastWarpPos[NUMBER_GANGSTER_VEHICLES]
VECTOR vTriadVehicleWarpTarget[COUNT_OF(TRIAD_VEHICLE_ENUM)]
VECTOR vTriadVehicleLastWarpPos[COUNT_OF(TRIAD_VEHICLE_ENUM)]
VECTOR vSwitchNodePos
VECTOR vActualCamCoord
VECTOR vGangsterVehicleBlipPos[NUMBER_GANGSTER_VEHICLES]
VECTOR vTriadVehicleBlipPos[COUNT_OF(TRIAD_VEHICLE_ENUM)]
VECTOR vHitStorePos
VECTOR vOffPistePos[3]
VECTOR vLastSwitchPos[3]
VECTOR vTriadDriveCoords
// Floats
FLOAT fPushCarForce
FLOAT fWheelRotation
FLOAT fWheelSpeed
FLOAT fCachedPlayerHeading
FLOAT fPushAnimSpeed
//FLOAT fAtWheelTime
FLOAT fHitRot
FLOAT fGangsterVehicleWarpHeading[NUMBER_GANGSTER_VEHICLES]
FLOAT fGangsterVehicleLastWarpHeading[NUMBER_GANGSTER_VEHICLES]
FLOAT fTriadVehicleWarpHeading[COUNT_OF(TRIAD_VEHICLE_ENUM)]
FLOAT fTriadVehicleLastWarpHeading[COUNT_OF(TRIAD_VEHICLE_ENUM)]
FLOAT fMaxGangsterWarpVehicleDistance
FLOAT fMaxTriadWarpVehicleDistance
FLOAT fSwitchNodeRot
FLOAT fStoreStevePhase
FLOAT fTravelDistance[3]
FLOAT fOffPisteRot[3]
FLOAT fLastSwitchRot[3]
FLOAT fBlockingTriadTime
//FLOAT fGondolaRadius = 10
// Ints
INT iReplayAttempt
INT iNumberSplineCams
INT iAllowSkipCutsceneTime
INT iFinaleCutsceneTime
INT iCutsceneTriggerTime
INT iNextRandomSpeechTime
INT iStageStartTime
INT iClearHelpTime
INT iGetInTextStage[3]
INT iSteveSyncScene
INT iCameramanSyncScene
INT iGondolaSyncScene[NUMBER_GONDOLAS]
INT iTriadSyncScene
//INT iTimelapseCut
INT iSteveReactTime
INT iGangsterSyncScene
INT iGangsterStateTime[COUNT_OF(GANGSTER_ENUM)]
INT iNextUpdateJourneysTime
//INT iEnableCraneTime
INT iHailStretchSpeechTime
INT iGangsterBanterCount
INT iStretchBanterCount
INT iResetPlayerCameraControlTime
INT iSetTriadStateTime
INT iAllowGondolaReactTime
INT iJourneyWarpTimer[3]
INT iJourneyStage[3]
INT iPushCarSoundID = GET_SOUND_ID()
INT iNextDevinBootSpeechTime
INT iNextAdditionalBangOnTrunkTime
INT iAllowLaunchCutsceneTime
INT iGuardsAlive
INT iGuardsAliveLastFrame
//INT iDevinIntoBoxTime
INT iSetStretchToCombatTime
INT iStretchDeadTime
INT iGangsterVehicleWarpTimer[NUMBER_GANGSTER_VEHICLES]
INT iTriadVehicleWarpTimer[COUNT_OF(TRIAD_VEHICLE_ENUM)]
INT iResetCopAccuracyTime
INT iTriadsEscapeTime
INT iCamViewCount
INT iWheelCamTime
INT iGangsterAggroTime
INT iSyncScene
INT iSteveDeadTime
//INT iTrevorReadySpeechTime
INT iDevinSpeechInBoxStage
INT iNextDevinSpeechInBoxTime
INT iNextCheckCarHealthTime
INT iCachedCarHealth
INT iTVSubCount
INT iPushCarSoundTime
INT iNextChengJrCurseTime
INT iNextDevinBangOnTrunkTime
INT iForceLamarCallTime
INT iMerryweatherForceAlertTime
INT iTriadWanderStage
INT iGondolaCheck
INT iBrowserTime
INT iRevengeForStretchSpeaker
INT iCreditsStartTime
INT iTrevorCallRonTime
INT iSwitchStartTime
// Other variables
SEQUENCE_INDEX sequence
SCRIPTTASKSTATUS taskStatus
structPedsForConversation finaleConversation
REL_GROUP_HASH triadRelGroup
REL_GROUP_HASH merryweatherRelGroup
REL_GROUP_HASH gangsterRelGroup
SCENARIO_BLOCKING_INDEX recScenarioBlocking
SCENARIO_BLOCKING_INDEX clubScenarioBlocking
SCENARIO_BLOCKING_INDEX loungersScenarioBlocking
SCENARIO_BLOCKING_INDEX loungersScenarioBlocking2
SCENARIO_BLOCKING_INDEX photographerScenarioBlocking
//TIMEOFDAY finaleTimeOfDay
TEXT_LABEL_23 tSavedBanterRoot
TEXT_LABEL_23 tResumeBanterLabel
//SWITCH CAM VARIABLES AND PROCEDURES
ENUM FINALEC2_SWITCH_CAM_STATE
SWITCH_CAM_IDLE,
SWITCH_CAM_REQUEST_ASSETS,
SWITCH_CAM_SETUP_SPLINE,
SWITCH_CAM_PLAYING_SPLINE,
SWITCH_CAM_SHUTDOWN_SPLINE,
SWITCH_CAM_RETURN_TO_GAMEPLAY
ENDENUM
FINALEC2_SWITCH_CAM_STATE eSwitchCamState = SWITCH_CAM_IDLE
SWITCH_CAM_STRUCT scsSwitchCamBulletCam
SWITCH_CAM_STRUCT scsSwitchCamExplosion
SWITCH_CAM_STRUCT scsSwitchCamGrenade
BOOL bSwitchCam_SteveKilledViaExplosion
BOOL bSwitchCam_SteveKilledViaGrenade
#IF IS_DEBUG_BUILD
BOOL bDEBUG_SwitchCamJumpToKillSteve
BOOL bDEBUG_DisableMissionFail = FALSE
BOOL bDEBUG_ForceBulletKillSteve
BOOL bDEBUG_ForceExplosionKillSteve
BOOL bDEBUG_BloodFX_Tester
#ENDIF
BOOL bPlayerControlGiven
FLOAT fGameplayCamHeadingToTrevorInHeli = 0.0
FLOAT fGameplayCamPitchToTrevorInHeli = 0.0
BOOL bSwitchCam_PlayedBloodSpurt
VECTOR vSwitchCam_BloodSpurtLoc = <<0.05, 0.2, 0.5>>
VECTOR vSwitchCam_BloodSpurtRot = <<0.0, 0.0, 0.0>>
FLOAT fSwitchCam_StartBloodSpurtPhase = 0.05
FLOAT fSwitchCam_StartBloodSpurtScale = 1.31
#IF IS_DEBUG_BUILD
//FLOAT fMichealToTrevor_HeliRecStartTime = 6300
#ENDIF
PROC SETUP_SPLINE_CAM_NODE_ARRAY_KILL_STEVE_BULLET_CAM(SWITCH_CAM_STRUCT &thisSwitchCam, PED_INDEX piTrevor, PED_INDEX piSteve)
CDEBUG3LN(DEBUG_MISSION, "SETUP_SPLINE_CAM_NODE_ARRAY_KILL_STEVE_BULLET_CAM")
IF NOT thisSwitchCam.bInitialized
//--- Start of Cam Data ---
thisSwitchCam.nodes[0].SwitchCamType = SWITCH_CAM_PATH_RELATIVE
thisSwitchCam.nodes[0].iForceCamPointAtEntityIndex = 1
thisSwitchCam.nodes[0].bIsGameplayCamCopy = FALSE
thisSwitchCam.nodes[0].iNodeTime = 0
thisSwitchCam.nodes[0].vNodePos = <<-1654.3093, -1100.6057, 22.3126>>
thisSwitchCam.nodes[0].vWorldPosLookAt = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[0].fNodeOffsetDist = 15.0000
thisSwitchCam.nodes[0].fNodeVerticleOffset = 0.0000
thisSwitchCam.nodes[0].bAttachToOriginPed = FALSE
thisSwitchCam.nodes[0].vNodeDir = <<6.7401, -0.0201, 145.6815>>
thisSwitchCam.nodes[0].bPointAtEntity = FALSE
thisSwitchCam.nodes[0].bPointAtOffsetIsRelative = FALSE
thisSwitchCam.nodes[0].bAttachOffsetIsRelative = FALSE
thisSwitchCam.nodes[0].fNodeFOV = 60.0000
IF NOT bJumpedAheadToTrevorHit
printstring("no jump") printnl()
thisSwitchCam.nodes[0].vClonedNodeOffset = <<0.0000, 0.0000, 0.0000>>
ELSE
printstring("jump") printnl()
thisSwitchCam.nodes[0].vClonedNodeOffset = <<0.0000, 0.0000, -2.0000>>
ENDIF
thisSwitchCam.nodes[0].iNodeToClone = 0
thisSwitchCam.nodes[0].NodeTimePostFX_Type = NO_EFFECT
thisSwitchCam.nodes[0].fNodeTimePostFXBlendTime = 0.0000
thisSwitchCam.nodes[0].fNodeTimePostFXTimeOffset = 0.0000
thisSwitchCam.nodes[0].fNodeMotionBlur = 1.0000
thisSwitchCam.nodes[0].NodeCamShakeType = CAM_SHAKE_DEFAULT
thisSwitchCam.nodes[0].fNodeCamShake = 0.0000
thisSwitchCam.nodes[0].iCamEaseType = 1
thisSwitchCam.nodes[0].fCamEaseScaler = 1.0000
thisSwitchCam.nodes[0].fCamNodeVelocityScale = 0.0000
thisSwitchCam.nodes[0].bCamEaseForceLinear = TRUE
thisSwitchCam.nodes[0].bCamEaseForceLevel = FALSE
thisSwitchCam.nodes[0].fTimeScale = 0.1000
thisSwitchCam.nodes[0].iTimeScaleEaseType = 0
thisSwitchCam.nodes[0].fTimeScaleEaseScaler = 0.0000
thisSwitchCam.nodes[0].bFlashEnabled = FALSE
thisSwitchCam.nodes[0].SCFE_FlashEffectUsed = SCFE_CODE_FLASH
thisSwitchCam.nodes[0].fMinExposure = 0.0000
thisSwitchCam.nodes[0].fMaxExposure = 0.0000
thisSwitchCam.nodes[0].iRampUpDuration = 0
thisSwitchCam.nodes[0].iRampDownDuration = 0
thisSwitchCam.nodes[0].iHoldDuration = 0
thisSwitchCam.nodes[0].fFlashNodePhaseOffset = 0.0000
thisSwitchCam.nodes[0].bIsLowDetailNode = FALSE
thisSwitchCam.nodes[0].bUseCustomDOF = FALSE
thisSwitchCam.nodes[0].NodeDOF_Info.fDOF_NearDOF = 0.0000
thisSwitchCam.nodes[0].NodeDOF_Info.fDOF_FarDOF = 0.0000
thisSwitchCam.nodes[0].NodeDOF_Info.fDOF_EffectStrength = 0.0000
thisSwitchCam.nodes[1].SwitchCamType = SWITCH_CAM_PATH_RELATIVE_ATTACHED
thisSwitchCam.nodes[1].iForceCamPointAtEntityIndex = 1
thisSwitchCam.nodes[1].bIsGameplayCamCopy = FALSE
thisSwitchCam.nodes[1].iNodeTime = 300
thisSwitchCam.nodes[1].vNodePos = <<-1659.3484, -1107.9875, 23.3689>>
thisSwitchCam.nodes[1].vWorldPosLookAt = <<-1662.8572, -1116.3562, 17.8841>>
thisSwitchCam.nodes[1].fNodeOffsetDist = 6.0000
thisSwitchCam.nodes[1].fNodeVerticleOffset = 0.0000
thisSwitchCam.nodes[1].bAttachToOriginPed = FALSE
thisSwitchCam.nodes[1].vNodeDir = <<6.7401, -0.0201, 145.6815>>
thisSwitchCam.nodes[1].bPointAtEntity = FALSE
thisSwitchCam.nodes[1].bPointAtOffsetIsRelative = FALSE
thisSwitchCam.nodes[1].bAttachOffsetIsRelative = FALSE
thisSwitchCam.nodes[1].fNodeFOV = 35.0000
IF NOT bJumpedAheadToTrevorHit
thisSwitchCam.nodes[1].vClonedNodeOffset = <<0.0000, 0.0000, 0.0000>>
ELSE
thisSwitchCam.nodes[1].vClonedNodeOffset = <<0.0000, 0.0000, -2.0000>>
ENDIF
thisSwitchCam.nodes[1].iNodeToClone = 0
thisSwitchCam.nodes[1].NodeTimePostFX_Type = NO_EFFECT
thisSwitchCam.nodes[1].fNodeTimePostFXBlendTime = 0.0000
thisSwitchCam.nodes[1].fNodeTimePostFXTimeOffset = 0.0000
thisSwitchCam.nodes[1].fNodeMotionBlur = 0.5000
thisSwitchCam.nodes[1].NodeCamShakeType = CAM_SHAKE_DEFAULT
thisSwitchCam.nodes[1].fNodeCamShake = 0.0000
thisSwitchCam.nodes[1].iCamEaseType = 0
thisSwitchCam.nodes[1].fCamEaseScaler = 0.0000
thisSwitchCam.nodes[1].fCamNodeVelocityScale = 0.0000
thisSwitchCam.nodes[1].bCamEaseForceLinear = TRUE
thisSwitchCam.nodes[1].bCamEaseForceLevel = FALSE
thisSwitchCam.nodes[1].fTimeScale = 0.1000
thisSwitchCam.nodes[1].iTimeScaleEaseType = 0
thisSwitchCam.nodes[1].fTimeScaleEaseScaler = 0.0000
thisSwitchCam.nodes[1].bFlashEnabled = FALSE
thisSwitchCam.nodes[1].SCFE_FlashEffectUsed = SCFE_CODE_FLASH
thisSwitchCam.nodes[1].fMinExposure = 0.0000
thisSwitchCam.nodes[1].fMaxExposure = 0.0000
thisSwitchCam.nodes[1].iRampUpDuration = 0
thisSwitchCam.nodes[1].iRampDownDuration = 0
thisSwitchCam.nodes[1].iHoldDuration = 0
thisSwitchCam.nodes[1].fFlashNodePhaseOffset = 0.0000
thisSwitchCam.nodes[1].bIsLowDetailNode = FALSE
thisSwitchCam.nodes[1].bUseCustomDOF = FALSE
thisSwitchCam.nodes[1].NodeDOF_Info.fDOF_NearDOF = 0.0000
thisSwitchCam.nodes[1].NodeDOF_Info.fDOF_FarDOF = 0.0000
thisSwitchCam.nodes[1].NodeDOF_Info.fDOF_EffectStrength = 0.0000
thisSwitchCam.nodes[2].SwitchCamType = SWITCH_CAM_PATH_RELATIVE_ATTACHED
thisSwitchCam.nodes[2].iForceCamPointAtEntityIndex = 1
thisSwitchCam.nodes[2].bIsGameplayCamCopy = FALSE
thisSwitchCam.nodes[2].iNodeTime = 500
thisSwitchCam.nodes[2].vNodePos = <<-1659.9082, -1108.8079, 23.4863>>
thisSwitchCam.nodes[2].vWorldPosLookAt = <<-1662.8572, -1116.3562, 17.8841>>
thisSwitchCam.nodes[2].fNodeOffsetDist = 5.0000
thisSwitchCam.nodes[2].fNodeVerticleOffset = 0.0000
thisSwitchCam.nodes[2].bAttachToOriginPed = FALSE
thisSwitchCam.nodes[2].vNodeDir = <<6.7401, -0.0201, 145.6815>>
thisSwitchCam.nodes[2].bPointAtEntity = FALSE
thisSwitchCam.nodes[2].bPointAtOffsetIsRelative = FALSE
thisSwitchCam.nodes[2].bAttachOffsetIsRelative = FALSE
thisSwitchCam.nodes[2].fNodeFOV = 35.0000
IF NOT bJumpedAheadToTrevorHit
thisSwitchCam.nodes[2].vClonedNodeOffset = <<0.0000, 0.0000, 0.0000>>
ELSE
thisSwitchCam.nodes[2].vClonedNodeOffset = <<0.0000, 0.0000, -2.0000>>
ENDIF
thisSwitchCam.nodes[2].iNodeToClone = 0
thisSwitchCam.nodes[2].NodeTimePostFX_Type = NO_EFFECT
thisSwitchCam.nodes[2].fNodeTimePostFXBlendTime = 0.0000
thisSwitchCam.nodes[2].fNodeTimePostFXTimeOffset = 0.0000
thisSwitchCam.nodes[2].fNodeMotionBlur = 0.0000
thisSwitchCam.nodes[2].NodeCamShakeType = CAM_SHAKE_DEFAULT
thisSwitchCam.nodes[2].fNodeCamShake = 0.0000
thisSwitchCam.nodes[2].iCamEaseType = 0
thisSwitchCam.nodes[2].fCamEaseScaler = 0.0000
thisSwitchCam.nodes[2].fCamNodeVelocityScale = 0.0000
thisSwitchCam.nodes[2].bCamEaseForceLinear = TRUE
thisSwitchCam.nodes[2].bCamEaseForceLevel = FALSE
thisSwitchCam.nodes[2].fTimeScale = 0.1000
thisSwitchCam.nodes[2].iTimeScaleEaseType = 0
thisSwitchCam.nodes[2].fTimeScaleEaseScaler = 0.0000
thisSwitchCam.nodes[2].bFlashEnabled = TRUE
thisSwitchCam.nodes[2].SCFE_FlashEffectUsed = SCFE_CODE_FLASH
thisSwitchCam.nodes[2].fMinExposure = 200.0000
thisSwitchCam.nodes[2].fMaxExposure = 200.0000
thisSwitchCam.nodes[2].iRampUpDuration = 50
thisSwitchCam.nodes[2].iRampDownDuration = 50
thisSwitchCam.nodes[2].iHoldDuration = 100
thisSwitchCam.nodes[2].fFlashNodePhaseOffset = 0.4100
thisSwitchCam.nodes[2].bIsLowDetailNode = FALSE
thisSwitchCam.nodes[2].bUseCustomDOF = FALSE
thisSwitchCam.nodes[2].NodeDOF_Info.fDOF_NearDOF = 0.0000
thisSwitchCam.nodes[2].NodeDOF_Info.fDOF_FarDOF = 0.0000
thisSwitchCam.nodes[2].NodeDOF_Info.fDOF_EffectStrength = 0.0000
thisSwitchCam.nodes[3].SwitchCamType = SWITCH_CAM_PATH_RELATIVE_ATTACHED
thisSwitchCam.nodes[3].iForceCamPointAtEntityIndex = 1
thisSwitchCam.nodes[3].bIsGameplayCamCopy = FALSE
thisSwitchCam.nodes[3].iNodeTime = 1
thisSwitchCam.nodes[3].vNodePos = <<-1659.9082, -1108.8079, 23.4863>>
thisSwitchCam.nodes[3].vWorldPosLookAt = <<-1662.8572, -1116.3562, 17.8841>>
thisSwitchCam.nodes[3].fNodeOffsetDist = 5.0000
thisSwitchCam.nodes[3].fNodeVerticleOffset = 0.0000
thisSwitchCam.nodes[3].bAttachToOriginPed = FALSE
thisSwitchCam.nodes[3].vNodeDir = <<6.7401, -0.0201, 145.6815>>
thisSwitchCam.nodes[3].bPointAtEntity = FALSE
thisSwitchCam.nodes[3].bPointAtOffsetIsRelative = FALSE
thisSwitchCam.nodes[3].bAttachOffsetIsRelative = FALSE
thisSwitchCam.nodes[3].fNodeFOV = 35.0000
IF NOT bJumpedAheadToTrevorHit
thisSwitchCam.nodes[3].vClonedNodeOffset = <<0.0000, 0.0000, 0.0000>>
ELSE
thisSwitchCam.nodes[3].vClonedNodeOffset = <<0.0000, 0.0000, -2.0000>>
ENDIF
thisSwitchCam.nodes[3].iNodeToClone = 0
thisSwitchCam.nodes[3].NodeTimePostFX_Type = NO_EFFECT
thisSwitchCam.nodes[3].fNodeTimePostFXBlendTime = 0.0000
thisSwitchCam.nodes[3].fNodeTimePostFXTimeOffset = 0.0000
thisSwitchCam.nodes[3].fNodeMotionBlur = 0.0000
thisSwitchCam.nodes[3].NodeCamShakeType = CAM_SHAKE_DEFAULT
thisSwitchCam.nodes[3].fNodeCamShake = 0.0000
thisSwitchCam.nodes[3].iCamEaseType = 0
thisSwitchCam.nodes[3].fCamEaseScaler = 0.0000
thisSwitchCam.nodes[3].fCamNodeVelocityScale = 0.0000
thisSwitchCam.nodes[3].bCamEaseForceLinear = TRUE
thisSwitchCam.nodes[3].bCamEaseForceLevel = FALSE
thisSwitchCam.nodes[3].fTimeScale = 1.0000
thisSwitchCam.nodes[3].iTimeScaleEaseType = 0
thisSwitchCam.nodes[3].fTimeScaleEaseScaler = 0.0000
thisSwitchCam.nodes[3].bFlashEnabled = TRUE
thisSwitchCam.nodes[3].SCFE_FlashEffectUsed = SCFE_CODE_FLASH
thisSwitchCam.nodes[3].fMinExposure = 200.0000
thisSwitchCam.nodes[3].fMaxExposure = 200.0000
thisSwitchCam.nodes[3].iRampUpDuration = 50
thisSwitchCam.nodes[3].iRampDownDuration = 50
thisSwitchCam.nodes[3].iHoldDuration = 100
thisSwitchCam.nodes[3].fFlashNodePhaseOffset = 0.4100
thisSwitchCam.nodes[3].bIsLowDetailNode = FALSE
thisSwitchCam.nodes[3].bUseCustomDOF = FALSE
thisSwitchCam.nodes[3].NodeDOF_Info.fDOF_NearDOF = 0.0000
thisSwitchCam.nodes[3].NodeDOF_Info.fDOF_FarDOF = 0.0000
thisSwitchCam.nodes[3].NodeDOF_Info.fDOF_EffectStrength = 0.0000
thisSwitchCam.iNumNodes = 4
thisSwitchCam.iCamSwitchFocusNode = 0
thisSwitchCam.fSwitchSoundAudioStartPhase = -1.0000
thisSwitchCam.fSwitchSoundAudioEndPhase = -1.0000
thisSwitchCam.bSplineNoSmoothing = TRUE
thisSwitchCam.bAddGameplayCamAsLastNode = FALSE
thisSwitchCam.iGameplayNodeBlendDuration = 0
//--- End of Cam Data ---
thisSwitchCam.strOutputStructName = "thisSwitchCam"
thisSwitchCam.strOutputFileName = "CameraInfo_FINALEC2_KillSteveBulletCam.txt"
thisSwitchCam.strXMLFileName = "CameraInfo_FINALEC2_KillSteveBulletCam.xml"
thisSwitchCam.bInitialized = TRUE
ENDIF
thisSwitchCam.piPeds[0] = piTrevor
thisSwitchCam.piPeds[1] = piSteve
ENDPROC
PROC SETUP_SPLINE_CAM_NODE_ARRAY_KILL_STEVE_EXPLOSION_CAM(SWITCH_CAM_STRUCT &thisSwitchCam, PED_INDEX piTrevor, PED_INDEX piSteve)
CDEBUG3LN(DEBUG_MISSION, "SETUP_SPLINE_CAM_NODE_ARRAY_KILL_STEVE_EXPLOSION_CAM")
IF NOT thisSwitchCam.bInitialized
//--- Start of Cam Data ---
thisSwitchCam.nodes[0].SwitchCamType = SWITCH_CAM_WORLD_POS
thisSwitchCam.nodes[0].iForceCamPointAtEntityIndex = 1
thisSwitchCam.nodes[0].bIsGameplayCamCopy = FALSE
thisSwitchCam.nodes[0].iNodeTime = 0
thisSwitchCam.nodes[0].vNodePos = <<-1631.6000, -1085.8401, 42.3664>>
thisSwitchCam.nodes[0].vWorldPosLookAt = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[0].fNodeOffsetDist = 35.0000
thisSwitchCam.nodes[0].fNodeVerticleOffset = 0.0000
thisSwitchCam.nodes[0].bAttachToOriginPed = FALSE
thisSwitchCam.nodes[0].vNodeDir = <<0.0000, 0.0000, 0.0001>>
thisSwitchCam.nodes[0].bPointAtEntity = TRUE
thisSwitchCam.nodes[0].bPointAtOffsetIsRelative = TRUE
thisSwitchCam.nodes[0].bAttachOffsetIsRelative = FALSE
thisSwitchCam.nodes[0].fNodeFOV = 25.0000
thisSwitchCam.nodes[0].vClonedNodeOffset = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[0].iNodeToClone = 0
thisSwitchCam.nodes[0].NodeTimePostFX_Type = NO_EFFECT
thisSwitchCam.nodes[0].fNodeTimePostFXBlendTime = 0.0000
thisSwitchCam.nodes[0].fNodeTimePostFXTimeOffset = 0.0000
thisSwitchCam.nodes[0].fNodeMotionBlur = 0.0000
thisSwitchCam.nodes[0].NodeCamShakeType = CAM_SHAKE_DEFAULT
thisSwitchCam.nodes[0].fNodeCamShake = 0.0000
thisSwitchCam.nodes[0].iCamEaseType = 1
thisSwitchCam.nodes[0].fCamEaseScaler = 1.0000
thisSwitchCam.nodes[0].fCamNodeVelocityScale = 0.0000
thisSwitchCam.nodes[0].bCamEaseForceLinear = TRUE
thisSwitchCam.nodes[0].bCamEaseForceLevel = FALSE
thisSwitchCam.nodes[0].fTimeScale = 0.1000
thisSwitchCam.nodes[0].iTimeScaleEaseType = 0
thisSwitchCam.nodes[0].fTimeScaleEaseScaler = 0.0000
thisSwitchCam.nodes[0].bFlashEnabled = FALSE
thisSwitchCam.nodes[0].SCFE_FlashEffectUsed = SCFE_CODE_FLASH
thisSwitchCam.nodes[0].fMinExposure = 0.0000
thisSwitchCam.nodes[0].fMaxExposure = 0.0000
thisSwitchCam.nodes[0].iRampUpDuration = 0
thisSwitchCam.nodes[0].iRampDownDuration = 0
thisSwitchCam.nodes[0].iHoldDuration = 0
thisSwitchCam.nodes[0].fFlashNodePhaseOffset = 0.0000
thisSwitchCam.nodes[0].bIsLowDetailNode = FALSE
thisSwitchCam.nodes[0].bUseCustomDOF = FALSE
thisSwitchCam.nodes[0].NodeDOF_Info.fDOF_NearDOF = 0.0000
thisSwitchCam.nodes[0].NodeDOF_Info.fDOF_FarDOF = 0.0000
thisSwitchCam.nodes[0].NodeDOF_Info.fDOF_EffectStrength = 0.0000
thisSwitchCam.nodes[1].SwitchCamType = SWITCH_CAM_WORLD_POS
thisSwitchCam.nodes[1].iForceCamPointAtEntityIndex = 1
thisSwitchCam.nodes[1].bIsGameplayCamCopy = FALSE
thisSwitchCam.nodes[1].iNodeTime = 800
thisSwitchCam.nodes[1].vNodePos = <<-1632.0530, -1086.2684, 42.3135>>
thisSwitchCam.nodes[1].vWorldPosLookAt = <<-1662.8572, -1116.3562, 17.8841>>
thisSwitchCam.nodes[1].fNodeOffsetDist = 36.0000
thisSwitchCam.nodes[1].fNodeVerticleOffset = 0.0000
thisSwitchCam.nodes[1].bAttachToOriginPed = FALSE
thisSwitchCam.nodes[1].vNodeDir = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[1].bPointAtEntity = TRUE
thisSwitchCam.nodes[1].bPointAtOffsetIsRelative = TRUE
thisSwitchCam.nodes[1].bAttachOffsetIsRelative = FALSE
thisSwitchCam.nodes[1].fNodeFOV = 25.0000
thisSwitchCam.nodes[1].vClonedNodeOffset = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[1].iNodeToClone = 0
thisSwitchCam.nodes[1].NodeTimePostFX_Type = NO_EFFECT
thisSwitchCam.nodes[1].fNodeTimePostFXBlendTime = 0.0000
thisSwitchCam.nodes[1].fNodeTimePostFXTimeOffset = 0.0000
thisSwitchCam.nodes[1].fNodeMotionBlur = 0.0000
thisSwitchCam.nodes[1].NodeCamShakeType = CAM_SHAKE_DEFAULT
thisSwitchCam.nodes[1].fNodeCamShake = 0.0000
thisSwitchCam.nodes[1].iCamEaseType = 0
thisSwitchCam.nodes[1].fCamEaseScaler = 0.0000
thisSwitchCam.nodes[1].fCamNodeVelocityScale = 0.0000
thisSwitchCam.nodes[1].bCamEaseForceLinear = TRUE
thisSwitchCam.nodes[1].bCamEaseForceLevel = FALSE
thisSwitchCam.nodes[1].fTimeScale = 0.1000
thisSwitchCam.nodes[1].iTimeScaleEaseType = 0
thisSwitchCam.nodes[1].fTimeScaleEaseScaler = 0.0000
thisSwitchCam.nodes[1].bFlashEnabled = FALSE
thisSwitchCam.nodes[1].SCFE_FlashEffectUsed = SCFE_CODE_FLASH
thisSwitchCam.nodes[1].fMinExposure = 0.0000
thisSwitchCam.nodes[1].fMaxExposure = 0.0000
thisSwitchCam.nodes[1].iRampUpDuration = 0
thisSwitchCam.nodes[1].iRampDownDuration = 0
thisSwitchCam.nodes[1].iHoldDuration = 0
thisSwitchCam.nodes[1].fFlashNodePhaseOffset = 0.0000
thisSwitchCam.nodes[1].bIsLowDetailNode = FALSE
thisSwitchCam.nodes[1].bUseCustomDOF = FALSE
thisSwitchCam.nodes[1].NodeDOF_Info.fDOF_NearDOF = 0.0000
thisSwitchCam.nodes[1].NodeDOF_Info.fDOF_FarDOF = 0.0000
thisSwitchCam.nodes[1].NodeDOF_Info.fDOF_EffectStrength = 0.0000
thisSwitchCam.nodes[2].SwitchCamType = SWITCH_CAM_WORLD_POS
thisSwitchCam.nodes[2].iForceCamPointAtEntityIndex = 1
thisSwitchCam.nodes[2].bIsGameplayCamCopy = FALSE
thisSwitchCam.nodes[2].iNodeTime = 1500
thisSwitchCam.nodes[2].vNodePos = <<-1633.5394, -1087.6753, 42.1400>>
thisSwitchCam.nodes[2].vWorldPosLookAt = <<-1662.8572, -1116.3562, 17.8841>>
thisSwitchCam.nodes[2].fNodeOffsetDist = 35.0000
thisSwitchCam.nodes[2].fNodeVerticleOffset = 0.0000
thisSwitchCam.nodes[2].bAttachToOriginPed = FALSE
thisSwitchCam.nodes[2].vNodeDir = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[2].bPointAtEntity = TRUE
thisSwitchCam.nodes[2].bPointAtOffsetIsRelative = TRUE
thisSwitchCam.nodes[2].bAttachOffsetIsRelative = FALSE
thisSwitchCam.nodes[2].fNodeFOV = 25.0000
thisSwitchCam.nodes[2].vClonedNodeOffset = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[2].iNodeToClone = 0
thisSwitchCam.nodes[2].NodeTimePostFX_Type = NO_EFFECT
thisSwitchCam.nodes[2].fNodeTimePostFXBlendTime = 0.0000
thisSwitchCam.nodes[2].fNodeTimePostFXTimeOffset = 0.0000
thisSwitchCam.nodes[2].fNodeMotionBlur = 0.0000
thisSwitchCam.nodes[2].NodeCamShakeType = CAM_SHAKE_DEFAULT
thisSwitchCam.nodes[2].fNodeCamShake = 0.0000
thisSwitchCam.nodes[2].iCamEaseType = 0
thisSwitchCam.nodes[2].fCamEaseScaler = 0.0000
thisSwitchCam.nodes[2].fCamNodeVelocityScale = 0.0000
thisSwitchCam.nodes[2].bCamEaseForceLinear = TRUE
thisSwitchCam.nodes[2].bCamEaseForceLevel = FALSE
thisSwitchCam.nodes[2].fTimeScale = 0.1000
thisSwitchCam.nodes[2].iTimeScaleEaseType = 0
thisSwitchCam.nodes[2].fTimeScaleEaseScaler = 0.0000
thisSwitchCam.nodes[2].bFlashEnabled = TRUE
thisSwitchCam.nodes[2].SCFE_FlashEffectUsed = SCFE_CODE_FLASH
thisSwitchCam.nodes[2].fMinExposure = 200.0000
thisSwitchCam.nodes[2].fMaxExposure = 200.0000
thisSwitchCam.nodes[2].iRampUpDuration = 50
thisSwitchCam.nodes[2].iRampDownDuration = 50
thisSwitchCam.nodes[2].iHoldDuration = 100
thisSwitchCam.nodes[2].fFlashNodePhaseOffset = 0.4100
thisSwitchCam.nodes[2].bIsLowDetailNode = FALSE
thisSwitchCam.nodes[2].bUseCustomDOF = FALSE
thisSwitchCam.nodes[2].NodeDOF_Info.fDOF_NearDOF = 0.0000
thisSwitchCam.nodes[2].NodeDOF_Info.fDOF_FarDOF = 0.0000
thisSwitchCam.nodes[2].NodeDOF_Info.fDOF_EffectStrength = 0.0000
thisSwitchCam.iNumNodes = 3
thisSwitchCam.iCamSwitchFocusNode = 0
thisSwitchCam.fSwitchSoundAudioStartPhase = -1.0000
thisSwitchCam.fSwitchSoundAudioEndPhase = -1.0000
thisSwitchCam.bSplineNoSmoothing = TRUE
thisSwitchCam.bAddGameplayCamAsLastNode = FALSE
thisSwitchCam.iGameplayNodeBlendDuration = 0
//--- End of Cam Data ---
thisSwitchCam.strOutputStructName = "thisSwitchCam"
thisSwitchCam.strOutputFileName = "CameraInfo_FINALEC2_KillSteveExplosionCam.txt"
thisSwitchCam.strXMLFileName = "CameraInfo_FINALEC2_KillSteveExplosionCam.xml"
thisSwitchCam.bInitialized = TRUE
ENDIF
thisSwitchCam.piPeds[0] = piTrevor
thisSwitchCam.piPeds[1] = piSteve
ENDPROC
PROC SETUP_SPLINE_CAM_NODE_ARRAY_KILL_STEVE_GRENADE_CAM(SWITCH_CAM_STRUCT &thisSwitchCam, PED_INDEX piTrevor, PED_INDEX piSteve)
CDEBUG3LN(DEBUG_MISSION, "SETUP_SPLINE_CAM_NODE_ARRAY_KILL_STEVE_EXPLOSION_CAM")
IF NOT thisSwitchCam.bInitialized
//--- Start of Cam Data ---
thisSwitchCam.nodes[0].SwitchCamType = SWITCH_CAM_WORLD_POS
thisSwitchCam.nodes[0].iForceCamPointAtEntityIndex = 1
thisSwitchCam.nodes[0].bIsGameplayCamCopy = FALSE
thisSwitchCam.nodes[0].iNodeTime = 0
thisSwitchCam.nodes[0].vNodePos = <<-1656.2043, -1122.4706, 16.6928>>
thisSwitchCam.nodes[0].vWorldPosLookAt = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[0].fNodeOffsetDist = 35.0000
thisSwitchCam.nodes[0].fNodeVerticleOffset = 0.0000
thisSwitchCam.nodes[0].bAttachToOriginPed = FALSE
thisSwitchCam.nodes[0].vNodeDir = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[0].bPointAtEntity = TRUE
thisSwitchCam.nodes[0].bPointAtOffsetIsRelative = TRUE
thisSwitchCam.nodes[0].bAttachOffsetIsRelative = FALSE
thisSwitchCam.nodes[0].fNodeFOV = 30.0000
thisSwitchCam.nodes[0].vClonedNodeOffset = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[0].iNodeToClone = 0
thisSwitchCam.nodes[0].NodeTimePostFX_Type = NO_EFFECT
thisSwitchCam.nodes[0].fNodeTimePostFXBlendTime = 0.0000
thisSwitchCam.nodes[0].fNodeTimePostFXTimeOffset = 0.0000
thisSwitchCam.nodes[0].fNodeMotionBlur = 0.0000
thisSwitchCam.nodes[0].NodeCamShakeType = CAM_SHAKE_DEFAULT
thisSwitchCam.nodes[0].fNodeCamShake = 0.0000
thisSwitchCam.nodes[0].iCamEaseType = 1
thisSwitchCam.nodes[0].fCamEaseScaler = 1.0000
thisSwitchCam.nodes[0].fCamNodeVelocityScale = 0.0000
thisSwitchCam.nodes[0].bCamEaseForceLinear = TRUE
thisSwitchCam.nodes[0].bCamEaseForceLevel = FALSE
thisSwitchCam.nodes[0].fTimeScale = 0.1000
thisSwitchCam.nodes[0].iTimeScaleEaseType = 0
thisSwitchCam.nodes[0].fTimeScaleEaseScaler = 0.0000
thisSwitchCam.nodes[0].bFlashEnabled = FALSE
thisSwitchCam.nodes[0].SCFE_FlashEffectUsed = SCFE_CODE_FLASH
thisSwitchCam.nodes[0].fMinExposure = 0.0000
thisSwitchCam.nodes[0].fMaxExposure = 0.0000
thisSwitchCam.nodes[0].iRampUpDuration = 0
thisSwitchCam.nodes[0].iRampDownDuration = 0
thisSwitchCam.nodes[0].iHoldDuration = 0
thisSwitchCam.nodes[0].fFlashNodePhaseOffset = 0.0000
thisSwitchCam.nodes[0].bIsLowDetailNode = FALSE
thisSwitchCam.nodes[0].bUseCustomDOF = FALSE
thisSwitchCam.nodes[0].NodeDOF_Info.fDOF_NearDOF = 0.0000
thisSwitchCam.nodes[0].NodeDOF_Info.fDOF_FarDOF = 0.0000
thisSwitchCam.nodes[0].NodeDOF_Info.fDOF_EffectStrength = 0.0000
thisSwitchCam.nodes[1].SwitchCamType = SWITCH_CAM_WORLD_POS
thisSwitchCam.nodes[1].iForceCamPointAtEntityIndex = 1
thisSwitchCam.nodes[1].bIsGameplayCamCopy = FALSE
thisSwitchCam.nodes[1].iNodeTime = 800
thisSwitchCam.nodes[1].vNodePos = <<-1656.2040, -1122.4709, 16.6930>>
thisSwitchCam.nodes[1].vWorldPosLookAt = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[1].fNodeOffsetDist = 36.0000
thisSwitchCam.nodes[1].fNodeVerticleOffset = 0.0000
thisSwitchCam.nodes[1].bAttachToOriginPed = FALSE
thisSwitchCam.nodes[1].vNodeDir = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[1].bPointAtEntity = TRUE
thisSwitchCam.nodes[1].bPointAtOffsetIsRelative = TRUE
thisSwitchCam.nodes[1].bAttachOffsetIsRelative = FALSE
thisSwitchCam.nodes[1].fNodeFOV = 30.0000
thisSwitchCam.nodes[1].vClonedNodeOffset = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[1].iNodeToClone = 0
thisSwitchCam.nodes[1].NodeTimePostFX_Type = NO_EFFECT
thisSwitchCam.nodes[1].fNodeTimePostFXBlendTime = 0.0000
thisSwitchCam.nodes[1].fNodeTimePostFXTimeOffset = 0.0000
thisSwitchCam.nodes[1].fNodeMotionBlur = 0.0000
thisSwitchCam.nodes[1].NodeCamShakeType = CAM_SHAKE_DEFAULT
thisSwitchCam.nodes[1].fNodeCamShake = 0.0000
thisSwitchCam.nodes[1].iCamEaseType = 0
thisSwitchCam.nodes[1].fCamEaseScaler = 0.0000
thisSwitchCam.nodes[1].fCamNodeVelocityScale = 0.0000
thisSwitchCam.nodes[1].bCamEaseForceLinear = TRUE
thisSwitchCam.nodes[1].bCamEaseForceLevel = FALSE
thisSwitchCam.nodes[1].fTimeScale = 0.1000
thisSwitchCam.nodes[1].iTimeScaleEaseType = 0
thisSwitchCam.nodes[1].fTimeScaleEaseScaler = 0.0000
thisSwitchCam.nodes[1].bFlashEnabled = FALSE
thisSwitchCam.nodes[1].SCFE_FlashEffectUsed = SCFE_CODE_FLASH
thisSwitchCam.nodes[1].fMinExposure = 0.0000
thisSwitchCam.nodes[1].fMaxExposure = 0.0000
thisSwitchCam.nodes[1].iRampUpDuration = 0
thisSwitchCam.nodes[1].iRampDownDuration = 0
thisSwitchCam.nodes[1].iHoldDuration = 0
thisSwitchCam.nodes[1].fFlashNodePhaseOffset = 0.0000
thisSwitchCam.nodes[1].bIsLowDetailNode = FALSE
thisSwitchCam.nodes[1].bUseCustomDOF = FALSE
thisSwitchCam.nodes[1].NodeDOF_Info.fDOF_NearDOF = 0.0000
thisSwitchCam.nodes[1].NodeDOF_Info.fDOF_FarDOF = 0.0000
thisSwitchCam.nodes[1].NodeDOF_Info.fDOF_EffectStrength = 0.0000
thisSwitchCam.nodes[2].SwitchCamType = SWITCH_CAM_WORLD_POS
thisSwitchCam.nodes[2].iForceCamPointAtEntityIndex = 1
thisSwitchCam.nodes[2].bIsGameplayCamCopy = FALSE
thisSwitchCam.nodes[2].iNodeTime = 1500
thisSwitchCam.nodes[2].vNodePos = <<-1656.2040, -1122.4709, 16.6930>>
thisSwitchCam.nodes[2].vWorldPosLookAt = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[2].fNodeOffsetDist = 35.0000
thisSwitchCam.nodes[2].fNodeVerticleOffset = 0.0000
thisSwitchCam.nodes[2].bAttachToOriginPed = FALSE
thisSwitchCam.nodes[2].vNodeDir = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[2].bPointAtEntity = TRUE
thisSwitchCam.nodes[2].bPointAtOffsetIsRelative = TRUE
thisSwitchCam.nodes[2].bAttachOffsetIsRelative = FALSE
thisSwitchCam.nodes[2].fNodeFOV = 30.0000
thisSwitchCam.nodes[2].vClonedNodeOffset = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[2].iNodeToClone = 0
thisSwitchCam.nodes[2].NodeTimePostFX_Type = NO_EFFECT
thisSwitchCam.nodes[2].fNodeTimePostFXBlendTime = 0.0000
thisSwitchCam.nodes[2].fNodeTimePostFXTimeOffset = 0.0000
thisSwitchCam.nodes[2].fNodeMotionBlur = 0.0000
thisSwitchCam.nodes[2].NodeCamShakeType = CAM_SHAKE_DEFAULT
thisSwitchCam.nodes[2].fNodeCamShake = 0.0000
thisSwitchCam.nodes[2].iCamEaseType = 0
thisSwitchCam.nodes[2].fCamEaseScaler = 0.0000
thisSwitchCam.nodes[2].fCamNodeVelocityScale = 0.0000
thisSwitchCam.nodes[2].bCamEaseForceLinear = TRUE
thisSwitchCam.nodes[2].bCamEaseForceLevel = FALSE
thisSwitchCam.nodes[2].fTimeScale = 0.1000
thisSwitchCam.nodes[2].iTimeScaleEaseType = 0
thisSwitchCam.nodes[2].fTimeScaleEaseScaler = 0.0000
thisSwitchCam.nodes[2].bFlashEnabled = FALSE
thisSwitchCam.nodes[2].SCFE_FlashEffectUsed = SCFE_CODE_FLASH
thisSwitchCam.nodes[2].fMinExposure = 200.0000
thisSwitchCam.nodes[2].fMaxExposure = 200.0000
thisSwitchCam.nodes[2].iRampUpDuration = 50
thisSwitchCam.nodes[2].iRampDownDuration = 50
thisSwitchCam.nodes[2].iHoldDuration = 100
thisSwitchCam.nodes[2].fFlashNodePhaseOffset = 0.4100
thisSwitchCam.nodes[2].bIsLowDetailNode = FALSE
thisSwitchCam.nodes[2].bUseCustomDOF = FALSE
thisSwitchCam.nodes[2].NodeDOF_Info.fDOF_NearDOF = 0.0000
thisSwitchCam.nodes[2].NodeDOF_Info.fDOF_FarDOF = 0.0000
thisSwitchCam.nodes[2].NodeDOF_Info.fDOF_EffectStrength = 0.0000
thisSwitchCam.iNumNodes = 3
thisSwitchCam.iCamSwitchFocusNode = 0
thisSwitchCam.fSwitchSoundAudioStartPhase = -1.0000
thisSwitchCam.fSwitchSoundAudioEndPhase = -1.0000
thisSwitchCam.bSplineNoSmoothing = TRUE
thisSwitchCam.bAddGameplayCamAsLastNode = FALSE
thisSwitchCam.iGameplayNodeBlendDuration = 0
//--- End of Cam Data ---
thisSwitchCam.strOutputStructName = "thisSwitchCam"
thisSwitchCam.strOutputFileName = "CameraInfo_FINALEC2_KillSteveGrenadeCam.txt"
thisSwitchCam.strXMLFileName = "CameraInfo_FINALEC2_KillSteveGrenadeCam.xml"
thisSwitchCam.bInitialized = TRUE
ENDIF
thisSwitchCam.piPeds[0] = piTrevor
thisSwitchCam.piPeds[1] = piSteve
ENDPROC
/// PURPOSE:
/// Handle the playback of the switch cam. The will setup, play, shut down and cleanup the switch cam spline
/// PARAMS:
/// thisSwitchCam - Switch camera to playback
/// bReturnTrueOnce - If you only want this function to return TRUE once upon completion. Set to FALSE to have this function to return true every time this is called once the camera is finished playback.
/// RETURNS:
/// TRUE when camera is complete, FALSE if playback is still active, or if the camera has completed playback and bReturnTrueOnce is set to TRUE.
FUNC BOOL HANDLE_SWITCH_CAM_BULLET_CAM(SWITCH_CAM_STRUCT &thisSwitchCam, BOOL bReturnTrueOnce = TRUE)
INT iCurrentNode
SWITCH eSwitchCamState
CASE SWITCH_CAM_IDLE
CDEBUG3LN(DEBUG_MISSION, "eSwitchCamState = SWITCH_CAM_IDLE")
BREAK
CASE SWITCH_CAM_REQUEST_ASSETS
CDEBUG3LN(DEBUG_MISSION, "eSwitchCamState = SWITCH_CAM_REQUEST_ASSETS")
REQUEST_PTFX_ASSET()
BREAK
CASE SWITCH_CAM_SETUP_SPLINE
CDEBUG3LN(DEBUG_MISSION, "eSwitchCamState = SWITCH_CAM_SETUP_SPLINE")
IF bSwitchCam_SteveKilledViaExplosion
SETUP_SPLINE_CAM_NODE_ARRAY_KILL_STEVE_EXPLOSION_CAM(thisSwitchCam, PLAYER_PED_ID(), stevePed[STEVE_TARGET])
ELIF bSwitchCam_SteveKilledViaGrenade
SETUP_SPLINE_CAM_NODE_ARRAY_KILL_STEVE_GRENADE_CAM(thisSwitchCam, PLAYER_PED_ID(), stevePed[STEVE_TARGET])
ELSE
SETUP_SPLINE_CAM_NODE_ARRAY_KILL_STEVE_BULLET_CAM(thisSwitchCam, PLAYER_PED_ID(), stevePed[STEVE_TARGET])
ENDIF
REQUEST_PTFX_ASSET()
//DESTROY_ALL_CAMS()
CREATE_SPLINE_CAM(thisSwitchCam)
SET_CAM_ACTIVE(thisSwitchCam.ciSpline, TRUE)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
DISPLAY_RADAR(FALSE)
DISPLAY_HUD(FALSE)
SETTIMERB(0)
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
bPlayerControlGiven = FALSE
eSwitchCamState = SWITCH_CAM_PLAYING_SPLINE
BREAK
CASE SWITCH_CAM_PLAYING_SPLINE
CDEBUG3LN(DEBUG_MISSION, "eSwitchCamState = SWITCH_CAM_PLAYING_SPLINE")
CDEBUG3LN(DEBUG_MISSION, GET_CAM_SPLINE_PHASE(thisSwitchCam.ciSpline))
iCurrentNode = UPDATE_SPLINE_CAM(thisSwitchCam)
IF NOT bSwitchCam_PlayedBloodSpurt
IF NOT bSwitchCam_SteveKilledViaExplosion
AND NOT bSwitchCam_SteveKilledViaGrenade
IF GET_CAM_SPLINE_PHASE(thisSwitchCam.ciSpline) >= fSwitchCam_StartBloodSpurtPhase
IF NOT IS_PED_INJURED(stevePed[STEVE_TARGET])
REMOVE_PARTICLE_FX_FROM_ENTITY(stevePed[STEVE_TARGET])
START_PARTICLE_FX_NON_LOOPED_ON_ENTITY("scr_finale2_blood_entry", stevePed[STEVE_TARGET], vSwitchCam_BloodSpurtLoc, vSwitchCam_BloodSpurtRot, fSwitchCam_StartBloodSpurtScale)
bSwitchCam_PlayedBloodSpurt = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
IF IS_CAM_ACTIVE(thisSwitchCam.ciSpline)
IF iCurrentNode >= thisSwitchCam.iCamSwitchFocusNode
SET_GAMEPLAY_CAM_RELATIVE_HEADING(fGameplayCamHeadingToTrevorInHeli)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(fGameplayCamPitchToTrevorInHeli)
ENDIF
//[MF] Once cam is at the end, reset the gameplay cam positon and advance to next state.
IF GET_CAM_SPLINE_PHASE(thisSwitchCam.ciSpline) >= 1.00
CDEBUG3LN(DEBUG_MISSION, "eSwitchCamState = SWITCH_CAM_RETURN_TO_GAMEPLAY")
SET_GAMEPLAY_CAM_RELATIVE_HEADING(fGameplayCamHeadingToTrevorInHeli)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(fGameplayCamPitchToTrevorInHeli)
eSwitchCamState = SWITCH_CAM_RETURN_TO_GAMEPLAY
ENDIF
ENDIF
BREAK
CASE SWITCH_CAM_RETURN_TO_GAMEPLAY
SET_TIME_SCALE(1.0)
IF NOT bPlayerControlGiven
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
DISPLAY_RADAR(TRUE)
DISPLAY_HUD(TRUE)
bPlayerControlGiven = TRUE
ENDIF
SETTIMERA(0)
eSwitchCamState = SWITCH_CAM_IDLE
thisSwitchCam.bIsSplineCamFinishedPlaying = TRUE
SET_PLAYER_CONTROL(PLAYER_ID(), true)
RETURN TRUE
BREAK
ENDSWITCH
IF bReturnTrueOnce
RETURN FALSE
ELSE
RETURN thisSwitchCam.bIsSplineCamFinishedPlaying
ENDIF
ENDFUNC
#IF IS_DEBUG_BUILD
/// PURPOSE:
/// Create the debug widgets for working with the scripted character switch cam.
PROC CREATE_SWITCH_CAM_SCRIPT_SPECIFIC_WIDGETS()
CDEBUG3LN(DEBUG_MISSION, "CREATE_SWITCH_CAM_SCRIPT_SPECIFIC_WIDGETS")
START_WIDGET_GROUP("Switch Cam Specific Debug Tools")
ADD_WIDGET_BOOL("Jump To Kill Steve", bDEBUG_SwitchCamJumpToKillSteve)
ADD_WIDGET_BOOL("Shoot Steve with Bullet", bDEBUG_ForceBulletKillSteve)
ADD_WIDGET_BOOL("Explode Steve", bDEBUG_ForceExplosionKillSteve)
START_WIDGET_GROUP("Blood Spurt Tuner")
ADD_WIDGET_BOOL("Start Blood FX Tuner", bDEBUG_BloodFX_Tester)
ADD_WIDGET_VECTOR_SLIDER("Blood Spurt Loc", vSwitchCam_BloodSpurtLoc, -10.0, 10.0, 0.1)
ADD_WIDGET_VECTOR_SLIDER("Blood Spurt Rot", vSwitchCam_BloodSpurtRot, -360.0, 360.0, 5.0)
ADD_WIDGET_FLOAT_SLIDER("Blood Spurt Start Phase", fSwitchCam_StartBloodSpurtPhase, 0.0, 1.0, 0.05)
ADD_WIDGET_FLOAT_SLIDER("Blood Spurt Start Scale", fSwitchCam_StartBloodSpurtScale, 0.0, 10.0, 0.2)
STOP_WIDGET_GROUP()
STOP_WIDGET_GROUP()
ENDPROC
#ENDIF
// Debug
#IF IS_DEBUG_BUILD
WIDGET_GROUP_ID finaleWidgets
TEXT_WIDGET_ID RBCamPosWidget, RBCamRotWidget
BOOL bRBDebugCamDoDump
VECTOR vRBDebugCamPos
VECTOR vRBDebugCamRot
FLOAT fRBDebugCamFOV
MissionStageMenuTextStruct stageMenu[MAX_SKIP_MENU_LENGTH]
INT iMenuMissionStage
INT iDebugStage = -1
BOOL bDebugJSkip
#ENDIF
// get recording prefix
FUNC STRING GET_FINALE_RECORDING_PREFIX()
RETURN "finalec"
ENDFUNC
FUNC STRING GET_DESCRIPTION_FOR_STAGE_AS_STRING(MISSION_STAGE_ENUM thisStage)
SWITCH thisStage
CASE STAGE_GET_TO_HIT
RETURN "Get to the hits"
BREAK
CASE STAGE_TREVOR_HIT
RETURN "Trevor kill Steve"
BREAK
CASE STAGE_MICHAEL_HIT
RETURN "Michael kill Stretch"
BREAK
CASE STAGE_FRANKLIN_HIT
RETURN "Franklin kill Cheng"
BREAK
CASE STAGE_PICKUP_DEVIN
RETURN "Get to Devin's house"
BREAK
CASE STAGE_DEVINS_HOUSE
RETURN "Kidnap Devin"
BREAK
CASE STAGE_GET_TO_CLIFF
RETURN "Get to the cliff"
BREAK
ENDSWITCH
RETURN "invalid"
ENDFUNC
// can advance mission
FUNC BOOL CAN_ADVANCE_MISSION()
IF missionFailState = MISSION_FAIL_STATE_NOT_FAILED
AND freeHotswapData.state = FREE_HOTSWAP_STATE_SELECTING
AND NOT IS_PLAYER_BROWSING_ITEMS_IN_ANY_SHOP()
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
// do mission god text
FUNC BOOL DO_MISSION_GOD_TEXT(STRING sGodText, BOOL bSupercedeText = TRUE, BOOL bSupercedeSpeech = FALSE)
IF bSupercedeText OR NOT IS_MESSAGE_BEING_DISPLAYED()
IF bSupercedeSpeech
OR NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
OR NOT IS_SUBTITLE_PREFERENCE_SWITCHED_ON()
IF CAN_ADVANCE_MISSION()
PRINT_NOW(sGodText, DEFAULT_GOD_TEXT_TIME, 1)
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
// do mission help text
FUNC BOOL DO_MISSION_HELP_TEXT(STRING sHelpText)
IF NOT IS_HELP_MESSAGE_BEING_DISPLAYED()
IF CAN_ADVANCE_MISSION()
PRINT_HELP(sHelpText)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
// do mission speech
FUNC BOOL DO_MISSION_SPEECH(STRING sSpeech, BOOL bSupercedeText = FALSE, INT iLine = 0, BOOL bFromSpecifiedLine = FALSE)
IF bSupercedeText OR NOT IS_MESSAGE_BEING_DISPLAYED() OR NOT IS_SUBTITLE_PREFERENCE_SWITCHED_ON()
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF CAN_ADVANCE_MISSION()
IF iLine = 0
RETURN CREATE_CONVERSATION(finaleConversation, "FINC1AU", sSpeech, CONV_PRIORITY_HIGH)
ELSE
TEXT_LABEL tLine
tLine = sSpeech
tLine+="_"
tLine+=iLine
IF NOT bFromSpecifiedLine
RETURN PLAY_SINGLE_LINE_FROM_CONVERSATION(finaleConversation, "FINC1AU", sSpeech, tLine, CONV_PRIORITY_HIGH)
ELSE
RETURN CREATE_CONVERSATION_FROM_SPECIFIC_LINE(finaleConversation, "FINC1AU", sSpeech, tLine, CONV_PRIORITY_HIGH)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
// remove mission text
PROC REMOVE_MISSION_TEXT(BOOL bClearSpeech = TRUE, BOOL bClearGodText = TRUE, BOOL bClearHelpText = TRUE, BOOL bKeepSubs = FALSE)
IF bClearSpeech
KILL_ANY_CONVERSATION()
ENDIF
IF bClearGodText
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
OR (bClearSpeech AND NOT bKeepSubs)
CLEAR_PRINTS()
ENDIF
CLEAR_REMINDER_MESSAGE()
ENDIF
IF bClearHelpText
IF GET_GAME_TIMER() >= iClearHelpTime + 1000
CLEAR_HELP()
iClearHelpTime = GET_GAME_TIMER()
ENDIF
ENDIF
ENDPROC
FUNC BLIP_INDEX CREATE_MISSION_BLIP_FOR_VEHICLE(VEHICLE_INDEX vehicle, bool isEnemyVehicle=FALSE)
IF CAN_ADVANCE_MISSION()
RETURN CREATE_BLIP_FOR_VEHICLE(vehicle, isEnemyVehicle)
ENDIF
RETURN NULL
ENDFUNC
FUNC BLIP_INDEX CREATE_MISSION_BLIP_FOR_PED(PED_INDEX ped, BOOL isEnemyPed=FALSE)
IF CAN_ADVANCE_MISSION()
RETURN CREATE_BLIP_FOR_PED(ped, isEnemyPed)
ENDIF
RETURN NULL
ENDFUNC
FUNC BLIP_INDEX CREATE_MISSION_BLIP_FOR_OBJECT(OBJECT_INDEX object)
IF CAN_ADVANCE_MISSION()
RETURN CREATE_BLIP_FOR_OBJECT(object)
ENDIF
RETURN NULL
ENDFUNC
FUNC BLIP_INDEX CREATE_MISSION_BLIP_FOR_COORD(VECTOR vCoords, BOOL bSetRoute = FALSE)
IF CAN_ADVANCE_MISSION()
RETURN CREATE_BLIP_FOR_COORD(vCoords, bSetRoute)
ENDIF
RETURN NULL
ENDFUNC
FUNC BOOL TRIGGER_MISSION_MUSIC_EVENT(STRING sEvent)
RETURN TRIGGER_MUSIC_EVENT(sEvent)
ENDFUNC
FUNC BOOL SHOULD_USE_START_VEHICLE()
IF IS_REPLAY_START_VEHICLE_AVAILABLE()
IF IS_REPLAY_START_VEHICLE_UNDER_SIZE_LIMIT(GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR())
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
// get model for a train crash model enum
FUNC MODEL_NAMES GET_MODEL_FOR_FINALE_MODEL_ENUM(FINALE_MODEL_ENUM FModel)
SWITCH FModel
CASE FM_MICHAEL
RETURN GET_PLAYER_PED_MODEL(CHAR_MICHAEL)
BREAK
CASE FM_FRANKLIN
RETURN GET_PLAYER_PED_MODEL(CHAR_FRANKLIN)
BREAK
CASE FM_TREVOR
RETURN GET_PLAYER_PED_MODEL(CHAR_TREVOR)
BREAK
CASE FM_DEVIN
RETURN GET_NPC_PED_MODEL(CHAR_DEVIN)
BREAK
CASE FM_MICHAEL_CAR
RETURN GET_PLAYER_VEH_MODEL(CHAR_MICHAEL)
BREAK
CASE FM_FRANKLIN_BIKE
RETURN GET_PLAYER_VEH_MODEL(CHAR_FRANKLIN, VEHICLE_TYPE_BIKE)
BREAK
CASE FM_TREVOR_CAR
RETURN GET_PLAYER_VEH_MODEL(CHAR_TREVOR)
BREAK
CASE FM_DEVIN_CAR
RETURN TORNADO
BREAK
//CASE FM_STRETCH_CAR
// RETURN PHOENIX
//BREAK
CASE FM_CHENG_SR
RETURN GET_NPC_PED_MODEL(CHAR_CHENGSR)
BREAK
CASE FM_CHENG_JR
RETURN GET_NPC_PED_MODEL(CHAR_CHENG)
BREAK
CASE FM_TRIAD
RETURN G_M_M_CHIGOON_02
BREAK
CASE FM_TRIAD_BOSS_CAR
RETURN WASHINGTON
BREAK
CASE FM_TRIAD_ESCORT_CAR
RETURN CAVALCADE
BREAK
CASE FM_GANGSTER_CAR
RETURN FELON
BREAK
CASE FM_STEVE
RETURN CS_STEVEHAINS
BREAK
CASE FM_CAMERAMAN
RETURN S_M_Y_GRIP_01
BREAK
CASE FM_BYSTANDER
RETURN A_F_Y_HIPSTER_04
BREAK
CASE FM_CAMERA
RETURN PROP_V_CAM_01
BREAK
CASE FM_STRETCH
RETURN GET_NPC_PED_MODEL(CHAR_STRETCH)
BREAK
CASE FM_GANGSTER
RETURN G_M_Y_BALLAORIG_01
BREAK
CASE FM_COP
RETURN S_M_Y_COP_01
BREAK
CASE FM_MERRYWEATHER
RETURN S_M_Y_BLACKOPS_01
BREAK
CASE FM_STRETCH_PHONE
RETURN PROP_PHONE_ING_02
BREAK
CASE FM_BASKETBALL
RETURN PROP_BSKBALL_01
BREAK
CASE FM_FERRIS_WHEEL
RETURN Prop_LD_Ferris_Wheel
BREAK
CASE FM_GONDOLA
RETURN PROP_FERRIS_CAR_01
BREAK
CASE FM_BOX
RETURN p_devin_box_01_s
BREAK
CASE FM_BOX_COLLISION
RETURN INT_TO_ENUM(MODEL_NAMES, HASH("Prop_Devin_box_Dummy_01"))
BREAK
CASE FM_TABLET
RETURN Prop_CS_Tablet
BREAK
//CASE FM_BULLDOZER
// RETURN BULLDOZER
//BREAK
ENDSWITCH
RETURN DUMMY_MODEL_FOR_SCRIPT
ENDFUNC
// suppress vehicles
PROC SUPPRESS_MISSION_VEHICLES(BOOL bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_MICHAEL_CAR), bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_TREVOR_CAR), bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_FRANKLIN_BIKE), bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_DEVIN_CAR), bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_TRIAD_BOSS_CAR), bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_TRIAD_ESCORT_CAR), bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_GANGSTER_CAR), bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(TORNADO2, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(TORNADO3, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(TORNADO4, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(VOODOO2, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(BALLER, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(BALLER2, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(GRANGER, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(CAVALCADE2, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(LANDSTALKER, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(POLICE, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(POLICE2, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(POLICE3, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(POLICEB, bSuppress)
SET_PED_MODEL_IS_SUPPRESSED(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_TRIAD), bSuppress)
SET_PED_MODEL_IS_SUPPRESSED(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_GANGSTER), bSuppress)
SET_PED_MODEL_IS_SUPPRESSED(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_STRETCH), bSuppress)
SET_PED_MODEL_IS_SUPPRESSED(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_STEVE), bSuppress)
SET_PED_MODEL_IS_SUPPRESSED(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_DEVIN), bSuppress)
SET_PED_MODEL_IS_SUPPRESSED(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_MERRYWEATHER), bSuppress)
ENDPROC
// set player out of any vehicle
PROC SET_PLAYER_OUT_OF_ANY_VEHICLE()
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
VECTOR vCoords = GET_ENTITY_COORDS(PLAYER_PED_ID())
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<vCoords.x, vCoords.y, vCoords.z + 1>>)
ENDIF
ENDIF
ENDPROC
// disable/reenable cargens
PROC ENABLE_CARGENS_FOR_MISSION(BOOL bEnable)
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<-3042.67, 70.47, 0.80>>, <<-2993.63, 104.81, 41.62>>, bEnable)
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<-1612.85730, 5140.95801, -0.46138>>, <<-1545.95996, 5192.41064, 100>>, bEnable)
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<-195.27240, -1520.47668, 27.33081>>, <<-172.58878, -1506.32727, 36.90620>>, bEnable)
ENDPROC
// switch off roads for mission
PROC SET_FINALE_ROADS_OFF(BOOL bSwitchOff)
INT i
VECTOR vMin
VECTOR vMax
REPEAT 1 i
SWITCH i
CASE 0
vMin = <<-1676.06372, -1054.87463, 10.05305>>
vMax = <<-1441.92542, -773.83691, 31.43933>>
BREAK
ENDSWITCH
IF bSwitchOff
SET_ROADS_IN_AREA(vMin, vMax, FALSE)
ELSE
SET_ROADS_BACK_TO_ORIGINAL(vMin, vMax)
ENDIF
ENDREPEAT
//SET_PED_PATHS_IN_AREA(<<-210.16, 834.94, 127.18>>, <<-53.02, 1032.16, 281.37>>, NOT bSwitchOff)
SET_PED_PATHS_IN_AREA(<<-227.33, -1525.38, 10.58>>, <<-184.80, -1503.12, 51.22>>, NOT bSwitchOff)
ENDPROC
FUNC STRING GET_FINALE_AUDIO_SCENE_AS_STRING(FINALE_AUDIO_SCENE_ENUM thisScene)
SWITCH thisScene
CASE FINALE_AUDIO_SCENE_FRANKLIN_DRIVE
RETURN "FINALE_FRANKLIN_DRIVE"
BREAK
CASE FINALE_AUDIO_SCENE_FRANKLIN_ON_FOOT
RETURN "FINALE_FRANKLIN_ON_FOOT"
BREAK
CASE FINALE_AUDIO_SCENE_FRANKLIN_KILL_CHENG
RETURN "FINALE_FRANKLIN_KILL_CHENG"
BREAK
CASE FINALE_AUDIO_SCENE_MICHAEL_DRIVE
RETURN "FINALE_MICHAEL_DRIVE"
BREAK
CASE FINALE_AUDIO_SCENE_MICHAEL_ON_FOOT
RETURN "FINALE_MICHAEL_ON_FOOT"
BREAK
CASE FINALE_AUDIO_SCENE_MICHAEL_KILL_STRETCH
RETURN "FINALE_MICHAEL_KILL_STRETCH"
BREAK
CASE FINALE_AUDIO_SCENE_TREVOR_DRIVE
RETURN "FINALE_TREVOR_DRIVE"
BREAK
CASE FINALE_AUDIO_SCENE_TREVOR_ON_FOOT
RETURN "FINALE_TREVOR_ON_FOOT"
BREAK
CASE FINALE_AUDIO_SCENE_TREVOR_KILL_STEVE
RETURN "FINALE_TREVOR_KILL_STEVE"
BREAK
CASE FINALE_AUDIO_SCENE_DRIVE_TO_DEVIN
RETURN "FINALE_DRIVE_TO_DEVIN"
BREAK
CASE FINALE_AUDIO_SCENE_DRIVE_TO_OCEAN
RETURN "FINALE_DRIVE_TO_OCEAN"
BREAK
CASE FINALE_AUDIO_SCENE_PUSH_CAR
RETURN "FINALE_PUSH_CAR"
BREAK
// SECOND LOT
CASE FINALE_AUDIO_SCENE_FRANKLIN_ESCAPE_TRIADS
RETURN "FINALE_FRANKLIN_ESCAPE_TRIADS"
BREAK
CASE FINALE_AUDIO_SCENE_MICHAEL_KILL_BALLAS
RETURN "FINALE_MICHAEL_KILL_BALLAS"
BREAK
CASE FINALE_AUDIO_SCENE_MICHAEL_ENEMY_CAR_ARRIVES
RETURN "FINALE_MICHAEL_ENEMY_CAR_ARRIVES"
BREAK
CASE FINALE_AUDIO_SCENE_TREVOR_FOCUS_ON_WHEEL
RETURN "FINALE_TREVOR_FOCUS_ON_WHEEL"
BREAK
CASE FINALE_AUDIO_SCENE_TREVOR_WATCH_STEVE_CAMERA
RETURN "FINALE_TREVOR_WATCH_STEVE_CAMERA"
BREAK
CASE FINALE_AUDIO_SCENE_TREVOR_KILL_CAM
RETURN "FINALE_TREVOR_KILL_CAM"
BREAK
CASE FINALE_AUDIO_SCENE_DEVINS_HOUSE_OVERVIEW
RETURN "FINALE_DEVINS_HOUSE_OVERVIEW"
BREAK
CASE FINALE_AUDIO_SCENE_KIDNAP_DEVIN_STEALTH
RETURN "FINALE_KIDNAP_DEVIN_STEALTH"
BREAK
CASE FINALE_AUDIO_SCENE_KIDNAP_DEVIN_ALERT
RETURN "FINALE_KIDNAP_DEVIN_ALERT"
BREAK
ENDSWITCH
RETURN ""
ENDFUNC
// start finale audio scene
FUNC BOOL START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_ENUM thisScene)
RETURN START_AUDIO_SCENE(GET_FINALE_AUDIO_SCENE_AS_STRING(thisScene))
ENDFUNC
// stop finale audio scene
PROC STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_ENUM thisScene)
STOP_AUDIO_SCENE(GET_FINALE_AUDIO_SCENE_AS_STRING(thisScene))
ENDPROC
// stop all finale audio scenes
PROC STOP_ALL_FINALE_AUDIO_SCENES(BOOL bStopAssassinationScenes = TRUE)
INT i
IF bStopAssassinationScenes
REPEAT COUNT_OF(FINALE_AUDIO_SCENE_ENUM) i
STOP_FINALE_AUDIO_SCENE(INT_TO_ENUM(FINALE_AUDIO_SCENE_ENUM, i))
ENDREPEAT
ELSE
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_FRANKLIN_DRIVE)
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_FRANKLIN_ON_FOOT)
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_MICHAEL_DRIVE)
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_MICHAEL_ON_FOOT)
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_TREVOR_DRIVE)
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_TREVOR_ON_FOOT)
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_DRIVE_TO_DEVIN)
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_DRIVE_TO_OCEAN)
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_PUSH_CAR)
ENDIF
ENDPROC
// handle audio scenes
PROC HANDLE_AUDIO_SCENES()
IF NOT bRunningCutscene
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF NOT bDoingDriveAudioScene
STOP_ALL_FINALE_AUDIO_SCENES(FALSE)
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_MICHAEL_DRIVE)
BREAK
CASE CHAR_TREVOR
IF currentMissionStage < STAGE_PICKUP_DEVIN
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_TREVOR_DRIVE)
ELIF currentMissionStage = STAGE_PICKUP_DEVIN
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_DRIVE_TO_DEVIN)
ELIF currentMissionStage = STAGE_GET_TO_CLIFF
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_DRIVE_TO_OCEAN)
ENDIF
BREAK
CASE CHAR_FRANKLIN
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_FRANKLIN_DRIVE)
BREAK
ENDSWITCH
bDoingOnFootAudioScene = FALSE
bDoingDriveAudioScene = TRUE
ENDIF
ELSE
IF NOT bDoingOnFootAudioScene
STOP_ALL_FINALE_AUDIO_SCENES(FALSE)
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_MICHAEL_ON_FOOT)
BREAK
CASE CHAR_TREVOR
IF currentMissionStage < STAGE_PICKUP_DEVIN
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_TREVOR_ON_FOOT)
ENDIF
BREAK
CASE CHAR_FRANKLIN
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_FRANKLIN_ON_FOOT)
BREAK
ENDSWITCH
bDoingDriveAudioScene = FALSE
bDoingOnFootAudioScene = TRUE
ENDIF
ENDIF
ENDIF
ENDPROC
// remove blips
PROC REMOVE_ALL_BLIPS()
IF DOES_BLIP_EXIST(gotoBlip)
REMOVE_BLIP(gotoBlip)
ENDIF
IF DOES_BLIP_EXIST(vehicleBlip)
REMOVE_BLIP(vehicleBlip)
ENDIF
IF DOES_BLIP_EXIST(devinBlip)
REMOVE_BLIP(devinBlip)
ENDIF
IF DOES_BLIP_EXIST(stretchBlip)
REMOVE_BLIP(stretchBlip)
ENDIF
IF DOES_BLIP_EXIST(chengBlip)
REMOVE_BLIP(chengBlip)
ENDIF
INT i
REPEAT 3 i
IF DOES_BLIP_EXIST(buddyBlip[i])
REMOVE_BLIP(buddyBlip[i])
ENDIF
ENDREPEAT
REPEAT COUNT_OF(STEVE_ENUM) i
IF DOES_BLIP_EXIST(steveBlip[i])
REMOVE_BLIP(steveBlip[i])
ENDIF
ENDREPEAT
REPEAT COUNT_OF(GANGSTER_ENUM) i
CLEANUP_AI_PED_BLIP(gangsterPed[i].blipStruct)
ENDREPEAT
REPEAT COUNT_OF(TRIAD_ENUM) i
CLEANUP_AI_PED_BLIP(triadPed[i].blipStruct)
ENDREPEAT
REPEAT COUNT_OF(MERRYWEATHER_ENUM) i
CLEANUP_AI_PED_BLIP(merryweatherPed[i].blipStruct)
ENDREPEAT
REPEAT NUMBER_GANGSTER_VEHICLES i
IF DOES_BLIP_EXIST(gangsterVehicleBlip[i])
REMOVE_BLIP(gangsterVehicleBlip[i])
ENDIF
ENDREPEAT
REPEAT COUNT_OF(TRIAD_VEHICLE_ENUM) i
IF DOES_BLIP_EXIST(triadVehicleBlip[i])
REMOVE_BLIP(triadVehicleBlip[i])
ENDIF
ENDREPEAT
ENDPROC
// common player and cam cleanup stuff
PROC DO_COMMON_PLAYER_AND_CAM_CLEANUP()
IF IS_PLAYER_PLAYING(PLAYER_ID())
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
SET_PLAYER_INVINCIBLE(PLAYER_ID(), FALSE)
ENDIF
DISPLAY_HUD(TRUE)
DISPLAY_RADAR(TRUE)
RENDER_SCRIPT_CAMS(FALSE, FALSE)
SET_SCRIPTS_SAFE_FOR_CUTSCENE(FALSE)
DISABLE_CELLPHONE(FALSE)
FORCE_CHASE_HINT_CAM(localChaseHintCamStruct, FALSE)
RESET_CUSTOM_CHASE_HINT_CAM_INTERP_IN_TIME(localChaseHintCamStruct)
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
ENDPROC
// cleanup the mission
PROC MISSION_CLEANUP()
REMOVE_MISSION_TEXT()
STOP_ALL_FINALE_AUDIO_SCENES()
PAUSE_CLOCK(FALSE)
IF bFailedOut
IF DOES_ENTITY_EXIST(wheelObject)
DELETE_OBJECT(wheelObject)
ENDIF
INT i
REPEAT NUMBER_GONDOLAS i
IF DOES_ENTITY_EXIST(gondolaObject[i])
DELETE_OBJECT(gondolaObject[i])
ENDIF
ENDREPEAT
ENDIF
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", FALSE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_FERRIS_WHEEL, BUILDINGSTATE_NORMAL, NOT bFailedOut)
//REQUEST_IPL("ferris_finale_Anim")
TRIGGER_MUSIC_EVENT("FINC2_FAIL")
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
SET_CREATE_RANDOM_COPS(TRUE)
SET_POLICE_IGNORE_PLAYER(PLAYER_ID(), FALSE)
LOCK_AUTOMATIC_DOOR_OPEN(AUTODOOR_DEVIN_GATE_L, FALSE)
LOCK_AUTOMATIC_DOOR_OPEN(AUTODOOR_DEVIN_GATE_R, FALSE)
STOP_SOUND(iPushCarSoundID)
RELEASE_SOUND_ID(iPushCarSoundID)
WATER_OVERRIDE_SET_STRENGTH(0.0)
SET_GPS_DISABLED_ZONE(<<0,0,0>>, <<0,0,0>>)
SET_INSTANCE_PRIORITY_HINT(INSTANCE_HINT_NONE)
//RESTORE_PLAYER_PED_VARIATIONS(PLAYER_PED_ID())
IF STREAMVOL_IS_VALID(trevorVolume)
STREAMVOL_DELETE(trevorVolume)
ENDIF
IF STREAMVOL_IS_VALID(devinVolume)
STREAMVOL_DELETE(devinVolume)
ENDIF
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
SET_ENTITY_VISIBLE(PLAYER_PED_ID(), TRUE)
IF NOT IS_PED_WEARING_HELMET(PLAYER_PED_ID())
SET_PED_HELMET_PROP_INDEX(PLAYER_PED_ID(), -1)
SET_PED_HELMET_TEXTURE_INDEX(PLAYER_PED_ID(), -1)
ENDIF
SET_PED_USING_ACTION_MODE(PLAYER_PED_ID(), FALSE)
SET_PED_CAN_SWITCH_WEAPON(PLAYER_PED_ID(), TRUE)
//RESTORE_PLAYER_PED_VARIATIONS(PLAYER_PED_ID())
IF IS_ENTITY_ATTACHED(PLAYER_PED_ID())
IF NOT GET_IS_PED_GADGET_EQUIPPED(PLAYER_PED_ID(), GADGETTYPE_PARACHUTE)
IF GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()) = NULL
CLEAR_PED_TASKS(PLAYER_PED_ID())
DETACH_ENTITY(PLAYER_PED_ID())
ENDIF
ENDIF
ENDIF
// reset proofs
SET_ENTITY_PROOFS(PLAYER_PED_ID(), FALSE, FALSE, FALSE, FALSE, FALSE)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(PLAYER_PED_ID(), FALSE)
SET_PED_CAN_BE_KNOCKED_OFF_VEHICLE(PLAYER_PED_ID(), KNOCKOFFVEHICLE_DEFAULT)
ENDIF
IF bThoroughCleanup
IF DOES_ENTITY_EXIST(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
DELETE_PED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
ENDIF
IF DOES_ENTITY_EXIST(sSelectorPeds.pedID[SELECTOR_PED_MICHAEL])
DELETE_PED(sSelectorPeds.pedID[SELECTOR_PED_MICHAEL])
ENDIF
IF DOES_ENTITY_EXIST(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
DELETE_PED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
ENDIF
ENDIF
DO_COMMON_PLAYER_AND_CAM_CLEANUP()
RESET_WANTED_LEVEL_DIFFICULTY(PLAYER_ID())
//IF mocapStreamingStage >= MOCAP_STREAMING_STAGE_WAIT
REMOVE_CUTSCENE()
//ENDIF
// enable emergency services
SET_WANTED_LEVEL_MULTIPLIER(1.0)
SET_MAX_WANTED_LEVEL(5)
ENABLE_DISPATCH_SERVICE(DT_AMBULANCE_DEPARTMENT, TRUE)
ENABLE_DISPATCH_SERVICE(DT_FIRE_DEPARTMENT, TRUE)
SET_FRONTEND_RADIO_ACTIVE(TRUE)
// enable other ambient stuff
SUPPRESS_MISSION_VEHICLES(FALSE)
SET_FINALE_ROADS_OFF(FALSE)
ENABLE_CARGENS_FOR_MISSION(TRUE)
REMOVE_SCENARIO_BLOCKING_AREA(recScenarioBlocking)
REMOVE_SCENARIO_BLOCKING_AREA(clubScenarioBlocking)
REMOVE_SCENARIO_BLOCKING_AREA(loungersScenarioBlocking)
REMOVE_SCENARIO_BLOCKING_AREA(loungersScenarioBlocking2)
REMOVE_SCENARIO_BLOCKING_AREA(photographerScenarioBlocking)
DISABLE_CELLPHONE(FALSE)
#IF IS_DEBUG_BUILD
IF DOES_WIDGET_GROUP_EXIST(finaleWidgets)
DELETE_WIDGET_GROUP(finaleWidgets)
ENDIF
#ENDIF
TERMINATE_THIS_THREAD()
ENDPROC
// mission passed
PROC MISSION_PASSED()
INFORM_MISSION_STATS_OF_INCREMENT(FIN_KILLS) // one for devin
IF NOT bAwardedAchievement
AWARD_ACHIEVEMENT_FOR_MISSION(ACH04) // To live or die in los santos
ENDIF
g_iFinaleCreditsToPlay = 2
IF IS_REPEAT_PLAY_ACTIVE()
g_MissionStatSystemSuppressVisual = TRUE
TRIGGER_MISSION_STATS_UI(TRUE, TRUE)
ENDIF
Mission_Flow_Mission_Passed(TRUE)
IF IS_REPEAT_PLAY_ACTIVE()
g_bMissionStatSystemBlocker = FALSE
ENDIF
MISSION_CLEANUP()
ENDPROC
// mission failed
PROC MISSION_FAILED(FAIL_REASON_ENUM reasonForFail)
IF CAN_ADVANCE_MISSION()
REMOVE_ALL_BLIPS()
REMOVE_MISSION_TEXT(TRUE, TRUE, TRUE, TRUE)
missionFailState = MISSION_FAIL_STATE_WAIT_FOR_FADE
savedFailReason = reasonForFail
TRIGGER_MUSIC_EVENT("FINC2_FAIL")
STRING failText
SWITCH savedFailReason
CASE FAIL_MICHAEL_DEAD
failText = "CMN_MDIED"
BREAK
CASE FAIL_FRANKLIN_DEAD
failText = "CMN_FDIED"
BREAK
CASE FAIL_TREVOR_DEAD
failText = "CMN_TDIED"
BREAK
CASE FAIL_DEVIN_DEAD
failText = "FC2_FAIL1"
BREAK
CASE FAIL_DEVIN_CAR_DESTROYED
failText = "FC2_FAIL2"
BREAK
CASE FAIL_DEVIN_CAR_ABANDONED
failText = "FC2_FAIL4"
BREAK
CASE FAIL_DEVIN_CAR_STUCK
failText = "FC2_FAIL3"
BREAK
CASE FAIL_MICHAEL_CAR_DESTROYED
failText = "CMN_MDEST"
BREAK
CASE FAIL_MICHAEL_CAR_ABANDONED
failText = "FC2_FAIL6"
BREAK
CASE FAIL_MICHAEL_CAR_STUCK
failText = "FC2_FAIL5"
BREAK
CASE FAIL_TREVOR_CAR_DESTROYED
failText = "CMN_TDEST"
BREAK
CASE FAIL_TREVOR_CAR_ABANDONED
failText = "FC2_FAIL8"
BREAK
CASE FAIL_TREVOR_CAR_STUCK
failText = "FC2_FAIL7"
BREAK
CASE FAIL_FRANKLIN_BIKE_DESTROYED
failText = "FC2_FAIL11"
BREAK
CASE FAIL_FRANKLIN_BIKE_ABANDONED
failText = "FC2_FAIL9"
BREAK
CASE FAIL_FRANKLIN_BIKE_STUCK
failText = "FC2_FAIL10"
BREAK
CASE FAIL_STEVE_TOO_LONG
failText = "FC2_FAIL12"
BREAK
CASE FAIL_STEVE_SPOOKED
failText = "FC2_FAIL13"
BREAK
//CASE FAIL_TRIADS_EARLY
// failText = "FC2_FAIL14"
//BREAK
CASE FAIL_WRONG_STEVE
failText = "FC2_FAIL15"
BREAK
CASE FAIL_WRONG_STRETCH
failText = "FC2_FAIL16"
BREAK
CASE FAIL_WRONG_TRIADS
failText = "FC2_FAIL17"
BREAK
CASE FAIL_WRONG_STEVE_DEAD
failText = "FC2_FAIL15B"
BREAK
CASE FAIL_WRONG_STRETCH_DEAD
failText = "FC2_FAIL16B"
BREAK
CASE FAIL_WRONG_TRIADS_DEAD
failText = "FC2_FAIL17B"
BREAK
CASE FAIL_ABANDONED_STEVE
failText = "FC2_FAIL18"
BREAK
CASE FAIL_LOST_STRETCH
failText = "FC2_FAIL19"
BREAK
CASE FAIL_LOST_CHENG
failText = "FC2_FAIL20"
BREAK
CASE FAIL_SPOOKED_DEVIN
failText = "FC2_FAIL21"
BREAK
CASE FAIL_NOT_DISPOSED_DEVIN
failText = "FC2_FAIL22"
BREAK
CASE FAIL_ABANDONED_DEVIN
failText = "FC2_FAIL23"
BREAK
CASE FAIL_POLICE_DEVIN
failText = "FC2_FAIL24"
BREAK
ENDSWITCH
MISSION_FLOW_MISSION_FAILED_WITH_REASON(failText)
ENDIF
ENDPROC
// remove car blip and text
PROC REMOVE_CAR_BLIP_AND_TEXT()
IF DOES_BLIP_EXIST(vehicleBlip)
REMOVE_BLIP(vehicleBlip)
ENDIF
IF IS_THIS_PRINT_BEING_DISPLAYED("CMN_GENGETINBK")
OR IS_THIS_PRINT_BEING_DISPLAYED("CMN_MGETIN")
OR IS_THIS_PRINT_BEING_DISPLAYED("CMN_TGETIN")
OR IS_THIS_PRINT_BEING_DISPLAYED("FC2_GODCAR1")
OR IS_THIS_PRINT_BEING_DISPLAYED("CMN_GENGETIN")
OR IS_THIS_PRINT_BEING_DISPLAYED("CMN_GENGETBCKBK")
OR IS_THIS_PRINT_BEING_DISPLAYED("CMN_MGETBCK")
OR IS_THIS_PRINT_BEING_DISPLAYED("CMN_TGETBCK")
OR IS_THIS_PRINT_BEING_DISPLAYED("FC2_GODCAR2")
OR IS_THIS_PRINT_BEING_DISPLAYED("CMN_GENGETBCK")
REMOVE_MISSION_TEXT(TRUE, TRUE, FALSE)
ENDIF
ENDPROC
// headsets
PROC SET_PLAYER_PED_WITH_HEADSET(enumCharacterList headSetCharacter, BOOL bHasHeadset)
PED_INDEX headsetPed
PED_COMP_NAME_ENUM componentEnum
SWITCH headSetCharacter
CASE CHAR_MICHAEL
componentEnum = PROPS_P0_HEADSET
BREAK
CASE CHAR_FRANKLIN
componentEnum = PROPS_P1_HEADSET
BREAK
CASE CHAR_TREVOR
componentEnum = PROPS_P2_HEADSET
BREAK
ENDSWITCH
IF GET_CURRENT_PLAYER_PED_ENUM() = headSetCharacter
headsetPed = PLAYER_PED_ID()
ELSE
headsetPed = sSelectorPeds.pedID[GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(headSetCharacter)]
ENDIF
IF NOT IS_PED_INJURED(headsetPed)
IF bHasHeadset
SET_PED_COMP_ITEM_CURRENT_SP(headsetPed, COMP_TYPE_PROPS, componentEnum)
ELSE
REMOVE_PED_COMP_ITEM_SP(headsetPed, COMP_TYPE_PROPS, componentEnum)
ENDIF
ENDIF
ENDPROC
// check all peds and vehicles for fail
PROC HANDLE_MISSION_FAIL_CHECKS()
INT i
IF NOT bRunningCutscene
// character peds
REPEAT COUNT_OF(sSelectorPeds.pedID) i
IF DOES_ENTITY_EXIST(sSelectorPeds.pedID[i])
IF IS_PED_INJURED(sSelectorPeds.pedID[i])
enumCharacterList injuredChar = INT_TO_ENUM(enumCharacterList, i)
IF injuredChar <> GET_CURRENT_PLAYER_PED_ENUM()
IF DOES_BLIP_EXIST(buddyBlip[i])
REMOVE_BLIP(buddyBlip[i])
ENDIF
IF IS_THIS_PRINT_BEING_DISPLAYED("FC1_GOMT")
REMOVE_MISSION_TEXT(TRUE, TRUE, FALSE)
ENDIF
SWITCH injuredChar
CASE CHAR_MICHAEL
// michael
MISSION_FAILED(FAIL_MICHAEL_DEAD)
BREAK
CASE CHAR_TREVOR
// trevor
MISSION_FAILED(FAIL_TREVOR_DEAD)
BREAK
CASE CHAR_FRANKLIN
// franklin
MISSION_FAILED(FAIL_FRANKLIN_DEAD)
BREAK
ENDSWITCH
ENDIF
ENDIF
ENDIF
ENDREPEAT
// player vehicles
REPEAT COUNT_OF(finaleVehicle) i
FINALE_VEHICLE_ENUM thisVehicle = INT_TO_ENUM(FINALE_VEHICLE_ENUM, i)
IF DOES_ENTITY_EXIST(finaleVehicle[thisVehicle])
IF NOT IS_VEHICLE_DRIVEABLE(finaleVehicle[thisVehicle])
REMOVE_CAR_BLIP_AND_TEXT()
SWITCH thisVehicle
CASE FV_FRANKLIN_CAR
// MISSION_FAILED(FAIL_FRANKLIN_BIKE_DESTROYED)
BREAK
CASE FV_TREVOR_CAR
// IF currentMissionStage < STAGE_GET_TO_CLIFF
// MISSION_FAILED(FAIL_TREVOR_CAR_DESTROYED)
// ENDIF
BREAK
CASE FV_MICHAEL_CAR
// MISSION_FAILED(FAIL_MICHAEL_CAR_DESTROYED)
BREAK
CASE FV_DEVIN_CAR
IF currentMissionStage = STAGE_GET_TO_CLIFF
IF IS_ENTITY_DEAD(finaleVehicle[thisVehicle])
MISSION_FAILED(FAIL_NOT_DISPOSED_DEVIN)
ELSE
MISSION_FAILED(FAIL_DEVIN_CAR_DESTROYED)
ENDIF
ENDIF
BREAK
ENDSWITCH
ELSE
enumCharacterList thisChar
BOOL bDoChecks = TRUE
SWITCH thisVehicle
CASE FV_FRANKLIN_CAR
//IF currentMissionStage = STAGE_GET_TO_HIT
// thisChar = CHAR_FRANKLIN
//ELSE
bDoChecks = FALSE
//ENDIF
BREAK
CASE FV_TREVOR_CAR
//IF currentMissionStage = STAGE_GET_TO_HIT
// thisChar = CHAR_TREVOR
//ELIF currentMissionStage = STAGE_PICKUP_DEVIN
// IF bTrevorReturningToCar
// bDoChecks = FALSE
// ELSE
// thisChar = CHAR_TREVOR
// ENDIF
//ELSE
bDoChecks = FALSE
//ENDIF
BREAK
CASE FV_MICHAEL_CAR
//IF currentMissionStage = STAGE_GET_TO_HIT
// thisChar = CHAR_MICHAEL
//ELSE
bDoChecks = FALSE
//ENDIF
BREAK
CASE FV_DEVIN_CAR
IF currentMissionStage = STAGE_GET_TO_CLIFF
thisChar = CHAR_TREVOR
ELSE
bDoChecks = FALSE
ENDIF
BREAK
ENDSWITCH
IF bDoChecks
IF GET_CURRENT_PLAYER_PED_ENUM() = thisChar
IF freeHotswapData.state = FREE_HOTSWAP_STATE_SELECTING
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), finaleVehicle[thisVehicle], FALSE) > STUCK_FAIL_RANGE_m
SWITCH thisVehicle
CASE FV_FRANKLIN_CAR
MISSION_FAILED(FAIL_FRANKLIN_BIKE_ABANDONED)
BREAK
CASE FV_TREVOR_CAR
MISSION_FAILED(FAIL_TREVOR_CAR_ABANDONED)
BREAK
CASE FV_MICHAEL_CAR
MISSION_FAILED(FAIL_MICHAEL_CAR_ABANDONED)
BREAK
CASE FV_DEVIN_CAR
MISSION_FAILED(FAIL_DEVIN_CAR_ABANDONED)
BREAK
ENDSWITCH
ENDIF
IF IS_VEHICLE_STUCK_TIMER_UP(finaleVehicle[thisVehicle], VEH_STUCK_JAMMED, JAMMED_TIME)
OR IS_VEHICLE_STUCK_TIMER_UP(finaleVehicle[thisVehicle], VEH_STUCK_HUNG_UP, HUNG_UP_TIME)
OR (IS_VEHICLE_STUCK_TIMER_UP(finaleVehicle[thisVehicle], VEH_STUCK_ON_SIDE, SIDE_TIME) AND thisVehicle <> FV_FRANKLIN_CAR)
OR (IS_VEHICLE_STUCK_TIMER_UP(finaleVehicle[thisVehicle], VEH_STUCK_ON_ROOF, ROOF_TIME) AND thisVehicle <> FV_FRANKLIN_CAR)
REMOVE_CAR_BLIP_AND_TEXT()
SWITCH thisVehicle
CASE FV_FRANKLIN_CAR
MISSION_FAILED(FAIL_FRANKLIN_BIKE_STUCK)
BREAK
CASE FV_TREVOR_CAR
MISSION_FAILED(FAIL_TREVOR_CAR_STUCK)
BREAK
CASE FV_MICHAEL_CAR
MISSION_FAILED(FAIL_MICHAEL_CAR_STUCK)
BREAK
CASE FV_DEVIN_CAR
MISSION_FAILED(FAIL_DEVIN_CAR_STUCK)
BREAK
ENDSWITCH
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
ENDIF
ENDPROC
// mission failed
PROC HANDLE_MISSION_FAIL_STATE()
HANDLE_MISSION_FAIL_CHECKS()
SWITCH missionFailState
CASE MISSION_FAIL_STATE_NOT_FAILED
BREAK
CASE MISSION_FAIL_STATE_WAIT_FOR_FADE
IF GET_MISSION_FLOW_SAFE_TO_CLEANUP()
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
SET_PLAYER_PED_WITH_HEADSET(GET_CURRENT_PLAYER_PED_ENUM(), FALSE)
ENDIF
// check if we need to respawn the player in a different position,
// if so call MISSION_FLOW_SET_FAIL_WARP_LOCATION() + SET_REPLAY_DECLINED_VEHICLE_WARP_LOCATION here
bThoroughCleanup = TRUE
bFailedOut = TRUE
MISSION_CLEANUP() // must only take 1 frame and terminate the thread
ELSE
//Maintain anything that could look weird during fade out (e.g. enemies walking off).
ENDIF
BREAK
ENDSWITCH
ENDPROC
// get mission vector
FUNC VECTOR GET_FINALE_VECTOR(FINALE_VECTOR_ENUM fVec)
SWITCH fVec
CASE FINVEC_PLAYER_INIT
RETURN <<1020.93109, -2038.86304, 29.85838>>
BREAK
CASE FINVEC_TREVOR_INIT
RETURN <<1112.35, -2003.90, 34.44>>
BREAK
CASE FINVEC_MICHAEL_INIT
RETURN <<1114.10, -2003.12, 34.44>>
BREAK
CASE FINVEC_FRANKLIN_BIKE_INIT
RETURN <<1022.91, -2041.58, 30.01>>
BREAK
CASE FINVEC_TREVOR_CAR_INIT
RETURN <<974.38483, -2081.01050, 29.98432>>
BREAK
CASE FINVEC_MICHAEL_CAR_INIT
RETURN <<989.67328, -2076.10498, 30.06461>>
BREAK
CASE FINVEC_FRANKLIN_BIKE_AT_CLUB
RETURN << -2997.2878, 93.6371, 10.6077 >>
BREAK
CASE FINVEC_TREVOR_CAR_AT_PIER
RETURN <<-1602.93, -1021.84, 12.07>>
BREAK
CASE FINVEC_TREVOR_CAR_AT_PICKUP
RETURN <<-2550.93, 1912.22, 167.96>>
BREAK
CASE FINVEC_TREVOR_CAR_DRIVE_TO_PICKUP
RETURN <<-2637.53564, 1599.74634, 124.22569>>
BREAK
CASE FINVEC_MICHAEL_CAR_AT_REC
RETURN <<-205.444, -1489.52, 30.9925>>
BREAK
CASE FINVEC_DEVIN_CAR_INIT
RETURN <<-2581.06, 1930.49, 166.30>>
BREAK
CASE FINVEC_TREVOR_AT_PIER
RETURN <<-1608.71, -1061.97, 12.02>>
BREAK
CASE FINVEC_REC
RETURN <<-210.93, -1492.20, 30.26>>
BREAK
CASE FINVEC_PIER
RETURN <<-1613.36, -1010.51, 12.04>>
BREAK
CASE FINVEC_CLUB
RETURN <<-3008.57, 109.54, 12.07>>
BREAK
CASE FINVEC_PICKUP
RETURN <<-2555.51367, 1912.51135, 167.89706>>
BREAK
CASE FINVEC_CLIFF
RETURN <<-1576.47, 5153.91, 18.97>>
BREAK
CASE FINVEC_GONDOLA
RETURN <<-1663.97, -1120.88, 41.7839>>
BREAK
CASE FINVEC_DEVIN_INIT
RETURN <<-2645.98950, 1871.41199, 159.15147>>
BREAK
CASE FINVEC_WHEEL
RETURN <<-1663.970, -1126.700, 30.700>>
BREAK
ENDSWITCH
RETURN <<0,0,0>>
ENDFUNC
// fill position, rotation, FOV for a camera shot
PROC FILL_CAMERA_PROPERTIES_FOR_FINALE_SHOT(FINALE_SHOT_DETAILS_ENUM cutsceneShot, VECTOR &vCamPos, VECTOR &vCamRot, FLOAT &fCamFOV)
SWITCH cutsceneShot
CASE FIN_SHOT_SNIPER
vCamPos = <<1049.7, -2017.96, 51.39>>
vCamRot = <<9.71, 0.0, 98.15>>
fCamFOV = 20.049
BREAK
CASE FIN_SHOT_GANGSTERS
vCamPos = <<-204.37, -1507.27, 32.29>>
vCamRot = <<-11.68, 0.0, -145.99>>
fCamFOV = 50.00
BREAK
CASE FIN_SHOT_STEVE
vCamPos = <<-1662.64, -1130.31, 43.65>>
vCamRot = <<-5.97, 0.0, 147.26>>
fCamFOV = 46.848
BREAK
CASE FIN_SHOT_TRIADS
vCamPos = <<-3004.91, 105.20, 20.73>>
vCamRot = <<-17.32, 0.0, 141.87>>
fCamFOV = 50.0
BREAK
CASE FIN_SHOT_STRETCH
vCamPos = <<-207.51, -1487.31, 31.75>>
vCamRot = <<-5.94, 0.0, -167.82>>
fCamFOV = 34.0
BREAK
CASE FIN_SHOT_KIDNAP
vCamPos = <<-2652.32, 1779.98, 193.98>>
vCamRot = <<-17.40, 0.0, -20.84>>
fCamFOV = 35.217
BREAK
CASE FIN_SHOT_HOUSE_1
vCamPos = <<-2711.9, 1910.3, 175.9>>
vCamRot = <<-1.4, 0.0, -102.8>>
fCamFOV = 37.3
BREAK
CASE FIN_SHOT_HOUSE_1B
vCamPos = <<-2710.6, 1908.8, 175.8>>
vCamRot = <<-1.8, 0.0, -102.2>>
fCamFOV = 37.3
BREAK
CASE FIN_SHOT_HOUSE_2
vCamPos = <<-2636.0, 1881.8, 160.1>>
vCamRot = <<1.9, 0.0, 137.1>>
fCamFOV = 29.5
BREAK
CASE FIN_SHOT_HOUSE_2B
vCamPos = <<-2636.4, 1881.4, 160.2>>
vCamRot = <<1.9, 0.0, 137.1>>
fCamFOV = 29.5
BREAK
CASE FIN_SHOT_HOUSE_3
vCamPos = <<-2647.9, 1870.5, 159.8>>
vCamRot = <<8.3, 0.0, -63.4>>
fCamFOV = 37.5
BREAK
CASE FIN_SHOT_HOUSE_3B
vCamPos = <<-2648.1, 1870.4, 159.7>>
vCamRot = <<8.3, 0.0, -63.4>>
fCamFOV = 37.5
BREAK
CASE FIN_SHOT_KIDNAP2
vCamPos = <<-2650.38, 1863.76, 160.21>>
vCamRot = <<-1.20, 0.0, -7.92>>
fCamFOV = 35.217
BREAK
CASE FIN_SHOT_CLIFFS
vCamPos = <<-1570.94, 5159.0, 20.71>>
vCamRot = <<0.93, 0.0, 86.76>>
fCamFOV = 40.0
BREAK
CASE FIN_SHOT_CLIFFSB
vCamPos = <<-1576.1322, 5160.8877, 24.1175>>
vCamRot = <<4.8389, -0.0110, 92.1057>>
fCamFOV = 40.0
BREAK
CASE FIN_SHOT_SNIPE
vCamPos = <<-1662.34, -1123.84, 43.28>>
vCamRot = <<-3.22, 0.0, 28.53>>
fCamFOV = 33.32
BREAK
ENDSWITCH
ENDPROC
// destroy a scripted cam if it exists
PROC DESTROY_MISSION_STATIC_CAM(CAMERA_INDEX &camIndex)
IF DOES_CAM_EXIST(camIndex)
DESTROY_CAM(camIndex)
ENDIF
ENDPROC
// create a scripted stationary cam if it doesn't already exist
PROC CREATE_MISSION_STATIC_CAM(CAMERA_INDEX &camIndex)
// get rid of any existing interp cams
IF DOES_CAM_EXIST(interpCam)
DESTROY_CAM(interpCam)
ENDIF
IF DOES_CAM_EXIST(camIndex)
DESTROY_CAM(camIndex)
ENDIF
IF NOT DOES_CAM_EXIST(camIndex)
camIndex = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", TRUE)
ENDIF
ENDPROC
// cam for a cutscene shot
PROC CREATE_CAM_FOR_FINALE_SHOT(FINALE_SHOT_DETAILS_ENUM cutsceneShot, BOOL bIsInterp = FALSE, INT iInterpTime = 10000)
VECTOR vCamPos, vCamRot
FLOAT fCamFOV
FILL_CAMERA_PROPERTIES_FOR_FINALE_SHOT(cutsceneShot, vCamPos, vCamRot, fCamFOV)
CREATE_MISSION_STATIC_CAM(staticCam)
DETACH_CAM(staticCam)
STOP_CAM_POINTING(staticCam)
SET_CAM_COORD(staticCam, vCamPos)
SET_CAM_ROT(staticCam, vCamRot)
SET_CAM_FOV(staticCam, fCamFOV)
CAMERA_GRAPH_TYPE graphTypePos
CAMERA_GRAPH_TYPE graphTypeRot
IF cutsceneShot <> FIN_SHOT_HOUSE_2
graphTypePos = GRAPH_TYPE_SIN_ACCEL_DECEL
graphTypeRot = GRAPH_TYPE_SIN_ACCEL_DECEL
ELSE
graphTypePos = GRAPH_TYPE_LINEAR
graphTypeRot = GRAPH_TYPE_LINEAR
ENDIF
// setup for interpolation
IF bIsInterp
FILL_CAMERA_PROPERTIES_FOR_FINALE_SHOT(INT_TO_ENUM(FINALE_SHOT_DETAILS_ENUM, ENUM_TO_INT(cutsceneShot)+1), vCamPos, vCamRot, fCamFOV)
CREATE_MISSION_STATIC_CAM(interpCam)
SET_CAM_COORD(interpCam, vCamPos)
SET_CAM_ROT(interpCam, vCamRot)
SET_CAM_FOV(interpCam, fCamFOV)
SET_CAM_ACTIVE_WITH_INTERP(interpCam, staticCam, iInterpTime, graphTypePos, graphTypeRot)
ENDIF
IF cutsceneShot = FIN_SHOT_HOUSE_1
OR cutsceneShot = FIN_SHOT_HOUSE_2
SHAKE_CAM(staticCam, "HAND_SHAKE", 0.3)
ENDIF
RENDER_SCRIPT_CAMS(TRUE, FALSE)
ENDPROC
FUNC VECTOR GET_IDEAL_CAR_CAM_POSITION()
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_DEVIN_CAR])
VECTOR vOffset
//IF fPushAnimSpeed >= 0.6
// vOffset = <<0.9, -3.3, 0.8>>
//ELSE
vOffset = <<0.9, -4.3 + fPushAnimSpeed / 3, 0.8>>
//ENDIF
RETURN GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(finaleVehicle[FV_DEVIN_CAR], vOffset)
ENDIF
RETURN <<0,0,0>>
ENDFUNC
// create cam attached to car
PROC CREATE_CAMERA_ATTACHED_TO_CAR()
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_DEVIN_CAR])
CREATE_MISSION_STATIC_CAM(staticCam)
//ATTACH_CAM_TO_ENTITY(staticCam, finaleVehicle[FV_DEVIN_CAR], <<0.9, -4.3, 0.8>>)
vActualCamCoord = GET_IDEAL_CAR_CAM_POSITION()
vActualCamCoord.z = 20.3
SET_CAM_COORD(staticCam, vActualCamCoord)
SET_CAM_ROT(staticCam, <<-8.7, 0.0, 110.3>>)
//POINT_CAM_AT_ENTITY(staticCam, finaleVehicle[FV_DEVIN_CAR], <<-4.0, 12.0, -1.0>>)
//SET_CAM_INHERIT_ROLL_VEHICLE(staticCam, finaleVehicle[FV_DEVIN_CAR])
SET_CAM_FOV(staticCam, 41.5)
SHAKE_CAM(staticCam, "HAND_SHAKE", 0.3)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
ENDIF
ENDPROC
// create an anim cam for sync scenes
PROC CREATE_MISSION_ANIM_CAM(BOOL bStartActivated = TRUE, BOOL bRenderScriptCams = TRUE)
IF DOES_CAM_EXIST(animCam)
DESTROY_CAM(animCam)
ENDIF
animCam = CREATE_CAM("DEFAULT_ANIMATED_CAMERA", bStartActivated)
RENDER_SCRIPT_CAMS(bRenderScriptCams, FALSE)
ENDPROC
//HUD elements
PROC SET_CUTSCENE_HUD_ELEMENTS()
DISABLE_CELLPHONE(TRUE)
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
ENDPROC
// setup mocap cutscene
PROC SET_MISSION_MOCAP_CUTSCENE()
REMOVE_MISSION_TEXT()
SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE)
SET_CUTSCENE_HUD_ELEMENTS()
ENDPROC
// setup stuff for finale cutscene
PROC SET_MISSION_CUTSCENE(BOOL bStart, BOOL bResetControlAndCameras = TRUE, BOOL bKillSpeech = TRUE, BOOL bInterpBackToGame = FALSE, BOOL bDoFade = TRUE, BOOL bResetHUDWhenNotReturningCams = FALSE, INT iInterpTime = DEFAULT_PED_CAM_INTERP_TIME, BOOL bSetRelativeHeading = TRUE)
REMOVE_MISSION_TEXT(bKillSpeech)
SET_SCRIPTS_SAFE_FOR_CUTSCENE(bStart)
IF bStart
SET_CUTSCENE_HUD_ELEMENTS()
DISPLAY_RADAR(FALSE)
DISPLAY_HUD(FALSE)
iAllowSkipCutsceneTime = GET_GAME_TIMER()
ELSE
IF bResetControlAndCameras
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
DISPLAY_RADAR(TRUE)
DISPLAY_HUD(TRUE)
DISABLE_CELLPHONE(FALSE)
RENDER_SCRIPT_CAMS(FALSE, bInterpBackToGame, iInterpTime)
IF DOES_CAM_EXIST(animCam)
DESTROY_CAM(animCam)
ENDIF
//IF DOES_CAM_EXIST(reactionCam)
// DESTROY_CAM(reactionCam)
//ENDIF
DESTROY_MISSION_STATIC_CAM(staticCam)
DESTROY_MISSION_STATIC_CAM(interpCam)
IF bSetRelativeHeading
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
ENDIF
ELSE
IF bResetHUDWhenNotReturningCams
DISPLAY_RADAR(TRUE)
DISPLAY_HUD(TRUE)
ENDIF
ENDIF
bRunningCutscene = FALSE
bSkippedCutscene = FALSE
bClearedForCutscene = FALSE
bCutsceneWaitStarted = FALSE
cutsceneStage = F_CUT_STAGE_INIT
IF bDoFade
IF IS_SCREEN_FADED_OUT()
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
ENDIF
ENDIF
ENDIF
ENDPROC
// prevent wanted level for cut
PROC PREVENT_WANTED_LEVEL_FOR_CUTSCENE()
SET_WANTED_LEVEL_MULTIPLIER(0.0)
SET_MAX_WANTED_LEVEL(0)
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
ENDPROC
// which ped is michael?
FUNC PED_INDEX GET_MICHAEL_PED()
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL
RETURN PLAYER_PED_ID()
ELSE
RETURN sSelectorPeds.pedID[SELECTOR_PED_MICHAEL]
ENDIF
ENDFUNC
// which ped is trevor?
FUNC PED_INDEX GET_TREVOR_PED()
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_TREVOR
RETURN PLAYER_PED_ID()
ELSE
RETURN sSelectorPeds.pedID[SELECTOR_PED_TREVOR]
ENDIF
ENDFUNC
// which ped is franklin?
FUNC PED_INDEX GET_FRANKLIN_PED()
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
RETURN PLAYER_PED_ID()
ELSE
RETURN sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN]
ENDIF
ENDFUNC
// unblock all selectors
PROC UNBLOCK_ALL_SELECTOR_PEDS()
sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_MICHAEL] = FALSE
sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_FRANKLIN] = FALSE
sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_TREVOR] = FALSE
ENDPROC
// get number of blocked peds
FUNC INT GET_NUMBER_BLOCKED_PEDS()
INT iReturn = 0
INT i
REPEAT 3 i
IF sSelectorPeds.bBlockSelectorPed[i]
iReturn++
ENDIF
ENDREPEAT
RETURN iReturn
ENDFUNC
FUNC VECTOR GET_MIN_GPS_BLOCK_AREA_COORDS(enumCharacterList thisChar)
SWITCH thisChar
CASE CHAR_TREVOR
RETURN <<-343, -1993, -100>>
BREAK
CASE CHAR_FRANKLIN
RETURN <<-398, -1862, -100>>
BREAK
ENDSWITCH
RETURN <<0,0,0>>
ENDFUNC
FUNC VECTOR GET_MAX_GPS_BLOCK_AREA_COORDS(enumCharacterList thisChar)
SWITCH thisChar
CASE CHAR_TREVOR
RETURN <<588, -357, 100>>
BREAK
CASE CHAR_FRANKLIN
RETURN <<183, -1040, 100>>
BREAK
ENDSWITCH
RETURN <<0,0,0>>
ENDFUNC
FUNC VECTOR GET_STAGING_POINT(enumCharacterList thisChar)
SWITCH thisChar
CASE CHAR_TREVOR
RETURN <<-681.76788, -1902.93726, 26.23245>>
BREAK
CASE CHAR_FRANKLIN
RETURN <<90.05392, -985.27271, 28.40667>>
BREAK
ENDSWITCH
RETURN <<0,0,0>>
ENDFUNC
// get correct model for mission vehicle
FUNC FINALE_MODEL_ENUM GET_MODEL_ENUM_FOR_FINALE_VEHICLE(FINALE_VEHICLE_ENUM fVehicle)
SWITCH fVehicle
CASE FV_FRANKLIN_CAR
RETURN FM_FRANKLIN_BIKE
BREAK
CASE FV_TREVOR_CAR
RETURN FM_TREVOR_CAR
BREAK
CASE FV_MICHAEL_CAR
RETURN FM_MICHAEL_CAR
BREAK
CASE FV_DEVIN_CAR
RETURN FM_DEVIN_CAR
BREAK
ENDSWITCH
RETURN FM_MICHAEL_CAR
ENDFUNC
// load objects if screen faded out
PROC LOAD_ALL_OBJECTS_IF_SCREEN_FADED_OUT()
IF IS_SCREEN_FADED_OUT()
LOAD_ALL_OBJECTS_NOW()
ENDIF
ENDPROC
// is this model required on this stage?
FUNC BOOL IS_MODEL_REQUIRED_FOR_MISSION_STAGE(FINALE_MODEL_ENUM sagModel, MISSION_STAGE_ENUM reqStage)
SWITCH sagModel
CASE FM_MICHAEL
CASE FM_TREVOR
CASE FM_FRANKLIN
//RETURN TRUE
BREAK
CASE FM_FRANKLIN_BIKE
CASE FM_TREVOR_CAR
CASE FM_MICHAEL_CAR
//IF reqStage >= STAGE_GET_TO_HIT
// RETURN TRUE
//ENDIF
BREAK
CASE FM_DEVIN
CASE FM_MERRYWEATHER
CASE FM_BOX
CASE FM_BOX_COLLISION
CASE FM_TABLET
IF reqStage = STAGE_DEVINS_HOUSE
RETURN TRUE
ENDIF
BREAK
CASE FM_DEVIN_CAR
IF reqStage >= STAGE_DEVINS_HOUSE
RETURN TRUE
ENDIF
BREAK
CASE FM_FERRIS_WHEEL
CASE FM_GONDOLA
//IF reqStage < STAGE_PICKUP_DEVIN
// RETURN TRUE
//ENDIF
BREAK
//CASE FM_BULLDOZER
// IF reqStage = STAGE_SHOOTOUT_STAGE_1
// OR reqStage = STAGE_SHOOTOUT_STAGE_2
// RETURN TRUE
// ENDIF
//BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
// add a request for a model
PROC ADD_MODEL_REQUEST(INT i)
MODEL_NAMES mModelToRequest = GET_MODEL_FOR_FINALE_MODEL_ENUM(INT_TO_ENUM(FINALE_MODEL_ENUM, i))
REQUEST_MODEL(mModelToRequest)
bModelRequestTracker[i] = TRUE
ENDPROC
// remove request
PROC CLEAR_MODEL_REQUEST(INT i)
IF bModelRequestTracker[i]
MODEL_NAMES mModelToRequest = GET_MODEL_FOR_FINALE_MODEL_ENUM(INT_TO_ENUM(FINALE_MODEL_ENUM, i))
IF HAS_MODEL_LOADED(mModelToRequest)
SET_MODEL_AS_NO_LONGER_NEEDED(mModelToRequest)
ENDIF
bModelRequestTracker[i] = FALSE
ENDIF
ENDPROC
// have all requests for models succeeded?
FUNC BOOL HAVE_ALL_MODEL_REQUESTS_SUCCEEDED()
INT i
// loop through and check for empty
REPEAT NUMBER_MODEL_REQUEST_SLOTS i
IF bModelRequestTracker[i] = TRUE
IF NOT HAS_MODEL_LOADED(GET_MODEL_FOR_FINALE_MODEL_ENUM(INT_TO_ENUM(FINALE_MODEL_ENUM, i)))
// a full slot is not loaded, return false
RETURN FALSE
ENDIF
ENDIF
ENDREPEAT
RETURN TRUE
ENDFUNC
// request the models for a particular stage
PROC REQUEST_MODELS_FOR_STAGE(MISSION_STAGE_ENUM requestStage, BOOL bWaitForLoad, BOOL bKeepModelsForCurrentStage)
INT i
REPEAT NUMBER_MODEL_REQUEST_SLOTS i
IF IS_MODEL_REQUIRED_FOR_MISSION_STAGE(INT_TO_ENUM(FINALE_MODEL_ENUM, i), requestStage)
// if we need this model, request it
ADD_MODEL_REQUEST(i)
ELSE
// otherwise try and get rid of it
IF NOT IS_MODEL_REQUIRED_FOR_MISSION_STAGE(INT_TO_ENUM(FINALE_MODEL_ENUM, i), currentMissionStage)
OR NOT bKeepModelsForCurrentStage
CLEAR_MODEL_REQUEST(i)
ENDIF
ENDIF
ENDREPEAT
// if wait for load, don't quit out 'til all the models are in
IF bWaitForLoad
IF NOT HAVE_ALL_MODEL_REQUESTS_SUCCEEDED()
LOAD_ALL_OBJECTS_IF_SCREEN_FADED_OUT()
WHILE NOT HAVE_ALL_MODEL_REQUESTS_SUCCEEDED()
WAIT(0)
ENDWHILE
ENDIF
ENDIF
ENDPROC
// is this recording required on this stage?
FUNC BOOL IS_RECORDING_REQUIRED_FOR_MISSION_STAGE(INT iRec, MISSION_STAGE_ENUM reqStage)
iRec = iRec
reqStage = reqStage
/*
SWITCH iRec
CASE 007 // trevor drive to lake
IF reqStage = STAGE_PICKUP_DEVIN
RETURN TRUE
ENDIF
BREAK
CASE 010 // franklin drive to club
CASE 008 // trevor drive to pier
CASE 009 // michael drive to rec
IF reqStage = STAGE_GET_TO_HIT
OR reqStage = STAGE_FRANKLIN_HIT
OR reqStage = STAGE_MICHAEL_HIT
OR reqStage = STAGE_TREVOR_HIT
RETURN TRUE
ENDIF
BREAK
ENDSWITCH
*/
RETURN FALSE
ENDFUNC
// add a request for a recording
PROC ADD_RECORDING_REQUEST(INT iRec)
bVehicleRecordingRequestTracker[iRec-1] = TRUE
REQUEST_VEHICLE_RECORDING(iRec, GET_FINALE_RECORDING_PREFIX())
ENDPROC
// clear a recording request slot
PROC CLEAR_RECORDING_REQUEST(INT iRec)
IF bVehicleRecordingRequestTracker[iRec-1]
bVehicleRecordingRequestTracker[iRec-1] = FALSE
IF HAS_VEHICLE_RECORDING_BEEN_LOADED(iRec, GET_FINALE_RECORDING_PREFIX())
REMOVE_VEHICLE_RECORDING(iRec, GET_FINALE_RECORDING_PREFIX())
ENDIF
ENDIF
ENDPROC
// have all requests for recordings succeeded?
FUNC BOOL HAVE_ALL_RECORDING_REQUESTS_SUCCEEDED()
INT i
// loop through and check for empty
REPEAT NUMBER_RECORDING_REQUEST_SLOTS i
IF bVehicleRecordingRequestTracker[i]
IF NOT HAS_VEHICLE_RECORDING_BEEN_LOADED(i+1, GET_FINALE_RECORDING_PREFIX())
// a full slot is not loaded, return false
RETURN FALSE
ENDIF
ENDIF
ENDREPEAT
RETURN TRUE
ENDFUNC
// get recordings for particular stage
PROC REQUEST_VEHICLE_RECORDINGS_FOR_STAGE(MISSION_STAGE_ENUM requestStage, BOOL bWaitForLoad, BOOL bKeepRecordingsForCurrentStage)
INT i
REPEAT NUMBER_RECORDING_REQUEST_SLOTS i
IF IS_RECORDING_REQUIRED_FOR_MISSION_STAGE(i+1, requestStage)
// if we need this recording, request it
ADD_RECORDING_REQUEST(i+1)
ELSE
// otherwise try and get rid of it
IF NOT IS_RECORDING_REQUIRED_FOR_MISSION_STAGE(i+1, currentMissionStage)
OR NOT bKeepRecordingsForCurrentStage
CLEAR_RECORDING_REQUEST(i+1)
ENDIF
ENDIF
ENDREPEAT
// if wait for load, don't quit out 'til all the recordings are in
IF bWaitForLoad
IF NOT HAVE_ALL_RECORDING_REQUESTS_SUCCEEDED()
LOAD_ALL_OBJECTS_IF_SCREEN_FADED_OUT()
WHILE NOT HAVE_ALL_RECORDING_REQUESTS_SUCCEEDED()
WAIT(0)
ENDWHILE
ENDIF
ENDIF
ENDPROC
// is this waypoint required on this stage?
FUNC BOOL IS_WAYPOINT_REQUIRED_FOR_MISSION_STAGE(INT iWaypoint, MISSION_STAGE_ENUM reqStage)
SWITCH iWaypoint + 1
CASE 5
CASE 6
CASE 7
CASE 8
CASE 9
CASE 10
CASE 11
CASE 12
CASE 13
CASE 14
CASE 15
CASE 16
CASE 17
CASE 18
IF reqStage = STAGE_DEVINS_HOUSE
RETURN TRUE
ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
FUNC TEXT_LABEL GET_WAYPOINT_LABEL_FROM_INT(INT iWaypoint)
TEXT_LABEL tWaypoint = "finc2"
tWaypoint += (iWaypoint+1)
RETURN tWaypoint
ENDFUNC
// add a request for a waypoint
PROC ADD_WAYPOINT_REQUEST(INT iWaypoint)
bWaypointRequestTracker[iWaypoint] = TRUE
TEXT_LABEL tWaypoint = GET_WAYPOINT_LABEL_FROM_INT(iWaypoint)
REQUEST_WAYPOINT_RECORDING(tWaypoint)
ENDPROC
// clear a waypoint request slot
PROC CLEAR_WAYPOINT_REQUEST(INT iWaypoint)
IF bWaypointRequestTracker[iWaypoint]
bWaypointRequestTracker[iWaypoint] = FALSE
TEXT_LABEL tWaypoint = GET_WAYPOINT_LABEL_FROM_INT(iWaypoint)
IF GET_IS_WAYPOINT_RECORDING_LOADED(tWaypoint) = FALSE
REMOVE_WAYPOINT_RECORDING(tWaypoint)
ENDIF
ENDIF
ENDPROC
// have all requests for waypoints succeeded?
FUNC BOOL HAVE_ALL_WAYPOINT_REQUESTS_SUCCEEDED()
INT i
// loop through and check for empty
REPEAT NUMBER_WAYPOINT_REQUEST_SLOTS i
IF bWaypointRequestTracker[i]
TEXT_LABEL tWaypoint = GET_WAYPOINT_LABEL_FROM_INT(i)
IF NOT GET_IS_WAYPOINT_RECORDING_LOADED(tWaypoint)
// a full slot is not loaded, return false
RETURN FALSE
ENDIF
ENDIF
ENDREPEAT
RETURN TRUE
ENDFUNC
// get recordings for particular stage
PROC REQUEST_WAYPOINT_RECORDINGS_FOR_STAGE(MISSION_STAGE_ENUM requestStage, BOOL bWaitForLoad, BOOL bKeepWaypointsForCurrentStage)
INT i
REPEAT NUMBER_WAYPOINT_REQUEST_SLOTS i
IF IS_WAYPOINT_REQUIRED_FOR_MISSION_STAGE(i, requestStage)
// if we need this waypoint, request it
ADD_WAYPOINT_REQUEST(i)
ELSE
// otherwise try and get rid of it
IF NOT IS_WAYPOINT_REQUIRED_FOR_MISSION_STAGE(i, currentMissionStage)
OR NOT bKeepWaypointsForCurrentStage
CLEAR_WAYPOINT_REQUEST(i)
ENDIF
ENDIF
ENDREPEAT
// if wait for load, don't quit out 'til all the waypoints are in
IF bWaitForLoad
IF NOT HAVE_ALL_WAYPOINT_REQUESTS_SUCCEEDED()
LOAD_ALL_OBJECTS_IF_SCREEN_FADED_OUT()
WHILE NOT HAVE_ALL_WAYPOINT_REQUESTS_SUCCEEDED()
WAIT(0)
ENDWHILE
ENDIF
ENDIF
ENDPROC
// get an anim dict enum as string
FUNC STRING GET_FINALE_ANIM_DICT_AS_STRING(FINALE_ANIM_DICT_ENUM animDict)
SWITCH animDict
CASE F_ANIM_DICT_STEVE_FILMING
RETURN "MISSFINALE_C2IG_1"
BREAK
CASE F_ANIM_DICT_STEVE_SPEECH
RETURN "MISSFINALE_C2MCS_1"
BREAK
CASE F_ANIM_DICT_CAMERAMAN_REACT
RETURN "MISSFINALE_C2IG_2"
BREAK
CASE F_ANIM_DICT_STEVE_REACT
RETURN "MISSFINALE_C2IG_4"
BREAK
CASE F_ANIM_DICT_STEVE_DEATH
RETURN "MISSFINALE_C2STEVE_CAMERAMAN_DEATH"
BREAK
CASE F_ANIM_DICT_WHEEL_BYSTANDERS
RETURN "MISSFINALE_C2IG_5"
BREAK
// CASE F_ANIM_DICT_DEVIN_CHECK_OUT_GIRL
// RETURN "MISSFINALE_C2IG_10"
// BREAK
// CASE F_ANIM_DICT_GANGSTERS_BBALL
// RETURN "MISSFINALE_C2LEADINOUTMCS_2_B"
// BREAK
CASE F_ANIM_DICT_GANGSTERS
RETURN "MISSFINALE_C2IG_7_ALT1"
BREAK
CASE F_ANIM_DICT_GANGSTERS_PHONE
RETURN "MISSFINALE_C2MCS_2_B"
BREAK
CASE F_ANIM_DICT_TRIADS_INTO_CARS
RETURN "MISSFINALE_C2IG_8"
BREAK
// CASE F_ANIM_DICT_TRIADS_IDLE
// RETURN "MISSFINALE_C2MCS_3_A_P1"
// BREAK
CASE F_ANIM_DICT_PUSH_CAR
RETURN "MISSFINALE_C2IG_11"
BREAK
// CASE F_ANIM_DICT_CLIFF_CAM
// RETURN "MISSFINALE_C2"
// BREAK
CASE F_ANIM_DICT_REACT_INTRO
RETURN "reaction@gunfire@intro_v1"
BREAK
CASE F_ANIM_DICT_REACT_FLEE
RETURN "reaction@gunfire@runs_v1"
BREAK
CASE F_ANIM_DICT_DEVIN_AND_BOX
RETURN "MISSFINALE_C2CAPTURE_DEVIN"
BREAK
ENDSWITCH
RETURN "invalid!"
ENDFUNC
// is this anim dict required on this stage?
FUNC BOOL IS_ANIM_DICT_REQUIRED_FOR_MISSION_STAGE(FINALE_ANIM_DICT_ENUM animDict, MISSION_STAGE_ENUM reqStage)
SWITCH animDict
CASE F_ANIM_DICT_PUSH_CAR
//CASE F_ANIM_DICT_CLIFF_CAM
IF reqStage = STAGE_GET_TO_CLIFF
RETURN TRUE
ENDIF
BREAK
CASE F_ANIM_DICT_DEVIN_AND_BOX
IF reqStage = STAGE_DEVINS_HOUSE
RETURN TRUE
ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
// add a request for an anim
PROC ADD_ANIM_DICT_REQUEST(FINALE_ANIM_DICT_ENUM animDict)
bAnimDictRequestTracker[animDict] = TRUE
STRING sAnimDict = GET_FINALE_ANIM_DICT_AS_STRING(animDict)
REQUEST_ANIM_DICT(sAnimDict)
ENDPROC
// clear an anim request slot
PROC CLEAR_ANIM_DICT_REQUEST(FINALE_ANIM_DICT_ENUM animDict)
IF bAnimDictRequestTracker[animDict]
bAnimDictRequestTracker[animDict] = FALSE
STRING sAnimDict = GET_FINALE_ANIM_DICT_AS_STRING(animDict)
IF HAS_ANIM_DICT_LOADED(sAnimDict)
REMOVE_ANIM_DICT(sAnimDict)
ENDIF
ENDIF
ENDPROC
// have all requests for anims succeeded?
FUNC BOOL HAVE_ALL_ANIM_DICT_REQUESTS_SUCCEEDED()
INT i
// loop through and check for empty
REPEAT COUNT_OF(FINALE_ANIM_DICT_ENUM) i
IF bAnimDictRequestTracker[i]
IF NOT HAS_ANIM_DICT_LOADED(GET_FINALE_ANIM_DICT_AS_STRING(INT_TO_ENUM(FINALE_ANIM_DICT_ENUM, i)))
// a full slot is not loaded, return false
RETURN FALSE
ENDIF
ENDIF
ENDREPEAT
RETURN TRUE
ENDFUNC
// get anims for particular stage
PROC REQUEST_ANIM_DICTS_FOR_STAGE(MISSION_STAGE_ENUM requestStage, BOOL bWaitForLoad, BOOL bKeepAnimsForCurrentStage)
INT i
REPEAT COUNT_OF(FINALE_ANIM_DICT_ENUM) i
FINALE_ANIM_DICT_ENUM thisAnimDict = INT_TO_ENUM(FINALE_ANIM_DICT_ENUM, i)
IF IS_ANIM_DICT_REQUIRED_FOR_MISSION_STAGE(thisAnimDict, requestStage)
// if we need this recording, request it
ADD_ANIM_DICT_REQUEST(thisAnimDict)
ELSE
// otherwise try and get rid of it
IF NOT IS_ANIM_DICT_REQUIRED_FOR_MISSION_STAGE(thisAnimDict, currentMissionStage)
OR NOT bKeepAnimsForCurrentStage
CLEAR_ANIM_DICT_REQUEST(thisAnimDict)
ENDIF
ENDIF
ENDREPEAT
// if wait for load, don't quit out 'til all the recordings are in
IF bWaitForLoad
IF NOT HAVE_ALL_ANIM_DICT_REQUESTS_SUCCEEDED()
LOAD_ALL_OBJECTS_IF_SCREEN_FADED_OUT()
WHILE NOT HAVE_ALL_ANIM_DICT_REQUESTS_SUCCEEDED()
WAIT(0)
ENDWHILE
ENDIF
ENDIF
ENDPROC
// get a weapon enum as a weapontype
FUNC WEAPON_TYPE GET_FINALE_WEAPON_TYPE(FINALE_WEAPON_ENUM weapon)
SWITCH weapon
CASE F_WEAPON_SNIPER
RETURN WEAPONTYPE_HEAVYSNIPER
BREAK
CASE F_WEAPON_PISTOL
RETURN WEAPONTYPE_PISTOL
BREAK
CASE F_WEAPON_TRIAD_SMG
RETURN WEAPONTYPE_MICROSMG
BREAK
CASE F_WEAPON_STICKY_BOMB
RETURN WEAPONTYPE_STICKYBOMB
BREAK
CASE F_WEAPON_MERRYWEATHER_RIFLE
RETURN WEAPONTYPE_CARBINERIFLE
BREAK
CASE F_WEAPON_MERRYWEATHER_SHOTGUN
RETURN WEAPONTYPE_PUMPSHOTGUN
BREAK
ENDSWITCH
RETURN WEAPONTYPE_UNARMED
ENDFUNC
// is this weapon required on this stage?
FUNC BOOL IS_WEAPON_REQUIRED_FOR_MISSION_STAGE(FINALE_WEAPON_ENUM weapon, MISSION_STAGE_ENUM reqStage)
SWITCH weapon
CASE F_WEAPON_SNIPER
IF reqStage = STAGE_TREVOR_HIT
RETURN TRUE
ENDIF
BREAK
CASE F_WEAPON_PISTOL
IF reqStage = STAGE_GET_TO_HIT
OR reqStage = STAGE_MICHAEL_HIT
RETURN TRUE
ENDIF
BREAK
CASE F_WEAPON_TRIAD_SMG
IF reqStage = STAGE_GET_TO_HIT
OR reqStage = STAGE_FRANKLIN_HIT
RETURN TRUE
ENDIF
BREAK
CASE F_WEAPON_MERRYWEATHER_RIFLE
IF reqStage = STAGE_DEVINS_HOUSE
RETURN TRUE
ENDIF
BREAK
CASE F_WEAPON_MERRYWEATHER_SHOTGUN
IF reqStage = STAGE_DEVINS_HOUSE
OR reqStage = STAGE_GET_TO_HIT
OR reqStage = STAGE_FRANKLIN_HIT
RETURN TRUE
ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
// add a request for a weapon
PROC ADD_WEAPON_REQUEST(FINALE_WEAPON_ENUM weapon)
bWeaponRequestTracker[weapon] = TRUE
WEAPON_TYPE weaponType = GET_FINALE_WEAPON_TYPE(weapon)
REQUEST_WEAPON_ASSET(weaponType)
ENDPROC
// clear a weapon request slot
PROC CLEAR_WEAPON_REQUEST(FINALE_WEAPON_ENUM weapon)
IF bWeaponRequestTracker[weapon]
bWeaponRequestTracker[weapon] = FALSE
WEAPON_TYPE weaponType = GET_FINALE_WEAPON_TYPE(weapon)
IF HAS_WEAPON_ASSET_LOADED(weaponType)
REMOVE_WEAPON_ASSET(weaponType)
ENDIF
ENDIF
ENDPROC
// have all requests for weapons succeeded?
FUNC BOOL HAVE_ALL_WEAPON_REQUESTS_SUCCEEDED()
INT i
// loop through and check for empty
REPEAT COUNT_OF(FINALE_WEAPON_ENUM) i
IF bWeaponRequestTracker[i]
IF NOT HAS_WEAPON_ASSET_LOADED(GET_FINALE_WEAPON_TYPE(INT_TO_ENUM(FINALE_WEAPON_ENUM, i)))
// a full slot is not loaded, return false
RETURN FALSE
ENDIF
ENDIF
ENDREPEAT
RETURN TRUE
ENDFUNC
// get weapons for particular stage
PROC REQUEST_WEAPONS_FOR_STAGE(MISSION_STAGE_ENUM requestStage, BOOL bWaitForLoad, BOOL bKeepWeaponsForCurrentStage)
INT i
REPEAT COUNT_OF(FINALE_WEAPON_ENUM) i
FINALE_WEAPON_ENUM thisWeapon = INT_TO_ENUM(FINALE_WEAPON_ENUM, i)
IF IS_WEAPON_REQUIRED_FOR_MISSION_STAGE(thisWeapon, requestStage)
// if we need this recording, request it
ADD_WEAPON_REQUEST(thisWeapon)
ELSE
// otherwise try and get rid of it
IF NOT IS_WEAPON_REQUIRED_FOR_MISSION_STAGE(thisWeapon, currentMissionStage)
OR NOT bKeepWeaponsForCurrentStage
CLEAR_WEAPON_REQUEST(thisWeapon)
ENDIF
ENDIF
ENDREPEAT
// if wait for load, don't quit out 'til all the recordings are in
IF bWaitForLoad
IF NOT HAVE_ALL_WEAPON_REQUESTS_SUCCEEDED()
LOAD_ALL_OBJECTS_IF_SCREEN_FADED_OUT()
WHILE NOT HAVE_ALL_WEAPON_REQUESTS_SUCCEEDED()
WAIT(0)
ENDWHILE
ENDIF
ENDIF
ENDPROC
// is this ptfx required on this stage?
FUNC BOOL IS_PTFX_REQUIRED_FOR_MISSION_STAGE(FINALE_PTFX_ENUM ptfx, MISSION_STAGE_ENUM reqStage)
reqStage=reqStage
SWITCH ptfx
CASE F_PTFX_SCRIPT
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
// add a request for a ptfx
PROC ADD_PTFX_REQUEST(FINALE_PTFX_ENUM ptfx)
bPTFXRequestTracker[ptfx] = TRUE
// STRING sPTFX = GET_FINALE_PTFX_AS_STRING(ptfx)
REQUEST_PTFX_ASSET()
ENDPROC
// clear a ptfx request slot
PROC CLEAR_PTFX_REQUEST(FINALE_PTFX_ENUM ptfx)
IF bPTFXRequestTracker[ptfx]
bPTFXRequestTracker[ptfx] = FALSE
// STRING sPTFX = GET_FINALE_PTFX_AS_STRING(ptfx)
IF HAS_PTFX_ASSET_LOADED()
REMOVE_PTFX_ASSET()
ENDIF
ENDIF
ENDPROC
// have all requests for ptfx succeeded?
FUNC BOOL HAVE_ALL_PTFX_REQUESTS_SUCCEEDED()
INT i
// loop through and check for empty
REPEAT COUNT_OF(FINALE_PTFX_ENUM) i
IF bPTFXRequestTracker[i]
IF NOT HAS_PTFX_ASSET_LOADED()
// a full slot is not loaded, return false
RETURN FALSE
ENDIF
ENDIF
ENDREPEAT
RETURN TRUE
ENDFUNC
// get ptfx for particular stage
PROC REQUEST_PTFX_FOR_STAGE(MISSION_STAGE_ENUM requestStage, BOOL bWaitForLoad, BOOL bKeepPTFXForCurrentStage)
INT i
REPEAT COUNT_OF(FINALE_PTFX_ENUM) i
FINALE_PTFX_ENUM thisPTFX = INT_TO_ENUM(FINALE_PTFX_ENUM, i)
IF IS_PTFX_REQUIRED_FOR_MISSION_STAGE(thisPTFX, requestStage)
// if we need this recording, request it
ADD_PTFX_REQUEST(thisPTFX)
ELSE
// otherwise try and get rid of it
IF NOT IS_PTFX_REQUIRED_FOR_MISSION_STAGE(thisPTFX, currentMissionStage)
OR NOT bKeepPTFXForCurrentStage
CLEAR_PTFX_REQUEST(thisPTFX)
ENDIF
ENDIF
ENDREPEAT
// if wait for load, don't quit out 'til all the recordings are in
IF bWaitForLoad
IF NOT HAVE_ALL_PTFX_REQUESTS_SUCCEEDED()
LOAD_ALL_OBJECTS_IF_SCREEN_FADED_OUT()
WHILE NOT HAVE_ALL_PTFX_REQUESTS_SUCCEEDED()
WAIT(0)
ENDWHILE
ENDIF
ENDIF
ENDPROC
// get a sfx enum as string
FUNC STRING GET_FINALE_SFX_AS_STRING(FINALE_SFX_ENUM sfx)
SWITCH sfx
CASE F_SFX_DEVIN_BANGING
RETURN "FINALE_C2_DEVIN_INSIDE_TRUNK"
BREAK
CASE F_SFX_STEVE_DEATH
RETURN "FINALE_C2_STEVE_CAMERAMAN_DEATH"
BREAK
ENDSWITCH
RETURN "invalid!"
ENDFUNC
// is this sfx required on this stage?
FUNC BOOL IS_SFX_REQUIRED_FOR_MISSION_STAGE(FINALE_SFX_ENUM sfx, MISSION_STAGE_ENUM reqStage)
reqStage=reqStage
SWITCH sfx
CASE F_SFX_DEVIN_BANGING
IF reqStage >= STAGE_GET_TO_CLIFF
RETURN TRUE
ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
// add a request for a sfx
PROC ADD_SFX_REQUEST(FINALE_SFX_ENUM sfx)
bSFXRequestTracker[sfx] = TRUE
STRING sSFX = GET_FINALE_SFX_AS_STRING(sfx)
REQUEST_SCRIPT_AUDIO_BANK(sSFX)
ENDPROC
// clear a sfx request slot
PROC CLEAR_SFX_REQUEST(FINALE_SFX_ENUM sfx)
IF bSFXRequestTracker[sfx]
bSFXRequestTracker[sfx] = FALSE
STRING sSFX = GET_FINALE_SFX_AS_STRING(sfx)
RELEASE_NAMED_SCRIPT_AUDIO_BANK(sSFX)
ENDIF
ENDPROC
// have all requests for sfx succeeded?
FUNC BOOL HAVE_ALL_SFX_REQUESTS_SUCCEEDED()
INT i
// loop through and check for empty
REPEAT COUNT_OF(FINALE_SFX_ENUM) i
IF bSFXRequestTracker[i]
IF NOT REQUEST_SCRIPT_AUDIO_BANK(GET_FINALE_SFX_AS_STRING(INT_TO_ENUM(FINALE_SFX_ENUM, i)))
// a full slot is not loaded, return false
RETURN FALSE
ENDIF
ENDIF
ENDREPEAT
RETURN TRUE
ENDFUNC
// get sfx for particular stage
PROC REQUEST_SFX_FOR_STAGE(MISSION_STAGE_ENUM requestStage, BOOL bWaitForLoad, BOOL bKeepSFXForCurrentStage)
INT i
REPEAT COUNT_OF(FINALE_SFX_ENUM) i
FINALE_SFX_ENUM thisSFX = INT_TO_ENUM(FINALE_SFX_ENUM, i)
IF IS_SFX_REQUIRED_FOR_MISSION_STAGE(thisSFX, requestStage)
// if we need this recording, request it
ADD_SFX_REQUEST(thisSFX)
ELSE
// otherwise try and get rid of it
IF NOT IS_SFX_REQUIRED_FOR_MISSION_STAGE(thisSFX, currentMissionStage)
OR NOT bKeepSFXForCurrentStage
CLEAR_SFX_REQUEST(thisSFX)
ENDIF
ENDIF
ENDREPEAT
// if wait for load, don't quit out 'til all the recordings are in
IF bWaitForLoad
IF NOT HAVE_ALL_SFX_REQUESTS_SUCCEEDED()
LOAD_ALL_OBJECTS_IF_SCREEN_FADED_OUT()
WHILE NOT HAVE_ALL_SFX_REQUESTS_SUCCEEDED()
WAIT(0)
ENDWHILE
ENDIF
ENDIF
ENDPROC
// is this misc asset required on this stage?
FUNC BOOL IS_MISC_ASSET_REQUIRED_FOR_MISSION_STAGE(FINALE_MISC_ASSET_ENUM miscAsset, MISSION_STAGE_ENUM reqStage)
SWITCH miscAsset
CASE F_MISC_ASSET_ALL_PATH_NODES
IF reqStage = STAGE_GET_TO_HIT
OR reqStage = STAGE_TREVOR_HIT
OR reqStage = STAGE_FRANKLIN_HIT
OR reqStage = STAGE_MICHAEL_HIT
RETURN FALSE
ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
// add a request for a misc asset
PROC ADD_MISC_ASSET_REQUEST(FINALE_MISC_ASSET_ENUM miscAsset)
bMiscAssetRequestTracker[miscAsset] = TRUE
SWITCH miscAsset
CASE F_MISC_ASSET_ALL_PATH_NODES
BREAK
ENDSWITCH
ENDPROC
// clear a misc asset slot
PROC CLEAR_MISC_ASSET_REQUEST(FINALE_MISC_ASSET_ENUM miscAsset)
IF bMiscAssetRequestTracker[miscAsset]
bMiscAssetRequestTracker[miscAsset] = FALSE
SWITCH miscAsset
CASE F_MISC_ASSET_ALL_PATH_NODES
BREAK
ENDSWITCH
ENDIF
ENDPROC
// have all requests for misc assets succeeded?
FUNC BOOL HAVE_ALL_MISC_ASSET_REQUESTS_SUCCEEDED()
INT i
// loop through and check for empty
REPEAT COUNT_OF(FINALE_MISC_ASSET_ENUM) i
IF bMiscAssetRequestTracker[i]
SWITCH INT_TO_ENUM(FINALE_MISC_ASSET_ENUM, i)
CASE F_MISC_ASSET_ALL_PATH_NODES
RETURN FALSE
BREAK
ENDSWITCH
ENDIF
ENDREPEAT
RETURN TRUE
ENDFUNC
// get misc assets for particular stage
PROC REQUEST_MISC_ASSETS_FOR_STAGE(MISSION_STAGE_ENUM requestStage, BOOL bWaitForLoad, BOOL bKeepMiscAssetsForCurrentStage)
INT i
REPEAT COUNT_OF(FINALE_MISC_ASSET_ENUM) i
FINALE_MISC_ASSET_ENUM thisMiscAsset = INT_TO_ENUM(FINALE_MISC_ASSET_ENUM, i)
IF IS_MISC_ASSET_REQUIRED_FOR_MISSION_STAGE(thisMiscAsset, requestStage)
// if we need this asset, request it
ADD_MISC_ASSET_REQUEST(thisMiscAsset)
ELSE
// otherwise try and get rid of it
IF NOT IS_MISC_ASSET_REQUIRED_FOR_MISSION_STAGE(thisMiscAsset, currentMissionStage)
OR NOT bKeepMiscAssetsForCurrentStage
CLEAR_MISC_ASSET_REQUEST(thisMiscAsset)
ENDIF
ENDIF
ENDREPEAT
// if wait for load, don't quit out 'til all the recordings are in
IF bWaitForLoad
IF NOT HAVE_ALL_MISC_ASSET_REQUESTS_SUCCEEDED()
LOAD_ALL_OBJECTS_IF_SCREEN_FADED_OUT()
WHILE NOT HAVE_ALL_MISC_ASSET_REQUESTS_SUCCEEDED()
WAIT(0)
ENDWHILE
ENDIF
ENDIF
ENDPROC
// request the text for the mission
PROC REQUEST_TEXT(BOOL bWaitForLoad)
REQUEST_ADDITIONAL_TEXT("FINC", MISSION_TEXT_SLOT)
IF bWaitForLoad
WHILE NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT)
WAIT(0)
ENDWHILE
ENDIF
ENDPROC
// set all common variables to what they should be when a new stage starts
PROC RESET_ALL_COMMON_VARIABLES()
hotswapStage = MISSION_HOTSWAP_STAGE_SELECT_CHARACTER
streamingStage = MISSION_STREAMING_STAGE_REQUEST
cutsceneStage = F_CUT_STAGE_INIT
bRunningCutscene = FALSE
bSkippedCutscene = FALSE
bClearedForCutscene = FALSE
bCutsceneWaitStarted = FALSE
bShownGodText = FALSE
bShownSwitchPrompt = FALSE
bShouldDoGetInText = FALSE
bDoneGotoSpeech = FALSE
bSavedBanter = FALSE
bRemovedBlipsForWanted = FALSE
bShownLoseWantedPrompt = FALSE
bDoingDriveAudioScene = FALSE
bDoingOnFootAudioScene = FALSE
iNextRandomSpeechTime = -1
freeHotswapData.swapTarget = GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(GET_CURRENT_PLAYER_PED_ENUM())
freeHotswapData.state = FREE_HOTSWAP_STATE_SELECTING
ENDPROC
// get all variables in the correct state for this stage
PROC RESET_VARIABLES_FOR_STAGE(MISSION_STAGE_ENUM resetStage)
RESET_ALL_COMMON_VARIABLES()
INT i
SWITCH resetStage
CASE STAGE_GET_TO_HIT
REPEAT 3 i
iGetInTextStage[i] = 2
bShownGotoText[i] = FALSE
ENDREPEAT
bResetAIDrive = FALSE
bStoppedSwitchToVehicle = FALSE
bRepositionedPreviousCharacter = FALSE
bAggroedTriads = FALSE
bJumpedAheadToMichaelHit = FALSE
bJumpedAheadToTrevorHit = FALSE
bJumpedAheadToFranklinHit = FALSE
bRemovedStretchPhone = FALSE
bDetachedBasketball = FALSE
bPlayerShootingInArea = FALSE
bGivenGun = FALSE
gangsterAggro = GANGSTER_AGGRO_NOT_AGGROED
BREAK
CASE STAGE_TREVOR_HIT
steveSpeechState = STEVE_SPEECH_STATE_NOT_STARTED
g_bFinale3BHitSuccessful[CHAR_TREVOR] = FALSE
bDoneReadySpeech[CHAR_TREVOR] = FALSE
bShownDoHitText[CHAR_TREVOR] = FALSE
bDoneHitSuccessfulSpeech[CHAR_TREVOR] = FALSE
bEscapedArea[CHAR_TREVOR] = FALSE
bShownEscapePrompt[CHAR_TREVOR] = FALSE
bDoneWhoNextQuestionSpeech = FALSE
bDoneWhoNextAnswerSpeech = FALSE
bDoneCameramanSpeech = FALSE
bPlayerShootingInArea = FALSE
bDoneSpookedSpeech = FALSE
bDoSpookedSpeech = FALSE
bResetCopAccuracy = FALSE
bLockedOutOfWheelCam = FALSE
bReleasedCamButton = FALSE
bLockIntoWheelCam = FALSE
bShouldDoCamView = FALSE
bCamViewTurnedOn = FALSE
bDoneDontGetCloseHelp = FALSE
bClearedLookAtForKilledStretch = FALSE
bTaskedCopsToWander = FALSE
bAllowWheelTopSpeed = FALSE
bSuppressShotCutscene = FALSE
bSwitchCam_PlayedBloodSpurt = FALSE
bSuppressBulletCam = FALSE
bSetDoBulletCam = FALSE
scsSwitchCamBulletCam.bInitialized = FALSE
scsSwitchCamExplosion.bInitialized = FALSE
scsSwitchCamGrenade.bInitialized = FALSE
bSwitchCam_SteveKilledViaExplosion = FALSE
bSwitchCam_SteveKilledViaGrenade = FALSE
eSwitchCamState = SWITCH_CAM_IDLE
//bWasInVehicle = FALSE
//bCheckedInVehicle = FALSE
//bKilledHintCamForLeaveVehicle = FALSE
iCamViewCount = 0
iTVSubCount = 0
fStoreStevePhase = 0.0
BREAK
CASE STAGE_FRANKLIN_HIT
g_bFinale3BHitSuccessful[CHAR_FRANKLIN] = FALSE
bDoneChengLeaveSpeech = FALSE
bDoneChengEscapeSpeech = FALSE
bDoneReadySpeech[CHAR_FRANKLIN] = FALSE
bShownDoHitText[CHAR_FRANKLIN] = FALSE
bDoneHitSuccessfulSpeech[CHAR_FRANKLIN] = FALSE
bEscapedArea[CHAR_FRANKLIN] = FALSE
bShownEscapePrompt[CHAR_FRANKLIN] = FALSE
bDoneWhoNextQuestionSpeech = FALSE
bDoneWhoNextAnswerSpeech = FALSE
bCacheChengInCar = FALSE
bRestoredVehicleDensity = FALSE
bRestoredTriadHealth = FALSE
// bDoRecognizeSpeech = FALSE
// bDoneRecognizeSpeech = FALSE
bDoneGotChengSpeech = FALSE
bDoneFrontCarFollow = FALSE
bDoneMySonDeadSpeech = FALSE
bDoneAttackChengMusic = FALSE
trevorDrivingToPickupStage = TREVOR_DRIVING_TO_PICKUP_NOT_STARTED
iTriadWanderStage = 0
fBlockingTriadTime = 0.0
BREAK
CASE STAGE_MICHAEL_HIT
g_bFinale3BHitSuccessful[CHAR_MICHAEL] = FALSE
bDoneReadySpeech[CHAR_MICHAEL] = FALSE
bShownDoHitText[CHAR_MICHAEL] = FALSE
bDoneHitSuccessfulSpeech[CHAR_MICHAEL] = FALSE
bEscapedArea[CHAR_MICHAEL] = FALSE
bShownEscapePrompt[CHAR_MICHAEL] = FALSE
bDoneWhoNextQuestionSpeech = FALSE
bDoneWhoNextAnswerSpeech = FALSE
bRemovedStretchPhone = FALSE
bDetachedBasketball = FALSE
bGivenGun = FALSE
bDoneHailStretchSpeech = FALSE
bDonePhoneIntroSpeech = FALSE
bKilledSpeechForHail = FALSE
bDoneStretchToCombatSpeech = FALSE
bDoneCowardlySpeech = FALSE
bDoneDisloyalSpeech = FALSE
bDoneStretchThreatenSpeech = FALSE
bDoneStretchOrderSpeech = FALSE
bCacheStretchInCar = FALSE
bDoneRevengeForStretchSpeech = FALSE
bGotRevengeForStretchSpeaker = FALSE
bDoneKillConversationForAttack = FALSE
bDoneInstanceHintShooting = FALSE
bDoneCarArriveAudioScene = FALSE
bDoneAttackStretchMusic = FALSE
iGangsterBanterCount = 0
iStretchBanterCount = 0
iRevengeForStretchSpeaker = -1
trevorDrivingToPickupStage = TREVOR_DRIVING_TO_PICKUP_NOT_STARTED
BREAK
CASE STAGE_PICKUP_DEVIN
REPEAT 3 i
g_bFinale3BHitSuccessful[i] = TRUE
ENDREPEAT
houseOverviewShot = HOUSE_OVERVIEW_SHOT_1
createDevinHouseStage = CREATE_DEVIN_HOUSE_STAGE_NOT_STARTED
bDoneDevinToGuardSpeech = FALSE
bRecreatedDevinVolume = FALSE
BREAK
CASE STAGE_DEVINS_HOUSE
REPEAT 3 i
g_bFinale3BHitSuccessful[i] = TRUE
ENDREPEAT
bDoneKidnapDevinText = FALSE
bRepeatedKidnapDevinText = FALSE
bDoneKillGuardsText = FALSE
bPlayerNearDeck = FALSE
bDoneDevinHideSpeech = FALSE
bDoneAlertedCue = FALSE
bDoneKilledAllCue = FALSE
bSetTornadoOutOfCut = FALSE
bTriggeredDevinDamageReaction = FALSE
iDevinSpeechInBoxStage = 1
BREAK
CASE STAGE_GET_TO_CLIFF
REPEAT 3 i
g_bFinale3BHitSuccessful[i] = TRUE
ENDREPEAT
cliffStage = CLIFF_STAGE_PAN_UP
devinBootSpeechState = DEVIN_BOOT_SPEECH_STATE_WAKE_UP
iGetInTextStage[CHAR_TREVOR] = 2
//bAppliedDevinBloodDecal = FALSE
bRemovedTrevorCar = FALSE
bDoneNearlyThereSpeech = FALSE
bDonePushCarSound = FALSE
bDoDevinBangOnTrunk = FALSE
bDoDevinAdditionalBangOnTrunk = FALSE
bSetDevinRadio = FALSE
fPushCarForce = MIN_PUSH_CAR_FORCE
fPushAnimSpeed = 0.0
BREAK
ENDSWITCH
ENDPROC
FUNC INT GET_NUMBER_JOURNEY_POINTS(enumCharacterList thisChar)
SWITCH thisChar
CASE CHAR_TREVOR
RETURN 9
BREAK
CASE CHAR_FRANKLIN
RETURN 11
BREAK
CASE CHAR_MICHAEL
RETURN 3
BREAK
ENDSWITCH
RETURN 0
ENDFUNC
// reset track mission vars
PROC RESET_TRACK_MISSION_VARS()
INT i
REPEAT 3 i
IF NOT bIsNaturalSkipToGetToHits
g_bFinale3BHitSuccessful[i] = FALSE
driveToHitState[i] = DRIVE_TO_HIT_STATE_AI
bUnblockedGPS[i] = FALSE
iJourneyStage[i] = 0
bIsOffPiste[i] = FALSE
fTravelDistance[i] = DEFAULT_TRAVEL_DISTANCE
ELSE
IF NOT g_bFinale3BHitSuccessful[i]
driveToHitState[i] = DRIVE_TO_HIT_STATE_AI
bIsOffPiste[i] = FALSE
iJourneyStage[i] = GET_NUMBER_JOURNEY_POINTS(INT_TO_ENUM(enumCharacterList, i)) - 1
ELSE
driveToHitState[i] = DRIVE_TO_HIT_STATE_DONE
ENDIF
ENDIF
ENDREPEAT
sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_TREVOR] = g_bFinale3BHitSuccessful[CHAR_TREVOR]
sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_MICHAEL] = g_bFinale3BHitSuccessful[CHAR_MICHAEL]
sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_FRANKLIN] = g_bFinale3BHitSuccessful[CHAR_FRANKLIN]
ENDPROC
// get player drive vehicle
FUNC FINALE_VEHICLE_ENUM GET_PLAYER_DRIVE_VEHICLE(enumCharacterList thisChar)
SWITCH thisChar
CASE CHAR_MICHAEL
RETURN FV_MICHAEL_CAR
BREAK
CASE CHAR_FRANKLIN
RETURN FV_FRANKLIN_CAR
BREAK
CASE CHAR_TREVOR
RETURN FV_TREVOR_CAR
BREAK
ENDSWITCH
RETURN FV_MICHAEL_CAR
ENDFUNC
// get vehicle player is driving
FUNC VEHICLE_INDEX GET_VEHICLE_PLAYER_IS_DRIVING(enumCharacterList thisChar)
PED_INDEX thisPed
SWITCH thisChar
CASE CHAR_MICHAEL
thisPed = GET_MICHAEL_PED()
BREAK
CASE CHAR_FRANKLIN
thisPed = GET_FRANKLIN_PED()
BREAK
CASE CHAR_TREVOR
thisPed = GET_TREVOR_PED()
BREAK
ENDSWITCH
IF NOT IS_PED_INJURED(thisPed)
IF IS_PED_SITTING_IN_ANY_VEHICLE(thisPed)
VEHICLE_INDEX thisVehicle = GET_VEHICLE_PED_IS_IN(thisPed)
IF GET_PED_IN_VEHICLE_SEAT(thisVehicle, VS_DRIVER) = thisPed
RETURN thisVehicle
ENDIF
ENDIF
ENDIF
RETURN NULL
ENDFUNC
// get player drive target
FUNC VECTOR GET_PLAYER_DRIVE_TARGET(enumCharacterList thisChar)
SWITCH thisChar
CASE CHAR_MICHAEL
RETURN GET_FINALE_VECTOR(FINVEC_MICHAEL_CAR_AT_REC)
BREAK
CASE CHAR_FRANKLIN
RETURN GET_FINALE_VECTOR(FINVEC_CLUB)
BREAK
CASE CHAR_TREVOR
IF NOT g_bFinale3BHitSuccessful[CHAR_TREVOR]
RETURN GET_FINALE_VECTOR(FINVEC_PIER)
ELSE
RETURN GET_FINALE_VECTOR(FINVEC_PICKUP)
ENDIF
BREAK
ENDSWITCH
RETURN <<0,0,0>>
ENDFUNC
// get player hit target
FUNC VECTOR GET_PLAYER_HIT_TARGET(enumCharacterList thisChar)
SWITCH thisChar
CASE CHAR_MICHAEL
RETURN << -203.5079, -1510.4370, 31.6161 >>
BREAK
CASE CHAR_FRANKLIN
RETURN << -3018.1008, 85.4329, 11.5978 >>
BREAK
CASE CHAR_TREVOR
RETURN <<-1662.81, -1121.16, 42.9496>>
BREAK
ENDSWITCH
RETURN <<0,0,0>>
ENDFUNC
// get player drive target heading
FUNC FLOAT GET_PLAYER_DRIVE_HEADING(enumCharacterList thisChar)
SWITCH thisChar
CASE CHAR_MICHAEL
RETURN MICHAEL_CAR_AT_REC_ROT
BREAK
CASE CHAR_FRANKLIN
RETURN 134.0
BREAK
CASE CHAR_TREVOR
RETURN -136.0
BREAK
ENDSWITCH
RETURN 0.0
ENDFUNC
// get player drive recording
FUNC INT GET_PLAYER_DRIVE_RECORDING(enumCharacterList thisChar)
SWITCH thisChar
CASE CHAR_MICHAEL
RETURN 009
BREAK
CASE CHAR_FRANKLIN
RETURN 010
BREAK
CASE CHAR_TREVOR
RETURN 008
BREAK
ENDSWITCH
RETURN 000
ENDFUNC
// get player time amost at destination
FUNC FLOAT GET_PLAYER_DRIVE_ALMOST_AT_TIME(enumCharacterList thisChar)
SWITCH thisChar
CASE CHAR_MICHAEL
RETURN 29000.0
BREAK
CASE CHAR_FRANKLIN
RETURN 160000.0
BREAK
CASE CHAR_TREVOR
RETURN 127700.0
BREAK
ENDSWITCH
RETURN 0.0
ENDFUNC
// get the closest point in the recording to where the vehicle currently is
PROC CALCULATE_POINT_TO_START_DRIVE_RECORDING(PED_INDEX ped, INT iRec, FLOAT &fReturnTime, VECTOR &vReturnPos)
IF NOT IS_PED_INJURED(ped)
VECTOR vStartCalculationPos
vStartCalculationPos = GET_ENTITY_COORDS(ped)
VECTOR vUpPointPos
VECTOR vDownPointPos
VECTOR vBestPointPos
FLOAT fCheckRecordingTime = GET_TOTAL_DURATION_OF_VEHICLE_RECORDING(iRec, GET_FINALE_RECORDING_PREFIX()) / 2
FLOAT fSearchUpDownTime = fCheckRecordingTime / 2
FLOAT fUpTime
FLOAT fDownTime
FLOAT fUpDistanceFromPos
FLOAT fDownDistanceFromPos
INT iChecksPerformed = 0
WHILE iChecksPerformed < 80
// check up distance
fUpTime = fCheckRecordingTime + fSearchUpDownTime
vUpPointPos = GET_POSITION_OF_VEHICLE_RECORDING_AT_TIME(iRec, fUpTime, GET_FINALE_RECORDING_PREFIX())
fUpDistanceFromPos = GET_DISTANCE_BETWEEN_COORDS(vStartCalculationPos, vUpPointPos)
// check down distance
fDownTime = fCheckRecordingTime - fSearchUpDownTime
vDownPointPos = GET_POSITION_OF_VEHICLE_RECORDING_AT_TIME(iRec, fDownTime, GET_FINALE_RECORDING_PREFIX())
fDownDistanceFromPos = GET_DISTANCE_BETWEEN_COORDS(vStartCalculationPos, vDownPointPos)
// work out if we should be going up or down
IF fUpDistanceFromPos < fDownDistanceFromPos
fCheckRecordingTime = fUpTime
vBestPointPos = vUpPointPos
ELSE
fCheckRecordingTime = fDownTime
vBestPointPos = vDownPointPos
ENDIF
fSearchUpDownTime = fSearchUpDownTime / 2
iChecksPerformed++
ENDWHILE
fReturnTime = fCheckRecordingTime
vReturnPos = vBestPointPos
ENDIF
ENDPROC
// set player AI drive
PROC SET_PLAYER_AI_DRIVE(enumCharacterList thisChar, FLOAT fSpeed = DRIVE_TO_TARGET_SPEED, BOOL bRepositionVehicle = FALSE, BOOL bWander = FALSE)
//FINALE_VEHICLE_ENUM thisVehicle = GET_PLAYER_DRIVE_VEHICLE(thisChar)
//VEHICLE_INDEX thisVehicle = GET_VEHICLE_PLAYER_IS_DRIVING(thisChar)
VEHICLE_INDEX thisVehicle = finaleVehicle[GET_PLAYER_DRIVE_VEHICLE(thisChar)]
VECTOR vTarget = GET_PLAYER_DRIVE_TARGET(thisChar)
IF driveToHitState[thisChar] <> DRIVE_TO_HIT_STATE_DONE
OR (g_bFinale3BHitSuccessful[CHAR_TREVOR] AND thisChar = CHAR_TREVOR)
PED_INDEX thisPed
SWITCH thisChar
CASE CHAR_MICHAEL
thisPed = GET_MICHAEL_PED()
BREAK
CASE CHAR_FRANKLIN
thisPed = GET_FRANKLIN_PED()
BREAK
CASE CHAR_TREVOR
thisPed = GET_TREVOR_PED()
BREAK
ENDSWITCH
IF NOT IS_PED_INJURED(thisPed)
AND IS_VEHICLE_DRIVEABLE(thisVehicle)
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(thisVehicle)
STOP_PLAYBACK_RECORDED_VEHICLE(thisVehicle)
ENDIF
IF NOT IS_ENTITY_AT_COORD(thisPed, vTarget, <<10,10,10>>, FALSE, FALSE)
AND (driveToHitState[thisChar] <> DRIVE_TO_HIT_STATE_DONE
OR (g_bFinale3BHitSuccessful[CHAR_TREVOR] AND thisChar = CHAR_TREVOR))
IF HAS_COLLISION_LOADED_AROUND_ENTITY(thisVehicle)
OR bRepositionVehicle
FREEZE_ENTITY_POSITION(thisVehicle, FALSE)
IF bRepositionVehicle
//SCRIPT_ASSERT("reposition vehicle!")
printstring("reposition vehicle") printnl()
CLEAR_AREA(vSwitchNodePos, 5, TRUE)
SET_ENTITY_COORDS(thisVehicle, vSwitchNodePos)
SET_ENTITY_HEADING(thisVehicle, fSwitchNodeRot)
SET_VEHICLE_ON_GROUND_PROPERLY(thisVehicle)
fSwitchNodeRot=fSwitchNodeRot
ENDIF
IF NOT bWander
//TASK_VEHICLE_DRIVE_TO_COORD_LONGRANGE(thisPed, thisVehicle, vTarget, fSpeed, DRIVINGMODE_AVOIDCARS, 4.0)
ELSE
//TASK_VEHICLE_MISSION(thisPed, thisVehicle, NULL, MISSION_CRUISE, 10.0, DF_SwerveAroundAllCars|DF_StopForPeds|DF_SteerAroundObjects|DF_UseShortCutLinks|DF_ChangeLanesAroundObstructions|DF_StopForCars|DF_DriveIntoOncomingTraffic, -1, -1)
//TASK_VEHICLE_TEMP_ACTION(thisPed, thisVehicle, TEMPACT_GOFORWARD, 10000)
ENDIF
TASK_VEHICLE_MISSION(thisPed, thisVehicle, NULL, MISSION_CRUISE, fSpeed, DRIVINGMODE_AVOIDCARS, -1, -1)
IF bRepositionVehicle
IF NOT IS_PED_INJURED(GET_PED_IN_VEHICLE_SEAT(thisVehicle))
SET_VEHICLE_FORWARD_SPEED(thisVehicle, POST_SWITCH_SPEED)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
//IF driveToHitState[thisChar] <> DRIVE_TO_HIT_STATE_AI
//driveToHitState[thisChar] = DRIVE_TO_HIT_STATE_AI
ENDIF
ENDPROC
/*
// set player recording drive
PROC SET_PLAYER_RECORDING_DRIVE(enumCharacterList thisChar, FLOAT fOverrideSkip = -1.0)
SELECTOR_SLOTS_ENUM thisSelector = GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(thisChar)
//FINALE_VEHICLE_ENUM thisVehicle = GET_PLAYER_DRIVE_VEHICLE(thisChar)
//VEHICLE_INDEX thisVehicle = GET_VEHICLE_PLAYER_IS_DRIVING(thisChar)
VEHICLE_INDEX thisVehicle = finaleVehicle[GET_PLAYER_DRIVE_VEHICLE(thisChar)]
INT iRec = GET_PLAYER_DRIVE_RECORDING(thisChar)
IF driveToHitState[thisChar] <> DRIVE_TO_HIT_STATE_DONE
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[thisSelector])
AND IS_VEHICLE_DRIVEABLE(thisVehicle)
IF NOT IS_PED_IN_VEHICLE(sSelectorPeds.pedID[thisSelector], thisVehicle)
SET_PED_INTO_VEHICLE(sSelectorPeds.pedID[thisSelector], thisVehicle)
ENDIF
VECTOR vStartDrivePoint
FLOAT fStartDriveTime
IF fOverrideSkip < 0
CALCULATE_POINT_TO_START_DRIVE_RECORDING(sSelectorPeds.pedID[thisSelector], iRec, fStartDriveTime, vStartDrivePoint)
ENDIF
IF (WOULD_ENTITY_BE_OCCLUDED(GET_ENTITY_MODEL(thisVehicle), vStartDrivePoint) AND NOT IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vStartDrivePoint, <<100,100,100>>, FALSE, FALSE))
OR fOverrideSkip >= 0.0
START_PLAYBACK_RECORDED_VEHICLE(thisVehicle, iRec, GET_FINALE_RECORDING_PREFIX())
IF fOverrideSkip < 0
SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(thisVehicle, fStartDriveTime)
ELSE
SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(thisVehicle, fOverrideSkip)
ENDIF
FORCE_PLAYBACK_RECORDED_VEHICLE_UPDATE(thisVehicle)
driveToHitState[thisChar] = DRIVE_TO_HIT_STATE_ON_RECORDING
ENDIF
ENDIF
ENDIF
ENDPROC
*/
// set michael and trevor init drive to
PROC SET_MICHAEL_AND_TREVOR_INITIAL_DRIVE_TO_HITS()
//SET_PLAYER_RECORDING_DRIVE(CHAR_MICHAEL, 2500)
//SET_PLAYER_RECORDING_DRIVE(CHAR_TREVOR, 3500)
ENDPROC
FUNC VECTOR GET_ALMOST_AT_HIT_POS(enumCharacterList thisChar)
SWITCH thisChar
CASE CHAR_MICHAEL
RETURN <<24.07882, -1633.28174, 27.30396>>
BREAK
CASE CHAR_TREVOR
RETURN <<-1463.51660, -781.07458, 21.975963>>
BREAK
CASE CHAR_FRANKLIN
RETURN <<-2419.62012, -232.66293, 13.91232>>
BREAK
ENDSWITCH
RETURN <<0,0,0>>
ENDFUNC
FUNC FLOAT GET_ALMOST_AT_HIT_ROT(enumCharacterList thisChar)
SWITCH thisChar
CASE CHAR_MICHAEL
RETURN 47.9
BREAK
CASE CHAR_TREVOR
RETURN 139.6
BREAK
CASE CHAR_FRANKLIN
RETURN 62.0
BREAK
ENDSWITCH
RETURN 0.0
ENDFUNC
FUNC VECTOR GET_JOURNEY_POS(enumCharacterList thisChar, INT i)
SWITCH thisChar
CASE CHAR_TREVOR
SWITCH i
CASE 0
RETURN <<572.77, -2041.91, 28.29>>
BREAK
CASE 1
RETURN <<306.81, -2130.84, 13.98>>
BREAK
CASE 2
RETURN <<-42.09, -2043.54, 19.06>>
BREAK
CASE 3
RETURN <<-378.47, -2076.81, 24.75>>
BREAK
CASE 4
RETURN <<-649.18, -1472.77, 9.62>>
BREAK
CASE 5
RETURN <<-788.80, -1074.18, 10.28>>
BREAK
CASE 6
RETURN <<-1123.68, -792.15, 16.45>>
BREAK
CASE 7
RETURN <<-1296.71, -880.73, 10.70>>
BREAK
CASE 8
RETURN GET_ALMOST_AT_HIT_POS(thisChar)
BREAK
ENDSWITCH
BREAK
CASE CHAR_FRANKLIN
SWITCH i
CASE 0
RETURN <<943.90, -1977.80, 28.73>>
BREAK
CASE 1
RETURN <<940.13, -1754.73, 29.66>>
BREAK
CASE 2
RETURN <<717.67, -1428.46, 29.99>>
BREAK
CASE 3
RETURN <<300.89, -1294.41, 29.0>>
BREAK
CASE 4
RETURN <<156.90, -1012.33, 27.89>>
BREAK
CASE 5
RETURN <<-540.68, -829.72, 27.52>>
BREAK
CASE 6
RETURN <<-888.03, -828.43, 16.87>>
BREAK
CASE 7
RETURN <<-1264.50, -618.77, 25.58>>
BREAK
CASE 8
RETURN <<-1571.62, -637.31, 28.35>>
BREAK
CASE 9
RETURN <<-1829.25, -503.28, 27.06>>
BREAK
CASE 10
RETURN GET_ALMOST_AT_HIT_POS(thisChar)
BREAK
ENDSWITCH
BREAK
CASE CHAR_MICHAEL
SWITCH i
CASE 0
RETURN <<612.07, -2039.58, 27.89>>
BREAK
CASE 1
RETURN <<455.97, -2013.61, 22.22>>
BREAK
CASE 2
RETURN GET_ALMOST_AT_HIT_POS(thisChar)
BREAK
ENDSWITCH
BREAK
ENDSWITCH
RETURN GET_ALMOST_AT_HIT_POS(thisChar)
ENDFUNC
FUNC FLOAT GET_JOURNEY_ROT(enumCharacterList thisChar, INT i)
SWITCH thisChar
CASE CHAR_TREVOR
SWITCH i
CASE 0
RETURN 85.06
BREAK
CASE 1
RETURN 46.30
BREAK
CASE 2
RETURN 108.41
BREAK
CASE 3
RETURN 64.5
BREAK
CASE 4
RETURN -3.34
BREAK
CASE 5
RETURN 27.76
BREAK
CASE 6
RETURN 131.12
BREAK
CASE 7
RETURN 36.14
BREAK
CASE 8
RETURN GET_ALMOST_AT_HIT_ROT(thisChar)
BREAK
ENDSWITCH
BREAK
CASE CHAR_FRANKLIN
SWITCH i
CASE 0
RETURN -9.81
BREAK
CASE 1
RETURN 77.7
BREAK
CASE 2
RETURN 83.3
BREAK
CASE 3
RETURN 89.4
BREAK
CASE 4
RETURN 65.5
BREAK
CASE 5
RETURN 89.66
BREAK
CASE 6
RETURN 87.87
BREAK
CASE 7
RETURN 126.30
BREAK
CASE 8
RETURN 47.89
BREAK
CASE 9
RETURN 53.76
BREAK
CASE 10
RETURN GET_ALMOST_AT_HIT_ROT(thisChar)
BREAK
ENDSWITCH
BREAK
CASE CHAR_MICHAEL
SWITCH i
CASE 0
RETURN 85.60
BREAK
CASE 1
RETURN 42.76
BREAK
CASE 2
RETURN GET_ALMOST_AT_HIT_ROT(thisChar)
BREAK
ENDSWITCH
BREAK
ENDSWITCH
RETURN GET_ALMOST_AT_HIT_ROT(thisChar)
ENDFUNC
FUNC VECTOR GET_PLAYER_HIDE_POS(enumCharacterList thisChar)
SWITCH thisChar
CASE CHAR_MICHAEL
RETURN <<-2480.6, 754.2, 92.7>>
BREAK
CASE CHAR_TREVOR
RETURN <<-2460.6, 754.2, 92.7>>
BREAK
CASE CHAR_FRANKLIN
RETURN <<-2440.6, 754.2, 92.7>>
BREAK
ENDSWITCH
RETURN <<2163, 7982, 110>>
ENDFUNC
// get a heading normalised between 0 and 360
FUNC FLOAT NORMALISE_HEADING(FLOAT fHeading)
FLOAT fReturn = fHeading
IF fReturn < 0
fReturn += 360
ELIF fReturn > 360
fReturn -= 360
ENDIF
RETURN fReturn
ENDFUNC
FUNC BOOL DOES_HEADING_MATCH_IDEAL_HEADING(FLOAT fHeading, FLOAT fIdealHeading, FLOAT allowAngleFrom0 = 90.0)
FLOAT fHeadingDiff = fHeading - fIdealHeading
IF fHeadingDiff < 0
fHeadingDiff *= -1
ENDIF
IF fHeadingDiff <= allowAngleFrom0
OR fHeadingDiff >= 360 - allowAngleFrom0
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
// update journeys to hits
PROC UPDATE_JOURNEYS_TO_HITS()
IF GET_GAME_TIMER() >= iNextUpdateJourneysTime
IF freeHotswapData.state = FREE_HOTSWAP_STATE_SELECTING
VECTOR vNodePos
vNodePos=vNodePos
FLOAT fNodeRot
fNodeRot=fNodeRot
INT i
REPEAT 3 i
enumCharacterList thisChar = INT_TO_ENUM(enumCharacterList, i)
SELECTOR_SLOTS_ENUM thisSelectorPed = GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(thisChar)
// update this char's vehicle
PED_INDEX thisPed
FINALE_VEHICLE_ENUM thisVehicleEnum = GET_PLAYER_DRIVE_VEHICLE(thisChar)
SWITCH thisChar
CASE CHAR_FRANKLIN
thisPed = GET_FRANKLIN_PED()
BREAK
CASE CHAR_MICHAEL
thisPed = GET_MICHAEL_PED()
BREAK
CASE CHAR_TREVOR
thisPed = GET_TREVOR_PED()
BREAK
ENDSWITCH
IF NOT IS_PED_INJURED(thisPed)
VEHICLE_INDEX drivingVehicle = GET_VEHICLE_PLAYER_IS_DRIVING(thisChar)
BOOL bVehicleIsDamageProof = TRUE
IF IS_VEHICLE_DRIVEABLE(drivingVehicle)
MODEL_NAMES thisModel = GET_ENTITY_MODEL(drivingVehicle)
IF NOT IS_THIS_MODEL_A_HELI(thisModel)
AND NOT IS_THIS_MODEL_A_BOAT(thisModel)
AND NOT IS_THIS_MODEL_A_PLANE(thisModel)
IF drivingVehicle <> finaleVehicle[thisVehicleEnum]
IF DOES_ENTITY_EXIST(finaleVehicle[thisVehicleEnum])
IF IS_ENTITY_A_MISSION_ENTITY(finaleVehicle[thisVehicleEnum])
SET_VEHICLE_AS_NO_LONGER_NEEDED(finaleVehicle[thisVehicleEnum])
ENDIF
ENDIF
ENDIF
finaleVehicle[thisVehicleEnum] = drivingVehicle
IF NOT IS_ENTITY_A_MISSION_ENTITY(finaleVehicle[thisVehicleEnum])
SET_ENTITY_SHOULD_FREEZE_WAITING_ON_COLLISION(finaleVehicle[thisVehicleEnum], TRUE)
SET_ENTITY_AS_MISSION_ENTITY(finaleVehicle[thisVehicleEnum], TRUE, TRUE)
ENDIF
ELSE
bVehicleIsDamageProof = FALSE
ENDIF
ELSE
bVehicleIsDamageProof = FALSE
ENDIF
IF thisChar = GET_CURRENT_PLAYER_PED_ENUM()
bVehicleIsDamageProof = FALSE
ENDIF
IF NOT IS_ENTITY_DEAD(finaleVehicle[thisVehicleEnum])
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(finaleVehicle[thisVehicleEnum], bVehicleIsDamageProof)
SET_VEHICLE_CAN_BE_VISIBLY_DAMAGED(finaleVehicle[thisVehicleEnum], NOT bVehicleIsDamageProof)
IF IS_THIS_MODEL_A_CAR(GET_ENTITY_MODEL(finaleVehicle[thisVehicleEnum]))
SET_VEHICLE_CAN_BREAK(finaleVehicle[thisVehicleEnum], NOT bVehicleIsDamageProof)
ENDIF
ELSE
IF DOES_ENTITY_EXIST(finaleVehicle[thisVehicleEnum])
IF IS_ENTITY_A_MISSION_ENTITY(finaleVehicle[thisVehicleEnum])
SET_VEHICLE_AS_NO_LONGER_NEEDED(finaleVehicle[thisVehicleEnum])
ENDIF
ENDIF
ENDIF
ENDIF
IF thisChar <> GET_CURRENT_PLAYER_PED_ENUM()
AND NOT IS_PED_INJURED(sSelectorPeds.pedID[thisSelectorPed])
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[thisVehicleEnum])
SWITCH driveToHitState[thisChar]
CASE DRIVE_TO_HIT_STATE_AI
IF GET_GAME_TIMER() >= iJourneyWarpTimer[thisChar]
IF NOT bIsOffPiste[thisChar]
INT iNumberJourneyPoints
iNumberJourneyPoints = GET_NUMBER_JOURNEY_POINTS(thisChar)
iJourneyStage[thisChar]++
IF iJourneyStage[thisChar] >= iNumberJourneyPoints
iJourneyStage[thisChar] = iNumberJourneyPoints - 1
ENDIF
iJourneyWarpTimer[thisChar] = GET_GAME_TIMER() + 15000
ELSE
VECTOR vHitPos
vHitPos = GET_JOURNEY_POS(thisChar, iJourneyStage[thisChar])
VECTOR vVectorDiff
vVectorDiff = vHitPos - vOffPistePos[thisChar]
FLOAT fLengthBetween
fLengthBetween = GET_DISTANCE_BETWEEN_COORDS(vOffPistePos[thisChar], vHitPos)
FLOAT fProportionBetween
fProportionBetween = fTravelDistance[thisChar] / fLengthBetween
VECTOR vDistanceToWarp
vDistanceToWarp = vVectorDiff * <<fProportionBetween,fProportionBetween,fProportionBetween>>
VECTOR vCheckPos
vCheckPos = vOffPistePos[thisChar] + vDistanceToWarp
IF GET_CLOSEST_VEHICLE_NODE_WITH_HEADING(vCheckPos, vNodePos, fNodeRot, NF_IGNORE_SLIPLANES | NF_IGNORE_SWITCHED_OFF_DEADENDS)
IF GET_DISTANCE_BETWEEN_COORDS(vNodePos, vHitPos) < OFF_PISTE_DISTANCE
bIsOffPiste[thisChar] = FALSE
ELSE
IF GET_DISTANCE_BETWEEN_COORDS(vNodePos, vOffPistePos[thisChar]) >= 15
fTravelDistance[thisChar] = DEFAULT_TRAVEL_DISTANCE
FLOAT fIdealHeading
fIdealHeading = GET_HEADING_BETWEEN_VECTORS_2D(vNodePos, vHitPos)
IF NOT DOES_HEADING_MATCH_IDEAL_HEADING(fNodeRot, fIdealHeading)
fNodeRot += 180
ENDIF
vOffPistePos[thisChar] = vNodePos
fOffPisteRot[thisChar] = fNodeRot
ELSE
fTravelDistance[thisChar] += DEFAULT_TRAVEL_DISTANCE
ENDIF
ENDIF
ELSE
fTravelDistance[thisChar] += DEFAULT_TRAVEL_DISTANCE
ENDIF
iJourneyWarpTimer[thisChar] = GET_GAME_TIMER() + 3000
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDIF
ENDIF
ENDREPEAT
ENDIF
iNextUpdateJourneysTime = GET_GAME_TIMER() + 400
ENDIF
ENDPROC
PROC RESET_DRIVE_TO_VALUES_BASED_ON_COMPLETED_HITS()
INT i
REPEAT 3 i
enumCharacterList thisChar = INT_TO_ENUM(enumCharacterList, i)
SELECTOR_SLOTS_ENUM thisSelector = GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(thisChar)
IF g_bFinale3BHitSuccessful[thisChar]
driveToHitState[thisChar] = DRIVE_TO_HIT_STATE_DONE
sSelectorPeds.bBlockSelectorPed[thisSelector] = TRUE
ELSE
iJourneyStage[i] = GET_NUMBER_JOURNEY_POINTS(INT_TO_ENUM(enumCharacterList, i)) - 1
bIsOffPiste[i] = FALSE
driveToHitState[thisChar] = DRIVE_TO_HIT_STATE_AI
sSelectorPeds.bBlockSelectorPed[thisSelector] = FALSE
ENDIF
ENDREPEAT
ENDPROC
// return the correct character to start a particular stage on
FUNC enumCharacterList GET_CHARACTER_FOR_MISSION_STAGE(MISSION_STAGE_ENUM getStage)
SWITCH getStage
CASE STAGE_GET_TO_HIT
RETURN CHAR_FRANKLIN
BREAK
CASE STAGE_TREVOR_HIT
RETURN CHAR_TREVOR
BREAK
CASE STAGE_MICHAEL_HIT
RETURN CHAR_MICHAEL
BREAK
CASE STAGE_FRANKLIN_HIT
RETURN CHAR_FRANKLIN
BREAK
CASE STAGE_PICKUP_DEVIN
RETURN CHAR_TREVOR
BREAK
CASE STAGE_DEVINS_HOUSE
RETURN CHAR_TREVOR
BREAK
CASE STAGE_GET_TO_CLIFF
RETURN CHAR_TREVOR
BREAK
ENDSWITCH
RETURN CHAR_MICHAEL
ENDFUNC
// set vehicle properties
PROC SET_FINALE_VEHICLE_PROPERTIES(FINALE_VEHICLE_ENUM fVehicle)
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[fVehicle])
SET_VEHICLE_CAN_LEAK_OIL(finaleVehicle[fVehicle], FALSE)
SET_VEHICLE_CAN_LEAK_PETROL(finaleVehicle[fVehicle], FALSE)
SET_DISABLE_VEHICLE_PETROL_TANK_FIRES(finaleVehicle[fVehicle], TRUE)
IF IS_THIS_MODEL_A_CAR(GET_ENTITY_MODEL(finaleVehicle[fVehicle]))
OR IS_THIS_MODEL_A_BIKE(GET_ENTITY_MODEL(finaleVehicle[fVehicle]))
SET_VEHICLE_TYRES_CAN_BURST(finaleVehicle[fVehicle], FALSE)
ENDIF
SWITCH fVehicle
CASE FV_DEVIN_CAR
SET_VEHICLE_COLOUR_COMBINATION(finaleVehicle[fVehicle], 0)
SET_VEHICLE_NUMBER_PLATE_TEXT(finaleVehicle[fVehicle], " M0NIED ")
//SET_VEHICLE_CAN_BREAK(finaleVehicle[fVehicle], FALSE)
SET_DOOR_ALLOWED_TO_BE_BROKEN_OFF(finaleVehicle[fVehicle], SC_DOOR_BOOT, FALSE)
SET_VEHICLE_DIRT_LEVEL(finaleVehicle[fVehicle], 0.0)
SET_VEHICLE_DOORS_LOCKED(finaleVehicle[fVehicle], VEHICLELOCK_LOCKED)
SET_VEHICLE_HAS_STRONG_AXLES(finaleVehicle[fVehicle], TRUE)
SET_VEHICLE_TYRES_CAN_BURST(finaleVehicle[fVehicle], FALSE)
SET_VEHICLE_STRONG(finaleVehicle[fVehicle], TRUE)
SET_VEHICLE_CAN_BREAK(finaleVehicle[fVehicle], FALSE)
//SET_VEHICLE_CAN_BE_VISIBLY_DAMAGED(finaleVehicle[fVehicle], FALSE)
BREAK
CASE FV_TREVOR_CAR
SET_ENTITY_SHOULD_FREEZE_WAITING_ON_COLLISION(finaleVehicle[fVehicle], TRUE)
BREAK
CASE FV_MICHAEL_CAR
SET_ENTITY_SHOULD_FREEZE_WAITING_ON_COLLISION(finaleVehicle[fVehicle], TRUE)
BREAK
CASE FV_FRANKLIN_CAR
SET_ENTITY_SHOULD_FREEZE_WAITING_ON_COLLISION(finaleVehicle[fVehicle], TRUE)
BREAK
ENDSWITCH
ENDIF
ENDPROC
// create a player vehicle for the mission
PROC FINALE_CREATE_VEHICLE(MISSION_STAGE_ENUM createStage, FINALE_VEHICLE_ENUM fVehicle, VECTOR vCreatePos, FLOAT fCreateRot, BOOL bKeepModel = TRUE, BOOL bKeepVehicle = TRUE, BOOL bMakeInvincible = FALSE, BOOL bSetOnGroundProperly = TRUE, BOOL bSetEngineOn = TRUE)
IF NOT IS_VEHICLE_DRIVEABLE(finaleVehicle[fVehicle])
FINALE_MODEL_ENUM vehicleModelEnum = GET_MODEL_ENUM_FOR_FINALE_VEHICLE(fVehicle)
SWITCH fVehicle
CASE FV_FRANKLIN_CAR
IF createStage = STAGE_FRANKLIN_HIT
IF IS_REPLAY_CHECKPOINT_VEHICLE_AVAILABLE()
AND NOT g_bShitskipAccepted
CREATE_VEHICLE_FOR_REPLAY(finaleVehicle[fVehicle], vCreatePos, fCreateRot, FALSE, FALSE, FALSE, FALSE, TRUE, GET_MODEL_FOR_FINALE_MODEL_ENUM(vehicleModelEnum))
bModelRequestTracker[vehicleModelEnum] = FALSE
ELSE
CREATE_PLAYER_VEHICLE(finaleVehicle[fVehicle], CHAR_FRANKLIN, vCreatePos, fCreateRot, FALSE, VEHICLE_TYPE_BIKE)
ENDIF
ELSE
CREATE_PLAYER_VEHICLE(finaleVehicle[fVehicle], CHAR_FRANKLIN, vCreatePos, fCreateRot, FALSE, VEHICLE_TYPE_BIKE)
ENDIF
BREAK
CASE FV_TREVOR_CAR
IF createStage = STAGE_TREVOR_HIT
OR createStage = STAGE_PICKUP_DEVIN
OR createStage = STAGE_DEVINS_HOUSE
IF IS_REPLAY_CHECKPOINT_VEHICLE_AVAILABLE()
AND NOT g_bShitskipAccepted
CREATE_VEHICLE_FOR_REPLAY(finaleVehicle[fVehicle], vCreatePos, fCreateRot, FALSE, FALSE, FALSE, FALSE, TRUE, GET_MODEL_FOR_FINALE_MODEL_ENUM(vehicleModelEnum))
bModelRequestTracker[vehicleModelEnum] = FALSE
ELSE
CREATE_PLAYER_VEHICLE(finaleVehicle[fVehicle], CHAR_TREVOR, vCreatePos, fCreateRot, FALSE)
ENDIF
ELSE
CREATE_PLAYER_VEHICLE(finaleVehicle[fVehicle], CHAR_TREVOR, vCreatePos, fCreateRot, FALSE)
ENDIF
BREAK
CASE FV_MICHAEL_CAR
IF createStage = STAGE_MICHAEL_HIT
IF IS_REPLAY_CHECKPOINT_VEHICLE_AVAILABLE()
AND NOT g_bShitskipAccepted
CREATE_VEHICLE_FOR_REPLAY(finaleVehicle[fVehicle], vCreatePos, fCreateRot, FALSE, FALSE, FALSE, FALSE, TRUE, GET_MODEL_FOR_FINALE_MODEL_ENUM(vehicleModelEnum))
bModelRequestTracker[vehicleModelEnum] = FALSE
ELSE
CREATE_PLAYER_VEHICLE(finaleVehicle[fVehicle], CHAR_MICHAEL, vCreatePos, fCreateRot, FALSE)
ENDIF
ELSE
CREATE_PLAYER_VEHICLE(finaleVehicle[fVehicle], CHAR_MICHAEL, vCreatePos, fCreateRot, FALSE)
ENDIF
BREAK
DEFAULT
finaleVehicle[fVehicle] = CREATE_VEHICLE(GET_MODEL_FOR_FINALE_MODEL_ENUM(vehicleModelEnum), vCreatePos, fCreateRot)
BREAK
ENDSWITCH
IF bSetOnGroundProperly
SET_VEHICLE_ON_GROUND_PROPERLY(finaleVehicle[fVehicle])
IF bSetEngineOn
SET_VEHICLE_ENGINE_ON(finaleVehicle[fVehicle], TRUE, TRUE)
ENDIF
ENDIF
IF NOT bKeepModel
CLEAR_MODEL_REQUEST(ENUM_TO_INT(vehicleModelEnum))
ENDIF
IF bMakeInvincible
SET_VEHICLE_CAN_BE_VISIBLY_DAMAGED(finaleVehicle[fVehicle], FALSE)
SET_VEHICLE_CAN_BREAK(finaleVehicle[fVehicle], FALSE)
SET_ENTITY_PROOFS(finaleVehicle[fVehicle], TRUE, TRUE, TRUE, TRUE, TRUE)
ENDIF
SET_FINALE_VEHICLE_PROPERTIES(fVehicle)
IF NOT bKeepVehicle
SET_VEHICLE_AS_NO_LONGER_NEEDED(finaleVehicle[fVehicle])
ENDIF
ENDIF
ENDPROC
// setup player character with their correct variations
PROC SETUP_PLAYER_CHARACTER_WITH_MISSION_VARIATIONS(PED_INDEX ped, enumCharacterList createChar, MISSION_STAGE_ENUM setStage)
setSTage = setStage
IF NOT IS_PED_INJURED(ped)
SWITCH createChar
CASE CHAR_MICHAEL
//IF setStage = STAGE_GET_TO_HIT
SET_PED_COMP_ITEM_CURRENT_SP(ped, COMP_TYPE_OUTFIT, OUTFIT_P0_LEATHER_AND_JEANS, FALSE)
//ENDIF
BREAK
CASE CHAR_TREVOR
//IF setStage = STAGE_GET_TO_HIT
SET_PED_COMP_ITEM_CURRENT_SP(ped, COMP_TYPE_OUTFIT, OUTFIT_P2_TSHIRT_JEANS_2, FALSE)
//ENDIF
BREAK
ENDSWITCH
ENDIF
ENDPROC
// apply attributes
PROC APPLY_PLAYER_ATTRIBUTES(PED_INDEX ped, BOOL bOnlyDamagedByPlayer)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped, TRUE)
SET_PED_RELATIONSHIP_GROUP_HASH(ped, RELGROUPHASH_PLAYER)
SET_PED_CAN_BE_TARGETTED(ped, FALSE)
SET_PED_KEEP_TASK(ped, TRUE)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(ped, bOnlyDamagedByPlayer)
SET_ENTITY_AS_MISSION_ENTITY(ped, TRUE, TRUE)
SET_PED_SUFFERS_CRITICAL_HITS(ped, FALSE)
SET_PED_CONFIG_FLAG(ped, PCF_DisableHurt, TRUE)
SET_PED_CONFIG_FLAG(ped, PCF_DisableExplosionReactions, TRUE)
//SET_PED_CONFIG_FLAG(ped, PCF_ForcedToStayInCover, TRUE)
SET_PED_CAN_BE_KNOCKED_OFF_VEHICLE(ped, KNOCKOFFVEHICLE_HARD)
SET_PED_CAN_SWITCH_WEAPON(ped, FALSE)
SET_RAGDOLL_BLOCKING_FLAGS(ped, RBF_BULLET_IMPACT)
// temp - setting health silly high
SET_PED_MAX_HEALTH(ped, 10000)
SET_ENTITY_HEALTH(ped, 10000)
//SET_PED_COMBAT_ATTRIBUTES(ped, CA_USE_COVER, FALSE)
//SET_PED_COMBAT_MOVEMENT(ped, CM_STATIONARY)
ENDPROC
// all player peds block non-temporary events and reset relationships
PROC REAPPLY_PLAYER_PED_ATTRIBUTES(BOOL bSetPlayerProofsOff = TRUE)
INT i
REPEAT COUNT_OF(sSelectorPeds.pedID) i
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[i])
BOOL bSetOnlyDamagedByPlayer = TRUE
APPLY_PLAYER_ATTRIBUTES(sSelectorPeds.pedID[i], bSetOnlyDamagedByPlayer)
ENDIF
ENDREPEAT
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF bSetPlayerProofsOff
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(PLAYER_PED_ID(), FALSE)
SET_ENTITY_PROOFS(PLAYER_PED_ID(), FALSE, FALSE, FALSE, FALSE, FALSE)
CLEAR_RAGDOLL_BLOCKING_FLAGS(PLAYER_PED_ID(), RBF_BULLET_IMPACT)
ENDIF
SET_PED_CAN_SWITCH_WEAPON(PLAYER_PED_ID(), TRUE)
SET_PED_CAN_BE_KNOCKED_OFF_VEHICLE(PLAYER_PED_ID(), KNOCKOFFVEHICLE_DEFAULT)
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_ForcedToStayInCover, FALSE)
IF currentMissionStage < STAGE_GET_TO_HIT
SET_PED_MAX_HEALTH(PLAYER_PED_ID(), 200)
SET_ENTITY_HEALTH(PLAYER_PED_ID(), 200)
ENDIF
ENDIF
ENDPROC
// create player character
PROC FINALE_CREATE_PLAYER_CHARACTER(enumCharacterList createChar, MISSION_STAGE_ENUM setStage, VECTOR vPos, FLOAT fRot, VEHICLE_INDEX veh = NULL, VEHICLE_SEAT seat = VS_DRIVER, BOOL bWaitForStreaming = FALSE)
SELECTOR_SLOTS_ENUM selectorSlot = GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(createChar)
IF NOT DOES_ENTITY_EXIST(sSelectorPeds.pedID[selectorSlot])
IF NOT IS_ENTITY_DEAD(veh)
// create in vehicle
WHILE NOT(CREATE_PLAYER_PED_INSIDE_VEHICLE(sSelectorPeds.pedID[selectorSlot], createChar, veh, seat, FALSE))
WAIT(0)
ENDWHILE
ELSE
// create on foot
WHILE NOT(CREATE_PLAYER_PED_ON_FOOT(sSelectorPeds.pedID[selectorSlot], createChar, vPos, fRot, FALSE))
WAIT(0)
ENDWHILE
ENDIF
IF bWaitForStreaming
BOOL bFullyStreamed = FALSE
WHILE NOT bFullyStreamed
WAIT(0)
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[selectorSlot])
IF HAVE_ALL_STREAMING_REQUESTS_COMPLETED(sSelectorPeds.pedID[selectorSlot])
bFullyStreamed = TRUE
ENDIF
ELSE
bFullyStreamed = TRUE
ENDIF
ENDWHILE
ENDIF
ENDIF
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[selectorSlot])
BOOL bSetOnlyDamagedByPlayer = FALSE
bSetOnlyDamagedByPlayer = TRUE
APPLY_PLAYER_ATTRIBUTES(sSelectorPeds.pedID[selectorSlot], bSetOnlyDamagedByPlayer)
SWITCH createChar
CASE CHAR_MICHAEL
ADD_PED_FOR_DIALOGUE(finaleConversation, 0, sSelectorPeds.pedID[selectorSlot], "MICHAEL")
BREAK
CASE CHAR_TREVOR
ADD_PED_FOR_DIALOGUE(finaleConversation, 1, sSelectorPeds.pedID[selectorSlot], "TREVOR")
BREAK
CASE CHAR_FRANKLIN
ADD_PED_FOR_DIALOGUE(finaleConversation, 2, sSelectorPeds.pedID[selectorSlot], "FRANKLIN")
BREAK
ENDSWITCH
SETUP_PLAYER_CHARACTER_WITH_MISSION_VARIATIONS(sSelectorPeds.pedID[selectorSlot], createChar, setStage)
ENDIF
ENDPROC
// set player in vehicle if not already in
PROC SET_PLAYER_PED_INTO_FINALE_VEHICLE(FINALE_VEHICLE_ENUM fVehicle, VEHICLE_SEAT seat, BOOL bKeepVehicle = TRUE)
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[fVehicle])
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), finaleVehicle[fVehicle])
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), finaleVehicle[fVehicle], seat)
IF NOT bKeepVehicle
SET_VEHICLE_AS_NO_LONGER_NEEDED(finaleVehicle[fVehicle])
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC SET_FRANKLIN_HELMET_INDEX()
PED_INDEX franklinPed = GET_FRANKLIN_PED()
IF NOT IS_PED_INJURED(franklinPed)
IF NOT IS_PED_WEARING_HELMET(franklinPed)
SET_PED_HELMET_PROP_INDEX(franklinPed, 6)
SET_PED_HELMET_TEXTURE_INDEX(franklinPed, 0)
ENDIF
ENDIF
ENDPROC
PROC SET_HELMET_IF_VEHICLE_A_BIKE(VEHICLE_INDEX veh)
IF IS_THIS_MODEL_A_BIKE(GET_ENTITY_MODEL(veh))
IF GET_PED_PROP_INDEX(PLAYER_PED_ID(), ANCHOR_HEAD) = -1
GIVE_PED_HELMET(PLAYER_PED_ID(), FALSE)
ENDIF
ENDIF
ENDPROC
// create the player characters, and transport if appropriate, for a mission stage
PROC CREATE_PLAYER_CHARACTERS_WITH_TRANSPORT_IN_MISSION_STAGE(MISSION_STAGE_ENUM setStage, BOOL bFromLastMission = FALSE)
// create transport
SWITCH setStage
CASE STAGE_GET_TO_HIT
VECTOR vCreateFranklinPos
VECTOR vCreateMichaelPos
VECTOR vCreateTrevorPos
FLOAT fCreateFranklinRot
FLOAT fCreateMichaelRot
FLOAT fCreateTrevorRot
IF bIsNaturalSkipToGetToHits
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
vCreateFranklinPos = GET_ALMOST_AT_HIT_POS(CHAR_FRANKLIN)
fCreateFranklinRot = GET_ALMOST_AT_HIT_ROT(CHAR_FRANKLIN)
ELSE
vCreateFranklinPos = GET_PLAYER_HIDE_POS(CHAR_FRANKLIN)
fCreateFranklinRot = 0
ENDIF
ELSE
vCreateFranklinPos = GET_FINALE_VECTOR(FINVEC_FRANKLIN_BIKE_INIT)
fCreateFranklinRot = FRANKLIN_BIKE_INIT_ROT
ENDIF
IF bIsNaturalSkipToGetToHits
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL
vCreateMichaelPos = GET_ALMOST_AT_HIT_POS(CHAR_MICHAEL)
fCreateMichaelRot = GET_ALMOST_AT_HIT_ROT(CHAR_MICHAEL)
ELSE
vCreateMichaelPos = GET_PLAYER_HIDE_POS(CHAR_MICHAEL)
fCreateMichaelRot = 0
ENDIF
ELSE
vCreateMichaelPos = GET_PLAYER_HIDE_POS(CHAR_MICHAEL)
fCreateMichaelRot = 0
ENDIF
IF bIsNaturalSkipToGetToHits
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_TREVOR
vCreateTrevorPos = GET_ALMOST_AT_HIT_POS(CHAR_TREVOR)
fCreateTrevorRot = GET_ALMOST_AT_HIT_ROT(CHAR_TREVOR)
ELSE
vCreateTrevorPos = GET_PLAYER_HIDE_POS(CHAR_TREVOR)
fCreateTrevorRot = 0
ENDIF
ELSE
vCreateTrevorPos = GET_PLAYER_HIDE_POS(CHAR_TREVOR)
fCreateTrevorRot = 0
ENDIF
IF NOT g_bFinale3BHitSuccessful[CHAR_FRANKLIN]
FINALE_CREATE_VEHICLE(setStage, FV_FRANKLIN_CAR, vCreateFranklinPos, fCreateFranklinRot, FALSE, TRUE, FALSE, FALSE, NOT bIsNaturalSkipToGetToHits)
IF GET_CURRENT_PLAYER_PED_ENUM() <> CHAR_FRANKLIN
FREEZE_ENTITY_POSITION(finaleVehicle[FV_FRANKLIN_CAR], TRUE)
ENDIF
ENDIF
IF NOT g_bFinale3BHitSuccessful[CHAR_MICHAEL]
FINALE_CREATE_VEHICLE(setStage, FV_MICHAEL_CAR, vCreateMichaelPos, fCreateMichaelRot, FALSE, TRUE)
IF GET_CURRENT_PLAYER_PED_ENUM() <> CHAR_MICHAEL
FREEZE_ENTITY_POSITION(finaleVehicle[FV_MICHAEL_CAR], TRUE)
ENDIF
ENDIF
FINALE_CREATE_VEHICLE(setStage, FV_TREVOR_CAR, vCreateTrevorPos, fCreateTrevorRot, FALSE, TRUE)
IF GET_CURRENT_PLAYER_PED_ENUM() <> CHAR_TREVOR
FREEZE_ENTITY_POSITION(finaleVehicle[FV_TREVOR_CAR], TRUE)
ENDIF
BREAK
CASE STAGE_TREVOR_HIT
CASE STAGE_FRANKLIN_HIT
CASE STAGE_MICHAEL_HIT
IF NOT g_bFinale3BHitSuccessful[CHAR_FRANKLIN]
IF setStage = STAGE_FRANKLIN_HIT
FINALE_CREATE_VEHICLE(setStage, FV_FRANKLIN_CAR, GET_FINALE_VECTOR(FINVEC_FRANKLIN_BIKE_AT_CLUB), FRANKLIN_BIKE_AT_CLUB_ROT, FALSE, TRUE)
ELSE
FINALE_CREATE_VEHICLE(setStage, FV_FRANKLIN_CAR, GET_PLAYER_HIDE_POS(CHAR_FRANKLIN), 0, FALSE, TRUE)
FREEZE_ENTITY_POSITION(finaleVehicle[FV_FRANKLIN_CAR], TRUE)
ENDIF
ENDIF
IF NOT g_bFinale3BHitSuccessful[CHAR_MICHAEL]
IF setStage = STAGE_MICHAEL_HIT
FINALE_CREATE_VEHICLE(setStage, FV_MICHAEL_CAR, GET_FINALE_VECTOR(FINVEC_MICHAEL_CAR_AT_REC), MICHAEL_CAR_AT_REC_ROT, FALSE, TRUE)
ELSE
FINALE_CREATE_VEHICLE(setStage, FV_MICHAEL_CAR, GET_PLAYER_HIDE_POS(CHAR_MICHAEL), 0, FALSE, TRUE)
FREEZE_ENTITY_POSITION(finaleVehicle[FV_MICHAEL_CAR], TRUE)
ENDIF
ENDIF
IF NOT g_bFinale3BHitSuccessful[CHAR_TREVOR]
IF setStage = STAGE_TREVOR_HIT
FINALE_CREATE_VEHICLE(setStage, FV_TREVOR_CAR, GET_FINALE_VECTOR(FINVEC_TREVOR_CAR_AT_PIER), TREVOR_CAR_AT_PIER_ROT, FALSE, TRUE)
ELSE
FINALE_CREATE_VEHICLE(setStage, FV_TREVOR_CAR, GET_PLAYER_HIDE_POS(CHAR_TREVOR), 0, FALSE, TRUE)
FREEZE_ENTITY_POSITION(finaleVehicle[FV_TREVOR_CAR], TRUE)
ENDIF
ELSE
FINALE_CREATE_VEHICLE(setStage, FV_TREVOR_CAR, GET_PLAYER_HIDE_POS(CHAR_TREVOR), TREVOR_CAR_AT_PIER_ROT, FALSE, TRUE)
FREEZE_ENTITY_POSITION(finaleVehicle[FV_TREVOR_CAR], TRUE)
ENDIF
BREAK
CASE STAGE_PICKUP_DEVIN
//FINALE_CREATE_VEHICLE(setStage, FV_FRANKLIN_CAR, GET_FINALE_VECTOR(FINVEC_FRANKLIN_BIKE_AT_CLUB), FRANKLIN_BIKE_AT_CLUB_ROT, FALSE, TRUE)
//FINALE_CREATE_VEHICLE(setStage, FV_MICHAEL_CAR, GET_FINALE_VECTOR(FINVEC_MICHAEL_CAR_AT_REC), MICHAEL_CAR_AT_REC_ROT, FALSE, TRUE)
FINALE_CREATE_VEHICLE(setStage, FV_TREVOR_CAR, GET_FINALE_VECTOR(FINVEC_TREVOR_CAR_DRIVE_TO_PICKUP), TREVOR_CAR_DRIVE_TO_PICKUP_ROT, FALSE, TRUE)
BREAK
CASE STAGE_DEVINS_HOUSE
//FINALE_CREATE_VEHICLE(setStage, FV_FRANKLIN_CAR, GET_FINALE_VECTOR(FINVEC_FRANKLIN_BIKE_AT_CLUB), FRANKLIN_BIKE_AT_CLUB_ROT, FALSE, TRUE)
//FINALE_CREATE_VEHICLE(setStage, FV_MICHAEL_CAR, GET_FINALE_VECTOR(FINVEC_MICHAEL_CAR_AT_REC), MICHAEL_CAR_AT_REC_ROT, FALSE, TRUE)
FINALE_CREATE_VEHICLE(setStage, FV_TREVOR_CAR, GET_FINALE_VECTOR(FINVEC_TREVOR_CAR_AT_PICKUP), TREVOR_CAR_AT_PICKUP_ROT, FALSE, TRUE)
BREAK
CASE STAGE_GET_TO_CLIFF
//FINALE_CREATE_VEHICLE(setStage, FV_FRANKLIN_CAR, GET_FINALE_VECTOR(FINVEC_FRANKLIN_BIKE_AT_CLUB), FRANKLIN_BIKE_AT_CLUB_ROT, FALSE, FALSE)
//FINALE_CREATE_VEHICLE(setStage, FV_MICHAEL_CAR, GET_FINALE_VECTOR(FINVEC_MICHAEL_CAR_AT_REC), MICHAEL_CAR_AT_REC_ROT, FALSE, FALSE)
FINALE_CREATE_VEHICLE(setStage, FV_TREVOR_CAR, GET_FINALE_VECTOR(FINVEC_TREVOR_CAR_AT_PICKUP), TREVOR_CAR_AT_PICKUP_ROT, FALSE, FALSE)
IF NOT bForcePassOnShitskip
FINALE_CREATE_VEHICLE(setStage, FV_DEVIN_CAR, GET_FINALE_VECTOR(FINVEC_DEVIN_CAR_INIT), DEVIN_CAR_INIT_ROT)
ELSE
FINALE_CREATE_VEHICLE(setStage, FV_DEVIN_CAR, GET_FINALE_VECTOR(FINVEC_CLIFF), 9.1)
ENDIF
BREAK
ENDSWITCH
// create the player characters
SWITCH setStage
CASE STAGE_GET_TO_HIT
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_FRANKLIN
IF NOT g_bFinale3BHitSuccessful[CHAR_MICHAEL]
FINALE_CREATE_PLAYER_CHARACTER(CHAR_MICHAEL, setStage, <<0,0,0>>, 0, finaleVehicle[FV_MICHAEL_CAR])
ELSE
ADD_PED_FOR_DIALOGUE(finaleConversation, 0, NULL, "MICHAEL")
ENDIF
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_FRANKLIN_CAR])
SET_ENTITY_COORDS(PLAYER_PED_ID(),GET_ENTITY_COORDS(player_ped_id()))
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_FRANKLIN_CAR])
ENDIF
//IF NOT g_bFinale3BHitSuccessful[CHAR_TREVOR]
FINALE_CREATE_PLAYER_CHARACTER(CHAR_TREVOR, setStage, <<0,0,0>>, 0, finaleVehicle[FV_TREVOR_CAR])
//ENDIF
SET_FRANKLIN_HELMET_INDEX()
IF NOT bFromLastMission
SET_HELMET_IF_VEHICLE_A_BIKE(finaleVehicle[FV_FRANKLIN_CAR])
ENDIF
BREAK
CASE CHAR_MICHAEL
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_MICHAEL_CAR])
IF NOT g_bFinale3BHitSuccessful[CHAR_FRANKLIN]
FINALE_CREATE_PLAYER_CHARACTER(CHAR_FRANKLIN, setStage, <<0,0,0>>, 0, finaleVehicle[FV_FRANKLIN_CAR])
ELSE
ADD_PED_FOR_DIALOGUE(finaleConversation, 2, NULL, "FRANKLIN")
ENDIF
//IF NOT g_bFinale3BHitSuccessful[CHAR_TREVOR]
FINALE_CREATE_PLAYER_CHARACTER(CHAR_TREVOR, setStage, <<0,0,0>>, 0, finaleVehicle[FV_TREVOR_CAR])
//ENDIF
SET_FRANKLIN_HELMET_INDEX()
IF NOT bFromLastMission
SET_HELMET_IF_VEHICLE_A_BIKE(finaleVehicle[FV_MICHAEL_CAR])
ENDIF
BREAK
CASE CHAR_TREVOR
IF NOT g_bFinale3BHitSuccessful[CHAR_MICHAEL]
FINALE_CREATE_PLAYER_CHARACTER(CHAR_MICHAEL, setStage, <<0,0,0>>, 0, finaleVehicle[FV_MICHAEL_CAR])
ELSE
ADD_PED_FOR_DIALOGUE(finaleConversation, 0, NULL, "MICHAEL")
ENDIF
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_TREVOR_CAR])
IF NOT g_bFinale3BHitSuccessful[CHAR_FRANKLIN]
FINALE_CREATE_PLAYER_CHARACTER(CHAR_FRANKLIN, setStage, <<0,0,0>>, 0, finaleVehicle[FV_FRANKLIN_CAR])
ELSE
ADD_PED_FOR_DIALOGUE(finaleConversation, 2, NULL, "FRANKLIN")
ENDIF
SET_FRANKLIN_HELMET_INDEX()
IF NOT bFromLastMission
SET_HELMET_IF_VEHICLE_A_BIKE(finaleVehicle[FV_TREVOR_CAR])
ENDIF
BREAK
ENDSWITCH
BREAK
CASE STAGE_TREVOR_HIT
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_TREVOR_CAR])
IF NOT g_bFinale3BHitSuccessful[CHAR_MICHAEL]
FINALE_CREATE_PLAYER_CHARACTER(CHAR_MICHAEL, setStage, <<0,0,0>>, 0, finaleVehicle[FV_MICHAEL_CAR])
ELSE
ADD_PED_FOR_DIALOGUE(finaleConversation, 0, NULL, "MICHAEL")
ENDIF
IF NOT g_bFinale3BHitSuccessful[CHAR_FRANKLIN]
FINALE_CREATE_PLAYER_CHARACTER(CHAR_FRANKLIN, setStage, <<0,0,0>>, 0, finaleVehicle[FV_FRANKLIN_CAR])
ELSE
ADD_PED_FOR_DIALOGUE(finaleConversation, 2, NULL, "FRANKLIN")
ENDIF
SET_FRANKLIN_HELMET_INDEX()
SET_HELMET_IF_VEHICLE_A_BIKE(finaleVehicle[FV_TREVOR_CAR])
BREAK
CASE STAGE_MICHAEL_HIT
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_MICHAEL_CAR])
IF NOT g_bFinale3BHitSuccessful[CHAR_FRANKLIN]
FINALE_CREATE_PLAYER_CHARACTER(CHAR_FRANKLIN, setStage, <<0,0,0>>, 0, finaleVehicle[FV_FRANKLIN_CAR])
ELSE
ADD_PED_FOR_DIALOGUE(finaleConversation, 2, NULL, "FRANKLIN")
ENDIF
FINALE_CREATE_PLAYER_CHARACTER(CHAR_TREVOR, setStage, <<0,0,0>>, 0, finaleVehicle[FV_TREVOR_CAR])
SET_FRANKLIN_HELMET_INDEX()
SET_HELMET_IF_VEHICLE_A_BIKE(finaleVehicle[FV_MICHAEL_CAR])
BREAK
CASE STAGE_FRANKLIN_HIT
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_FRANKLIN_CAR])
IF NOT g_bFinale3BHitSuccessful[CHAR_MICHAEL]
FINALE_CREATE_PLAYER_CHARACTER(CHAR_MICHAEL, setStage, <<0,0,0>>, 0, finaleVehicle[FV_MICHAEL_CAR])
ELSE
ADD_PED_FOR_DIALOGUE(finaleConversation, 0, NULL, "MICHAEL")
ENDIF
FINALE_CREATE_PLAYER_CHARACTER(CHAR_TREVOR, setStage, <<0,0,0>>, 0, finaleVehicle[FV_TREVOR_CAR])
SET_FRANKLIN_HELMET_INDEX()
SET_HELMET_IF_VEHICLE_A_BIKE(finaleVehicle[FV_FRANKLIN_CAR])
BREAK
CASE STAGE_PICKUP_DEVIN
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_TREVOR_CAR])
//FINALE_CREATE_PLAYER_CHARACTER(CHAR_MICHAEL, setStage, <<0,0,0>>, 0, finaleVehicle[FV_MICHAEL_CAR])
//FINALE_CREATE_PLAYER_CHARACTER(CHAR_FRANKLIN, setStage, <<0,0,0>>, 0, finaleVehicle[FV_FRANKLIN_CAR])
SET_HELMET_IF_VEHICLE_A_BIKE(finaleVehicle[FV_TREVOR_CAR])
BREAK
CASE STAGE_DEVINS_HOUSE
//SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_TREVOR_CAR])
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-2553.96143, 1910.75488, 167.91422>>)
SET_ENTITY_HEADING(PLAYER_PED_ID(), 57.3)
//FINALE_CREATE_PLAYER_CHARACTER(CHAR_MICHAEL, setStage, <<0,0,0>>, 0, finaleVehicle[FV_MICHAEL_CAR])
//FINALE_CREATE_PLAYER_CHARACTER(CHAR_FRANKLIN, setStage, <<0,0,0>>, 0, finaleVehicle[FV_FRANKLIN_CAR])
SET_HELMET_IF_VEHICLE_A_BIKE(finaleVehicle[FV_TREVOR_CAR])
BREAK
CASE STAGE_GET_TO_CLIFF
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_DEVIN_CAR])
//FINALE_CREATE_PLAYER_CHARACTER(CHAR_MICHAEL, setStage, <<0,0,0>>, 0, finaleVehicle[FV_MICHAEL_CAR])
//FINALE_CREATE_PLAYER_CHARACTER(CHAR_FRANKLIN, setStage, <<0,0,0>>, 0, finaleVehicle[FV_FRANKLIN_CAR])
BREAK
ENDSWITCH
ENDPROC
// close all vehicle doors
PROC CLOSE_ALL_VEHICLE_DOORS(VEHICLE_INDEX veh)
IF IS_VEHICLE_DRIVEABLE(veh)
SET_VEHICLE_DOOR_CONTROL(veh, SC_DOOR_FRONT_RIGHT, DT_DOOR_SWINGING_FREE, 0.0)
SET_VEHICLE_DOOR_CONTROL(veh, SC_DOOR_FRONT_LEFT, DT_DOOR_SWINGING_FREE, 0.0)
SET_VEHICLE_DOOR_CONTROL(veh, SC_DOOR_REAR_LEFT, DT_DOOR_SWINGING_FREE, 0.0)
SET_VEHICLE_DOOR_CONTROL(veh, SC_DOOR_REAR_RIGHT, DT_DOOR_SWINGING_FREE, 0.0)
ENDIF
ENDPROC
// close all vehicle doors
PROC SHUT_ALL_VEHICLE_DOORS(VEHICLE_INDEX veh)
IF IS_VEHICLE_DRIVEABLE(veh)
SET_VEHICLE_DOOR_SHUT(veh, SC_DOOR_FRONT_RIGHT)
SET_VEHICLE_DOOR_SHUT(veh, SC_DOOR_FRONT_LEFT)
SET_VEHICLE_DOOR_SHUT(veh, SC_DOOR_REAR_LEFT)
SET_VEHICLE_DOOR_SHUT(veh, SC_DOOR_REAR_RIGHT)
IF veh = finaleVehicle[FV_DEVIN_CAR]
SET_VEHICLE_DOOR_SHUT(veh, SC_DOOR_BOOT)
ENDIF
ENDIF
ENDPROC
// create synced scene attached to gondola
PROC CREATE_SYNCED_SCENE_ATTACHED_TO_GONDOLA(INT &iScene, BOOL bLooped)
iScene = CREATE_SYNCHRONIZED_SCENE(<<0,0,0>>, <<0,0,GONDOLA_SCENE_ROT>>)
IF DOES_ENTITY_EXIST(gondolaObject[STEVE_GONDOLA])
SET_SYNCHRONIZED_SCENE_ORIGIN(iScene, <<0,0,0>>, <<0,0,GONDOLA_SCENE_ROT>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iScene, gondolaObject[STEVE_GONDOLA], -1)
ELSE
SET_SYNCHRONIZED_SCENE_ORIGIN(iScene, GET_FINALE_VECTOR(FINVEC_GONDOLA), <<0,0,GONDOLA_SCENE_ROT>>)
ENDIF
SET_SYNCHRONIZED_SCENE_LOOPED(iScene, bLooped)
ENDPROC
// steve filming
PROC SET_STEVE_STATE(STEVE_ENUM thisEnum, STEVE_STATE_ENUM newState, BOOL bForceInstant = FALSE)
PED_INDEX thisPed
STRING sDict
STRING sAnim
BOOL bInstant
BOOL bLooping
BOOL bSlowIn = FALSE
BOOL bSlowOut = FALSE
FLOAT fRate = 1.0
IF newState = STEVE_STATE_REACT
IF DOES_CAM_EXIST(animCam)
DESTROY_CAM(animCam)
ENDIF
ENDIF
SWITCH newState
CASE STEVE_STATE_SPEECH
sDict = GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_STEVE_SPEECH)
IF thisEnum = STEVE_TARGET
sAnim = "FIN_C2_MCS_1_STEVE"
ELSE
sAnim = "FIN_C2_MCS_1_CAMMAN"
ENDIF
bLooping = FALSE
bInstant = TRUE
bSlowOut = TRUE
BREAK
CASE STEVE_STATE_FILMING
sDict = GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_STEVE_FILMING)
IF thisEnum = STEVE_TARGET
sAnim = "Film_Idle_PedA"
ELSE
sAnim = "Film_Idle_PedB"
ENDIF
bLooping = TRUE
bInstant = false
BREAK
CASE STEVE_STATE_END_FILMING
sDict = GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_STEVE_FILMING)
IF thisEnum = STEVE_TARGET
sAnim = "Film_Idle_Outro_PedA"
ELSE
sAnim = "Film_Idle_Outro_PedB"
ENDIF
bLooping = FALSE
bInstant = FALSE
BREAK
CASE STEVE_STATE_IDLE
sDict = GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_STEVE_FILMING)
IF thisEnum = STEVE_TARGET
sAnim = "Relax_Idle_PedA"
ELSE
sAnim = "Relax_Idle_PedB"
ENDIF
bLooping = TRUE
bInstant = FALSE
bSlowIn = TRUE
BREAK
CASE STEVE_STATE_REACT
//STOP_SYNCHRONIZED_AUDIO_EVENT(iSteveSyncScene)
IF thisEnum = STEVE_TARGET
sDict = GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_STEVE_REACT)
sAnim = "Reaction"
bInstant = FALSE
ELSE
sDict = GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_CAMERAMAN_REACT)
sAnim = "Reaction"
bInstant = FALSE
ENDIF
fRate = 0.8
bLooping = FALSE
BREAK
CASE STEVE_STATE_COWER
//STOP_SYNCHRONIZED_AUDIO_EVENT(iSteveSyncScene)
IF thisEnum = STEVE_TARGET
sDict = GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_STEVE_REACT)
sAnim = "Idle"
ELSE
sDict = GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_CAMERAMAN_REACT)
sAnim = "Idle"
ENDIF
bLooping = TRUE
bInstant = FALSE
BREAK
CASE STEVE_STATE_DEAD
//STOP_SYNCHRONIZED_AUDIO_EVENT(iSteveSyncScene)
BREAK
ENDSWITCH
IF thisEnum = STEVE_TARGET
thisPed = stevePed[STEVE_TARGET]
ELSE
thisPed = stevePed[STEVE_CAMERAMAN]
ENDIF
FLOAT fBlendIn
IF bInstant
OR bForceInstant
fBlendIn = INSTANT_BLEND_IN
ELSE
IF bSlowIn
fBlendIn = REALLY_SLOW_BLEND_IN
ELSE
fBlendIn = NORMAL_BLEND_IN
ENDIF
ENDIF
FLOAT fBlendout
IF bSlowOut
fBlendout = REALLY_SLOW_BLEND_OUT
ELSE
fBlendout = NORMAL_BLEND_OUT
ENDIF
IF NOT IS_PED_INJURED(thisPed)
IF thisEnum = STEVE_TARGET
IF newState = STEVE_STATE_REACT
TASK_LOOK_AT_ENTITY(thisPed, PLAYER_PED_ID(), -1, SLF_WHILE_NOT_IN_FOV, SLF_LOOKAT_VERY_HIGH)
ENDIF
// steve
CREATE_SYNCED_SCENE_ATTACHED_TO_GONDOLA(iSteveSyncScene, bLooping)
TASK_SYNCHRONIZED_SCENE(thisPed, iSteveSyncScene, sDict, sAnim, fBlendIn, fBlendout, SYNCED_SCENE_DONT_INTERRUPT)
SET_SYNCHRONIZED_SCENE_RATE(iSteveSyncScene, fRate)
IF newState = STEVE_STATE_REACT
iSteveReactTime = GET_GAME_TIMER()
ENDIF
ELSE
// cameraman
CREATE_SYNCED_SCENE_ATTACHED_TO_GONDOLA(iCameramanSyncScene, bLooping)
TASK_SYNCHRONIZED_SCENE(thisPed, iCameramanSyncScene, sDict, sAnim, fBlendIn, fBlendout, SYNCED_SCENE_DONT_INTERRUPT)
SET_SYNCHRONIZED_SCENE_RATE(iCameramanSyncScene, fRate)
IF newState = STEVE_STATE_REACT
//CREATE_MISSION_ANIM_CAM(FALSE, FALSE)
PRINTSTRING("CREATING CAM") PRINTNL()
reactionCam = CREATE_CAM("DEFAULT_ANIMATED_CAMERA", TRUE)
PLAY_SYNCHRONIZED_CAM_ANIM(reactionCam, iCameramanSyncScene, "Reaction_Cam", sDict)
ENDIF
ENDIF
IF bInstant
FORCE_PED_AI_AND_ANIMATION_UPDATE(thisPed)
ENDIF
ENDIF
steveState[thisEnum] = newState
ENDPROC
// get steve ped phase
FUNC FLOAT GET_STEVE_PED_PHASE(STEVE_ENUM thisEnum)
IF thisEnum = STEVE_TARGET
IF IS_SYNCHRONIZED_SCENE_RUNNING(iSteveSyncScene)
RETURN GET_SYNCHRONIZED_SCENE_PHASE(iSteveSyncScene)
ENDIF
ELSE
IF IS_SYNCHRONIZED_SCENE_RUNNING(iCameramanSyncScene)
RETURN GET_SYNCHRONIZED_SCENE_PHASE(iCameramanSyncScene)
ENDIF
ENDIF
RETURN 0.0
ENDFUNC
// attach camera
PROC ATTACH_CAMERA_TO_CAMERAMAN()
IF NOT IS_PED_INJURED(stevePed[STEVE_CAMERAMAN])
AND DOES_ENTITY_EXIST(cameraObject)
ATTACH_ENTITY_TO_ENTITY(cameraObject, stevePed[STEVE_CAMERAMAN], GET_PED_BONE_INDEX(stevePed[STEVE_CAMERAMAN], BONETAG_PH_R_HAND), <<0,0,0>>, <<0,0,0>>, FALSE, FALSE, TRUE)
ENDIF
ENDPROC
// create steve
PROC CREATE_STEVE()
// steve
IF NOT DOES_ENTITY_EXIST(stevePed[STEVE_TARGET])
// CREATE_NPC_PED_ON_FOOT(stevePed[STEVE_TARGET], CHAR_STEVE, <<-1663.9, -1132.0, 41.8>>, 117.97, FALSE)
stevePed[STEVE_TARGET] = CREATE_PED(PEDTYPE_MISSION, GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_STEVE), <<-1663.9, -1132.0, 41.8>>, 0.0)
ENDIF
// cameraman
IF NOT DOES_ENTITY_EXIST(stevePed[STEVE_CAMERAMAN])
stevePed[STEVE_CAMERAMAN] = CREATE_PED(PEDTYPE_MISSION, GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_CAMERAMAN), <<-1663.9, -1142.0, 41.8>>, 0.0)
SET_PED_COMPONENT_VARIATION(stevePed[STEVE_CAMERAMAN], PED_COMP_HEAD, 0, 1)
SET_PED_COMPONENT_VARIATION(stevePed[STEVE_CAMERAMAN], PED_COMP_TORSO, 0, 0)
SET_PED_COMPONENT_VARIATION(stevePed[STEVE_CAMERAMAN], PED_COMP_LEG, 0, 0)
SET_PED_COMPONENT_VARIATION(stevePed[STEVE_CAMERAMAN], PED_COMP_SPECIAL, 1, 0)
ENDIF
INT i
REPEAT COUNT_OF(STEVE_ENUM) i
IF NOT IS_PED_INJURED(stevePed[i])
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(stevePed[i], TRUE)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(stevePed[i], TRUE)
SET_PED_KEEP_TASK(stevePed[i], TRUE)
SET_PED_DIES_WHEN_INJURED(stevePed[i], TRUE)
SET_PED_CONFIG_FLAG(stevePed[i], PCF_RunFromFiresAndExplosions, FALSE)
SET_PED_CONFIG_FLAG(stevePed[i], PCF_DisableExplosionReactions, TRUE)
SET_PED_CONFIG_FLAG(stevePed[i], PCF_DontInfluenceWantedLevel, TRUE)
SET_PED_CAN_RAGDOLL(stevePed[i], FALSE)
SET_PED_SUFFERS_CRITICAL_HITS(stevePed[i], FALSE)
SET_PED_MAX_HEALTH(stevePed[i], 10000)
SET_ENTITY_HEALTH(stevePed[i], 10000)
bSteveDead[i] = FALSE
IF i=0
INFORM_MISSION_STATS_OF_HEADSHOT_WATCH_ENTITY(stevePed[i])
SET_ENTITY_IS_TARGET_PRIORITY(stevePed[i], TRUE, 25)
ADD_ENTITY_TO_AUDIO_MIX_GROUP(stevePed[i], "FINALE_STEVE_GROUP")
ENDIF
ENDIF
ENDREPEAT
SET_STEVE_STATE(STEVE_TARGET, STEVE_STATE_FILMING)
SET_STEVE_STATE(STEVE_CAMERAMAN, STEVE_STATE_FILMING)
ADD_PED_FOR_DIALOGUE(finaleConversation, 4, stevePed[STEVE_TARGET], "STEVE")
ADD_PED_FOR_DIALOGUE(finaleConversation, 7, stevePed[STEVE_CAMERAMAN], "CAMERAMAN")
// attach the camera
cameraObject = CREATE_OBJECT(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_CAMERA), <<-1663.9, -1142.0, 38.8>>)
ATTACH_CAMERA_TO_CAMERAMAN()
//fAtWheelTime = 0.0
bSteveInGondola = FALSE
bBeenCloseToSteve = FALSE
ENDPROC
// delete steve
PROC DELETE_STEVE()
INT i
IF DOES_ENTITY_EXIST(cameraObject)
DELETE_OBJECT(cameraObject)
ENDIF
REPEAT COUNT_OF(STEVE_ENUM) i
IF DOES_ENTITY_EXIST(stevePed[i])
DELETE_PED(stevePed[i])
ENDIF
ENDREPEAT
ENDPROC
// delete wheel bystanders
PROC DELETE_WHEEL_BYSTANDERS()
INT i, j
REPEAT NUMBER_OCCUPIED_GONDOLAS i
REPEAT 2 j
IF DOES_ENTITY_EXIST(occupiedGondola[i].ped[j])
DELETE_PED(occupiedGondola[i].ped[j])
ENDIF
ENDREPEAT
occupiedGondola[i].state = OCCUPIED_GONDOLA_NOT_CREATED
ENDREPEAT
ENDPROC
PROC DELETE_PIER_COPS()
INT i
REPEAT NUMBER_PIER_COPS i
IF DOES_ENTITY_EXIST(copPed[i])
DELETE_PED(copPed[i])
ENDIF
ENDREPEAT
ENDPROC
// convert steve to gondola
PROC CONVERT_STEVE_TO_GONDOLA()
IF createHitStage[CHAR_TREVOR] = CREATE_HIT_STAGE_DONE
IF NOT DOES_ENTITY_EXIST(gondolaObject[STEVE_GONDOLA])
//GET_GONDOLA()
ELSE
IF NOT bSteveInGondola
IF createHitStage[CHAR_TREVOR] = CREATE_HIT_STAGE_DONE
IF IS_SYNCHRONIZED_SCENE_RUNNING(iSteveSyncScene)
SET_SYNCHRONIZED_SCENE_ORIGIN(iSteveSyncScene, <<0,0,0>>, <<0,0,GONDOLA_SCENE_ROT>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSteveSyncScene, gondolaObject[STEVE_GONDOLA], -1)
ENDIF
IF IS_SYNCHRONIZED_SCENE_RUNNING(iCameramanSyncScene)
SET_SYNCHRONIZED_SCENE_ORIGIN(iCameramanSyncScene, <<0,0,0>>, <<0,0,GONDOLA_SCENE_ROT>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iCameramanSyncScene, gondolaObject[STEVE_GONDOLA], -1)
ENDIF
bSteveInGondola = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
// get bystander variant
FUNC INT GET_WHEEL_BYSTANDER_VARIANT(INT iGondola, INT iIndex)
SWITCH iGondola
CASE 0
IF iIndex=0
RETURN 0
ELSE
RETURN 1
ENDIF
BREAK
CASE 1
IF iIndex=0
RETURN 0
ELSE
RETURN 1
ENDIF
BREAK
CASE 2
IF iIndex=0
RETURN 2
ELSE
RETURN 3
ENDIF
BREAK
CASE 3
IF iIndex=0
RETURN 2
ELSE
RETURN 3
ENDIF
BREAK
CASE 4
IF iIndex=0
RETURN 2
ELSE
RETURN 3
ENDIF
BREAK
CASE 5
IF iIndex=0
RETURN 0
ELSE
RETURN 1
ENDIF
BREAK
ENDSWITCH
RETURN 0
ENDFUNC
FUNC FLOAT GET_ANIM_ROT_FOR_OCCUPIED_GONDOLA(INT iGondola)
SWITCH iGondola
CASE 0
RETURN 180.0
BREAK
CASE 1
RETURN 0.0
BREAK
CASE 2
RETURN 90.0
BREAK
CASE 3
RETURN 220.0
BREAK
CASE 4
RETURN 317.0
BREAK
CASE 5
RETURN 172.0
BREAK
ENDSWITCH
RETURN 0.0
ENDFUNC
FUNC INT GET_GONDOLA_INDEX_FOR_OCCUPIED_GONDOLA(INT iGondola)
SWITCH iGondola
CASE 0
RETURN 0
BREAK
CASE 1
RETURN 5
BREAK
CASE 2
RETURN 2
BREAK
CASE 3
RETURN 8
BREAK
CASE 4
RETURN 13
BREAK
CASE 5
RETURN 11
BREAK
ENDSWITCH
RETURN 0
ENDFUNC
// create a synchronized scene for a bystander
PROC CREATE_WHEEL_BYSTANDER_SYNCHRONIZED_SCENE(INT iOccupiedGondola, BOOL bLooped)
FLOAT fAnimRot = GET_ANIM_ROT_FOR_OCCUPIED_GONDOLA(iOccupiedGondola)
iGondolaSyncScene[iOccupiedGondola] = CREATE_SYNCHRONIZED_SCENE(<<0,0,0>>, <<0,0,fAnimRot>>)
SET_SYNCHRONIZED_SCENE_ORIGIN(iGondolaSyncScene[iOccupiedGondola], <<0,0,0>>, <<0,0,fAnimRot>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iGondolaSyncScene[iOccupiedGondola], gondolaObject[GET_GONDOLA_INDEX_FOR_OCCUPIED_GONDOLA(iOccupiedGondola)], -1)
SET_SYNCHRONIZED_SCENE_LOOPED(iGondolaSyncScene[iOccupiedGondola], bLooped)
ENDPROC
// handle wheel bystanders
PROC HANDLE_WHEEL_BYSTANDERS()
INT i, j
STRING sAnim
REPEAT NUMBER_OCCUPIED_GONDOLAS i
INT iGondola = GET_GONDOLA_INDEX_FOR_OCCUPIED_GONDOLA(i)
SWITCH occupiedGondola[i].state
CASE OCCUPIED_GONDOLA_NOT_CREATED
IF createHitStage[CHAR_TREVOR] = CREATE_HIT_STAGE_DONE
IF DOES_ENTITY_EXIST(gondolaObject[iGondola])
CREATE_WHEEL_BYSTANDER_SYNCHRONIZED_SCENE(i, TRUE)
REPEAT 2 j
occupiedGondola[i].ped[j] = CREATE_PED(PEDTYPE_MISSION, GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_BYSTANDER), GET_ENTITY_COORDS(gondolaObject[iGondola]))
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(occupiedGondola[i].ped[j], TRUE)
SET_PED_KEEP_TASK(occupiedGondola[i].ped[j], TRUE)
SET_PED_CONFIG_FLAG(occupiedGondola[i].ped[j], PCF_RunFromFiresAndExplosions, FALSE)
SET_PED_CONFIG_FLAG(occupiedGondola[i].ped[j], PCF_DisableExplosionReactions, TRUE)
INT iVariant
ivariant = GET_WHEEL_BYSTANDER_VARIANT(i,j)
SWITCH iVariant
CASE 0
sAnim = "Stand_Idle_1_PEDA"
BREAK
CASE 1
sAnim = "Stand_Idle_1_PEDB"
BREAK
CASE 2
sAnim = "Stand_Idle_2_PEDA"
BREAK
CASE 3
sAnim = "Stand_Idle_2_PEDB"
BREAK
ENDSWITCH
TASK_SYNCHRONIZED_SCENE(occupiedGondola[i].ped[j], iGondolaSyncScene[i], GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_WHEEL_BYSTANDERS), sAnim, INSTANT_BLEND_IN, NORMAL_BLEND_OUT)
FORCE_PED_AI_AND_ANIMATION_UPDATE(occupiedGondola[i].ped[j])
ENDREPEAT
occupiedGondola[i].state = OCCUPIED_GONDOLA_UNALERTED
ENDIF
ENDIF
BREAK
CASE OCCUPIED_GONDOLA_UNALERTED
IF DOES_ENTITY_EXIST(gondolaObject[iGondola])
VECTOR vGondolaPos
vGondolaPos = GET_ENTITY_COORDS(gondolaObject[iGondola])
IF IS_SNIPER_BULLET_IN_AREA(vGondolaPos - <<5,5,5>>, vGondolaPos + <<5,5,5>>)
OR IS_BULLET_IN_AREA(vGondolaPos, 5.0)
OR bPlayerShootingInArea
OR g_bFinale3BHitSuccessful[CHAR_TREVOR]
OR (bRunningCutscene AND bDoShotSteveCutscene)
PRINTSTRING("goto pre react!") printnl()
occupiedGondola[i].state = OCCUPIED_GONDOLA_PRE_REACT
ENDIF
IF iGondolaCheck = i
REPEAT 2 j
IF NOT IS_PED_INJURED(occupiedGondola[i].ped[j])
IF IS_PLAYER_FREE_AIMING_AT_ENTITY(PLAYER_ID(), occupiedGondola[i].ped[j])
OR IS_PLAYER_TARGETTING_ENTITY(PLAYER_ID(), occupiedGondola[i].ped[j])
VECTOR vOffset
vOffset = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(occupiedGondola[i].ped[j], GET_ENTITY_COORDS(PLAYER_PED_ID()))
IF (vOffset.y > -0.5 AND vOffset.y < 20)
AND (vOffset.x < 10 AND vOffset.x > -10)
AND (vOffset.z < 3 OR vOffset.z > -3)
printstring("here5") printnl()
PRINTSTRING("goto pre react!") printnl()
occupiedGondola[i].state = OCCUPIED_GONDOLA_PRE_REACT
ENDIF
ENDIF
ELSE
PRINTSTRING("goto pre react!") printnl()
occupiedGondola[i].state = OCCUPIED_GONDOLA_PRE_REACT
ENDIF
ENDREPEAT
ENDIF
ENDIF
BREAK
CASE OCCUPIED_GONDOLA_PRE_REACT
IF GET_GAME_TIMER() >= iAllowGondolaReactTime
CREATE_WHEEL_BYSTANDER_SYNCHRONIZED_SCENE(i, FALSE)
REPEAT 2 j
IF NOT IS_PED_INJURED(occupiedGondola[i].ped[j])
INT iVariant
ivariant = GET_WHEEL_BYSTANDER_VARIANT(i,j)
SWITCH iVariant
CASE 0
sAnim = "Reaction_1_PEDA"
BREAK
CASE 1
sAnim = "Reaction_1_PEDB"
BREAK
CASE 2
sAnim = "Reaction_2_PEDA"
BREAK
CASE 3
sAnim = "Reaction_2_PEDB"
BREAK
ENDSWITCH
TASK_LOOK_AT_ENTITY(occupiedGondola[i].ped[j], PLAYER_PED_ID(), -1, SLF_WHILE_NOT_IN_FOV, SLF_LOOKAT_VERY_HIGH)
TASK_SYNCHRONIZED_SCENE(occupiedGondola[i].ped[j], iGondolaSyncScene[i], GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_WHEEL_BYSTANDERS), sAnim, NORMAL_BLEND_IN, NORMAL_BLEND_OUT)
ENDIF
ENDREPEAT
PRINTSTRING("goto react!") printnl()
occupiedGondola[i].state = OCCUPIED_GONDOLA_REACT
iAllowGondolaReactTime = GET_GAME_TIMER() + 100
ENDIF
BREAK
CASE OCCUPIED_GONDOLA_REACT
IF DOES_ENTITY_EXIST(gondolaObject[iGondola])
IF IS_SYNCHRONIZED_SCENE_RUNNING(iGondolaSyncScene[i])
IF GET_SYNCHRONIZED_SCENE_PHASE(iGondolaSyncScene[i]) >= 0.98
CREATE_WHEEL_BYSTANDER_SYNCHRONIZED_SCENE(i, TRUE)
REPEAT 2 j
IF NOT IS_PED_INJURED(occupiedGondola[i].ped[j])
INT iVariant
ivariant = GET_WHEEL_BYSTANDER_VARIANT(i,j)
SWITCH iVariant
CASE 0
sAnim = "Cower_Idle_1_PEDA"
BREAK
CASE 1
sAnim = "Cower_Idle_1_PEDB"
BREAK
CASE 2
sAnim = "Cower_Idle_2_PEDA"
BREAK
CASE 3
sAnim = "Cower_Idle_2_PEDB"
BREAK
ENDSWITCH
TASK_SYNCHRONIZED_SCENE(occupiedGondola[i].ped[j], iGondolaSyncScene[i], GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_WHEEL_BYSTANDERS), sAnim, NORMAL_BLEND_IN, NORMAL_BLEND_OUT)
ENDIF
ENDREPEAT
occupiedGondola[i].state = OCCUPIED_GONDOLA_COWERING
ENDIF
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDREPEAT
iGondolaCheck++
IF iGondolaCheck >= NUMBER_OCCUPIED_GONDOLAS
iGondolaCheck=0
ENDIF
ENDPROC
// pier cops
PROC HANDLE_PIER_COPS()
BOOL bIsTargeting = FALSE
IF IS_PLAYER_FREE_AIMING(PLAYER_ID())
OR IS_PLAYER_TARGETTING_ANYTHING(PLAYER_ID())
WEAPON_TYPE weapon
GET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), weapon)
IF weapon <> WEAPONTYPE_UNARMED
bIsTargeting = TRUE
ENDIF
ENDIF
IF createHitStage[CHAR_TREVOR] = CREATE_HIT_STAGE_DONE
INT i
REPEAT NUMBER_PIER_COPS i
IF NOT DOES_ENTITY_EXIST(copPed[i])
VECTOR vPos
FLOAT fRot
SWITCH i
CASE 0
vPos = <<-1619.97888, -1082.37048, 12.01724>>
fRot = 47.6
BREAK
CASE 1
vPos = <<-1652.33423, -1093.49402, 12.12104>>
fRot = -132.8
BREAK
ENDSWITCH
copPed[i] = CREATE_PED(PEDTYPE_COP, GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_COP), vPos, fRot)
GIVE_WEAPON_TO_PED(copPed[i], GET_FINALE_WEAPON_TYPE(F_WEAPON_PISTOL), INFINITE_AMMO, FALSE)
TASK_LOOK_AT_ENTITY(copPed[i], PLAYER_PED_ID(), -1)
ELSE
IF bIsTargeting
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 0
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(copPed[i], <<0,0,-1>>), GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(copPed[i], <<0,7,3>>), 2)
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 1)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
ENDIF
ENDPROC
// create devin
PROC CREATE_DEVIN()
IF NOT DOES_ENTITY_EXIST(devinPed)
CREATE_NPC_PED_ON_FOOT(devinPed, CHAR_DEVIN,<<-2644.44922, 1872.91162, 159.15158>>, -75.3, FALSE)
ENDIF
IF NOT DOES_ENTITY_EXIST(boxObject)
boxObject = CREATE_OBJECT(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_BOX), <<-2649.0779, 1872.5195, 159.15074>>)
SET_ENTITY_HEADING(boxObject, 120.81)
SET_ENTITY_LOD_DIST(boxObject, 250)
FREEZE_ENTITY_POSITION(boxObject, TRUE)
ENDIF
IF NOT DOES_ENTITY_EXIST(boxCollisionObject)
boxCollisionObject = CREATE_OBJECT(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_BOX_COLLISION), <<-2649.4679, 1872.2895, 159.00074>>)
SET_ENTITY_ROTATION(boxCollisionObject, <<65,0,120.81>>)
FREEZE_ENTITY_POSITION(boxCollisionObject, TRUE)
ENDIF
IF NOT DOES_ENTITY_EXIST(tabletObject)
tabletObject = CREATE_OBJECT(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_TABLET), <<-2644, 1872, 160>>)
ENDIF
iSyncScene = CREATE_SYNCHRONIZED_SCENE(<<-2645.961, 1872.599, 159.153>>, <<0, 0, 102.44>>)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncScene, TRUE)
IF NOT IS_PED_INJURED(devinPed)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(devinPed, TRUE)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(devinPed, TRUE)
SET_PED_KEEP_TASK(devinPed, TRUE)
SET_PED_DIES_WHEN_INJURED(devinPed, TRUE)
// REMEMBER TO CHANGE CUTSCENE VARS IF THIS CHANGES
SET_PED_COMPONENT_VARIATION(devinPed, PED_COMP_HEAD, 0, 0)
SET_PED_COMPONENT_VARIATION(devinPed, PED_COMP_SPECIAL, 3, 0)
SET_PED_COMPONENT_VARIATION(devinPed, PED_COMP_DECL, 1, 0)
SET_PED_COMPONENT_VARIATION(devinPed, PED_COMP_SPECIAL2, 0, 0)
SET_PED_COMPONENT_VARIATION(devinPed, PED_COMP_FEET, 0, 0)
SET_PED_COMPONENT_VARIATION(devinPed, PED_COMP_LEG, 4, 0)
SET_PED_COMPONENT_VARIATION(devinPed, PED_COMP_TORSO, 5, 0)
SET_PED_COMPONENT_VARIATION(devinPed, PED_COMP_JBIB, 0, 0)
//TASK_PLAY_ANIM(devinPed, GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_DEVIN_CHECK_OUT_GIRL), "look_in_boot_devin", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING)
TASK_SYNCHRONIZED_SCENE(devinPed, iSyncScene, GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_DEVIN_AND_BOX), "LOUNGE_LOOP_DEV", INSTANT_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_USE_PHYSICS)
PLAY_SYNCHRONIZED_ENTITY_ANIM(boxObject, iSyncScene, "LOUNGE_LOOP_BOX", GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_DEVIN_AND_BOX), INSTANT_BLEND_IN)
PLAY_SYNCHRONIZED_ENTITY_ANIM(tabletObject, iSyncScene, "LOUNGE_LOOP_TAB", GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_DEVIN_AND_BOX), INSTANT_BLEND_IN)
SET_PED_CONFIG_FLAG(devinPed, PCF_ForceRagdollUponDeath, TRUE)
ADD_PED_FOR_DIALOGUE(finaleConversation, 8, devinPed, "DEVIN")
devinIntoBoxState = DEVIN_INTO_BOX_STATE_NOT_STARTED
bBlockedDevinRagdoll = FALSE
bStoppedTabletAnim = FALSE
devinHideReason = DEVIN_HIDE_REASON_NONE
ENDIF
ENDPROC
// create merryweather
PROC CREATE_MERRYWEATHER(BOOL bCreate)
VECTOR vPos
FLOAT fRot
BOOL bIsPatrol
BOOL bGunOut
MERRYWEATHER_ENUM thisMerryweather
FINALE_WEAPON_ENUM useWeapon
INT i
REPEAT COUNT_OF(MERRYWEATHER_ENUM) i
thisMerryweather = INT_TO_ENUM(MERRYWEATHER_ENUM, i)
IF NOT DOES_ENTITY_EXIST(merryweatherPed[i].ped)
OR NOT bCreate
bIsPatrol = FALSE
bGunOut = TRUE
SWITCH thisMerryweather
CASE MERRYWEATHER_IN_GARAGE
useWeapon = F_WEAPON_MERRYWEATHER_RIFLE
vPos = <<-2601.21436, 1931.04749, 166.29492>>
fRot = 96.6
bGunOut = FALSE
BREAK
CASE MERRYWEATHER_DRIVE
useWeapon = F_WEAPON_MERRYWEATHER_SHOTGUN
vPos = <<-2584.21338, 1917.43079, 166.29663>>
fRot = 0.4
bIsPatrol = TRUE
BREAK
CASE MERRYWEATHER_WALKWAY_1
useWeapon = F_WEAPON_MERRYWEATHER_RIFLE
vPos = <<-2568.89209, 1887.70728, 162.69647>>
fRot = 143.3
bIsPatrol = TRUE
BREAK
CASE MERRYWEATHER_WALKWAY_2
useWeapon = F_WEAPON_MERRYWEATHER_RIFLE
vPos = <<-2600.31714, 1860.21265, 166.30408>>
fRot = 128.8
bIsPatrol = TRUE
BREAK
CASE MERRYWEATHER_OVERLOOK_POOL
useWeapon = F_WEAPON_MERRYWEATHER_SHOTGUN
vPos = <<-2626.86987, 1876.52502, 162.42644>>
fRot = -160.1
bIsPatrol = TRUE
BREAK
CASE MERRYWEATHER_OVERLOOK_SEA
useWeapon = F_WEAPON_MERRYWEATHER_RIFLE
vPos = <<-2606.68872, 1923.90723, 166.38388>>
fRot = 4.7
bIsPatrol = TRUE
BREAK
CASE MERRYWEATHER_VIEWING_PLATFORM
useWeapon = F_WEAPON_MERRYWEATHER_RIFLE
vPos = <<-2624.30762, 1901.76428, 162.42647>>
fRot = 40.6
bIsPatrol = TRUE
BREAK
CASE MERRYWEATHER_PATROL_COURTYARD
useWeapon = F_WEAPON_MERRYWEATHER_RIFLE
vPos = <<-2613.51147, 1870.65515, 166.30359>>
fRot = 127.4
bIsPatrol = TRUE
BREAK
ENDSWITCH
IF bCreate
merryweatherPed[i].ped = CREATE_PED(PEDTYPE_MISSION, GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_MERRYWEATHER), vPos, fRot)
ELSE
IF NOT IS_PED_INJURED(merryweatherPed[i].ped)
CLEAR_PED_TASKS(merryweatherPed[i].ped)
SET_ENTITY_COORDS(merryweatherPed[i].ped, vPos)
SET_ENTITY_HEADING(merryweatherPed[i].ped, fRot)
ENDIF
ENDIF
IF bCreate
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(merryweatherPed[i].ped, TRUE)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(merryweatherPed[i].ped, TRUE)
SET_PED_KEEP_TASK(merryweatherPed[i].ped, TRUE)
SET_PED_DIES_WHEN_INJURED(merryweatherPed[i].ped, TRUE)
SET_PED_RELATIONSHIP_GROUP_HASH(merryweatherPed[i].ped, merryweatherRelGroup)
GIVE_WEAPON_TO_PED(merryweatherPed[i].ped, GET_FINALE_WEAPON_TYPE(useWeapon), INFINITE_AMMO, bGunOut)
SET_PED_CONFIG_FLAG(merryweatherPed[i].ped, PCF_CanAttackNonWantedPlayerAsLaw, TRUE)
SET_PED_CONFIG_FLAG(merryweatherPed[i].ped, PCF_DontInfluenceWantedLevel, TRUE)
SET_PED_CONFIG_FLAG(merryweatherPed[i].ped, PCF_DisableHurt, TRUE)
SET_PED_SEEING_RANGE(merryweatherPed[i].ped, 30)
REQUEST_PED_VISIBILITY_TRACKING(merryweatherPed[i].ped)
SET_PED_PATH_CAN_DROP_FROM_HEIGHT(merryweatherPed[i].ped, FALSE)
//SET_PED_PATH_CAN_USE_CLIMBOVERS(merryweatherPed[i].ped, FALSE)
STOP_PED_WEAPON_FIRING_WHEN_DROPPED(merryweatherPed[i].ped)
SET_PED_SPHERE_DEFENSIVE_AREA(merryweatherPed[i].ped, vPos, 8.0)
SET_PED_ACCURACY(merryweatherPed[i].ped, 15)
ADD_ENTITY_TO_AUDIO_MIX_GROUP(merryweatherPed[i].ped, "FINALE_MERRYWEATHER_GROUP")
ENDIF
merryweatherPed[i].bIsAlerted = FALSE
merryweatherPed[i].bDoneCharge = FALSE
merryweatherPed[i].iSeenTime = -1
merryweatherPed[i].fToChargeTimer = 0.0
IF NOT bIsPatrol
merryweatherPed[i].aiState = MERRYWEATHER_AI_STATIC
ELSE
merryweatherPed[i].aiState = MERRYWEATHER_AI_PATROL
ENDIF
merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_WAIT_1
// special cases
SWITCH thisMerryweather
CASE MERRYWEATHER_IN_GARAGE
TASK_START_SCENARIO_IN_PLACE(merryweatherPed[i].ped, "WORLD_HUMAN_SMOKING", -1, FALSE)
BREAK
ENDSWITCH
ENDIF
ENDREPEAT
bDoneMerryweatherCombatSpeech1 = FALSE
bDoneMerryweatherCombatSpeech2 = FALSE
bDoneMerryweatherCombatSpeech3 = FALSE
bSetMerryweatherSpeaker1 = FALSE
bSetMerryweatherSpeaker2 = FALSE
IF GET_RANDOM_INT_IN_RANGE(0,2) = 0
bFlipMerryweatherDialogue = TRUE
ELSE
bFlipMerryweatherDialogue = FALSE
ENDIF
bDoSpottedSpeech = FALSE
iMerryweatherSpeaker1 = -1
iMerryweatherSpeaker2 = -1
bTrespassing = FALSE
iMerryweatherForceAlertTime = -1
bGeneralMerryweatherAlert = FALSE
iGuardsAliveLastFrame = 0
ENDPROC
// create devin house
PROC CREATE_DEVIN_HOUSE()
CREATE_DEVIN()
CREATE_MERRYWEATHER(TRUE)
FINALE_CREATE_VEHICLE(STAGE_PICKUP_DEVIN, FV_DEVIN_CAR, GET_FINALE_VECTOR(FINVEC_DEVIN_CAR_INIT), DEVIN_CAR_INIT_ROT, TRUE, TRUE, FALSE, TRUE, FALSE)
ENDPROC
// get anim dict for gangster ai state
FUNC STRING GET_ANIM_DICT_FOR_GANGSTER_AI_STATE(GANGSTER_ENUM thisGangster, GANGSTER_STATE_ENUM getState)
SWITCH getState
//CASE GANGSTER_STATE_BBALL
// RETURN GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_GANGSTERS_BBALL)
//BREAK
CASE GANGSTER_STATE_IDLE
RETURN GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_GANGSTERS)
BREAK
CASE GANGSTER_STATE_TO_ACTION_SLOW
RETURN GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_GANGSTERS)
BREAK
CASE GANGSTER_STATE_TO_ACTION_FAST
IF thisGangster = GANGSTER_STRETCH
RETURN GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_GANGSTERS)
ELSE
RETURN GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_REACT_INTRO)
ENDIF
BREAK
CASE GANGSTER_STATE_ENTERING_FLEE
RETURN GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_REACT_FLEE)
BREAK
CASE GANGSTER_STATE_GATHER_AT_PHONE
RETURN GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_GANGSTERS_PHONE)
BREAK
ENDSWITCH
RETURN "error"
ENDFUNC
// get anim for gangster ai state
FUNC STRING GET_ANIM_FOR_GANGSTER_AI_STATE(GANGSTER_ENUM thisGangster, GANGSTER_STATE_ENUM getState)
SWITCH getState
CASE GANGSTER_STATE_BBALL
SWITCH thisGangster
CASE GANGSTER_STRETCH
RETURN "MCS_2_B_Leadin_C"
BREAK
CASE GANGSTER_L
RETURN "MCS_2_B_Leadin_A"
BREAK
CASE GANGSTER_M
RETURN "MCS_2_B_Leadin_B"
BREAK
CASE GANGSTER_R
RETURN "MCS_2_B_Leadin_D"
BREAK
ENDSWITCH
BREAK
CASE GANGSTER_STATE_IDLE
SWITCH thisGangster
CASE GANGSTER_STRETCH
RETURN "Idle_PEDC"
BREAK
CASE GANGSTER_L
RETURN "Idle_PEDA"
BREAK
CASE GANGSTER_M
RETURN "Idle_PEDB"
BREAK
CASE GANGSTER_R
RETURN "Idle_PEDD"
BREAK
ENDSWITCH
BREAK
CASE GANGSTER_STATE_GATHER_AT_PHONE
SWITCH thisGangster
CASE GANGSTER_STRETCH
RETURN "MCS_2_B_TakeOut_Phone_PEDC"
BREAK
CASE GANGSTER_L
RETURN "MCS_2_B_TakeOut_Phone_PEDA"
BREAK
CASE GANGSTER_M
RETURN "MCS_2_B_TakeOut_Phone_PEDB"
BREAK
CASE GANGSTER_R
RETURN "MCS_2_B_TakeOut_Phone_PEDD"
BREAK
ENDSWITCH
BREAK
CASE GANGSTER_STATE_TO_ACTION_FAST
SWITCH thisGangster
CASE GANGSTER_STRETCH
RETURN "Outro_quick_PEDC"
BREAK
CASE GANGSTER_L
RETURN "react_left"
BREAK
CASE GANGSTER_M
RETURN "react_front"
BREAK
CASE GANGSTER_R
RETURN "react_right"
BREAK
ENDSWITCH
BREAK
CASE GANGSTER_STATE_ENTERING_FLEE
SWITCH thisGangster
CASE GANGSTER_L
RETURN "react_left_run_fwd"
BREAK
CASE GANGSTER_M
RETURN "react_front_run_left"
BREAK
CASE GANGSTER_R
RETURN "react_right_run_bwd"
BREAK
ENDSWITCH
BREAK
CASE GANGSTER_STATE_TO_ACTION_SLOW
SWITCH thisGangster
CASE GANGSTER_STRETCH
RETURN "Outro_quick_PEDC"
BREAK
CASE GANGSTER_L
RETURN "Outro_PEDA"
BREAK
CASE GANGSTER_M
RETURN "Outro_PEDB"
BREAK
CASE GANGSTER_R
RETURN "Outro_PEDD"
BREAK
ENDSWITCH
BREAK
ENDSWITCH
RETURN "error"
ENDFUNC
// set gangster state
PROC SET_GANGSTER_STATE(GANGSTER_ENUM thisGangster, GANGSTER_STATE_ENUM newState)
IF NOT IS_PED_INJURED(gangsterPed[thisGangster].ped)
SWITCH newState
CASE GANGSTER_STATE_COMBAT
CLEAR_SEQUENCE_TASK(sequence)
OPEN_SEQUENCE_TASK(sequence)
TASK_CLEAR_LOOK_AT(NULL)
//TASK_AIM_GUN_AT_ENTITY(NULL, PLAYER_PED_ID(), 1000, TRUE)
TASK_COMBAT_PED(NULL, PLAYER_PED_ID(), COMBAT_PED_DISABLE_AIM_INTRO)
CLOSE_SEQUENCE_TASK(sequence)
TASK_PERFORM_SEQUENCE(gangsterPed[thisGangster].ped, sequence)
IF thisGangster = GANGSTER_STRETCH
iSetStretchToCombatTime = GET_GAME_TIMER()
ENDIF
BREAK
CASE GANGSTER_STATE_FLEE
//FORCE_PED_MOTION_STATE(gangsterPed[thisGangster].ped, MS_ON_FOOT_SPRINT, FALSE, FAUS_DEFAULT)
SET_PED_MIN_MOVE_BLEND_RATIO(gangsterPed[thisGangster].ped, PEDMOVE_RUN)
//VECTOR vFleeTo
STRING sWaypoint
INT iFirstPoint
SWITCH thisGangster
CASE GANGSTER_L
IF gangsterPed[thisGangster].state = GANGSTER_STATE_ENTERING_FLEE
sWaypoint = "finc23"
iFirstPoint = 23
ELSE
sWaypoint = "finc22"
iFirstPoint = 1
ENDIF
BREAK
CASE GANGSTER_M
IF gangsterPed[thisGangster].state = GANGSTER_STATE_ENTERING_FLEE
sWaypoint = "finc21"
iFirstPoint = 8
ELSE
sWaypoint = "finc23"
iFirstPoint = 1
ENDIF
BREAK
CASE GANGSTER_R
IF gangsterPed[thisGangster].state = GANGSTER_STATE_ENTERING_FLEE
sWaypoint = "finc22"
iFirstPoint = 12
ELSE
sWaypoint = "finc21"
iFirstPoint = 1
ENDIF
BREAK
ENDSWITCH
TASK_CLEAR_LOOK_AT(gangsterPed[thisGangster].ped)
TASK_FOLLOW_WAYPOINT_RECORDING(gangsterPed[thisGangster].ped, sWaypoint, iFirstPoint)
//vFleeTo=vFleeTo
//TASK_GO_STRAIGHT_TO_COORD(gangsterPed[thisGangster], vFleeTo, PEDMOVE_RUN)
//TASK_SMART_FLEE_PED(gangsterPed[thisGangster], PLAYER_PED_ID(), 1000, -1)
BREAK
DEFAULT
BOOL bInstant
BOOL bSlowBlendOut
bSlowBlendOut = FALSE
FLOAT fBlendIn
FLOAT fBlendOut
ANIMATION_FLAGS playFlags
SWITCH newState
CASE GANGSTER_STATE_IDLE
playFlags = AF_LOOPING
bInstant = TRUE
BREAK
CASE GANGSTER_STATE_TO_ACTION_SLOW
IF thisGangster = GANGSTER_STRETCH
playFlags = AF_HOLD_LAST_FRAME
bSlowBlendOut = TRUE
ELSE
playFlags = AF_TAG_SYNC_OUT
ENDIF
bInstant = FALSE
BREAK
CASE GANGSTER_STATE_TO_ACTION_FAST
playFlags = AF_HOLD_LAST_FRAME
bInstant = FALSE
IF thisGangster = GANGSTER_STRETCH
bSlowBlendOut = TRUE
ENDIF
BREAK
CASE GANGSTER_STATE_ENTERING_FLEE
playFlags = AF_TAG_SYNC_OUT
bInstant = FALSE
BREAK
ENDSWITCH
IF bInstant
fBlendIn = INSTANT_BLEND_IN
ELSE
fBlendIn = SLOW_BLEND_IN
ENDIF
IF bSlowBlendOut
fBlendOut = -1.0
ELSE
fBlendOut = NORMAL_BLEND_OUT
ENDIF
TASK_PLAY_ANIM(gangsterPed[thisGangster].ped, GET_ANIM_DICT_FOR_GANGSTER_AI_STATE(thisGangster, newState), GET_ANIM_FOR_GANGSTER_AI_STATE(thisGangster, newState), fBlendIn, fBlendOut, -1, playFlags)
IF bInstant
FORCE_PED_AI_AND_ANIMATION_UPDATE(gangsterPed[thisGangster].ped)
ENDIF
// look at
IF newState = GANGSTER_STATE_TO_ACTION_SLOW
OR newState = GANGSTER_STATE_TO_ACTION_FAST
TASK_LOOK_AT_ENTITY(gangsterPed[thisGangster].ped, PLAYER_PED_ID(), -1, SLF_WHILE_NOT_IN_FOV | SLF_WIDEST_YAW_LIMIT, SLF_LOOKAT_VERY_HIGH)
ENDIF
BREAK
ENDSWITCH
iGangsterStateTime[thisGangster] = GET_GAME_TIMER()
gangsterPed[thisGangster].state = newState
ENDIF
ENDPROC
// set overall gangster state
PROC SET_OVERALL_GANGSTER_STATE(GANGSTER_STATE_ENUM newState, BOOL bInstant)
INT i
SWITCH newState
CASE GANGSTER_STATE_BBALL
iGangsterSyncScene = CREATE_SYNCHRONIZED_SCENE(<< -203.056, -1509.578, 34.581 >>, <<-0.000, 0.000, -64.800>>)
BREAK
// CASE GANGSTER_STATE_BBALL
CASE GANGSTER_STATE_GATHER_AT_PHONE
CASE GANGSTER_STATE_IDLE
iGangsterSyncScene = CREATE_SYNCHRONIZED_SCENE(<< -203.056, -1509.578, 30.615 >>, << -0.000, 0.000, -64.800 >>)
BREAK
ENDSWITCH
FLOAT fBlendIn
IF bInstant
fBlendIn = INSTANT_BLEND_IN
ELSE
fBlendIn = NORMAL_BLEND_IN
ENDIF
BOOL bLooping
IF newState = GANGSTER_STATE_IDLE
bLooping = TRUE
ELSE
bLooping = FALSE
ENDIF
FLOAT fSpeed
IF newState = GANGSTER_STATE_GATHER_AT_PHONE
fSpeed = 0.0
bGangstersFrozen = TRUE
ELSE
fSpeed = 1.0
bGangstersFrozen = FALSE
ENDIF
REPEAT NUMBER_STRETCH_CREW i
GANGSTER_ENUM thisGangster = INT_TO_ENUM(GANGSTER_ENUM, i)
IF NOT IS_PED_INJURED(gangsterPed[thisGangster].ped)
TASK_SYNCHRONIZED_SCENE(gangsterPed[thisGangster].ped, iGangsterSyncScene, GET_ANIM_DICT_FOR_GANGSTER_AI_STATE(thisGangster, newState), GET_ANIM_FOR_GANGSTER_AI_STATE(thisGangster, newState), fBlendIn, NORMAL_BLEND_OUT, SYNCED_SCENE_USE_PHYSICS)
SET_SYNCHRONIZED_SCENE_LOOPED(iGangsterSyncScene, bLooping)
SET_SYNCHRONIZED_SCENE_RATE(iGangsterSyncScene, fSpeed)
FORCE_PED_AI_AND_ANIMATION_UPDATE(gangsterPed[thisGangster].ped)
iGangsterStateTime[thisGangster] = GET_GAME_TIMER()
gangsterPed[thisGangster].STATE = newState
ENDIF
ENDREPEAT
ENDPROC
// gangster pos
FUNC VECTOR GET_GANGSTER_POS(GANGSTER_ENUM thisGangster)
SWITCH thisGangster
CASE GANGSTER_STRETCH
RETURN <<-204.24, -1508.53, 30.61>>
BREAK
CASE GANGSTER_L
RETURN <<-202.80, -1508.26, 30.61>>
BREAK
CASE GANGSTER_M
RETURN <<-203.45, -1508.76, 30.61>>
BREAK
CASE GANGSTER_R
RETURN <<-205.20, -1508.67, 30.61>>
BREAK
CASE GANGSTER_GROUP_CHAT_1
RETURN <<-230.29129, -1525.71460, 30.53708>>
BREAK
CASE GANGSTER_GROUP_CHAT_2
RETURN <<-230.86536, -1524.27002, 30.49504>>
BREAK
CASE GANGSTER_GROUP_CHAT_3
RETURN <<-231.68109, -1525.03625, 30.49134>>
BREAK
CASE GANGSTER_DRINKING_1
RETURN <<-229.57817, -1548.57324, 30.58296>>
BREAK
ENDSWITCH
RETURN <<0,0,0>>
ENDFUNC
// gangster rot
FUNC FLOAT GET_GANGSTER_ROT(GANGSTER_ENUM thisGangster)
SWITCH thisGangster
CASE GANGSTER_STRETCH
RETURN 40.0
BREAK
CASE GANGSTER_L
RETURN 88.0
BREAK
CASE GANGSTER_M
RETURN 60.0
BREAK
CASE GANGSTER_R
RETURN -95.0
BREAK
CASE GANGSTER_GROUP_CHAT_1
RETURN 18.4
BREAK
CASE GANGSTER_GROUP_CHAT_2
RETURN -159.8
BREAK
CASE GANGSTER_GROUP_CHAT_3
RETURN -81.2
BREAK
CASE GANGSTER_DRINKING_1
RETURN -46.3
BREAK
ENDSWITCH
RETURN 0.0
ENDFUNC
FUNC INT GET_GANGSTER_VEHICLE_FOR_GANGSTER(GANGSTER_ENUM thisGangster)
SWITCH thisGangster
CASE GANGSTER_CAR_ROAD_DRIVER
CASE GANGSTER_CAR_ROAD_PASSENGER
RETURN 0
BREAK
//CASE GANGSTER_CAR_COURT_DRIVER
// RETURN 0
//BREAK
//CASE GANGSTER_CAR_CAR_PARK_DRIVER
// RETURN 1
//BREAK
ENDSWITCH
RETURN -1
ENDFUNC
// create stretch
PROC CREATE_GANGSTERS(MISSION_STAGE_ENUM createStage)
INT i
REPEAT NUMBER_GANGSTER_VEHICLES i
IF NOT DOES_ENTITY_EXIST(gangsterVehicle[i])
VECTOR vPos
FLOAT fRot
INT iColour
SWITCH i
CASE 0
/*
vPos = <<-192.45752, -1500.80249, 31.05030>>
fRot = 21.9
iColour = 0
*/
vPos = <<-181.99211, -1514.29260, 32.21401>>
fRot = -42.7
iColour = 0
BREAK
CASE 1
vPos = <<-219.40829, -1491.94409, 30.24725>>
fRot = -44.4
iColour = 0
BREAK
CASE 2
vPos = <<-181.99211, -1514.29260, 32.21401>>
fRot = -42.7
iColour = 0
BREAK
ENDSWITCH
bGangsterVehicleOnGo[i] = FALSE
gangsterVehicle[i] = CREATE_VEHICLE(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_GANGSTER_CAR), vPos, fRot)
SET_VEHICLE_NOT_STEALABLE_AMBIENTLY(gangsterVehicle[i], FALSE)
SET_VEHICLE_ON_GROUND_PROPERLY(gangsterVehicle[i])
SET_VEHICLE_COLOUR_COMBINATION(gangsterVehicle[i], iColour)
ADD_ENTITY_TO_AUDIO_MIX_GROUP(gangsterVehicle[i], "FINALE_BALLA_CARS")
ENDIF
ENDREPEAT
REPEAT COUNT_OF(GANGSTER_ENUM) i
IF NOT DOES_ENTITY_EXIST(gangsterPed[i].ped)
GANGSTER_ENUM thisGangster = INT_TO_ENUM(GANGSTER_ENUM, i)
IF thisGangster = GANGSTER_STRETCH
CREATE_NPC_PED_ON_FOOT(gangsterPed[i].ped, CHAR_STRETCH, GET_GANGSTER_POS(thisGangster), GET_GANGSTER_ROT(thisGangster), FALSE)
ELSE
IF thisGangster < GANGSTER_CAR_ROAD_DRIVER
gangsterPed[i].ped = CREATE_PED(PEDTYPE_MISSION, GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_GANGSTER), GET_GANGSTER_POS(thisGangster), GET_GANGSTER_ROT(thisGangster))
ELSE
INT iVehicle
VEHICLE_SEAT vehicleSeat
SWITCH thisGangster
CASE GANGSTER_CAR_ROAD_DRIVER
iVehicle = 0
vehicleSeat = VS_DRIVER
BREAK
CASE GANGSTER_CAR_ROAD_PASSENGER
iVehicle = 0
vehicleSeat= VS_FRONT_RIGHT
BREAK
//CASE GANGSTER_CAR_COURT_DRIVER
/// iVehicle = 0
// vehicleSeat = VS_DRIVER
//BREAK
//CASE GANGSTER_CAR_CAR_PARK_DRIVER
// iVehicle = 1
// vehicleSeat = VS_DRIVER
//BREAK
ENDSWITCH
IF IS_VEHICLE_DRIVEABLE(gangsterVehicle[iVehicle])
gangsterPed[i].ped = CREATE_PED_INSIDE_VEHICLE(gangsterVehicle[iVehicle], PEDTYPE_MISSION, GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_GANGSTER), vehicleSeat)
ENDIF
ENDIF
IF thisGangster <= GANGSTER_R
// specific variations
INT iHeadVar
INT iHeadTex
INT iTorsoVar
INT iTorsoTex
INT iLegTex
INT iAccsVar
INT iAccsTex
SWITCH thisGangster
CASE GANGSTER_L
iHeadVar = 0
iHeadTex = 2
iTorsoVar = 0
iTorsoTex = 0
iLegTex = 1
iAccsVar = 0
iAccsTex = 0
BREAK
CASE GANGSTER_M
iHeadVar = 1
iHeadTex = 0
iTorsoVar = 1
iTorsoTex = 3
iLegTex = 0
iAccsVar = 0
iAccsTex = 0
BREAK
CASE GANGSTER_R
iHeadVar = 1
iHeadTex = 1
iTorsoVar = 0
iTorsoTex = 1
iLegTex = 2
iAccsVar = 0
iAccsTex = 0
BREAK
ENDSWITCH
SET_PED_COMPONENT_VARIATION(gangsterPed[i].ped, PED_COMP_HEAD, iHeadVar, iHeadTex)
SET_PED_COMPONENT_VARIATION(gangsterPed[i].ped, PED_COMP_TORSO, iTorsoVar, iTorsoTex)
SET_PED_COMPONENT_VARIATION(gangsterPed[i].ped, PED_COMP_LEG, 0, iLegTex)
SET_PED_COMPONENT_VARIATION(gangsterPed[i].ped, PED_COMP_SPECIAL, iAccsVar, iAccsTex)
CLEAR_ALL_PED_PROPS(gangsterPed[i].ped)
SWITCH thisGangster
CASE GANGSTER_L
SET_PED_PROP_INDEX(gangsterPed[i].ped, ANCHOR_HEAD, 1, 0)
BREAK
//CASE GANGSTER_M
// SET_PED_PROP_INDEX(gangsterPed[i], ANCHOR_HEAD, 1, 0)
//BREAK
ENDSWITCH
IF bWaitForGangsterVariations
BOOL bStreamingCompleted = FALSE
WHILE NOT bStreamingCompleted
IF NOT IS_PED_INJURED(gangsterPed[i].ped)
IF HAVE_ALL_STREAMING_REQUESTS_COMPLETED(gangsterPed[i].ped)
bStreamingCompleted = TRUE
ENDIF
ELSE
bStreamingCompleted = TRUE
ENDIF
WAIT(0)
ENDWHILE
ENDIF
ENDIF
ENDIF
IF NOT IS_PED_INJURED(gangsterPed[i].ped)
IF thisGangster > GANGSTER_R
AND thisGangster < GANGSTER_CAR_ROAD_DRIVER
STRING sScenario
SWITCH thisGangster
CASE GANGSTER_GROUP_CHAT_1
sScenario = "WORLD_HUMAN_HANG_OUT_STREET"
BREAK
CASE GANGSTER_GROUP_CHAT_2
sScenario = "WORLD_HUMAN_HANG_OUT_STREET"
BREAK
CASE GANGSTER_GROUP_CHAT_3
sScenario = "WORLD_HUMAN_SMOKING"
BREAK
CASE GANGSTER_DRINKING_1
sScenario = "WORLD_HUMAN_DRINKING"
BREAK
ENDSWITCH
TASK_START_SCENARIO_IN_PLACE(gangsterPed[i].ped, sScenario, -1, FALSE)
ENDIF
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(gangsterPed[i].ped, TRUE)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(gangsterPed[i].ped, TRUE)
SET_PED_KEEP_TASK(gangsterPed[i].ped, TRUE)
SET_PED_DIES_WHEN_INJURED(gangsterPed[i].ped, TRUE)
SET_PED_RELATIONSHIP_GROUP_HASH(gangsterPed[i].ped, gangsterRelGroup)
SET_PED_CONFIG_FLAG(gangsterPed[i].ped, PCF_DontInfluenceWantedLevel, TRUE)
IF thisGangster <> GANGSTER_L
AND thisGangster <> GANGSTER_M
AND thisGangster <> GANGSTER_R
SET_PED_COMBAT_MOVEMENT(gangsterPed[i].ped, CM_WILLADVANCE)
SET_PED_COMBAT_ATTRIBUTES(gangsterPed[i].ped, CA_CAN_CHARGE, TRUE)
SET_PED_COMBAT_ATTRIBUTES(gangsterPed[i].ped, CA_USE_VEHICLE, TRUE)
SET_PED_COMBAT_ATTRIBUTES(gangsterPed[i].ped, CA_CAN_COMMANDEER_VEHICLES, TRUE)
ENDIF
IF thisGangster >= GANGSTER_CAR_ROAD_DRIVER
SET_PED_COMBAT_ATTRIBUTES(gangsterPed[i].ped, CA_LEAVE_VEHICLES, FALSE)
SET_PED_COMBAT_ATTRIBUTES(gangsterPed[i].ped, CA_JUST_FOLLOW_VEHICLE, TRUE)
ENDIF
REQUEST_PED_VISIBILITY_TRACKING(gangsterPed[i].ped)
SET_PED_ACCURACY(gangsterPed[i].ped, 1)
INFORM_MISSION_STATS_OF_HEADSHOT_WATCH_ENTITY(gangsterPed[i].ped)
GIVE_WEAPON_TO_PED(gangsterPed[i].ped, GET_FINALE_WEAPON_TYPE(F_WEAPON_PISTOL), INFINITE_AMMO, FALSE)
IF thisGangster = GANGSTER_STRETCH
// basketball
basketballObject = CREATE_OBJECT(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_BASKETBALL), <<0,1,2>>)
SET_ENTITY_LOD_DIST(basketballObject, 100)
ATTACH_ENTITY_TO_ENTITY(basketballObject, gangsterPed[i].ped, GET_PED_BONE_INDEX(gangsterPed[i].ped, BONETAG_PH_L_HAND), <<0,0,0>>, <<0,0,0>>)
SET_PED_CONFIG_FLAG(gangsterPed[i].ped, PCF_DisableHurt, TRUE)
// phone
stretchPhoneObject = CREATE_OBJECT(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_STRETCH_PHONE), <<0,1,2>>)
SET_ENTITY_LOD_DIST(stretchPhoneObject, 100)
ATTACH_ENTITY_TO_ENTITY(stretchPhoneObject, gangsterPed[i].ped, GET_PED_BONE_INDEX(gangsterPed[i].ped, BONETAG_PH_R_HAND), <<0,0,0>>, <<0,0,0>>)
ENDIF
IF thisGangster = GANGSTER_STRETCH
ADD_ENTITY_TO_AUDIO_MIX_GROUP(gangsterPed[i].ped, "FINALE_STRETCH_GROUP")
ELSE
ADD_ENTITY_TO_AUDIO_MIX_GROUP(gangsterPed[i].ped, "FINALE_ENEMY_BALLAS")
ENDIF
gangsterPed[i].bRegisteredDead = FALSE
gangsterPed[i].bToCombat = FALSE
gangsterPed[i].bAllowLeaveCar = FALSE
gangsterPed[i].iToCombatTime = -1
//SET_GANGSTER_STATE(thisGangster, GANGSTER_STATE_IDLE)
ENDIF
ENDIF
ENDREPEAT
IF createStage = STAGE_MICHAEL_HIT
SET_OVERALL_GANGSTER_STATE(GANGSTER_STATE_IDLE, TRUE)
ELSE
SET_OVERALL_GANGSTER_STATE(GANGSTER_STATE_GATHER_AT_PHONE, TRUE)
ENDIF
ADD_PED_FOR_DIALOGUE(finaleConversation, 4, gangsterPed[GANGSTER_R].ped, "GANGBANGER2")
ADD_PED_FOR_DIALOGUE(finaleConversation, 6, gangsterPed[GANGSTER_M].ped, "TEAMMATE")
ADD_PED_FOR_DIALOGUE(finaleConversation, 7, gangsterPed[GANGSTER_STRETCH].ped, "STRETCH")
bGangstersHostileFromAggro = FALSE
bDamagedGangster = FALSE
iGangsterAggroTime = -1
bWaitForGangsterVariations = FALSE
// car
//IF NOT DOES_ENTITY_EXIST(stretchVehicle)
// stretchVehicle = CREATE_VEHICLE(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_STRETCH_CAR), <<-194.04, -1499.90, 31.39>>, 10.8)
//ENDIF
ENDPROC
// delete gangsters
PROC DELETE_GANGSTERS()
INT i
IF DOES_ENTITY_EXIST(basketballObject)
DELETE_OBJECT(basketballObject)
ENDIF
IF DOES_ENTITY_EXIST(stretchPhoneObject)
DELETE_OBJECT(stretchPhoneObject)
ENDIF
REPEAT COUNT_OF(GANGSTER_ENUM) i
IF DOES_ENTITY_EXIST(gangsterPed[i].ped)
DELETE_PED(gangsterPed[i].ped)
ENDIF
ENDREPEAT
REPEAT NUMBER_GANGSTER_VEHICLES i
IF DOES_ENTITY_EXIST(gangsterVehicle[i])
IF gangsterVehicle[i] <> finaleVehicle[FV_FRANKLIN_CAR]
AND gangsterVehicle[i] <> finaleVehicle[FV_MICHAEL_CAR]
AND gangsterVehicle[i] <> finaleVehicle[FV_TREVOR_CAR]
SET_VEHICLE_AS_NO_LONGER_NEEDED(gangsterVehicle[i])
ENDIF
ENDIF
ENDREPEAT
//IF DOES_ENTITY_EXIST(stretchVehicle)
// DELETE_VEHICLE(stretchVehicle)
//ENDIF
ENDPROC
// is stretch in car
FUNC BOOL IS_STRETCH_IN_CAR()
//IF NOT IS_PED_INJURED(gangsterPed[GANGSTER_STRETCH])
//AND IS_VEHICLE_DRIVEABLE(stretchVehicle)
// IF IS_PED_IN_VEHICLE(gangsterPed[GANGSTER_STRETCH], stretchVehicle)
// RETURN TRUE
// ENDIF
//ENDIF
RETURN FALSE
ENDFUNC
// create blip for stretch
PROC CREATE_MISSION_BLIP_FOR_STRETCH(BOOL bInCar)
IF NOT IS_PED_INJURED(gangsterPed[GANGSTER_STRETCH].ped)
IF bInCar
//IF IS_VEHICLE_DRIVEABLE(stretchVehicle)
// gangsterBlip[GANGSTER_STRETCH] = CREATE_MISSION_BLIP_FOR_VEHICLE(stretchVehicle, TRUE)
//ENDIF
ELSE
stretchBlip = CREATE_MISSION_BLIP_FOR_PED(gangsterPed[GANGSTER_STRETCH].ped, TRUE)
ENDIF
ENDIF
ENDPROC
// get a vehicle for triad to ride in
FUNC TRIAD_VEHICLE_ENUM GET_VEHICLE_FOR_TRIAD(TRIAD_ENUM thisTriad)
SWITCH thisTriad
CASE TRIAD_CHENG_SR
CASE TRIAD_CHENG_JR
CASE TRIAD_BOSSES_DRIVER
CASE TRIAD_BOSSES_FR
RETURN TRIAD_VEHICLE_BOSSES
BREAK
CASE TRIAD_ESCORT_FRONT_DRIVER
CASE TRIAD_ESCORT_FRONT_FR
CASE TRIAD_ESCORT_FRONT_BL
RETURN TRIAD_VEHICLE_ESCORT_FRONT
BREAK
CASE TRIAD_ESCORT_REAR_DRIVER
CASE TRIAD_ESCORT_REAR_FR
CASE TRIAD_ESCORT_REAR_BL
RETURN TRIAD_VEHICLE_ESCORT_REAR
BREAK
ENDSWITCH
RETURN TRIAD_VEHICLE_BOSSES
ENDFUNC
// get phase they must enter vehicle
FUNC FLOAT GET_TRIAD_MUST_ENTER_VEHICLE_PHASE(TRIAD_ENUM thisTriad)
SWITCH thisTriad
CASE TRIAD_CHENG_SR
RETURN 0.0
BREAK
CASE TRIAD_CHENG_JR
RETURN 0.0
BREAK
CASE TRIAD_BOSSES_DRIVER
RETURN 0.0
BREAK
CASE TRIAD_BOSSES_FR
RETURN 0.0
BREAK
CASE TRIAD_ESCORT_FRONT_DRIVER
RETURN 0.0
BREAK
CASE TRIAD_ESCORT_FRONT_FR
RETURN 0.771
BREAK
CASE TRIAD_ESCORT_FRONT_BL
RETURN 0.759
BREAK
CASE TRIAD_ESCORT_REAR_DRIVER
RETURN 0.0
BREAK
CASE TRIAD_ESCORT_REAR_FR
RETURN 0.771
BREAK
CASE TRIAD_ESCORT_REAR_BL
RETURN 0.853//
BREAK
ENDSWITCH
RETURN 0.0
ENDFUNC
// get phase they are in vehicle
FUNC FLOAT GET_TRIAD_INSIDE_VEHICLE_PHASE(TRIAD_ENUM thisTriad)
SWITCH thisTriad
CASE TRIAD_CHENG_SR
RETURN 0.694
BREAK
CASE TRIAD_CHENG_JR
RETURN 0.0
BREAK
CASE TRIAD_BOSSES_DRIVER
RETURN 0.0
BREAK
CASE TRIAD_BOSSES_FR
RETURN 0.0
BREAK
CASE TRIAD_ESCORT_FRONT_DRIVER
RETURN 0.0
BREAK
CASE TRIAD_ESCORT_FRONT_FR
RETURN 0.822
BREAK
CASE TRIAD_ESCORT_FRONT_BL
RETURN 0.827
BREAK
CASE TRIAD_ESCORT_REAR_DRIVER
RETURN 0.0
BREAK
CASE TRIAD_ESCORT_REAR_FR
RETURN 0.840
BREAK
CASE TRIAD_ESCORT_REAR_BL
RETURN 0.910
BREAK
ENDSWITCH
RETURN 0.0
ENDFUNC
// set a triad into car
PROC SET_TRIAD_INTO_CAR(TRIAD_ENUM thisTriad)
IF NOT IS_PED_INJURED(triadPed[thisTriad].ped)
IF NOT IS_PED_IN_ANY_VEHICLE(triadPed[thisTriad].ped)
TRIAD_VEHICLE_ENUM inVehicle = GET_VEHICLE_FOR_TRIAD(thisTriad)
VEHICLE_SEAT seat
SWITCH thisTriad
CASE TRIAD_CHENG_SR
seat = VS_BACK_LEFT
BREAK
CASE TRIAD_CHENG_JR
seat = VS_BACK_RIGHT
BREAK
CASE TRIAD_BOSSES_DRIVER
seat = VS_DRIVER
BREAK
CASE TRIAD_BOSSES_FR
seat = VS_FRONT_RIGHT
BREAK
CASE TRIAD_ESCORT_FRONT_DRIVER
seat = VS_DRIVER
BREAK
CASE TRIAD_ESCORT_FRONT_FR
seat = VS_FRONT_RIGHT
BREAK
CASE TRIAD_ESCORT_FRONT_BL
seat = VS_BACK_LEFT
BREAK
CASE TRIAD_ESCORT_REAR_DRIVER
seat = VS_DRIVER
BREAK
CASE TRIAD_ESCORT_REAR_FR
seat = VS_FRONT_RIGHT
BREAK
CASE TRIAD_ESCORT_REAR_BL
seat = VS_BACK_LEFT
BREAK
ENDSWITCH
IF IS_VEHICLE_DRIVEABLE(triadVehicle[inVehicle])
CLEAR_PED_TASKS(triadPed[thisTriad].ped)
SET_PED_INTO_VEHICLE(triadPed[thisTriad].ped, triadVehicle[inVehicle], seat)
ENDIF
ENDIF
ENDIF
ENDPROC
// are all triads in cars
FUNC BOOL ARE_ALL_TRIADS_IN_CARS()
IF IS_SYNCHRONIZED_SCENE_RUNNING(iTriadSyncScene)
AND GET_GAME_TIMER() >= iSetTriadStateTime + 1000
FLOAT fPhase = GET_SYNCHRONIZED_SCENE_PHASE(iTriadSyncScene)
INT i
REPEAT COUNT_OF(TRIAD_ENUM) i
TRIAD_ENUM thisTriad = INT_TO_ENUM(TRIAD_ENUM, i)
IF NOT IS_PED_INJURED(triadPed[thisTriad].ped)
IF GET_SCRIPT_TASK_STATUS(triadPed[thisTriad].ped, SCRIPT_TASK_SYNCHRONIZED_SCENE) = PERFORMING_TASK
IF fPhase < GET_TRIAD_INSIDE_VEHICLE_PHASE(thisTriad)
RETURN FALSE
ENDIF
ENDIF
ENDIF
ENDREPEAT
ELSE
RETURN FALSE
ENDIF
RETURN TRUE
ENDFUNC
// set triads badass
PROC SET_TRIADS_BADASS(BOOL bSet)
INT i
REPEAT COUNT_OF(TRIAD_ENUM) i
IF NOT IS_PED_INJURED(triadPed[i].ped)
IF bSet
SET_PED_MAX_HEALTH(triadPed[i].ped, 400)
SET_ENTITY_HEALTH(triadPed[i].ped, 400)
ELSE
SET_PED_MAX_HEALTH(triadPed[i].ped, 200)
SET_ENTITY_HEALTH(triadPed[i].ped, 200)
ENDIF
ENDIF
ENDREPEAT
ENDPROC
// set triad state
PROC SET_TRIAD_STATE(TRIAD_STATE_ENUM newState, BOOL bForce = TRUE, BOOL bFreeze = FALSE)
INT i
TRIAD_ENUM thisTriad
SWITCH newState
CASE TRIAD_STATE_ENTER_CARS
CASE TRIAD_STATE_IDLE
CASE TRIAD_STATE_SLAP
iTriadSyncScene = CREATE_SYNCHRONIZED_SCENE(<<0,0,0>>, <<0,0,0>>)
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_BOSSES])
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iTriadSyncScene, triadVehicle[TRIAD_VEHICLE_BOSSES], 0)
ENDIF
IF newState = TRIAD_STATE_IDLE
SET_SYNCHRONIZED_SCENE_LOOPED(iTriadSyncScene, TRUE)
SET_SYNCHRONIZED_SCENE_HOLD_LAST_FRAME(iTriadSyncScene, FALSE)
ELSE
SET_SYNCHRONIZED_SCENE_LOOPED(iTriadSyncScene, FALSE)
SET_SYNCHRONIZED_SCENE_HOLD_LAST_FRAME(iTriadSyncScene, TRUE)
ENDIF
STRING sAnim
STRING sDict
BOOL bDoAnim
REPEAT COUNT_OF(TRIAD_ENUM) i
thisTriad = INT_TO_ENUM(TRIAD_ENUM, i)
bDoAnim = TRUE
IF NOT IS_PED_INJURED(triadPed[i].ped)
SWITCH newState
CASE TRIAD_STATE_ENTER_CARS
sDict = GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_TRIADS_INTO_CARS)
SWITCH thisTriad
CASE TRIAD_CHENG_SR
sAnim = "IG8_PEDC"
BREAK
CASE TRIAD_CHENG_JR
sAnim = "IG8_PEDE"
BREAK
CASE TRIAD_BOSSES_DRIVER
sAnim = "IG8_PEDD"
BREAK
CASE TRIAD_BOSSES_FR
bDoAnim = FALSE
BREAK
CASE TRIAD_ESCORT_FRONT_DRIVER
sAnim = "IG8_PEDI"
BREAK
CASE TRIAD_ESCORT_FRONT_FR
sAnim = "IG8_PEDH"
BREAK
CASE TRIAD_ESCORT_FRONT_BL
sAnim = "IG8_PEDB"
BREAK
CASE TRIAD_ESCORT_REAR_DRIVER
sAnim = "IG8_PEDG"
BREAK
CASE TRIAD_ESCORT_REAR_FR
sAnim = "IG8_PEDF"
BREAK
CASE TRIAD_ESCORT_REAR_BL
sAnim = "IG8_PEDA"
BREAK
ENDSWITCH
BREAK
CASE TRIAD_STATE_IDLE
//sDict = GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_TRIADS_IDLE)
SWITCH thisTriad
CASE TRIAD_CHENG_SR
sAnim = "IDLE_PEDC"
BREAK
CASE TRIAD_CHENG_JR
sAnim = "IDLE_PEDE"
BREAK
CASE TRIAD_BOSSES_DRIVER
sAnim = "IDLE_PEDD"
BREAK
CASE TRIAD_BOSSES_FR
bDoAnim = FALSE
BREAK
CASE TRIAD_ESCORT_FRONT_DRIVER
sAnim = "IDLE_PEDI"
BREAK
CASE TRIAD_ESCORT_FRONT_FR
sAnim = "IDLE_PEDH"
BREAK
CASE TRIAD_ESCORT_FRONT_BL
sAnim = "IDLE_PEDB"
BREAK
CASE TRIAD_ESCORT_REAR_DRIVER
sAnim = "IDLE_PEDG"
BREAK
CASE TRIAD_ESCORT_REAR_FR
sAnim = "IDLE_PEDF"
BREAK
CASE TRIAD_ESCORT_REAR_BL
sAnim = "IDLE_PEDA"
BREAK
ENDSWITCH
BREAK
CASE TRIAD_STATE_SLAP
// sDict = GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_TRIADS_IDLE)
SWITCH thisTriad
CASE TRIAD_CHENG_SR
sAnim = "OUTRO_PEDC"
BREAK
CASE TRIAD_CHENG_JR
sAnim = "OUTRO_PEDE"
BREAK
CASE TRIAD_BOSSES_DRIVER
sAnim = "OUTRO_PEDD"
BREAK
CASE TRIAD_BOSSES_FR
bDoAnim = FALSE
BREAK
CASE TRIAD_ESCORT_FRONT_DRIVER
sAnim = "OUTRO_PEDI"
BREAK
CASE TRIAD_ESCORT_FRONT_FR
sAnim = "OUTRO_PEDH"
BREAK
CASE TRIAD_ESCORT_FRONT_BL
sAnim = "OUTRO_PEDB"
BREAK
CASE TRIAD_ESCORT_REAR_DRIVER
sAnim = "OUTRO_PEDG"
BREAK
CASE TRIAD_ESCORT_REAR_FR
sAnim = "OUTRO_PEDF"
BREAK
CASE TRIAD_ESCORT_REAR_BL
sAnim = "OUTRO_PEDA"
BREAK
ENDSWITCH
BREAK
ENDSWITCH
IF bDoAnim
IF IS_PED_IN_ANY_VEHICLE(triadPed[i].ped)
SET_ENTITY_COORDS(triadPed[i].ped, GET_ENTITY_COORDS(triadPed[i].ped))
ENDIF
FLOAT fBlendIn
IF bForce
fBlendIn = INSTANT_BLEND_IN
ELSE
fBlendIn = NORMAL_BLEND_IN
ENDIF
TASK_SYNCHRONIZED_SCENE(triadPed[i].ped, iTriadSyncScene, sDict, sAnim, fBlendIn, NORMAL_BLEND_OUT)
IF bForce
FORCE_PED_AI_AND_ANIMATION_UPDATE(triadPed[thisTriad].ped)
ENDIF
ENDIF
ENDIF
ENDREPEAT
IF newState = TRIAD_STATE_ENTER_CARS
REPEAT COUNT_OF(TRIAD_VEHICLE_ENUM) i
TRIAD_VEHICLE_ENUM thisVehicle
thisVehicle = INT_TO_ENUM(TRIAD_VEHICLE_ENUM, i)
IF IS_VEHICLE_DRIVEABLE(triadVehicle[thisVehicle])
SWITCH thisVehicle
CASE TRIAD_VEHICLE_BOSSES
sAnim = "IG8_WASH"
BREAK
CASE TRIAD_VEHICLE_ESCORT_FRONT
sAnim = "IG8_CAVFRONT"
BREAK
CASE TRIAD_VEHICLE_ESCORT_REAR
sAnim = "IG8_CAVREAR"
BREAK
ENDSWITCH
//PLAY_SYNCHRONIZED_ENTITY_ANIM(triadVehicle[thisVehicle], iTriadSyncScene, sAnim, GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_TRIADS_INTO_CARS), INSTANT_BLEND_IN)
FLOAT fPhase // CHANGE PEDS ALSO
IF bForce // CHANGE VEHS ALSO
fPhase = 0.78 // 0.54
ELSE
fPhase = 0.6
ENDIF
PLAY_ENTITY_ANIM(triadVehicle[thisVehicle], sAnim, GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_TRIADS_INTO_CARS), INSTANT_BLEND_IN, FALSE, FALSE, FALSE, fPhase)
ENDIF
ENDREPEAT
SET_TRIADS_BADASS(TRUE)
IF bForce // CHANGE VEHS ALSO
SET_SYNCHRONIZED_SCENE_PHASE(iTriadSyncScene, 0.78) // 0.54
ELSE
SET_SYNCHRONIZED_SCENE_PHASE(iTriadSyncScene, 0.60)//0.45) // 0.54
ENDIF
IF bFreeze
SET_SYNCHRONIZED_SCENE_RATE(iTriadSyncScene, 0.0)
ELSE
SET_SYNCHRONIZED_SCENE_RATE(iTriadSyncScene, 1.0)
ENDIF
ENDIF
BREAK
CASE TRIAD_STATE_DRIVING_LEAVE_CLUB
// convert into cars
TRIAD_VEHICLE_ENUM inVehicle
REPEAT COUNT_OF(TRIAD_ENUM) i
thisTriad = INT_TO_ENUM(TRIAD_ENUM, i)
IF NOT IS_PED_INJURED(triadPed[i].ped)
IF GET_SCRIPT_TASK_STATUS(triadPed[i].ped, SCRIPT_TASK_SYNCHRONIZED_SCENE) = PERFORMING_TASK
SET_TRIAD_INTO_CAR(thisTriad)
ENDIF
inVehicle = GET_VEHICLE_FOR_TRIAD(thisTriad)
IF IS_VEHICLE_DRIVEABLE(triadVehicle[inVehicle])
// tasks
SWITCH thisTriad
CASE TRIAD_ESCORT_FRONT_DRIVER
TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(triadPed[thisTriad].ped, triadVehicle[inVehicle], "finc24", triadDrivingMode, 7)//, EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN)
BREAK
CASE TRIAD_BOSSES_DRIVER
CLEAR_SEQUENCE_TASK(sequence)
OPEN_SEQUENCE_TASK(sequence)
TASK_PAUSE(NULL, 600)
TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(NULL, triadVehicle[inVehicle], "finc24", triadDrivingMode, 4)//, EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN)
CLOSE_SEQUENCE_TASK(sequence)
TASK_PERFORM_SEQUENCE(triadPed[thisTriad].ped, sequence)
BREAK
CASE TRIAD_ESCORT_REAR_DRIVER
CLEAR_SEQUENCE_TASK(sequence)
OPEN_SEQUENCE_TASK(sequence)
TASK_PAUSE(NULL, 1200)
TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(NULL, triadVehicle[inVehicle], "finc24", triadDrivingMode, 3, EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN)//, EWAYPOINT_VEHICLES_USE_AI_SLOWDOWN)
CLOSE_SEQUENCE_TASK(sequence)
TASK_PERFORM_SEQUENCE(triadPed[thisTriad].ped, sequence)
BREAK
ENDSWITCH
ENDIF
ENDIF
ENDREPEAT
REPEAT COUNT_OF(TRIAD_VEHICLE_ENUM) i
IF IS_VEHICLE_DRIVEABLE(triadVehicle[i])
STOP_SYNCHRONIZED_ENTITY_ANIM(triadVehicle[i], INSTANT_BLEND_OUT, TRUE)
CLOSE_ALL_VEHICLE_DOORS(triadVehicle[i])
SHUT_ALL_VEHICLE_DOORS(triadVehicle[i])
ENDIF
ENDREPEAT
BREAK
CASE TRIAD_STATE_DRIVING_WANDER
DRIVINGMODE triadWanderMode // CHANGE THIS IN WANDER
triadWanderMode = DF_SwerveAroundAllCars|DF_StopForPeds|DF_SteerAroundObjects|DF_SteerAroundStationaryCars|DF_StopAtLights|DF_ChangeLanesAroundObstructions
SWITCH iTriadWanderStage
CASE 0
vTriadDriveCoords = <<-3067.67, 1369.19, 19.34>>
BREAK
CASE 1
vTriadDriveCoords = <<-2618.68823, 2860.72437, 15.70077>>
BREAK
CASE 2
vTriadDriveCoords = <<-1842.83496, 4669.32861, 56.04228>>
BREAK
CASE 3
vTriadDriveCoords = <<-197.48712, 6170.60059, 30.24010>>
BREAK
CASE 4
vTriadDriveCoords = <<245.7, 6558.60059, 30.34010>>
BREAK
CASE 5
vTriadDriveCoords = <<617.38715, 6526.60156, 27.22127>>
BREAK
CASE 6
vTriadDriveCoords = <<1495.68250, 6433.73682, 21.45721>>
BREAK
CASE 7
vTriadDriveCoords = <<1968.07507, 6174.22266, 44.76606>>
BREAK
CASE 8
vTriadDriveCoords = <<2681.71558, 4805.89160, 43.58303>>
BREAK
CASE 9
vTriadDriveCoords = <<2883.11816, 3700.99268, 51.67475>>
BREAK
CASE 10
vTriadDriveCoords = <<1845.99512, 2950.11133, 44.75816>>
BREAK
CASE 11
vTriadDriveCoords = <<982.86292, 2695.79736, 38.91315>>
BREAK
CASE 12
vTriadDriveCoords = <<-494.12231, 2847.70703, 32.80378>>
BREAK
CASE 13
vTriadDriveCoords = <<-1818.58533, 2398.81836, 30.03060>>
BREAK
CASE 14
vTriadDriveCoords = <<-2680.56567, 2289.68896, 19.73934>>
BREAK
CASE 15
vTriadDriveCoords = <<-494.12231, 2847.70703, 32.80378>>
BREAK
ENDSWITCH
iTriadWanderStage++
IF iTriadWanderStage = 16
iTriadWanderStage = 1
ENDIF
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT])
AND NOT IS_PED_INJURED(triadPed[TRIAD_ESCORT_FRONT_DRIVER].ped)
//TASK_VEHICLE_DRIVE_TO_COORD(triadPed[TRIAD_ESCORT_FRONT_DRIVER], triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT], <<-3067.67, 1369.19, 19.34>>, 16.0, DRIVINGSTYLE_NORMAL, GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_TRIAD_ESCORT_CAR), DRIVINGMODE_AVOIDCARS, 10, -1 )
TASK_VEHICLE_DRIVE_TO_COORD_LONGRANGE(triadPed[TRIAD_ESCORT_FRONT_DRIVER].ped, triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT], vTriadDriveCoords, 16.0, triadWanderMode, 10)
ENDIF
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_BOSSES])
AND IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT])
AND NOT IS_PED_INJURED(triadPed[TRIAD_BOSSES_DRIVER].ped)
TASK_VEHICLE_ESCORT(triadPed[TRIAD_BOSSES_DRIVER].ped, triadVehicle[TRIAD_VEHICLE_BOSSES], triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT], VEHICLE_ESCORT_REAR, 24.0, triadWanderMode, 12.0)
ENDIF
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_ESCORT_REAR])
AND IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_BOSSES])
AND NOT IS_PED_INJURED(triadPed[TRIAD_ESCORT_REAR_DRIVER].ped)
TASK_VEHICLE_ESCORT(triadPed[TRIAD_ESCORT_REAR_DRIVER].ped, triadVehicle[TRIAD_VEHICLE_ESCORT_REAR], triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT], VEHICLE_ESCORT_REAR, 24.0, triadWanderMode, 24.0)
ENDIF
BREAK
CASE TRIAD_STATE_DRIVING_ESCAPE
//DRIVINGMODE triadEscapeMode
//triadEscapeMode = DF_SwerveAroundAllCars|DF_SteerAroundObjects|DF_SteerAroundStationaryCars|DF_ChangeLanesAroundObstructions
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_BOSSES])
AND NOT IS_PED_INJURED(triadPed[TRIAD_BOSSES_DRIVER].ped)
TASK_VEHICLE_MISSION_PED_TARGET(triadPed[TRIAD_BOSSES_DRIVER].ped, triadVehicle[TRIAD_VEHICLE_BOSSES], PLAYER_PED_ID(), MISSION_FLEE, 20.0, DRIVINGMODE_AVOIDCARS, -1, -1)
ENDIF
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_ESCORT_REAR])
AND IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_BOSSES])
AND NOT IS_PED_INJURED(triadPed[TRIAD_ESCORT_REAR_DRIVER].ped)
TASK_VEHICLE_MISSION(triadPed[TRIAD_ESCORT_REAR_DRIVER].ped, triadVehicle[TRIAD_VEHICLE_ESCORT_REAR], triadVehicle[TRIAD_VEHICLE_BOSSES], MISSION_FOLLOW, 35.0, DRIVINGMODE_AVOIDCARS, -1, -1)
//TASK_VEHICLE_ESCORT(triadPed[TRIAD_ESCORT_REAR_DRIVER].ped, triadVehicle[TRIAD_VEHICLE_ESCORT_REAR], triadVehicle[TRIAD_VEHICLE_BOSSES], VEHICLE_ESCORT_LEFT, 28.0, DRIVINGMODE_PLOUGHTHROUGH, -1)
ENDIF
iNextChengJrCurseTime = GET_GAME_TIMER() + 10000
iTriadsEscapeTime = GET_GAME_TIMER()
BREAK
CASE TRIAD_STATE_CHASE_DOWN_PLAYER
iNextChengJrCurseTime = GET_GAME_TIMER() + 10000
/*
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT])
SET_VEHICLE_AS_NO_LONGER_NEEDED(triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT])
ENDIF
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_ESCORT_REAR])
SET_VEHICLE_AS_NO_LONGER_NEEDED(triadVehicle[TRIAD_VEHICLE_ESCORT_REAR])
ENDIF
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_BOSSES])
SET_VEHICLE_AS_NO_LONGER_NEEDED(triadVehicle[TRIAD_VEHICLE_BOSSES])
ENDIF
*/
BREAK
ENDSWITCH
iSetTriadStateTime = GET_GAME_TIMER()
triadState = newState
ENDPROC
// apply properties to triad peds
PROC APPLY_PROPERTIES_TO_TRIAD_PEDS()
INT i
REPEAT COUNT_OF(TRIAD_ENUM) i
IF NOT IS_PED_INJURED(triadPed[i].ped)
TRIAD_ENUM thisTriad = INT_TO_ENUM(TRIAD_ENUM, i)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(triadPed[i].ped, TRUE)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(triadPed[i].ped, TRUE)
SET_PED_KEEP_TASK(triadPed[i].ped, TRUE)
SET_PED_DIES_WHEN_INJURED(triadPed[i].ped, TRUE)
SET_PED_RELATIONSHIP_GROUP_HASH(triadPed[i].ped, triadRelGroup)
SET_PED_ACCURACY(triadPed[i].ped, 2)
REQUEST_PED_VISIBILITY_TRACKING(triadPed[i].ped)
IF NOT triadPed[i].bSetHeadshotEntity
INFORM_MISSION_STATS_OF_HEADSHOT_WATCH_ENTITY(triadPed[i].ped)
triadPed[i].bSetHeadshotEntity = TRUE
ENDIF
IF thisTriad = TRIAD_CHENG_SR
//OR thisTriad = TRIAD_CHENG_JR
SET_PED_CONFIG_FLAG(triadPed[i].ped, PCF_DisableHurt, TRUE)
ENDIF
SET_PED_CONFIG_FLAG(triadPed[i].ped, PCF_DontInfluenceWantedLevel, TRUE)
// weapons
BOOL bGiveWeapon = TRUE
BOOL bForceWeapon = FALSE
BOOL bShotgun = FALSE
SWITCH thisTriad
CASE TRIAD_CHENG_SR
bShotgun = TRUE
BREAK
CASE TRIAD_ESCORT_FRONT_FR
bForceWeapon = TRUE
BREAK
CASE TRIAD_ESCORT_REAR_FR
bForceWeapon = TRUE
BREAK
ENDSWITCH
IF bGiveWeapon
WEAPON_TYPE triadWeapon
IF bShotgun
triadWeapon = GET_FINALE_WEAPON_TYPE(F_WEAPON_MERRYWEATHER_SHOTGUN)
ELSE
triadWeapon = GET_FINALE_WEAPON_TYPE(F_WEAPON_TRIAD_SMG)
ENDIF
GIVE_WEAPON_TO_PED(triadPed[i].ped, triadWeapon, INFINITE_AMMO, bForceWeapon)
ENDIF
ENDIF
ENDREPEAT
ENDPROC
// create triads
PROC CREATE_TRIADS(MISSION_STAGE_ENUM createStage)
INT i
VECTOR vPos
FLOAT fRot
INT iVehicle
// vehicles
REPEAT COUNT_OF(TRIAD_VEHICLE_ENUM) i
IF NOT DOES_ENTITY_EXIST(triadVehicle[i])
TRIAD_VEHICLE_ENUM thisVehicle = INT_TO_ENUM(TRIAD_VEHICLE_ENUM, i)
FINALE_MODEL_ENUM vehicleModel
SWITCH thisVehicle
CASE TRIAD_VEHICLE_BOSSES
vehicleModel = FM_TRIAD_BOSS_CAR
vPos = << -3018.44, 87.2183, 10.6 >>
fRot = 62.916012
BREAK
CASE TRIAD_VEHICLE_ESCORT_FRONT
vehicleModel = FM_TRIAD_ESCORT_CAR
vPos = << -3022.72, 91.8035, 10.6 >>
fRot = 41.657009
BREAK
CASE TRIAD_VEHICLE_ESCORT_REAR
vehicleModel = FM_TRIAD_ESCORT_CAR
vPos = << -3012.37, 86.6375, 10.6 >>
fRot = 97.919632
BREAK
ENDSWITCH
triadVehicle[i] = CREATE_VEHICLE(GET_MODEL_FOR_FINALE_MODEL_ENUM(vehicleModel), vPos, fRot)
SET_VEHICLE_ON_GROUND_PROPERLY(triadVehicle[i])
SET_VEHICLE_COLOUR_COMBINATION(triadVehicle[i], 0)
SET_HORN_ENABLED(triadVehicle[i], FALSE)
SET_VEHICLE_ENGINE_ON(triadVehicle[i], TRUE, TRUE)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(triadVehicle[i], TRUE)
SET_VEHICLE_STEERING_BIAS_SCALAR(triadVehicle[i], 0.3)
SET_VEHICLE_USE_MORE_RESTRICTIVE_SPAWN_CHECKS(triadVehicle[i], TRUE)
//IF thisVehicle <> TRIAD_VEHICLE_BOSSES
//
//ENDIF
//SET_VEHICLE_USE_ALTERNATE_HANDLING(triadVehicle[i], TRUE)
// special cases
IF thisVehicle = TRIAD_VEHICLE_BOSSES
SET_VEHICLE_DOOR_CONTROL(triadVehicle[i], SC_DOOR_FRONT_LEFT, DT_DOOR_INTACT, 0.5)
ADD_ENTITY_TO_AUDIO_MIX_GROUP(triadVehicle[i], "FINALE_CHENGS_VEHICLE_GROUP")
ELSE
ADD_ENTITY_TO_AUDIO_MIX_GROUP(triadVehicle[i], "FINALE_TRIAD_VEHICLES_GROUP")
ENDIF
ENDIF
ENDREPEAT
// peds
REPEAT COUNT_OF(TRIAD_ENUM) i
IF NOT DOES_ENTITY_EXIST(triadPed[i].ped)
TRIAD_ENUM thisTriad = INT_TO_ENUM(TRIAD_ENUM, i)
FINALE_MODEL_ENUM pedModel = FM_TRIAD
iVehicle = -1
VEHICLE_SEAT seat
SWITCH thisTriad
CASE TRIAD_CHENG_SR
vPos = <<-3018.46, 87.56, 10.61>>
fRot = -109.6
pedModel = FM_CHENG_SR
BREAK
CASE TRIAD_CHENG_JR
iVehicle = ENUM_TO_INT(TRIAD_VEHICLE_BOSSES)
pedModel = FM_CHENG_JR
seat = VS_BACK_RIGHT
BREAK
CASE TRIAD_BOSSES_DRIVER
vPos = <<-3018.43, 85.71, 10.61>>
fRot = 62.4
BREAK
CASE TRIAD_BOSSES_FR
iVehicle = ENUM_TO_INT(TRIAD_VEHICLE_BOSSES)
seat = VS_FRONT_RIGHT
BREAK
CASE TRIAD_ESCORT_FRONT_DRIVER
iVehicle = ENUM_TO_INT(TRIAD_VEHICLE_ESCORT_FRONT)
seat = VS_DRIVER
BREAK
CASE TRIAD_ESCORT_FRONT_FR
vPos = <<-3019.42, 91.32, 10.67>>
fRot = -30.2
BREAK
CASE TRIAD_ESCORT_FRONT_BL
vPos = <<-3019.30, 89.01, 10.74>>
fRot = -83.2
BREAK
CASE TRIAD_ESCORT_REAR_DRIVER
iVehicle = ENUM_TO_INT(TRIAD_VEHICLE_ESCORT_REAR)
seat = VS_DRIVER
BREAK
CASE TRIAD_ESCORT_REAR_FR
vPos = <<-3014.00, 88.73, 10.61>>
fRot = 1.5
BREAK
CASE TRIAD_ESCORT_REAR_BL
vPos = <<-3016.98, 87.08, 10.69>>
fRot = 67.2
BREAK
ENDSWITCH
triadPed[i].bInCombat = FALSE
triadPed[i].bRegisteredDead = FALSE
triadPed[i].bSetHeadshotEntity = FALSE
triadPed[i].fInStoppedVehicleTime = 0.0
IF thisTriad = TRIAD_CHENG_SR
CREATE_NPC_PED_ON_FOOT(triadPed[i].ped, CHAR_CHENGSR, vPos, fRot, FALSE)
REQUEST_PED_VISIBILITY_TRACKING(triadPed[i].ped)
ELIF thisTriad = TRIAD_CHENG_JR
CREATE_NPC_PED_INSIDE_VEHICLE(triadPed[i].ped, CHAR_CHENG, triadVehicle[iVehicle], seat, FALSE)
ELSE
IF iVehicle >= 0
IF IS_VEHICLE_DRIVEABLE(triadVehicle[iVehicle])
triadPed[i].ped = CREATE_PED_INSIDE_VEHICLE(triadVehicle[iVehicle], PEDTYPE_MISSION, GET_MODEL_FOR_FINALE_MODEL_ENUM(pedModel), seat)
ENDIF
ELSE
triadPed[i].ped = CREATE_PED(PEDTYPE_MISSION, GET_MODEL_FOR_FINALE_MODEL_ENUM(pedModel), vPos, fRot)
ENDIF
// variations
INT iHeadTex
INT iHairVar
INT iHairTex
INT iTorsoVar
INT iTorsoTex
INT iLegVar
INT iLegTex
INT iAccsVar
INT iAccsTex
SWITCH thisTriad
CASE TRIAD_BOSSES_DRIVER
iHeadTex = 2
iHairVar = 1
iHairTex = 0
iTorsoVar = 0
iTorsoTex = 1
iLegVar = 0
iLegTex = 0
iAccsVar = 1
iAccsTex = 0
BREAK
CASE TRIAD_BOSSES_FR
iHeadTex = 0
iHairVar = 2
iHairTex = 0
iTorsoVar = 1
iTorsoTex = 1
iLegVar = 1
iLegTex = 0
iAccsVar = 0
iAccsTex = 0
BREAK
CASE TRIAD_ESCORT_FRONT_DRIVER
iHeadTex = 1
iHairVar = 0
iHairTex = 2
iTorsoVar = 0
iTorsoTex = 0
iLegVar = 1
iLegTex = 2
iAccsVar = 0
iAccsTex = 0
BREAK
CASE TRIAD_ESCORT_FRONT_FR
iHeadTex = 0
iHairVar = 1
iHairTex = 2
iTorsoVar = 1
iTorsoTex = 0
iLegVar = 0
iLegTex = 1
iAccsVar = 1
iAccsTex = 1
BREAK
CASE TRIAD_ESCORT_FRONT_BL
iHeadTex = 2
iHairVar = 2
iHairTex = 0
iTorsoVar = 1
iTorsoTex = 2
iLegVar = 0
iLegTex = 2
iAccsVar = 0
iAccsTex = 0
BREAK
CASE TRIAD_ESCORT_REAR_DRIVER
iHeadTex = 0
iHairVar = 0
iHairTex = 0
iTorsoVar = 1
iTorsoTex = 1
iLegVar = 1
iLegTex = 0
iAccsVar = 1
iAccsTex = 0
BREAK
CASE TRIAD_ESCORT_REAR_FR
iHeadTex = 1
iHairVar = 2
iHairTex = 0
iTorsoVar = 0
iTorsoTex = 2
iLegVar = 1
iLegTex = 0
iAccsVar = 0
iAccsTex = 0
BREAK
CASE TRIAD_ESCORT_REAR_BL
iHeadTex = 2
iHairVar = 1
iHairTex = 1
iTorsoVar = 0
iTorsoTex = 1
iLegVar = 0
iLegTex = 0
iAccsVar = 0
iAccsTex = 0
BREAK
ENDSWITCH
SET_PED_COMPONENT_VARIATION(triadPed[i].ped, PED_COMP_HEAD, 0, iHeadTex)
SET_PED_COMPONENT_VARIATION(triadPed[i].ped, PED_COMP_HAIR, iHairVar, iHairTex)
SET_PED_COMPONENT_VARIATION(triadPed[i].ped, PED_COMP_TORSO, iTorsoVar, iTorsoTex)
SET_PED_COMPONENT_VARIATION(triadPed[i].ped, PED_COMP_LEG, iLegVar, iLegTex)
SET_PED_COMPONENT_VARIATION(triadPed[i].ped, PED_COMP_SPECIAL, iAccsVar, iAccsTex)
IF bWaitForTriadVariations
BOOL bStreamingCompleted = FALSE
WHILE NOT bStreamingCompleted
IF NOT IS_PED_INJURED(triadPed[i].ped)
IF HAVE_ALL_STREAMING_REQUESTS_COMPLETED(triadPed[i].ped)
bStreamingCompleted = TRUE
ENDIF
ELSE
bStreamingCompleted = TRUE
ENDIF
WAIT(0)
ENDWHILE
ENDIF
ENDIF
ENDIF
ENDREPEAT
triadState = TRIAD_STATE_IDLE
bAggroedTriads = FALSE
bTriadsMustChasePlayer = FALSE
bDoneTriadsWander = FALSE
bWaitForTriadVariations = FALSE
APPLY_PROPERTIES_TO_TRIAD_PEDS()
IF NOT IS_PED_INJURED(triadPed[TRIAD_CHENG_SR].ped)
ADD_PED_FOR_DIALOGUE(finaleConversation, 4, triadPed[TRIAD_CHENG_SR].ped, "CHENGSR")
ENDIF
IF NOT IS_PED_INJURED(triadPed[TRIAD_ESCORT_FRONT_DRIVER].ped)
ADD_PED_FOR_DIALOGUE(finaleConversation, 5, triadPed[TRIAD_ESCORT_FRONT_DRIVER].ped, "F3TRIAD1")
ENDIF
IF createStage = STAGE_GET_TO_HIT
SET_TRIAD_STATE(TRIAD_STATE_ENTER_CARS, FALSE, TRUE)
bTriadsFrozen = TRUE
ELIF createStage = STAGE_FRANKLIN_HIT
SET_TRIAD_STATE(TRIAD_STATE_ENTER_CARS)
bTriadsFrozen = FALSE
ENDIF
ENDPROC
// handle triad drivebys
PROC HANDLE_TRIAD_DRIVEBYS()
INT i
REPEAT COUNT_OF(triadPed) i
TRIAD_ENUM thisTriad = INT_TO_ENUM(TRIAD_ENUM, i)
IF NOT triadPed[thisTriad].bInCombat
IF NOT IS_PED_INJURED(triadPed[i].ped)
IF thisTriad <> TRIAD_CHENG_SR
AND thisTriad <> TRIAD_CHENG_JR
IF IS_PED_IN_ANY_VEHICLE(triadPed[i].ped)
BOOL bResetDriveby = FALSE
IF GET_SCRIPT_TASK_STATUS(triadPed[i].ped, SCRIPT_TASK_DRIVE_BY) = FINISHED_TASK
AND GET_GAME_TIMER() >= iSetTriadStateTime + 2000
IF IS_DRIVEBY_TASK_UNDERNEATH_DRIVING_TASK(triadPed[i].ped)
IF GET_GAME_TIMER() >= triadPed[i].iDrivebyTime + 10000
bResetDriveby = TRUE
ENDIF
ELSE
bResetDriveby = TRUE
ENDIF
ENDIF
IF bResetDriveby
TASK_DRIVE_BY(triadPed[i].ped, PLAYER_PED_ID(), NULL, <<0,0,0>>, 120, 10, TRUE)
triadPed[i].iDrivebyTime = GET_GAME_TIMER()
ENDIF
ENDIF
ELSE
IF NOT IS_PED_HEADTRACKING_ENTITY(triadPed[i].ped, PLAYER_PED_ID())
TASK_LOOK_AT_ENTITY(triadPed[i].ped, PLAYER_PED_ID(), -1, SLF_WHILE_NOT_IN_FOV)
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
ENDPROC
// is cheng in car
FUNC BOOL IS_CHENG_IN_CAR()
IF NOT IS_PED_INJURED(triadPed[TRIAD_CHENG_SR].ped)
AND IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_BOSSES])
IF IS_PED_IN_VEHICLE(triadPed[TRIAD_CHENG_SR].ped, triadVehicle[TRIAD_VEHICLE_BOSSES])
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
// create blip for cheng
PROC CREATE_MISSION_BLIP_FOR_CHENG(BOOL bInCar)
IF NOT IS_PED_INJURED(triadPed[TRIAD_CHENG_SR].ped)
IF bInCar
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_BOSSES])
chengBlip = CREATE_MISSION_BLIP_FOR_VEHICLE(triadVehicle[TRIAD_VEHICLE_BOSSES], TRUE)
ENDIF
ELSE
chengBlip = CREATE_MISSION_BLIP_FOR_PED(triadPed[TRIAD_CHENG_SR].ped, TRUE)
ENDIF
ENDIF
ENDPROC
// delete triads
PROC DELETE_TRIADS()
INT i
REPEAT COUNT_OF(TRIAD_ENUM) i
IF DOES_ENTITY_EXIST(triadPed[i].ped)
SET_PED_AS_NO_LONGER_NEEDED(triadPed[i].ped)
ENDIF
ENDREPEAT
REPEAT COUNT_OF(TRIAD_VEHICLE_ENUM) i
IF DOES_ENTITY_EXIST(triadVehicle[i])
IF triadVehicle[i] <> finaleVehicle[FV_FRANKLIN_CAR]
AND triadVehicle[i] <> finaleVehicle[FV_MICHAEL_CAR]
AND triadVehicle[i] <> finaleVehicle[FV_TREVOR_CAR]
SET_VEHICLE_AS_NO_LONGER_NEEDED(triadVehicle[i])
ENDIF
ENDIF
ENDREPEAT
ENDPROC
// get push car anim
FUNC STRING GET_PUSH_CAR_ANIM_FOR_CHAR(enumCharacterList getChar)
SWITCH getChar
CASE CHAR_TREVOR
RETURN "PushCar_offCliff_T"
BREAK
CASE CHAR_MICHAEL
RETURN "PushCar_offCliff_M"
BREAK
CASE CHAR_FRANKLIN
RETURN "PushCar_offCliff_F"
BREAK
ENDSWITCH
RETURN "error"
ENDFUNC
// get phase of push anim
FUNC FLOAT GET_PED_PUSH_CAR_PHASE(PED_INDEX ped, enumCharacterList getChar)
STRING sAnim = GET_PUSH_CAR_ANIM_FOR_CHAR(getChar)
IF IS_ENTITY_PLAYING_ANIM(ped, GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_PUSH_CAR), sAnim)
RETURN GET_ENTITY_ANIM_CURRENT_TIME(ped, GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_PUSH_CAR), sAnim)
ENDIF
RETURN 0.0
ENDFUNC
// update pushing car
PROC UPDATE_CHAR_PUSH_CAR_POS_AND_ROT(PED_INDEX ped, enumCharacterList getChar, VECTOR &vPos, VECTOR &vRot, FLOAT fForcePhase = -1.0)
FLOAT fPhase
IF fForcePhase >= 0
fPhase = fForcePhase
ELSE
fPhase = GET_PED_PUSH_CAR_PHASE(ped, getChar)
ENDIF
vPos = GET_ANIM_INITIAL_OFFSET_POSITION(GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_PUSH_CAR), GET_PUSH_CAR_ANIM_FOR_CHAR(getChar) , <<0,0,0>>, <<0,0,0>>, fPhase)
vRot = GET_ANIM_INITIAL_OFFSET_ROTATION(GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_PUSH_CAR), GET_PUSH_CAR_ANIM_FOR_CHAR(getChar) , <<0,0,0>>, <<0,0,0>>, fPhase)
ENDPROC
// give trevor sniper
CONST_INT SNIPER_AMMO 20
PROC GIVE_TREVOR_SNIPER()
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF NOT HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), GET_FINALE_WEAPON_TYPE(F_WEAPON_SNIPER))
GIVE_WEAPON_TO_PED(PLAYER_PED_ID(), GET_FINALE_WEAPON_TYPE(F_WEAPON_SNIPER), SNIPER_AMMO, FALSE, FALSE)
ELSE
IF GET_AMMO_IN_PED_WEAPON(PLAYER_PED_ID(), GET_FINALE_WEAPON_TYPE(F_WEAPON_SNIPER)) < SNIPER_AMMO
SET_PED_AMMO(PLAYER_PED_ID(),GET_FINALE_WEAPON_TYPE(F_WEAPON_SNIPER), SNIPER_AMMO)
ENDIF
ENDIF
ENDIF
ENDPROC
// give michael pistol
CONST_INT PISTOL_AMMO 32
PROC GIVE_MICHAEL_PISTOL()
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF NOT HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), GET_FINALE_WEAPON_TYPE(F_WEAPON_PISTOL))
GIVE_WEAPON_TO_PED(PLAYER_PED_ID(), GET_FINALE_WEAPON_TYPE(F_WEAPON_PISTOL), PISTOL_AMMO, FALSE, FALSE)
ELSE
IF GET_AMMO_IN_PED_WEAPON(PLAYER_PED_ID(), GET_FINALE_WEAPON_TYPE(F_WEAPON_PISTOL)) < PISTOL_AMMO
SET_PED_AMMO(PLAYER_PED_ID(),GET_FINALE_WEAPON_TYPE(F_WEAPON_PISTOL), PISTOL_AMMO)
ENDIF
ENDIF
ENDIF
ENDPROC
// create bulldozer
//PROC CREATE_BULLDOZER()
// bulldozerVehicle = CREATE_VEHICLE(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_BULLDOZER), <<1097.66, -2040.25, 29.99>>, 57.5)
//ENDPROC
// move the last player vehicle if at coord
PROC CLEAR_INIT_POS(VECTOR vCheckPos)
CLEAR_AREA(vCheckPos, CLEAR_POS_RADIUS, TRUE)
ENDPROC
// set next random speech time
PROC SET_NEXT_RANDOM_SPEECH_TIME(INT iTime = -1)
IF iTime >= 0
// if supplied an argument, set it to that
iNextRandomSpeechTime = GET_GAME_TIMER() + iTime
ELSE
iNextRandomSpeechTime = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(MIN_RANDOM_SPEECH_TIME, MAX_RANDOM_SPEECH_TIME)
ENDIF
ENDPROC
// handle random speech
FUNC BOOL DO_RANDOM_SPEECH(STRING sSpeech, INT iNextMinTime = -1, INT iNextMaxTime = -1)
// initialise next speech time if not yet done so
IF iNextRandomSpeechTime < 0
SET_NEXT_RANDOM_SPEECH_TIME()
ENDIF
IF GET_GAME_TIMER() >= iNextRandomSpeechTime
IF DO_MISSION_SPEECH(sSpeech)
INT iSetNextSpeechTime = -1
IF iNextMinTime > 0
iSetNextSpeechTime = GET_RANDOM_INT_IN_RANGE(iNextMinTime, iNextMaxTime)
ENDIF
SET_NEXT_RANDOM_SPEECH_TIME(iSetNextSpeechTime)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
// init wheel properties
PROC INIT_WHEEL_PROPERTIES()
fWheelRotation = INIT_WHEEL_ROTATION
fWheelSpeed = 0.0
bStartedWheel = FALSE
bStoppedWheel = FALSE
ENDPROC
// get position for gondolas
FUNC VECTOR GET_GONDOLA_POSITION(INT iGondola)
FLOAT fAngle = (360.0 / NUMBER_GONDOLAS) * iGondola
//fAngle += fWheelRotation
RETURN GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(wheelObject, <<0, GONDOLA_RADIUS * COS(fAngle), GONDOLA_RADIUS * SIN(fAngle)>>)
ENDFUNC
// set gondola position
PROC SET_GONDOLA_POSITION(INT iGondola, BOOL bForce)
IF DOES_ENTITY_EXIST(gondolaObject[iGondola])
VECTOR vPos = GET_GONDOLA_POSITION(iGondola)
IF bForce
SET_ENTITY_COORDS(gondolaObject[iGondola], vPos)
ELSE
SLIDE_OBJECT(gondolaObject[iGondola], vPos, <<1,1,1>>, FALSE)
ENDIF
//SET_ENTITY_HEADING(gondolaObject[iGondola], 0)
FREEZE_ENTITY_POSITION(gondolaObject[iGondola], TRUE)
ENDIF
ENDPROC
// set wheel position
PROC SET_WHEEL_POSITION()
SET_ENTITY_COORDS(wheelObject, GET_FINALE_VECTOR(FINVEC_WHEEL))
SET_ENTITY_ROTATION(wheelObject, <<fwheelrotation,0,0>>)
FREEZE_ENTITY_POSITION(wheelObject, TRUE)
ENDPROC
// reset wheel create state
PROC RESET_WHEEL_CREATE_STATE()
//SET_BUILDING_STATE(BUILDINGNAME_IPL_FERRIS_WHEEL, BUILDINGSTATE_NORMAL)
REQUEST_IPL("ferris_finale_Anim")
IF DOES_ENTITY_EXIST(wheelObject)
DELETE_OBJECT(wheelObject)
ENDIF
INT i
REPEAT NUMBER_GONDOLAS i
IF DOES_ENTITY_EXIST(gondolaObject[i])
DELETE_OBJECT(gondolaObject[i])
ENDIF
ENDREPEAT
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_FERRIS_WHEEL))
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_GONDOLA))
wheelCreateState = WHEEL_CREATE_STATE_NOT_STARTED
ENDPROC
// handle create wheel
PROC HANDLE_CREATE_WHEEL()
INT i
SWITCH wheelCreateState
CASE WHEEL_CREATE_STATE_NOT_STARTED
IF currentMissionStage < STAGE_PICKUP_DEVIN
AND NOT g_bFinale3BHitSuccessful[CHAR_TREVOR]
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_FERRIS_WHEEL))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_GONDOLA))
wheelCreateState = WHEEL_CREATE_STATE_WAITING
ENDIF
BREAK
CASE WHEEL_CREATE_STATE_WAITING
IF HAVE_ALL_MODEL_REQUESTS_SUCCEEDED()
//SET_BUILDING_STATE(BUILDINGNAME_IPL_FERRIS_WHEEL, BUILDINGSTATE_DESTROYED)
REMOVE_IPL("ferris_finale_Anim")
wheelObject = CREATE_OBJECT(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_FERRIS_WHEEL), <<0,1,2>>)
ONLY_CLEAN_UP_OBJECT_WHEN_OUT_OF_RANGE(wheelObject)
SET_WHEEL_POSITION()
SET_ENTITY_LOD_DIST(wheelObject, 1000)
// gondolas
REPEAT NUMBER_GONDOLAS i
gondolaObject[i] = CREATE_OBJECT(GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_GONDOLA), <<0,1,2>>)
ONLY_CLEAN_UP_OBJECT_WHEN_OUT_OF_RANGE(gondolaObject[i])
SET_GONDOLA_POSITION(i, TRUE)
SET_ENTITY_LOD_DIST(gondolaObject[i], 1000)
ENDREPEAT
wheelCreateState = WHEEL_CREATE_STATE_DONE
ENDIF
BREAK
CASE WHEEL_CREATE_STATE_DONE
IF DOES_ENTITY_EXIST(wheelObject)
IF IS_IPL_ACTIVE("ferris_finale_Anim")
REMOVE_IPL("ferris_finale_Anim")
ENDIF
IF (g_bFinale3BHitSuccessful[CHAR_TREVOR] OR currentMissionStage >= STAGE_PICKUP_DEVIN)
AND NOT IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_FINALE_VECTOR(FINVEC_WHEEL), <<350,350,350>>, FALSE, FALSE)
AND NOT IS_PLAYER_SWITCH_IN_PROGRESS()
AND IS_ENTITY_OCCLUDED(wheelObject)
DELETE_STEVE()
DELETE_WHEEL_BYSTANDERS()
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_STEVE))
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_CAMERAMAN))
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_BYSTANDER))
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_CAMERA))
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_COP))
CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_STEVE_FILMING)
CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_STEVE_SPEECH)
CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_STEVE_REACT)
CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_STEVE_DEATH)
CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_CAMERAMAN_REACT)
CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_WHEEL_BYSTANDERS)
CLEAR_SFX_REQUEST(F_SFX_STEVE_DEATH)
RESET_WHEEL_CREATE_STATE()
wheelCreateState = WHEEL_CREATE_STATE_NOT_STARTED
ELSE
CONST_FLOAT WHEEL_DECELERATION -0.25
IF bStartedWheel
IF NOT bStoppedWheel
IF NOT g_bFinale3BHitSuccessful[CHAR_TREVOR]
IF bAllowWheelTopSpeed
fWheelSpeed = fWheelSpeed +@ -0.10//-0.25
IF fWheelSpeed < -6
fWheelSpeed = -6
ENDIF
ELSE
fWheelSpeed = fWheelSpeed +@ -0.25//-0.25
IF fWheelSpeed < -2
fWheelSpeed = -2
ENDIF
ENDIF
ELSE
fWheelSpeed = fWheelSpeed -@ WHEEL_DECELERATION
IF fWheelSpeed >= 0
fWheelSpeed = 0
bStoppedWheel = TRUE
ENDIF
ENDIF
// printfloat(fWheelSpeed) printnl()
fWheelRotation = fWheelRotation +@ fWheelSpeed
IF fWheelRotation > 360
fWheelRotation -= 360
ENDIF
SET_WHEEL_POSITION()
REPEAT NUMBER_GONDOLAS i
SET_GONDOLA_POSITION(i, FALSE)
ENDREPEAT
ENDIF
ENDIF
ENDIF
ELSE
RESET_WHEEL_CREATE_STATE()
ENDIF
BREAK
ENDSWITCH
ENDPROC
/*
PROC CREATE_CAM_ATTACHED_TO_GONDOLA()
IF DOES_ENTITY_EXIST(gondolaObject[STEVE_GONDOLA])
CREATE_MISSION_STATIC_CAM(staticCam)
ATTACH_CAM_TO_ENTITY(staticCam, gondolaObject[STEVE_GONDOLA], <<1.0, -0.9,-1.5>>)
POINT_CAM_AT_ENTITY(staticCam, gondolaObject[STEVE_GONDOLA], <<0.4,0,-1.6>>)
SET_CAM_FOV(staticCam, 55.0)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
ENDIF
ENDPROC
*/
// get player cover coord
FUNC VECTOR GET_PLAYER_COVER_COORD(INT iCover)
SWITCH iCover
CASE 0
RETURN <<1106.91, -2012.00, 34.44>>
BREAK
CASE 1
RETURN <<1112.63, -2004.30, 34.44>>
BREAK
CASE 2
RETURN <<1080.78, -1980.85, 33.63>>
BREAK
ENDSWITCH
RETURN <<0,0,0>>
ENDFUNC
/*
// lamar car controls
PROC BLOCK_LAMAR_CAR_CONTROLS()
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_LAMAR_CAR])
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_LAMAR_CAR])
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ACCELERATE)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_BRAKE)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_HANDBRAKE)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_DUCK)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_MOVE_LR)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_MOVE_UD)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_CIN_CAM)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ATTACK)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ATTACK2)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_HEADLIGHT)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_HORN)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_NEXT_RADIO)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_PREV_RADIO)
ENDIF
ENDIF
ENDPROC
*/
// should we set the checkpoint for replay on this stage init?
FUNC BOOL SHOULD_SET_CHECKPOINT_FOR_THIS_STAGE(MISSION_STAGE_ENUM setStage)
SWITCH setStage
CASE STAGE_GET_TO_HIT
CASE STAGE_TREVOR_HIT
CASE STAGE_MICHAEL_HIT
CASE STAGE_FRANKLIN_HIT
CASE STAGE_PICKUP_DEVIN
CASE STAGE_DEVINS_HOUSE
CASE STAGE_GET_TO_CLIFF
RETURN TRUE
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
// do a hint on hud
PROC DO_MISSION_HINT(SELECTOR_SLOTS_ENUM thisPed)
INT i
FOR i=0 TO 2
SELECTOR_SLOTS_ENUM sPed = INT_TO_ENUM(SELECTOR_SLOTS_ENUM, i)
IF sPed = thisPed
SET_SELECTOR_PED_HINT(sSelectorPeds, sPed, TRUE)
ELSE
SET_SELECTOR_PED_HINT(sSelectorPeds, sPed, FALSE)
ENDIF
ENDFOR
ENDPROC
// clear hud hint
PROC CLEAR_MISSION_HINT()
INT i
FOR i=0 TO 2
SELECTOR_SLOTS_ENUM sPed = INT_TO_ENUM(SELECTOR_SLOTS_ENUM, i)
SET_SELECTOR_PED_HINT(sSelectorPeds, sPed, FALSE)
ENDFOR
ENDPROC
// start a particular stage of the mission
PROC SET_MISSION_STAGE(MISSION_STAGE_ENUM setStage, BOOL bJumpingToStage = FALSE, BOOL bClearTextAndSpeech = TRUE, BOOL bRenderScriptCamsFalse = TRUE, BOOL bInitialisingAfterIntro = FALSE, BOOL bClearMap = TRUE, BOOL bUseAutomaticStreaming = TRUE, BOOL bHandleFadeIn = TRUE)
IF bJumpingToStage
AND setStage = STAGE_GET_TO_HIT
RESET_TRACK_MISSION_VARS()
ENDIF
IF bJumpingToStage
AND NOT bInitialisingAfterIntro
// clear area and load scene around start pos
VECTOR vStartPos
FLOAT fStartRot
SWITCH setStage
CASE STAGE_GET_TO_HIT
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_FRANKLIN
IF bIsNaturalSkipToGetToHits
vStartPos = GET_ALMOST_AT_HIT_POS(CHAR_FRANKLIN) - <<0,0,2>>
fStartRot = GET_ALMOST_AT_HIT_ROT(CHAR_FRANKLIN)
ELSE
vStartPos = GET_FINALE_VECTOR(FINVEC_FRANKLIN_BIKE_INIT)
fStartRot = FRANKLIN_BIKE_INIT_ROT
ENDIF
BREAK
CASE CHAR_MICHAEL
IF bIsNaturalSkipToGetToHits
vStartPos = GET_ALMOST_AT_HIT_POS(CHAR_MICHAEL) - <<0,0,2>>
fStartRot = GET_ALMOST_AT_HIT_ROT(CHAR_MICHAEL)
ELSE
vStartPos = GET_FINALE_VECTOR(FINVEC_MICHAEL_CAR_INIT)
fStartRot = MICHAEL_CAR_INIT_ROT
ENDIF
BREAK
CASE CHAR_TREVOR
IF bIsNaturalSkipToGetToHits
vStartPos = GET_ALMOST_AT_HIT_POS(CHAR_TREVOR) - <<0,0,2>>
fStartRot = GET_ALMOST_AT_HIT_ROT(CHAR_TREVOR)
ELSE
vStartPos = GET_FINALE_VECTOR(FINVEC_TREVOR_CAR_INIT)
fStartRot = TREVOR_CAR_INIT_ROT
ENDIF
BREAK
ENDSWITCH
BREAK
CASE STAGE_FRANKLIN_HIT
vStartPos = GET_FINALE_VECTOR(FINVEC_FRANKLIN_BIKE_AT_CLUB)
fStartRot = FRANKLIN_BIKE_AT_CLUB_ROT
BREAK
CASE STAGE_TREVOR_HIT
vStartPos = GET_FINALE_VECTOR(FINVEC_TREVOR_CAR_AT_PIER)
fStartRot = TREVOR_CAR_AT_PIER_ROT
BREAK
CASE STAGE_MICHAEL_HIT
vStartPos = GET_FINALE_VECTOR(FINVEC_MICHAEL_CAR_AT_REC)
fStartRot = MICHAEL_CAR_AT_REC_ROT
BREAK
CASE STAGE_PICKUP_DEVIN
vStartPos = GET_FINALE_VECTOR(FINVEC_TREVOR_CAR_DRIVE_TO_PICKUP)
fStartRot = TREVOR_CAR_DRIVE_TO_PICKUP_ROT
BREAK
CASE STAGE_DEVINS_HOUSE
vStartPos = <<-2553.77246, 1911.67798, 167.94528>>
fStartRot = 62.4
BREAK
CASE STAGE_GET_TO_CLIFF
IF NOT bForcePassOnShitskip
vStartPos = GET_FINALE_VECTOR(FINVEC_DEVIN_CAR_INIT)
fStartRot = DEVIN_CAR_INIT_ROT
ELSE
vStartPos = GET_FINALE_VECTOR(FINVEC_CLIFF)
fStartRot = 9.1
ENDIF
BREAK
ENDSWITCH
// clear area for replay
SET_PLAYER_OUT_OF_ANY_VEHICLE()
IF bClearMap
CLEAR_AREA(vStartPos, 10000, TRUE)
ENDIF
WAIT(0)
// set weather
SET_WEATHER_TYPE_NOW_PERSIST("extrasunny")
// set to coords and wait for streaming
//SET_ENTITY_COORDS(PLAYER_PED_ID(), vStartPos)
IF IS_REPLAY_IN_PROGRESS()
AND NOT bSuppressFutureReplaySetups
START_REPLAY_SETUP(vStartPos, fStartRot)
ELSE
SET_ENTITY_COORDS(PLAYER_PED_ID(), vStartPos)
SET_ENTITY_HEADING(PLAYER_PED_ID(), fStartRot)
ENDIF
ENDIF
IF bInitialisingAfterIntro
IF NOT IS_REPLAY_IN_PROGRESS()
IF NOT DOES_ENTITY_EXIST(finaleVehicle[FV_FRANKLIN_CAR])
bForceRelativeCamReset = TRUE
ENDIF
ENDIF
ENDIF
IF bUseAutomaticStreaming
// get the models and force their load
REQUEST_MODELS_FOR_STAGE(setStage, NOT bInitialisingAfterIntro, FALSE)
// get the recordings and force their load
REQUEST_VEHICLE_RECORDINGS_FOR_STAGE(setStage, NOT bInitialisingAfterIntro, FALSE)
// get the waypoints and force their load
REQUEST_WAYPOINT_RECORDINGS_FOR_STAGE(setStage, NOT bInitialisingAfterIntro, FALSE)
// get the anims and force their load
REQUEST_ANIM_DICTS_FOR_STAGE(setStage, NOT bInitialisingAfterIntro, FALSE)
// get the weapons and force their load
REQUEST_WEAPONS_FOR_STAGE(setStage, NOT bInitialisingAfterIntro, FALSE)
// get the ptfx and force their load
REQUEST_PTFX_FOR_STAGE(setStage, NOT bInitialisingAfterIntro, FALSE)
// get the sfx and force their load
REQUEST_SFX_FOR_STAGE(setStage, NOT bInitialisingAfterIntro, FALSE)
// get the misc assets and force their load
REQUEST_MISC_ASSETS_FOR_STAGE(setStage, NOT bInitialisingAfterIntro, FALSE)
ENDIF
IF bInitialisingAfterIntro
WHILE NOT HAVE_ALL_MODEL_REQUESTS_SUCCEEDED()
OR NOT HAVE_ALL_RECORDING_REQUESTS_SUCCEEDED()
OR NOT HAVE_ALL_WAYPOINT_REQUESTS_SUCCEEDED()
OR NOT HAVE_ALL_ANIM_DICT_REQUESTS_SUCCEEDED()
OR NOT HAVE_ALL_WEAPON_REQUESTS_SUCCEEDED()
OR NOT HAVE_ALL_PTFX_REQUESTS_SUCCEEDED()
OR NOT HAVE_ALL_SFX_REQUESTS_SUCCEEDED()
OR NOT HAVE_ALL_MISC_ASSET_REQUESTS_SUCCEEDED()
//OR NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT)
WAIT(0)
ENDWHILE
ENDIF
// request all the vehicle models for replays etc
IF bJumpingToStage
// do we need a replay vehicle
BOOL bRequestDefaultFranklinVehicle = FALSE
BOOL bRequestDefaultTrevorVehicle = FALSE
BOOL bRequestDefaultMichaelVehicle = FALSE
BOOL bRequestReplayCheckpointVehicle = FALSE
BOOL bRequestReplayStartVehicle = FALSE
bRequestDefaultFranklinVehicle = TRUE
bRequestDefaultTrevorVehicle = TRUE
bRequestDefaultMichaelVehicle = TRUE
IF IS_REPLAY_IN_PROGRESS()
AND NOT g_bShitskipAccepted
IF IS_REPLAY_CHECKPOINT_VEHICLE_AVAILABLE()
bRequestReplayCheckpointVehicle = TRUE
REQUEST_REPLAY_CHECKPOINT_VEHICLE_MODEL()
SWITCH setStage
CASE STAGE_TREVOR_HIT
CASE STAGE_PICKUP_DEVIN
CASE STAGE_DEVINS_HOUSE
bRequestDefaultTrevorVehicle = FALSE
BREAK
CASE STAGE_FRANKLIN_HIT
bRequestDefaultFranklinVehicle = FALSE
BREAK
CASE STAGE_MICHAEL_HIT
bRequestDefaultMichaelVehicle = FALSE
BREAK
ENDSWITCH
ENDIF
ENDIF
IF setStage < STAGE_PICKUP_DEVIN
IF bRequestDefaultFranklinVehicle
IF NOT g_bFinale3BHitSuccessful[CHAR_FRANKLIN]
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_FRANKLIN_BIKE))
ENDIF
ENDIF
IF bRequestDefaultMichaelVehicle
IF NOT g_bFinale3BHitSuccessful[CHAR_MICHAEL]
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_MICHAEL_CAR))
ENDIF
ENDIF
IF NOT g_bFinale3BHitSuccessful[CHAR_FRANKLIN]
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_FRANKLIN))
ENDIF
IF NOT g_bFinale3BHitSuccessful[CHAR_MICHAEL]
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_MICHAEL))
ENDIF
ENDIF
IF bRequestDefaultTrevorVehicle
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_TREVOR_CAR))
ENDIF
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_TREVOR))
// wait for them all to load in
IF NOT bInitialisingAfterIntro
LOAD_ALL_OBJECTS_IF_SCREEN_FADED_OUT()
ENDIF
WHILE NOT HAVE_ALL_MODEL_REQUESTS_SUCCEEDED()
WAIT(0)
ENDWHILE
IF bRequestReplayCheckpointVehicle
WHILE NOT HAS_REPLAY_CHECKPOINT_VEHICLE_LOADED()
WAIT(0)
ENDWHILE
ENDIF
IF bRequestReplayStartVehicle
WHILE NOT HAS_REPLAY_START_VEHICLE_LOADED()
WAIT(0)
ENDWHILE
ENDIF
ENDIF
// get the text and force its load
REQUEST_TEXT(TRUE)
// reset mocap streaming
//IF mocapStreamingStage >= MOCAP_STREAMING_STAGE_WAIT
REMOVE_CUTSCENE()
mocapStreamingStage = MOCAP_STREAMING_STAGE_REQUEST
//ENDIF
// reset vars
RESET_VARIABLES_FOR_STAGE(setStage)
#IF IS_DEBUG_BUILD
bDebugJSkip = FALSE
#ENDIF
// get rid of blips and text
IF bJumpingToStage
REMOVE_ALL_BLIPS()
ENDIF
IF setStage = STAGE_FRANKLIN_HIT
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
ENDIF
FORCE_CHASE_HINT_CAM(localChaseHintCamStruct, FALSE)
RESET_CUSTOM_CHASE_HINT_CAM_INTERP_IN_TIME(localChaseHintCamStruct)
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
REMOVE_MISSION_TEXT(bClearTextAndSpeech OR bJumpingToStage, bClearTextAndSpeech OR bJumpingToStage)
INT i
// setup streaming
IF bJumpingToStage
REPEAT 3 i
createHitStage[i] = CREATE_HIT_STAGE_NOT_STARTED
ENDREPEAT
ENDIF
//REPEAT 3 i
// REMOVE_COVER_POINT(initialCover[i])
//ENDREPEAT
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", FALSE)
IF bJumpingToStage
IF setStage <> STAGE_GET_TO_HIT
OR NOT bIsNaturalSkipToGetToHits
// set the correct player character if not already
enumCharacterList stageCharacter = GET_CHARACTER_FOR_MISSION_STAGE(setStage)
SELECTOR_SLOTS_ENUM selectorSlot = GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(stageCharacter)
IF GET_CURRENT_PLAYER_PED_ENUM() <> stageCharacter
WHILE NOT CREATE_PLAYER_PED_ON_FOOT(sSelectorPeds.pedID[selectorSlot], stageCharacter, GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_HEADING(PLAYER_PED_ID()), FALSE)
WAIT(0)
ENDWHILE
WHILE NOT MAKE_SELECTOR_PED_SELECTION(sSelectorPeds, selectorSlot)
WAIT(0)
ENDWHILE
WHILE NOT TAKE_CONTROL_OF_SELECTOR_PED(sSelectorPeds, TRUE)
WAIT(0)
ENDWHILE
REPEAT 3 i
IF DOES_ENTITY_EXIST(sSelectorPeds.pedID[i])
DELETE_PED(sSelectorPeds.pedID[i])
ENDIF
ENDREPEAT
ENDIF
ENDIF
ENDIF
IF bJumpingToStage
// remove all dialogue
IF bJumpingToStage
FOR i=0 TO 9
REMOVE_PED_FOR_DIALOGUE(finaleConversation, i)
ENDFOR
ENDIF
IF NOT bIsNaturalSkipToGetToHits
SET_GPS_DISABLED_ZONE(GET_MIN_GPS_BLOCK_AREA_COORDS(CHAR_FRANKLIN), GET_MAX_GPS_BLOCK_AREA_COORDS(CHAR_FRANKLIN))
ENDIF
// setup player with dialogue
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL
ADD_PED_FOR_DIALOGUE(finaleConversation, 0, PLAYER_PED_ID(), "MICHAEL")
BREAK
CASE CHAR_TREVOR
ADD_PED_FOR_DIALOGUE(finaleConversation, 1, PLAYER_PED_ID(), "TREVOR")
BREAK
CASE CHAR_FRANKLIN
ADD_PED_FOR_DIALOGUE(finaleConversation, 2, PLAYER_PED_ID(), "FRANKLIN")
BREAK
ENDSWITCH
sSelectorPeds.eCurrentSelectorPed = GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(GET_CHARACTER_FOR_MISSION_STAGE(setStage))
IF NOT bInitialisingAfterIntro
finaleVehicle[FV_FRANKLIN_CAR] = NULL
finaleVehicle[FV_MICHAEL_CAR] = NULL
finaleVehicle[FV_TREVOR_CAR] = NULL
ENDIF
IF NOT bInitialisingAfterIntro
IF IS_PED_WEARING_HELMET(PLAYER_PED_ID())
REMOVE_PED_HELMET(PLAYER_PED_ID(), TRUE)
ENDIF
ENDIF
// create the player characters for the stage
CREATE_PLAYER_CHARACTERS_WITH_TRANSPORT_IN_MISSION_STAGE(setStage, bInitialisingAfterIntro)
SETUP_PLAYER_CHARACTER_WITH_MISSION_VARIATIONS(PLAYER_PED_ID(), GET_CHARACTER_FOR_MISSION_STAGE(setStage), setStage)
IF bInitialisingAfterIntro
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_FRANKLIN_CAR])
AND NOT IS_PED_INJURED(PLAYER_PED_ID())
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_FRANKLIN_CAR])
// SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_FRANKLIN_CAR])
ENDIF
ENDIF
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_TREVOR_CAR])
AND NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
IF NOT IS_PED_IN_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], finaleVehicle[FV_TREVOR_CAR])
SET_PED_INTO_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], finaleVehicle[FV_TREVOR_CAR])
ENDIF
ENDIF
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_MICHAEL_CAR])
AND NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_MICHAEL])
IF NOT IS_PED_IN_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_MICHAEL], finaleVehicle[FV_MICHAEL_CAR])
SET_PED_INTO_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_MICHAEL], finaleVehicle[FV_MICHAEL_CAR])
ENDIF
ENDIF
ENDIF
IF bJumpingToStage
//IF setStage = STAGE_GET_TO_HIT
//AND bIsNaturalSkipToGetToHits
// WAIT(0)
//LOAD_SCENE(GET_ENTITY_COORDS(PLAYER_PED_ID()))
// WAIT(0)
//ENDIF
IF NOT bInitialisingAfterIntro
LOAD_ALL_OBJECTS_IF_SCREEN_FADED_OUT()
ENDIF
WHILE NOT HAVE_ALL_STREAMING_REQUESTS_COMPLETED(PLAYER_PED_ID())
WAIT(0)
ENDWHILE
ENDIF
ENDIF
IF bJumpingToStage
IF setStage = STAGE_FRANKLIN_HIT
OR setStage = STAGE_MICHAEL_HIT
OR setStage = STAGE_TREVOR_HIT
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
bDoFadeInOnHitCreation = TRUE
ELSE
bDoFadeInOnHitCreation = FALSE
ENDIF
ELSE
bDoFadeInOnHitCreation = FALSE
ENDIF
// setup player control/cameras
IF bRenderScriptCamsFalse
RENDER_SCRIPT_CAMS(FALSE, FALSE)
ENDIF
// do any other necessary setup for the stage
SWITCH setStage
CASE STAGE_GET_TO_HIT
IF bInitialisingAfterIntro
SET_PLAYER_PED_WITH_HEADSET(CHAR_MICHAEL, TRUE)
SET_PLAYER_PED_WITH_HEADSET(CHAR_TREVOR, TRUE)
SET_PLAYER_PED_WITH_HEADSET(CHAR_FRANKLIN, TRUE)
ENDIF
//iJourneyWarpTimer[0] = GET_GAME_TIMER() + 15000
//iJourneyWarpTimer[1] = GET_GAME_TIMER() + 15000
//iJourneyWarpTimer[2] = GET_GAME_TIMER() + 15000
IF bJumpingToStage
SET_MICHAEL_AND_TREVOR_INITIAL_DRIVE_TO_HITS()
//SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
INIT_WHEEL_PROPERTIES()
bDoneOnlyYourTargetSpeech = FALSE
bDoneOnlyYourTargetReplySpeech = FALSE
bDoneFranklinCallLamar = FALSE
bDoneTrevorCallRon = FALSE
iForceLamarCallTime = -1
ELSE
REAPPLY_PLAYER_PED_ATTRIBUTES()
ENDIF
BREAK
CASE STAGE_TREVOR_HIT
IF bJumpingToStage
TRIGGER_MISSION_MUSIC_EVENT("FINC2_STEVE_START")
bShownSteveIntro = TRUE
bDoneReadySpeech[CHAR_TREVOR] = TRUE
bJumpedAheadToTrevorHit = FALSE
INIT_WHEEL_PROPERTIES()
bUsingWheelCam = FALSE
bDoneWheelCamHelp = FALSE
bStartedWheel = TRUE
ELSE
bShownSteveIntro = FALSE
bShownDoHitText[CHAR_TREVOR] = TRUE
ENDIF
ADD_PED_FOR_DIALOGUE(finaleConversation, 8, NULL, "LESTER")
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_TREVOR_KILL_STEVE)
GIVE_TREVOR_SNIPER()
RESET_DRIVE_TO_VALUES_BASED_ON_COMPLETED_HITS()
BREAK
CASE STAGE_FRANKLIN_HIT
TRIGGER_MISSION_MUSIC_EVENT("FINC2_CHENG_START")
IF bJumpingToStage
bWaitForTriadVariations = TRUE
bJumpedAheadToFranklinHit = FALSE
bAggroedTriads = FALSE
ELSE
bShownDoHitText[CHAR_FRANKLIN] = TRUE
ENDIF
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_FRANKLIN_KILL_CHENG)
RESET_DRIVE_TO_VALUES_BASED_ON_COMPLETED_HITS()
BREAK
CASE STAGE_MICHAEL_HIT
TRIGGER_MISSION_MUSIC_EVENT("FINC2_STRETCH_START")
IF bJumpingToStage
bWaitForGangsterVariations = TRUE
bDonePhoneIntroSpeech = TRUE
bJumpedAheadToMichaelHit = FALSE
ELSE
bShownDoHitText[CHAR_MICHAEL] = TRUE
ENDIF
IF NOT bJumpedAheadToMichaelHit
gangsterAggro = GANGSTER_AGGRO_NOT_AGGROED
ENDIF
GIVE_MICHAEL_PISTOL()
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_MICHAEL_KILL_STRETCH)
RESET_DRIVE_TO_VALUES_BASED_ON_COMPLETED_HITS()
SET_NEXT_RANDOM_SPEECH_TIME(10000)
BREAK
CASE STAGE_PICKUP_DEVIN
CLEAR_SELECTOR_PED_PRIORITY(sSelectorPeds)
IF bJumpingToStage
iGetInTextStage[CHAR_TREVOR] = 2
//IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_TREVOR_CAR])
// START_PLAYBACK_RECORDED_VEHICLE(finaleVehicle[FV_TREVOR_CAR], 007, GET_FINALE_RECORDING_PREFIX())
// SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(finaleVehicle[FV_TREVOR_CAR], 4000)
// WAIT(0)
//ENDIF
ELSE
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_TREVOR_CAR])
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_TREVOR_CAR])
iGetInTextStage[CHAR_TREVOR] = 2
ELSE
iGetInTextStage[CHAR_TREVOR] = 0
ENDIF
ENDIF
ENDIF
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_TREVOR_CAR])
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(finaleVehicle[FV_TREVOR_CAR])
STOP_PLAYBACK_RECORDED_VEHICLE(finaleVehicle[FV_TREVOR_CAR])
ENDIF
ENDIF
BREAK
CASE STAGE_DEVINS_HOUSE
IF bJumpingToStage
CREATE_DEVIN_HOUSE()
TRIGGER_MISSION_MUSIC_EVENT("FINC2_OUTSIDE_DEVINS")
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_KIDNAP_DEVIN_STEALTH)
ENDIF
BREAK
CASE STAGE_GET_TO_CLIFF
LOCK_AUTOMATIC_DOOR_OPEN(AUTODOOR_DEVIN_GATE_L, TRUE)
LOCK_AUTOMATIC_DOOR_OPEN(AUTODOOR_DEVIN_GATE_R, TRUE)
SET_GPS_DISABLED_ZONE(<<-2553.46094, 1814.88831, 127.72006>>, <<-2481.37866, 1859.36536, 194.89583>>)
REMOVE_PED_FOR_DIALOGUE(finaleConversation, 8)
ADD_PED_FOR_DIALOGUE(finaleConversation, 7, NULL, "DEVIN")
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_DEVIN_CAR])
SET_VEHICLE_DOORS_LOCKED(finaleVehicle[FV_DEVIN_CAR], VEHICLELOCK_UNLOCKED)
ENDIF
iNextDevinBootSpeechTime = GET_GAME_TIMER() + 45000
BREAK
ENDSWITCH
// headsets
IF bJumpingToStage
SET_PLAYER_PED_WITH_HEADSET(CHAR_MICHAEL, TRUE)
SET_PLAYER_PED_WITH_HEADSET(CHAR_TREVOR, TRUE)
SET_PLAYER_PED_WITH_HEADSET(CHAR_FRANKLIN, TRUE)
ENDIF
// devin gate
//LOCK_AUTOMATIC_DOOR_OPEN(AUTODOOR_DEVIN_GATE_L, setStage = STAGE_GET_TO_CLIFF)
//LOCK_AUTOMATIC_DOOR_OPEN(AUTODOOR_DEVIN_GATE_R, setStage = STAGE_GET_TO_CLIFF)
// clear selector hint
CLEAR_MISSION_HINT()
// wanted level, emergency services
IF setStage = STAGE_FRANKLIN_HIT
OR setStage = STAGE_MICHAEL_HIT
SET_WANTED_LEVEL_MULTIPLIER(0.1)
SET_MAX_WANTED_LEVEL(5)
ENABLE_DISPATCH_SERVICE(DT_AMBULANCE_DEPARTMENT, FALSE)
ENABLE_DISPATCH_SERVICE(DT_FIRE_DEPARTMENT, FALSE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_AUTOMOBILE, FALSE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_VEHICLE_REQUEST, FALSE)
ELIF setStage = STAGE_DEVINS_HOUSE
SET_WANTED_LEVEL_MULTIPLIER(0.0)
SET_MAX_WANTED_LEVEL(0)
ENABLE_DISPATCH_SERVICE(DT_AMBULANCE_DEPARTMENT, FALSE)
ENABLE_DISPATCH_SERVICE(DT_FIRE_DEPARTMENT, FALSE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_AUTOMOBILE, FALSE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_VEHICLE_REQUEST, FALSE)
ELSE
SET_WANTED_LEVEL_MULTIPLIER(1.0)
SET_MAX_WANTED_LEVEL(5)
ENABLE_DISPATCH_SERVICE(DT_AMBULANCE_DEPARTMENT, TRUE)
ENABLE_DISPATCH_SERVICE(DT_FIRE_DEPARTMENT, TRUE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_AUTOMOBILE, TRUE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_VEHICLE_REQUEST, TRUE)
ENDIF
SET_CREATE_RANDOM_COPS(FALSE)
IF bJumpingToStage
WHILE IS_SCREEN_FADING_OUT()
WAIT(0)
ENDWHILE
IF NOT bSuppressFutureReplaySetups
IF IS_REPLAY_IN_PROGRESS()
IF IS_REPLAY_BEING_SET_UP()
VEHICLE_INDEX endReplayVehicle
SWITCH setStage
CASE STAGE_GET_TO_HIT
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL
endReplayVehicle = finaleVehicle[FV_MICHAEL_CAR]
BREAK
CASE CHAR_FRANKLIN
endReplayVehicle = finaleVehicle[FV_FRANKLIN_CAR]
BREAK
CASE CHAR_TREVOR
endReplayVehicle = finaleVehicle[FV_TREVOR_CAR]
BREAK
ENDSWITCH
BREAK
CASE STAGE_FRANKLIN_HIT
endReplayVehicle = finaleVehicle[FV_FRANKLIN_CAR]
BREAK
CASE STAGE_MICHAEL_HIT
endReplayVehicle = finaleVehicle[FV_MICHAEL_CAR]
BREAK
CASE STAGE_TREVOR_HIT
CASE STAGE_PICKUP_DEVIN
endReplayVehicle = finaleVehicle[FV_TREVOR_CAR]
BREAK
CASE STAGE_GET_TO_CLIFF
endReplayVehicle = finaleVehicle[FV_DEVIN_CAR]
BREAK
ENDSWITCH
BOOL bReturnControl = TRUE
VEHICLE_SEAT seat = VS_DRIVER
END_REPLAY_SETUP(endReplayVehicle, seat, bReturnControl)
bSuppressFutureReplaySetups = TRUE
ENDIF
ENDIF
ENDIF
// post replay setup specific skip stuff
IF bJumpingToStage
IF NOT bInitialisingAfterIntro
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
ENDIF
IF setStage = STAGE_PICKUP_DEVIN
IF bJumpingToStage
wait(0)
PRINTSTRING("set pickup devin") printnl()
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_TREVOR_CAR])
PRINTSTRING("APPLYING SPEED") printnl()
SET_VEHICLE_FORWARD_SPEED(finaleVehicle[FV_TREVOR_CAR], 20)
ENDIF
ENDIF
ELIF setStage = STAGE_GET_TO_HIT
IF NOT bInitialisingAfterIntro
IF bIsNaturalSkipToGetToHits
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_TREVOR
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_TREVOR_CAR])
SET_VEHICLE_FORWARD_SPEED(finaleVehicle[FV_TREVOR_CAR], 20)
ENDIF
BREAK
CASE CHAR_MICHAEL
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_MICHAEL_CAR])
SET_VEHICLE_FORWARD_SPEED(finaleVehicle[FV_MICHAEL_CAR], 20)
ENDIF
BREAK
CASE CHAR_FRANKLIN
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_FRANKLIN_CAR])
SET_VEHICLE_FORWARD_SPEED(finaleVehicle[FV_FRANKLIN_CAR], 20)
ENDIF
BREAK
ENDSWITCH
ENDIF
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
WAIT(1000)
ENDIF
ENDIF
ENDIF
ENDIF
IF setStage = STAGE_TREVOR_HIT
IF bJumpingToStage
IF NOT bJumpedAheadToTrevorHit
SET_GAMEPLAY_CAM_RELATIVE_HEADING(-80)
ENDIF
ENDIF
ELIF setStage = STAGE_MICHAEL_HIT
IF NOT bJumpedAheadToMichaelHit
SET_GAMEPLAY_CAM_RELATIVE_HEADING(35)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(-10)
ENDIF
ELIF setStage = STAGE_FRANKLIN_HIT
IF NOT bJumpedAheadToFranklinHit
CLEAR_AREA_OF_VEHICLES(<<-2984.57715, 443.11536, 14.05719>>, 10000, TRUE)
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(-12)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(-10)
ENDIF
ENDIF
IF bForceRelativeCamReset
SET_HELMET_IF_VEHICLE_A_BIKE(finaleVehicle[FV_FRANKLIN_CAR])
REQUEST_ANIM_DICT("veh@bike@police@front@base")
WHILE NOT HAS_ANIM_DICT_LOADED("veh@bike@police@front@base")
WAIT(0)
ENDWHILE
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
TASK_PLAY_ANIM(PLAYER_PED_ID(), "veh@bike@police@front@base", "still", INSTANT_BLEND_IN, REALLY_SLOW_BLEND_OUT, 1000)
FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID())
ENDIF
WAIT(0)
LOAD_SCENE(GET_ENTITY_COORDS(PLAYER_PED_ID()))
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0)
REMOVE_ANIM_DICT("veh@bike@police@front@base")
bForceRelativeCamReset = FALSE
ENDIF
//SWITCH setStage
//ENDSWITCH
ENDIF
bHandleFadeIn=bHandleFadeIn
// set value for replay
BOOL bFinalCheckpoint = FALSE
BOOL bCanLowerCheckpoint = FALSE
IF ENUM_TO_INT(setStage) >= ENUM_TO_INT(STAGE_GET_TO_CLIFF)
bFinalCheckpoint = TRUE // skipping from this point would end the mission
ENDIF
IF setStage = STAGE_TREVOR_HIT
OR setStage = STAGE_MICHAEL_HIT
OR setStage = STAGE_FRANKLIN_HIT
OR setStage = STAGE_GET_TO_HIT
bCanLowerCheckpoint = TRUE
ENDIF
iReplayAttempt=iReplayAttempt
IF SHOULD_SET_CHECKPOINT_FOR_THIS_STAGE(setStage)
Set_Replay_Mid_Mission_Stage_With_Name(ENUM_TO_INT(setStage), GET_DESCRIPTION_FOR_STAGE_AS_STRING(setStage), bFinalCheckpoint, bCanLowerCheckpoint)
IF ENUM_TO_INT(setStage) <> 0
AND NOT bJumpingToStage
iReplayAttempt = 0
ENDIF
ENDIF
iStageStartTime = GET_GAME_TIMER()
currentMissionStage = setStage
ENDPROC
// handle streaming mocap
PROC HANDLE_STREAMING_MOCAP(STRING sMocap, VECTOR vStreamPos, FLOAT fStreamInDistance, FLOAT fStreamOutDistance)
SWITCH mocapStreamingStage
CASE MOCAP_STREAMING_STAGE_REQUEST
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vStreamPos, <<fStreamInDistance, fStreamInDistance, fStreamInDistance>>)
REQUEST_CUTSCENE(sMocap)
mocapStreamingStage = MOCAP_STREAMING_STAGE_WAIT
ENDIF
BREAK
CASE MOCAP_STREAMING_STAGE_WAIT
IF HAS_CUTSCENE_LOADED()
mocapStreamingStage = MOCAP_STREAMING_STAGE_COMPLETE
ENDIF
BREAK
CASE MOCAP_STREAMING_STAGE_COMPLETE
IF NOT IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vStreamPos, <<fStreamOutDistance, fStreamOutDistance, fStreamOutDistance>>)
REMOVE_CUTSCENE()
mocapStreamingStage = MOCAP_STREAMING_STAGE_REQUEST
ENDIF
BREAK
ENDSWITCH
ENDPROC
// should we start streaming for next mission stage?
FUNC BOOL SHOULD_START_STREAMING_FOR_NEXT_MISSION_STAGE()
SWITCH currentMissionStage
CASE STAGE_PICKUP_DEVIN
IF bRunningCutscene
RETURN TRUE
ENDIF
BREAK
CASE STAGE_DEVINS_HOUSE
IF bRunningCutscene
RETURN TRUE
ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
// stream in assets for next mission stage during gameplay to cut down on load times
PROC DO_STREAMING_FOR_NEXT_MISSION_STAGE(BOOL bStreamDuringIntro)
SWITCH streamingStage
CASE MISSION_STREAMING_STAGE_REQUEST
IF SHOULD_START_STREAMING_FOR_NEXT_MISSION_STAGE()
OR bStreamDuringIntro
MISSION_STAGE_ENUM nextStageEnum
IF bStreamDuringIntro
nextStageEnum = INT_TO_ENUM(MISSION_STAGE_ENUM, 0)
ELSE
nextStageEnum = INT_TO_ENUM(MISSION_STAGE_ENUM, ENUM_TO_INT(currentMissionStage) + 1)
ENDIF
REQUEST_MODELS_FOR_STAGE(nextStageEnum, FALSE, TRUE)
REQUEST_VEHICLE_RECORDINGS_FOR_STAGE(nextStageEnum, FALSE, TRUE)
REQUEST_WAYPOINT_RECORDINGS_FOR_STAGE(nextStageEnum, FALSE, TRUE)
REQUEST_ANIM_DICTS_FOR_STAGE(nextStageEnum, FALSE, TRUE)
REQUEST_WEAPONS_FOR_STAGE(nextStageEnum, FALSE, TRUE)
REQUEST_PTFX_FOR_STAGE(nextStageEnum, FALSE, TRUE)
REQUEST_SFX_FOR_STAGE(nextStageEnum, FALSE, TRUE)
REQUEST_MISC_ASSETS_FOR_STAGE(nextStageEnum, FALSE, TRUE)
REQUEST_TEXT(FALSE)
streamingStage = MISSION_STREAMING_STAGE_WAIT
ENDIF
BREAK
CASE MISSION_STREAMING_STAGE_WAIT
IF HAVE_ALL_MODEL_REQUESTS_SUCCEEDED()
AND HAVE_ALL_RECORDING_REQUESTS_SUCCEEDED()
AND HAVE_ALL_WAYPOINT_REQUESTS_SUCCEEDED()
AND HAVE_ALL_ANIM_DICT_REQUESTS_SUCCEEDED()
AND HAVE_ALL_WEAPON_REQUESTS_SUCCEEDED()
AND HAVE_ALL_PTFX_REQUESTS_SUCCEEDED()
AND HAVE_ALL_SFX_REQUESTS_SUCCEEDED()
AND HAVE_ALL_MISC_ASSET_REQUESTS_SUCCEEDED()
AND HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT)
streamingStage = MISSION_STREAMING_STAGE_COMPLETE
ENDIF
BREAK
ENDSWITCH
ENDPROC
// debug skip mocap
#IF IS_DEBUG_BUILD
PROC DEBUG_SKIP_MOCAP()
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J)
STOP_CUTSCENE()
WHILE NOT IS_SCREEN_FADED_OUT()
WAIT(0)
ENDWHILE
ENDIF
ENDPROC
#ENDIF
// get rid of everything
PROC CLEAR_MISSION_FOR_SKIP()
INT i
RESET_MISSION_STATS_ENTITY_WATCH()
SET_PLAYER_OUT_OF_ANY_VEHICLE()
RESET_WANTED_LEVEL_DIFFICULTY(PLAYER_ID())
SET_GPS_DISABLED_ZONE(<<0,0,0>>, <<0,0,0>>)
STOP_ALL_FINALE_AUDIO_SCENES()
SET_POLICE_IGNORE_PLAYER(PLAYER_ID(), FALSE)
RESET_WHEEL_CREATE_STATE()
sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_MICHAEL] = FALSE
sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_FRANKLIN] = FALSE
sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_TREVOR] = FALSE
IF STREAMVOL_IS_VALID(trevorVolume)
STREAMVOL_DELETE(trevorVolume)
ENDIF
IF STREAMVOL_IS_VALID(devinVolume)
STREAMVOL_DELETE(devinVolume)
ENDIF
WAIT(100)
STOP_SOUND(iPushCarSoundID)
SET_FRONTEND_RADIO_ACTIVE(TRUE)
// delete entities
REPEAT 3 i
IF DOES_ENTITY_EXIST(sSelectorPeds.pedID[i])
DELETE_PED(sSelectorPeds.pedID[i])
ENDIF
ENDREPEAT
IF DOES_ENTITY_EXIST(devinPed)
DELETE_PED(devinPed)
ENDIF
IF DOES_ENTITY_EXIST(girlPed)
DELETE_PED(girlPed)
ENDIF
REPEAT COUNT_OF(TRIAD_ENUM) i
IF DOES_ENTITY_EXIST(triadPed[i].ped)
DELETE_PED(triadPed[i].ped)
ENDIF
ENDREPEAT
REPEAT COUNT_OF(GANGSTER_ENUM) i
IF DOES_ENTITY_EXIST(gangsterPed[i].ped)
DELETE_PED(gangsterPed[i].ped)
ENDIF
ENDREPEAT
REPEAT COUNT_OF(STEVE_ENUM) i
IF DOES_ENTITY_EXIST(stevePed[i])
DELETE_PED(stevePed[i])
ENDIF
ENDREPEAT
REPEAT COUNT_OF(MERRYWEATHER_ENUM) i
IF DOES_ENTITY_EXIST(merryweatherPed[i].ped)
DELETE_PED(merryweatherPed[i].ped)
ENDIF
ENDREPEAT
REPEAT NUMBER_PIER_COPS i
IF DOES_ENTITY_EXIST(copPed[i])
DELETE_PED(copPed[i])
ENDIF
ENDREPEAT
DELETE_WHEEL_BYSTANDERS()
REPEAT COUNT_OF(finaleVehicle) i
IF DOES_ENTITY_EXIST(finaleVehicle[i])
IF IS_ENTITY_A_MISSION_ENTITY(finaleVehicle[i])
DELETE_VEHICLE(finaleVehicle[i])
ENDIF
ENDIF
ENDREPEAT
REPEAT COUNT_OF(TRIAD_VEHICLE_ENUM) i
IF DOES_ENTITY_EXIST(triadVehicle[i])
IF IS_ENTITY_A_MISSION_ENTITY(triadVehicle[i])
DELETE_VEHICLE(triadVehicle[i])
ENDIF
ENDIF
ENDREPEAT
REPEAT NUMBER_GANGSTER_VEHICLES i
IF DOES_ENTITY_EXIST(gangsterVehicle[i])
DELETE_VEHICLE(gangsterVehicle[i])
ENDIF
ENDREPEAT
//IF DOES_ENTITY_EXIST(bulldozerVehicle)
// DELETE_VEHICLE(bulldozerVehicle)
//ENDIF
//IF DOES_ENTITY_EXIST(stretchVehicle)
// DELETE_VEHICLE(stretchVehicle)
//ENDIF
IF DOES_ENTITY_EXIST(cameraObject)
DELETE_OBJECT(cameraObject)
ENDIF
IF DOES_ENTITY_EXIST(stretchPhoneObject)
DELETE_OBJECT(stretchPhoneObject)
ENDIF
IF DOES_ENTITY_EXIST(basketballObject)
DELETE_OBJECT(basketballObject)
ENDIF
IF DOES_ENTITY_EXIST(wheelObject)
DELETE_OBJECT(wheelObject)
ENDIF
IF DOES_ENTITY_EXIST(boxObject)
DELETE_OBJECT(boxObject)
ENDIF
IF DOES_ENTITY_EXIST(boxCollisionObject)
DELETE_OBJECT(boxCollisionObject)
ENDIF
IF DOES_ENTITY_EXIST(tabletObject)
DELETE_OBJECT(tabletObject)
ENDIF
REPEAT NUMBER_GONDOLAS i
IF DOES_ENTITY_EXIST(gondolaObject[i])
DELETE_OBJECT(gondolaObject[i])
ENDIF
ENDREPEAT
IF DOES_CAM_EXIST(staticCam)
DESTROY_CAM(staticCam)
ENDIF
IF DOES_CAM_EXIST(animCam)
// DESTROY_CAM(animCam)
ENDIF
IF DOES_CAM_EXIST(reactionCam)
DESTROY_CAM(reactionCam)
ENDIF
CLEAR_AREA(GET_FINALE_VECTOR(FINVEC_PLAYER_INIT), 10000, TRUE)
ENDPROC
// common stuff to clear mission
PROC COMMON_MISSION_CLEAR()
REMOVE_ALL_BLIPS()
IF IS_ENTITY_ATTACHED(PLAYER_PED_ID())
IF NOT GET_IS_PED_GADGET_EQUIPPED(PLAYER_PED_ID(), GADGETTYPE_PARACHUTE)
IF GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()) = NULL
CLEAR_PED_TASKS(PLAYER_PED_ID())
DETACH_ENTITY(PLAYER_PED_ID())
ENDIF
ENDIF
ENDIF
UNBLOCK_ALL_SELECTOR_PEDS()
CLEAR_SELECTOR_PED_PRIORITY(sSelectorPeds)
FORCE_CHASE_HINT_CAM(localChaseHintCamStruct, FALSE)
RESET_CUSTOM_CHASE_HINT_CAM_INTERP_IN_TIME(localChaseHintCamStruct)
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
SET_PED_USING_ACTION_MODE(PLAYER_PED_ID(), FALSE)
SET_SCRIPTS_SAFE_FOR_CUTSCENE(FALSE)
DISABLE_CELLPHONE(FALSE)
CLEAR_MISSION_FOR_SKIP()
ENDPROC
// handle shitskip
FUNC BOOL HANDLE_MISSION_SHITSKIP()
// new shitskip system
IF IS_REPLAY_IN_PROGRESS()
IF g_bShitskipAccepted = TRUE
CPRINTLN(DEBUG_REPLAY, "Finale 3: starting shitskip")
// get next replay stage
MISSION_STAGE_ENUM nextReplayStage
//BOOL bPassMission = FALSE
SWITCH INT_TO_ENUM(MISSION_STAGE_ENUM, Get_Replay_Mid_Mission_Stage())
CASE STAGE_FRANKLIN_HIT
g_bFinale3BHitSuccessful[CHAR_FRANKLIN] = TRUE
BREAK
CASE STAGE_TREVOR_HIT
g_bFinale3BHitSuccessful[CHAR_TREVOR] = TRUE
BREAK
CASE STAGE_MICHAEL_HIT
g_bFinale3BHitSuccessful[CHAR_MICHAEL] = TRUE
BREAK
ENDSWITCH
SWITCH INT_TO_ENUM(MISSION_STAGE_ENUM, Get_Replay_Mid_Mission_Stage())
CASE STAGE_GET_TO_HIT
CASE STAGE_FRANKLIN_HIT
CASE STAGE_TREVOR_HIT
CASE STAGE_MICHAEL_HIT
IF NOT g_bFinale3BHitSuccessful[CHAR_FRANKLIN]
nextReplayStage = STAGE_FRANKLIN_HIT
ELIF NOT g_bFinale3BHitSuccessful[CHAR_TREVOR]
nextReplayStage = STAGE_TREVOR_HIT
ELIF NOT g_bFinale3BHitSuccessful[CHAR_MICHAEL]
nextReplayStage = STAGE_MICHAEL_HIT
ELSE
nextReplayStage = STAGE_PICKUP_DEVIN
ENDIF
BREAK
CASE STAGE_PICKUP_DEVIN
nextReplayStage = STAGE_DEVINS_HOUSE
BREAK
CASE STAGE_DEVINS_HOUSE
nextReplayStage = STAGE_GET_TO_CLIFF
BREAK
CASE STAGE_GET_TO_CLIFF
nextReplayStage = STAGE_GET_TO_CLIFF
bForcePassOnShitskip = TRUE
BREAK
ENDSWITCH
// set the next mission stage nicely
COMMON_MISSION_CLEAR()
SET_MISSION_STAGE(nextReplayStage, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE)
//WAIT(SKIP_FADE_WAIT_TIME)
IF NOT bForcePassOnShitskip
IF NOT (nextReplayStage = STAGE_FRANKLIN_HIT)
AND NOT (nextReplayStage = STAGE_TREVOR_HIT)
AND NOT (nextReplayStage = STAGE_MICHAEL_HIT)
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
ENDIF
ENDIF
RETURN TRUE
ELSE
CPRINTLN(DEBUG_REPLAY, "Finale 3: no shitskip")
ENDIF
ENDIF
RETURN FALSE // did not do a shitskip
ENDFUNC
PROC NUKE_ALL_PEDS_IN_VEHICLE(VEHICLE_INDEX &veh)
INT i
PED_INDEX passengerPed
FOR i=-1 TO 2
passengerPed = GET_PED_IN_VEHICLE_SEAT(veh, INT_TO_ENUM(VEHICLE_SEAT,i))
IF DOES_ENTITY_EXIST(passengerPed)
SET_ENTITY_AS_MISSION_ENTITY(passengerPed, TRUE, TRUE)
DELETE_PED(passengerPed)
ENDIF
ENDFOR
ENDPROC
// do mission init start mission
PROC DO_MISSION_INIT_START_MISSION()
ADD_RELATIONSHIP_GROUP("Triad group", triadRelGroup)
ADD_RELATIONSHIP_GROUP("Merryweather group", merryweatherRelGroup)
ADD_RELATIONSHIP_GROUP("Gangster group", gangsterRelGroup)
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, RELGROUPHASH_PLAYER, merryweatherRelGroup)
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, merryweatherRelGroup, RELGROUPHASH_PLAYER)
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, RELGROUPHASH_PLAYER, triadRelGroup)
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, triadRelGroup, RELGROUPHASH_PLAYER)
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, RELGROUPHASH_PLAYER, gangsterRelGroup)
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, gangsterRelGroup, RELGROUPHASH_PLAYER)
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
BOOL bDoFadeIn = TRUE
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF NOT Is_Replay_In_Progress()
// no replay - kick mission off normally
#IF IS_DEBUG_BUILD
IF iDebugStage >= 0
SET_MISSION_STAGE(INT_TO_ENUM(MISSION_STAGE_ENUM, iDebugStage), TRUE)
IF iDebugStage = 0
bIsNaturalSkipToGetToHits = FALSE
ENDIF
ELSE
#ENDIF
// set the entities carried over from last mission
//IF DOES_ENTITY_EXIST(g_sTriggerSceneAssets.veh[0])
//finaleVehicle[FV_TREVOR_CAR] = g_sTriggerSceneAssets.veh[0]
//SET_ENTITY_AS_MISSION_ENTITY(finaleVehicle[FV_TREVOR_CAR], TRUE, TRUE)
//NUKE_ALL_PEDS_IN_VEHICLE(finaleVehicle[FV_TREVOR_CAR])
//ENDIF
//IF DOES_ENTITY_EXIST(g_sTriggerSceneAssets.veh[1])
// finaleVehicle[FV_MICHAEL_CAR] = g_sTriggerSceneAssets.veh[1]
// SET_ENTITY_AS_MISSION_ENTITY(finaleVehicle[FV_MICHAEL_CAR], TRUE, TRUE)
// NUKE_ALL_PEDS_IN_VEHICLE(finaleVehicle[FV_MICHAEL_CAR])
//ENDIF
IF DOES_ENTITY_EXIST(g_sTriggerSceneAssets.veh[2])
PRINTSTRING("vehicle exists") printnl()
finaleVehicle[FV_FRANKLIN_CAR] = g_sTriggerSceneAssets.veh[2]
SET_ENTITY_AS_MISSION_ENTITY(finaleVehicle[FV_FRANKLIN_CAR], TRUE, TRUE)
g_sTriggerSceneAssets.veh[2] = NULL
ELSE
//PRINTSTRING("SET PLAYER POS") printnl()
//SET_ENTITY_COORDS(PLAYER_PED_ID(), GET_FINALE_VECTOR(FINVEC_PLAYER_INIT))
//SET_ENTITY_HEADING(PLAYER_PED_ID(), PLAYER_INIT_ROT)
//SET_GAMEPLAY_CAM_RELATIVE_HEADING()
ENDIF
IF DOES_ENTITY_EXIST(g_sTriggerSceneAssets.ped[0])
sSelectorPeds.pedID[SELECTOR_PED_TREVOR] = g_sTriggerSceneAssets.ped[0]
SET_ENTITY_AS_MISSION_ENTITY(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], TRUE, TRUE)
g_sTriggerSceneAssets.ped[0] = NULL
ENDIF
IF DOES_ENTITY_EXIST(g_sTriggerSceneAssets.ped[1])
sSelectorPeds.pedID[SELECTOR_PED_MICHAEL] = g_sTriggerSceneAssets.ped[1]
SET_ENTITY_AS_MISSION_ENTITY(sSelectorPeds.pedID[SELECTOR_PED_MICHAEL], TRUE, TRUE)
g_sTriggerSceneAssets.ped[1] = NULL
ENDIF
SET_MISSION_STAGE(STAGE_GET_TO_HIT, TRUE, TRUE, TRUE, TRUE)
bIsNaturalSkipToGetToHits = FALSE
#IF IS_DEBUG_BUILD
ENDIF
#ENDIF
ELSE
IF HANDLE_MISSION_SHITSKIP()
CPRINTLN(DEBUG_REPLAY, "Finale 3: shitskip done")
IF currentMissionStage = STAGE_TREVOR_HIT
OR currentMissionStage = STAGE_FRANKLIN_HIT
OR currentMissionStage = STAGE_MICHAEL_HIT
bDoFadeIn = FALSE
ENDIF
ELSE
INT iReplayStage
iReplayStage = Get_Replay_Mid_Mission_Stage()
MISSION_STAGE_ENUM replayStage = INT_TO_ENUM(MISSION_STAGE_ENUM, iReplayStage)
IF replayStage = STAGE_TREVOR_HIT
OR replayStage = STAGE_FRANKLIN_HIT
OR replayStage = STAGE_MICHAEL_HIT
bDoFadeIn = FALSE
ENDIF
IF replayStage = STAGE_GET_TO_HIT
IF g_bFinale3BHitSuccessful[CHAR_TREVOR]
OR g_bFinale3BHitSuccessful[CHAR_FRANKLIN]
OR g_bFinale3BHitSuccessful[CHAR_MICHAEL]
bIsNaturalSkipToGetToHits = TRUE
ELSE
bIsNaturalSkipToGetToHits = FALSE
ENDIF
ENDIF
SET_MISSION_STAGE(INT_TO_ENUM(MISSION_STAGE_ENUM, iReplayStage), TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, bDoFadeIn)
// WAIT(SKIP_FADE_WAIT_TIME)
ENDIF
ENDIF
IF bDoFadeIn
AND NOT bForcePassOnShitskip
IF IS_SCREEN_FADED_OUT()
OR IS_SCREEN_FADING_OUT()
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
SHUTDOWN_LOADING_SCREEN()
ENDIF
ENDIF
ENDIF
missionInitStage = MISSION_INIT_DONE
ENDPROC
// initialise mission
FUNC BOOL INIT_MISSION()
SWITCH missionInitStage
CASE MISSION_INIT_PRE_INTRO
IF IS_BIT_SET(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_LOADED_DIRECTLY_INTO_MISSION)
IF GET_CURRENT_PLAYER_PED_ENUM() <> CHAR_FRANKLIN
VECTOR vPlayerPos
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID())
ENDIF
WHILE NOT CREATE_PLAYER_PED_ON_FOOT(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], CHAR_FRANKLIN, vPlayerPos, GET_ENTITY_HEADING(PLAYER_PED_ID()), FALSE)
WAIT(0)
ENDWHILE
WHILE NOT MAKE_SELECTOR_PED_SELECTION(sSelectorPeds, SELECTOR_PED_FRANKLIN)
WAIT(0)
ENDWHILE
WHILE NOT TAKE_CONTROL_OF_SELECTOR_PED(sSelectorPeds, TRUE)
WAIT(0)
ENDWHILE
INT i
REPEAT 3 i
IF DOES_ENTITY_EXIST(sSelectorPeds.pedID[i])
DELETE_PED(sSelectorPeds.pedID[i])
ENDIF
ENDREPEAT
ENDIF
ENDIF
CLEAR_BIT(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_LOADED_DIRECTLY_INTO_MISSION)
g_bFinaleCreditsPlaylistStarted = FALSE
REMOVE_MISSION_TEXT()
SUPPRESS_MISSION_VEHICLES(TRUE)
ENABLE_CARGENS_FOR_MISSION(FALSE)
SET_FINALE_ROADS_OFF(TRUE)
SET_WEATHER_TYPE_OVERTIME_PERSIST("extrasunny", 30.0)
IF NOT Is_Replay_In_Progress()
iReplayAttempt = 0
ELSE
iReplayAttempt = g_savedGlobals.sFlow.missionSavedData[SP_MISSION_FINALE_C2].missionFailsNoProgress + 1
ENDIF
recScenarioBlocking = ADD_SCENARIO_BLOCKING_AREA(<<-254.15, -1550.78, -10>>, <<-168.97, -1472.22, 100>>)
clubScenarioBlocking = ADD_SCENARIO_BLOCKING_AREA(<<-3063.04907, 98.93727, -10>>, <<-2966.61328, 133.85361, 28>>)
loungersScenarioBlocking = ADD_SCENARIO_BLOCKING_AREA(<<-2647.4, 1867.0,150.0>>, <<-2637.9, 1875.2, 165.2>>)
loungersScenarioBlocking2 = ADD_SCENARIO_BLOCKING_AREA(<<-2665.31128, 1856.01636, 142.52293>>, <<-2587.73145, 1923.10034, 170.43306>>)
photographerScenarioBlocking = ADD_SCENARIO_BLOCKING_AREA(<<-2558.85864, 1913.66553, 157.84938>>, <<-2551.98755, 1917.07471, 177.53345>>)
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON)
g_savedGlobals.sAmbient.iChaseHelpTextDisplayed_mission = iCHASE_HINT_HELP_DISPLAY_MAX
DO_MISSION_INIT_START_MISSION()
BREAK
CASE MISSION_INIT_DONE
REPLAY_RECORD_BACK_FOR_TIME(0.0, 10.0, REPLAY_IMPORTANCE_HIGHEST)
RETURN TRUE
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
// common start functions for creating a custom hotswap
PROC DO_COMMON_CUSTOM_HOTSWAP_START()
INT i
REPEAT NUMBER_SPLINE_CAMS i
IF DOES_CAM_EXIST(splineCam[i])
DESTROY_CAM(splineCam[i])
ENDIF
ENDREPEAT
iNumberSplineCams = 0
REPEAT COUNT_OF(sCamDetails.camInterpIDs) i
IF DOES_CAM_EXIST(sCamDetails.camInterpIDs[i])
DESTROY_CAM(sCamDetails.camInterpIDs[i])
ENDIF
ENDREPEAT
IF DOES_CAM_EXIST(sCamDetails.camID)
DESTROY_CAM(sCamDetails.camID)
ENDIF
sCamDetails.camID = CREATE_CAMERA(CAMTYPE_SPLINE_SMOOTHED, FALSE)
ENDPROC
// common end functions for creating a custom hotswap
PROC DO_COMMON_CUSTOM_HOTSWAP_END()
SET_CAM_SPLINE_PHASE(sCamDetails.camID, 0.0)
SET_CAM_SPLINE_SMOOTHING_STYLE(sCamDetails.camID, CAM_SPLINE_SLOW_IN_OUT_SMOOTH)
sCamDetails.bSplineCreated = TRUE
sCamDetails.pedTo = sSelectorPeds.pedID[sSelectorPeds.eNewSelectorPed]
sCamDetails.bRun = TRUE
ENDPROC
// add point to spline
PROC ADD_POINT_TO_SPLINE(VECTOR vPos, VECTOR vRot)
splineCam[iNumberSplineCams] = CREATE_CAMERA_WITH_PARAMS(CAMTYPE_SCRIPTED, vPos, vRot, SELECTOR_CAM_DEFAULT_FOV, TRUE)
ADD_CAM_SPLINE_NODE_USING_CAMERA(sCamDetails.camID, splineCam[iNumberSplineCams], 800)
iNumberSplineCams++
ENDPROC
PROC DO_PED_CRUISE(PED_INDEX ped)
IF NOT IS_PED_INJURED(ped)
IF IS_PED_IN_ANY_VEHICLE(ped)
VEHICLE_INDEX inVeh
inVeh = GET_VEHICLE_PED_IS_USING(ped)
IF IS_VEHICLE_DRIVEABLE(inVeh)
TASK_VEHICLE_MISSION(ped, inVeh, NULL, MISSION_CRUISE, 17.0, DRIVINGMODE_AVOIDCARS, -1, -1)
ENDIF
ENDIF
ENDIF
ENDPROC
// constantly run the hotswap selector/spline cam, and return true when selected the target ped
FUNC BOOL DO_MISSION_HOTSWAP(SELECTOR_SLOTS_ENUM targetCharacter, BOOL bInstantSwap = FALSE, HOTSWAP_CAM_ENUM hotswapCam = HOTSWAP_CAM_DEFAULT, BOOL bKeepTasks = FALSE)
SWITCH hotswapStage
CASE MISSION_HOTSWAP_STAGE_SELECT_CHARACTER
REMOVE_MISSION_TEXT(FALSE)
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
OR NOT IS_SUBTITLE_PREFERENCE_SWITCHED_ON()
CLEAR_PRINTS()
ENDIF
sSelectorPeds.bInitialised = TRUE
sSelectorPeds.eNewSelectorPed = targetCharacter
sCamDetails.pedTo = sSelectorPeds.pedID[targetCharacter]
sCamDetails.bOKToSwitchPed = FALSE
sCamDetails.bPedSwitched = FALSE
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", TRUE)
hotswapStage = MISSION_HOTSWAP_STAGE_DO_SPLINE_CAM
BREAK
CASE MISSION_HOTSWAP_STAGE_DO_SPLINE_CAM
SELECTOR_CAM_INTERP_TYPE camInterpType
IF NOT bInstantSwap
BOOL bDoingSwap
SWITCH hotswapCam
CASE HOTSWAP_CAM_DEFAULT
bDoingSwap = RUN_SWITCH_CAM_FROM_PLAYER_TO_PED(sCamDetails, DEFAULT, ENUM_TO_INT(SWITCH_FLAG_PAUSE_BEFORE_DESCENT))//, SWITCH_TYPE_LONG)//RUN_CAM_SPLINE_FROM_PLAYER_TO_PED(sCamDetails)
BREAK
CASE HOTSWAP_CAM_FREE_HOTSWAP_SPLINE
FLOAT fRelativeHeading
fRelativeHeading = 0.0
bDoingSwap = RUN_CAM_SPLINE_FROM_PLAYER_TO_PED(sCamDetails, 0.0, fRelativeHeading, camInterpType)
BREAK
ENDSWITCH
IF bDoingSwap
IF sCamDetails.bOKToSwitchPed
IF NOT sCamDetails.bPedSwitched
IF TAKE_CONTROL_OF_SELECTOR_PED(sSelectorPeds, TRUE, TRUE, TCF_CLEAR_TASK_INTERRUPT_CHECKS)
//DO_PED_CRUISE(sSelectorPeds.pedID[sSelectorPeds.ePreviousSelectorPed])
REAPPLY_PLAYER_PED_ATTRIBUTES(FALSE)
bDoingOnFootAudioScene = FALSE
bDoingDriveAudioScene = FALSE
sCamDetails.bPedSwitched = TRUE
ENDIF
ENDIF
ENDIF
ELSE
IF GET_CURRENT_PLAYER_PED_ENUM() = GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(targetCharacter)
INT i
REPEAT COUNT_OF(sCamDetails.camInterpIDs) i
IF DOES_CAM_EXIST(sCamDetails.camInterpIDs[i])
DESTROY_CAM(sCamDetails.camInterpIDs[i])
ENDIF
ENDREPEAT
REPEAT NUMBER_SPLINE_CAMS i
IF DOES_CAM_EXIST(splineCam[i])
DESTROY_CAM(splineCam[i])
ENDIF
ENDREPEAT
iNumberSplineCams = 0
IF DOES_CAM_EXIST(sCamDetails.camID)
DESTROY_CAM(sCamDetails.camID)
ENDIF
REAPPLY_PLAYER_PED_ATTRIBUTES()
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", FALSE)
hotswapStage = MISSION_HOTSWAP_STAGE_DONE
RETURN TRUE
ENDIF
ENDIF
ELSE
IF TAKE_CONTROL_OF_SELECTOR_PED(sSelectorPeds, TRUE, bKeepTasks)
sCamDetails.bPedSwitched = TRUE
REAPPLY_PLAYER_PED_ATTRIBUTES()
hotswapStage = MISSION_HOTSWAP_STAGE_DONE
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", FALSE)
RETURN TRUE
ENDIF
ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
// can we do a free hotswap
FUNC BOOL CAN_DO_FREE_HOTSWAP()
IF GET_NUMBER_BLOCKED_PEDS() < 2
OR sSelectorPeds.bBlockSelectorPed[GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(GET_CURRENT_PLAYER_PED_ENUM())]
OR freeHotswapData.state = FREE_HOTSWAP_STATE_IN_PROGRESS
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
// free hotswapping between peds
PROC HANDLE_FREE_HOTSWAP()
SWITCH freeHotswapData.state
CASE FREE_HOTSWAP_STATE_SELECTING
IF NOT bLockSelector
IF UPDATE_SELECTOR_HUD(sSelectorPeds, FALSE)
#IF IS_DEBUG_BUILD
OR bDebugJSkip
#ENDIF
IF currentMissionStage < STAGE_PICKUP_DEVIN
OR trevorDrivingToPickupStage = TREVOR_DRIVING_TO_PICKUP_DRIVING
hotswapStage = MISSION_HOTSWAP_STAGE_SELECT_CHARACTER
freeHotswapData.swapTarget = sSelectorPeds.eNewSelectorPed
freeHotswapData.state = FREE_HOTSWAP_STATE_IN_PROGRESS
enumCharacterList switchToChar
switchToChar = GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget)
switchToChar=switchToChar
INFORM_MISSION_STATS_OF_INCREMENT(FIN_SWITCHES)
IF mocapStreamingStage >= MOCAP_STREAMING_STAGE_WAIT
REMOVE_CUTSCENE()
mocapStreamingStage = MOCAP_STREAMING_STAGE_REQUEST
ENDIF
bRepositionedPreviousCharacter = FALSE
bStoppedSwitchToVehicle = FALSE
bResetAIDrive = FALSE
bDoneSecondAIDrive = FALSE
bAllowDescent = FALSE
sCamDetails.bPedSwitched = FALSE
// get closest journey point
INT iNumberJourneyPoints
iNumberJourneyPoints = GET_NUMBER_JOURNEY_POINTS(GET_CURRENT_PLAYER_PED_ENUM())
INT i
INT iClosest
iClosest = -1
FLOAT fClosestDistance
fClosestDistance = 9999999
VECTOR vCurrentPos
vCurrentPos = GET_ENTITY_COORDS(PLAYER_PED_ID())
REPEAT iNumberJourneyPoints i
FLOAT fThisDistance
fThisDistance = GET_DISTANCE_BETWEEN_COORDS(vCurrentPos, GET_JOURNEY_POS(GET_CURRENT_PLAYER_PED_ENUM(), i), FALSE)
IF fThisDistance < fClosestDistance
AND fThisDistance < OFF_PISTE_DISTANCE
fClosestDistance = fThisDistance
iClosest = i
ENDIF
ENDREPEAT
IF iClosest >= 0
iJourneyStage[GET_CURRENT_PLAYER_PED_ENUM()] = iClosest
ELSE
bIsOffPiste[GET_CURRENT_PLAYER_PED_ENUM()] = TRUE
vOffPistePos[GET_CURRENT_PLAYER_PED_ENUM()] = vCurrentPos
fOffPisteRot[GET_CURRENT_PLAYER_PED_ENUM()] = GET_ENTITY_HEADING(PLAYER_PED_ID())
ENDIF
iSwitchStartTime = GET_GAME_TIMER()
freeHotswapData.state = FREE_HOTSWAP_STATE_IN_PROGRESS
IF currentMissionStage = STAGE_GET_TO_HIT
OR currentMissionStage = STAGE_TREVOR_HIT
OR currentMissionStage = STAGE_FRANKLIN_HIT
OR currentMissionStage = STAGE_MICHAEL_HIT
//DO_PED_CRUISE(PLAYER_PED_ID())
SET_PLAYER_AI_DRIVE(GET_CURRENT_PLAYER_PED_ENUM())
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE FREE_HOTSWAP_STATE_IN_PROGRESS
// ensure crosshair doesn't display
//IF IS_PLAYER_SWITCH_IN_PROGRESS()
// IF GET_PLAYER_SWITCH_JUMP_CUT_INDEX() > 0
// printstring("hide hud 1" ) printnl()
// DISPLAY_HUD(FALSE)
// ENDIF
//ENDIF
//SWITCH_TYPE thisSwitchType
//thisSwitchType = SWITCH_TYPE_AUTO
//IF IS_PLAYER_SWITCH_IN_PROGRESS()
// thisSwitchType = GET_PLAYER_SWITCH_TYPE()
//ELSE
// thisSwitchType = SWITCH_TYPE_AUTO
//ENDIF
//printstring("Here1") printnl()
IF NOT bAllowDescent
IF IS_PLAYER_SWITCH_IN_PROGRESS()
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[freeHotswapData.swapTarget])
IF HAS_COLLISION_LOADED_AROUND_ENTITY(sSelectorPeds.pedID[freeHotswapData.swapTarget])
OR GET_GAME_TIMER() >= iSwitchStartTime + 10000
ALLOW_PLAYER_SWITCH_DESCENT()
bAllowDescent = TRUE
ENDIF
ELSE
bAllowDescent = TRUE
ENDIF
ENDIF
ENDIF
IF NOT bStoppedSwitchToVehicle
// printstring("hereA1") printnl()
BOOL bAllowSwitchToVehicle
bAllowSwitchToVehicle = TRUE
//IF IS_PLAYER_SWITCH_IN_PROGRESS()
//IF thisSwitchType = SWITCH_TYPE_SHORT
// bAllowSwitchToVehicle = FALSE
//ENDIF
//ENDIF
IF bAllowSwitchToVehicle
// printstring("hereA2") printnl()
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[freeHotswapData.swapTarget])
//printstring("hereA3") printnl()
CLEAR_PED_TASKS(sSelectorPeds.pedID[freeHotswapData.swapTarget])
//printstring("hereA4") printnl()
VEHICLE_INDEX thisVehicle
thisVehicle = finaleVehicle[GET_PLAYER_DRIVE_VEHICLE(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget))]
//printstring("hereA5") printnl()
VECTOR vClosestNodePos
vClosestNodePos=vClosestNodePos
FLOAT fClosestNodeRot
fClosestNodeRot=fClosestNodeRot
IF IS_VEHICLE_DRIVEABLE(thisVehicle)
vSwitchNodePos = GET_ENTITY_COORDS(thisVehicle)
fSwitchNodeRot = GET_ENTITY_HEADING(thisVehicle)
ENDIF
IF g_bFinale3BHitSuccessful[CHAR_TREVOR]
AND GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget) = CHAR_TREVOR
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_FINALE_VECTOR(FINVEC_TREVOR_CAR_DRIVE_TO_PICKUP), FALSE) > 300
vSwitchNodePos = GET_FINALE_VECTOR(FINVEC_TREVOR_CAR_DRIVE_TO_PICKUP)
fSwitchNodeRot = TREVOR_CAR_DRIVE_TO_PICKUP_ROT
ELSE
vSwitchNodePos = <<-2066.36, 2011.39, 190.49>>
fSwitchNodeRot = 104.63
ENDIF
ELSE
IF NOT bIsOffPiste[freeHotswapData.swapTarget]
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_JOURNEY_POS(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget), iJourneyStage[GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget)]), FALSE) > MIN_SWITCH_DIST
ELSE
// need to find a good point far enough away
INT iClosest
iClosest = -1
FLOAT fClosestDistance
fClosestDistance = 99999999.0
INT iNumberJourneyPoints
iNumberJourneyPoints = GET_NUMBER_JOURNEY_POINTS(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget))
INT i
REPEAT iNumberJourneyPoints i
IF i <> iJourneyStage[GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget)]
FLOAT fThisDistance
fThisDistance = GET_DISTANCE_BETWEEN_COORDS(GET_JOURNEY_POS(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget), iJourneyStage[GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget)]), GET_JOURNEY_POS(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget), i), FALSE)
IF i < iJourneyStage[GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget)]
fThisDistance += 2000
ENDIF
IF fThisDistance < fClosestDistance
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_JOURNEY_POS(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget), i), FALSE) > MIN_SWITCH_DIST
fClosestDistance = fThisDistance
iClosest = i
ENDIF
ENDIF
ENDIF
ENDREPEAT
IF iClosest >= 0
//PRINTSTRING("SETTING JURNEY STAGE TO ") PRINTINT(iClosest) PRINTNL()
iJourneyStage[GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget)] = iClosest
ENDIF
ENDIF
vSwitchNodePos = GET_JOURNEY_POS(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget), iJourneyStage[GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget)])
fSwitchNodeRot = GET_JOURNEY_ROT(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget), iJourneyStage[GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget)])
ELSE
vSwitchNodePos = vOffPistePos[freeHotswapData.swapTarget]
fSwitchNodeRot = fOffPisteRot[freeHotswapData.swapTarget]
ENDIF
ENDIF
IF IS_VEHICLE_DRIVEABLE(thisVehicle)
IF NOT IS_PED_IN_VEHICLE(sSelectorPeds.pedID[freeHotswapData.swapTarget], thisVehicle)
SET_PED_INTO_VEHICLE(sSelectorPeds.pedID[freeHotswapData.swapTarget], thisVehicle)
ENDIF
//printstring("hereA8") printnl()
SET_VEHICLE_USE_MORE_RESTRICTIVE_SPAWN_CHECKS(thisVehicle, TRUE)
SET_ENTITY_COORDS(thisVehicle, vSwitchNodePos)
SET_ENTITY_HEADING(thisVehicle, fSwitchNodeRot)
SET_VEHICLE_ON_GROUND_PROPERLY(thisVehicle)
FREEZE_ENTITY_POSITION(thisVehicle, TRUE)
SET_ENTITY_VISIBLE(thisVehicle, FALSE)
SET_ENTITY_VISIBLE(sSelectorPeds.pedID[freeHotswapData.swapTarget], FALSE)
ELSE
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), vLastSwitchPos[GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget)], FALSE) > MIN_SWITCH_DIST
SET_ENTITY_COORDS_NO_OFFSET(sSelectorPeds.pedID[freeHotswapData.swapTarget], vLastSwitchPos[GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget)])
SET_ENTITY_HEADING(sSelectorPeds.pedID[freeHotswapData.swapTarget], fLastSwitchRot[GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(freeHotswapData.swapTarget)])
ELSE
SET_ENTITY_COORDS_NO_OFFSET(sSelectorPeds.pedID[freeHotswapData.swapTarget], vSwitchNodePos)
SET_ENTITY_HEADING(sSelectorPeds.pedID[freeHotswapData.swapTarget], fSwitchNodeRot)
ENDIF
ENDIF
ENDIF
ENDIF
bStoppedSwitchToVehicle = TRUE
ENDIF
VECTOR vHideCoords
IF NOT bRepositionedPreviousCharacter
IF sCamDetails.bPedSwitched
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[sSelectorPeds.ePreviousSelectorPed])
vLastSwitchPos[GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(sSelectorPeds.ePreviousSelectorPed)] = GET_ENTITY_COORDS(sSelectorPeds.pedID[sSelectorPeds.ePreviousSelectorPed])
fLastSwitchRot[GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(sSelectorPeds.ePreviousSelectorPed)] = GET_ENTITY_HEADING(sSelectorPeds.pedID[sSelectorPeds.ePreviousSelectorPed])
IF sSelectorPeds.ePreviousSelectorPed = SELECTOR_PED_TREVOR
AND g_bFinale3BHitSuccessful[CHAR_TREVOR]
vLastSwitchPos[CHAR_TREVOR] = <<-2601.99, 1685.07, 140.71>>
fLastSwitchRot[CHAR_TREVOR] = 5.86
ENDIF
vHideCoords = GET_PLAYER_HIDE_POS(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(sSelectorPeds.ePreviousSelectorPed))
VEHICLE_INDEX thisVehicle
thisVehicle = finaleVehicle[GET_PLAYER_DRIVE_VEHICLE(GET_PLAYER_PED_ENUM_FROM_SELECTOR_SLOT(sSelectorPeds.ePreviousSelectorPed))]
IF IS_VEHICLE_DRIVEABLE(thisVehicle)
//printstring("hereA4") printnl()
IF NOT IS_PED_IN_VEHICLE(sSelectorPeds.pedID[sSelectorPeds.ePreviousSelectorPed], thisVehicle)
SET_PED_INTO_VEHICLE(sSelectorPeds.pedID[sSelectorPeds.ePreviousSelectorPed], thisVehicle)
ENDIF
SET_ENTITY_COORDS(thisVehicle, vHideCoords)
FREEZE_ENTITY_POSITION(thisVehicle, TRUE)
ELSE
SET_ENTITY_COORDS(sSelectorPeds.pedID[sSelectorPeds.ePreviousSelectorPed], vHideCoords)
FREEZE_ENTITY_POSITION(sSelectorPeds.pedID[sSelectorPeds.ePreviousSelectorPed], TRUE)
ENDIF
ENDIF
REMOVE_ALL_BLIPS()
bRepositionedPreviousCharacter = TRUE
ENDIF
ENDIF
//printstring("switch state = ") PRINTINT(GET_PLAYER_SWITCH_JUMP_CUT_INDEX()) PRINTNL()
VEHICLE_INDEX thisVehicle
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
thisVehicle = GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())
ENDIF
IF NOT bResetAIDrive
OR NOT bDoneSecondAIDrive
//printstring("hereB1") printnl()
IF sCamDetails.bPedSwitched
//printstring("hereB2") printnl()
BOOL bAllowResetAIDrive
bAllowResetAIDrive = FALSE
IF bStoppedSwitchToVehicle
//printstring("hereB3") printnl()
IF IS_PLAYER_SWITCH_IN_PROGRESS()
AND bAllowDescent
//printstring("hereB4") printnl()
//IF thisSwitchType = SWITCH_TYPE_LONG
//printstring("hereB5") printnl()
IF (GET_PLAYER_SWITCH_JUMP_CUT_INDEX() = 0 AND NOT bResetAIDrive)
OR GET_PLAYER_SWITCH_STATE() >= SWITCH_STATE_OUTRO_HOLD
//printstring("hereB6") printnl()
IF bResetAIDrive
bDoneSecondAIDrive = TRUE
ENDIF
bAllowResetAIDrive = TRUE
ENDIF
//ELIF thisSwitchType = SWITCH_TYPE_MEDIUM
//printstring("hereB7") printnl()
// IF GET_PLAYER_SWITCH_STATE() >= SWITCH_STATE_OUTRO_HOLD
//printstring("hereB8") printnl()
// bAllowResetAIDrive = TRUE
// bDoneSecondAIDrive = TRUE
// ENDIF
//ENDIF
ENDIF
ENDIF
//IF thisSwitchType = SWITCH_TYPE_SHORT
// bAllowResetAIDrive = TRUE
// bDoneSecondAIDrive = TRUE
///ENDIF
IF bAllowResetAIDrive
//printstring("hereC1") printnl()
SET_ENTITY_VISIBLE(PLAYER_PED_ID(), TRUE)
IF NOT IS_ENTITY_DEAD(thisVehicle)
SET_ENTITY_VISIBLE(thisVehicle, TRUE)
ENDIF
IF IS_VEHICLE_DRIVEABLE(thisVehicle)
//printstring("hereC2") printnl()
IF HAS_COLLISION_LOADED_AROUND_ENTITY(thisVehicle)
//printstring("hereC3") printnl()
//printstring("hereC4") printnl()
FLOAT fOverrideDriveSpeed
BOOL bReposition
bReposition = FALSE
fOverrideDriveSpeed = DRIVE_TO_TARGET_SPEED
IF IS_PLAYER_SWITCH_IN_PROGRESS()
//IF thisSwitchType = SWITCH_TYPE_LONG
//OR thisSwitchType = SWITCH_TYPE_MEDIUM
IF NOT bDoneSecondAIDrive
OR NOT IS_ENTITY_AT_COORD(thisVehicle, vSwitchNodePos, <<10,10,10>>)
bReposition = TRUE
fOverrideDriveSpeed = 8
ENDIF
//ENDIF
ENDIF
//SCRIPT_ASSERT("do AI drive!")
printstring("do AI drive") printnl()
//DO_PED_CRUISE(PLAYER_PED_ID())
SET_PLAYER_AI_DRIVE(GET_CURRENT_PLAYER_PED_ENUM(), fOverrideDriveSpeed, bReposition, TRUE)
ENDIF
ELSE
IF HAS_COLLISION_LOADED_AROUND_ENTITY(PLAYER_PED_ID())
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), FALSE)
SET_ENTITY_COORDS_NO_OFFSET(PLAYER_PED_ID(), vLastSwitchPos[GET_CURRENT_PLAYER_PED_ENUM()])
SET_ENTITY_HEADING(PLAYER_PED_ID(), fLastSwitchRot[GET_CURRENT_PLAYER_PED_ENUM()])
CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID())
FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID())
ENDIF
ENDIF
bResetAIDrive = TRUE
ENDIF
ENDIF
ENDIF
IF bResetAIDrive
IF sCamDetails.bPedSwitched
IF IS_VEHICLE_DRIVEABLE(thisVehicle)
IF HAS_COLLISION_LOADED_AROUND_ENTITY(thisVehicle)
//IF thisSwitchType <> SWITCH_TYPE_SHORT
//AND thisSwitchType <> SWITCH_TYPE_AUTO
SET_VEHICLE_FORWARD_SPEED(thisVehicle, POST_SWITCH_SPEED)
//ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
IF currentMissionStage = STAGE_GET_TO_HIT
OR currentMissionStage = STAGE_TREVOR_HIT
OR currentMissionStage = STAGE_FRANKLIN_HIT
OR currentMissionStage = STAGE_MICHAEL_HIT
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.4)
ENDIF
BOOL bDoneHotswap
bDoneHotswap = FALSE
bDoneHotswap = DO_MISSION_HOTSWAP(freeHotswapData.swapTarget, FALSE, HOTSWAP_CAM_DEFAULT, TRUE)
IF bDoneHotswap
thisVehicle = finaleVehicle[GET_PLAYER_DRIVE_VEHICLE(GET_CURRENT_PLAYER_PED_ENUM())]
IF NOT bUnblockedGPS[GET_CURRENT_PLAYER_PED_ENUM()]
SET_GPS_DISABLED_ZONE(GET_MIN_GPS_BLOCK_AREA_COORDS(GET_CURRENT_PLAYER_PED_ENUM()), GET_MAX_GPS_BLOCK_AREA_COORDS(GET_CURRENT_PLAYER_PED_ENUM()))
ENDIF
IF IS_VEHICLE_DRIVEABLE(thisVehicle)
RESET_VEHICLE_STUCK_TIMER(thisVehicle, VEH_STUCK_JAMMED)
RESET_VEHICLE_STUCK_TIMER(thisVehicle, VEH_STUCK_HUNG_UP)
RESET_VEHICLE_STUCK_TIMER(thisVehicle, VEH_STUCK_ON_SIDE)
RESET_VEHICLE_STUCK_TIMER(thisVehicle, VEH_STUCK_ON_ROOF)
SET_VEHICLE_USE_MORE_RESTRICTIVE_SPAWN_CHECKS(thisVehicle, FALSE)
FREEZE_ENTITY_POSITION(thisVehicle, FALSE)
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(thisVehicle)
STOP_PLAYBACK_RECORDED_VEHICLE(thisVehicle)
ENDIF
ENDIF
bIsOffPiste[GET_CURRENT_PLAYER_PED_ENUM()] = FALSE
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), FALSE)
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
REMOVE_ALL_BLIPS()
bShownSwitchPrompt = FALSE
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_WaitingForPlayerControlInterrupt, TRUE)
DISPLAY_HUD(TRUE)
DISPLAY_RADAR(TRUE)
freeHotswapData.state = FREE_HOTSWAP_STATE_SELECTING
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
iForceLamarCallTime = GET_GAME_TIMER() + 5000
ENDIF
CLEAR_PED_TASKS(PLAYER_PED_ID())
SET_PED_CAN_SWITCH_WEAPON(PLAYER_PED_ID(), TRUE)
ENDIF
BREAK
ENDSWITCH
ENDPROC
// store banter
FUNC BOOL STORE_BANTER()
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
TEXT_LABEL_23 tBanter = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT()
IF ARE_STRINGS_EQUAL(tBanter, "FINC1_DEVTAK")
bSavedBanter = TRUE
tSavedBanterRoot = tBanter
tResumeBanterLabel = GET_STANDARD_CONVERSATION_LABEL_FOR_FUTURE_RESUMPTION()
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
// restore banter
FUNC BOOL RESTORE_BANTER()
IF bSavedBanter
IF CAN_ADVANCE_MISSION()
IF CREATE_CONVERSATION_FROM_SPECIFIC_LINE(finaleConversation, "FINC1AU", tSavedBanterRoot, tResumeBanterLabel, CONV_PRIORITY_HIGH)
RETURN TRUE
ENDIF
ENDIF
ELSE
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
// handle text for on bike
FUNC BOOL HANDLE_GET_TO_LOCATION(BOOL bWithVehicle, BOOL bWithBuddy, BOOL bEnforceWantedLevel = FALSE)
FINALE_VEHICLE_ENUM vehicleEnum
enumCharacterList currentPlayer = GET_CURRENT_PLAYER_PED_ENUM()
SELECTOR_SLOTS_ENUM buddyEnum
BOOL bPlayerVehicleOK = TRUE
BOOL bBuddyVehicleOK = TRUE
BOOL bBuddyGroupOK = TRUE
BOOL bWantedLevelOK = TRUE
BOOL bOverallOK = TRUE
BOOL bAllOK = FALSE
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL
vehicleEnum = FV_MICHAEL_CAR
BREAK
CASE CHAR_FRANKLIN
vehicleEnum = FV_FRANKLIN_CAR
BREAK
CASE CHAR_TREVOR
IF currentMissionStage = STAGE_GET_TO_CLIFF
vehicleEnum = FV_DEVIN_CAR
ELSE
vehicleEnum = FV_TREVOR_CAR
ENDIF
BREAK
ENDSWITCH
IF bWithBuddy
bBuddyGroupOK = FALSE
ENDIF
IF bWithVehicle
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[vehicleEnum])
IF bWithBuddy
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[buddyEnum])
IF NOT IS_PED_IN_VEHICLE(sSelectorPeds.pedID[buddyEnum], finaleVehicle[vehicleEnum])
bBuddyVehicleOK = FALSE
ENDIF
ENDIF
ENDIF
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), finaleVehicle[vehicleEnum])
bPlayerVehicleOK = FALSE
ENDIF
ELSE
bOverallOK = FALSE
ENDIF
ENDIF
IF bEnforceWantedLevel
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0
bWantedLevelOK = FALSE
ENDIF
ENDIF
IF bOverallOK
IF bBuddyGroupOK
// buddy is group member / not required to be in group
IF bPlayerVehicleOK
// player is in vehicle
IF iGetInTextStage[currentPlayer] < 2
iGetInTextStage[currentPlayer] = 2
ENDIF
IF bBuddyVehicleOK
IF bWantedLevelOK
bAllOK = TRUE
IF NOT IS_PLAYER_BROWSING_ITEMS_IN_ANY_SHOP()
bRemovedBlipsForWanted = FALSE
bShownLoseWantedPrompt = FALSE
RETURN TRUE
ENDIF
ELSE
IF NOT bRemovedBlipsForWanted
REMOVE_ALL_BLIPS()
bRemovedBlipsForWanted = TRUE
ELSE
REMOVE_CAR_BLIP_AND_TEXT()
ENDIF
//IF NOT bKilledConversationOnWanted
// STORE_BANTER()
// KILL_ANY_CONVERSATION()
// REMOVE_MISSION_TEXT(FALSE, TRUE, FALSE)
// bKilledConversationOnWanted = TRUE
//ELSE
IF NOT bShownLoseWantedPrompt
bShownLoseWantedPrompt = DO_MISSION_GOD_TEXT("LOSE_WANTED")
ENABLE_DISPATCH_SERVICE(DT_POLICE_AUTOMOBILE, TRUE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_VEHICLE_REQUEST, TRUE)
SET_CREATE_RANDOM_COPS(TRUE)
ENDIF
//ENDIF
ENDIF
ENDIF
ELSE
// player is not in the vehicle - blip it
IF NOT DOES_BLIP_EXIST(vehicleBlip)
REMOVE_MISSION_TEXT(FALSE, TRUE, FALSE)
REMOVE_ALL_BLIPS()
IF iGetInTextStage[currentPlayer] = 0
OR iGetInTextStage[currentPlayer] = 2
bShouldDoGetInText = TRUE
ENDIF
vehicleBlip = CREATE_MISSION_BLIP_FOR_VEHICLE(finaleVehicle[vehicleEnum])
ENDIF
IF bShouldDoGetInText
STRING sGetInString
SWITCH iGetInTextStage[currentPlayer]
CASE 0
SWITCH vehicleEnum
CASE FV_FRANKLIN_CAR
sGetInString = "CMN_GENGETINBK"
BREAK
CASE FV_MICHAEL_CAR
sGetInString = "CMN_MGETIN"
BREAK
CASE FV_TREVOR_CAR
sGetInString = "CMN_TGETIN"
BREAK
CASE FV_DEVIN_CAR
sGetInString = "FC2_GODCAR1"
BREAK
ENDSWITCH
BREAK
CASE 2
SWITCH vehicleEnum
CASE FV_FRANKLIN_CAR
sGetInString = "CMN_GENGETBCKBK"
BREAK
CASE FV_MICHAEL_CAR
sGetInString = "CMN_MGETBCK"
BREAK
CASE FV_TREVOR_CAR
sGetInString = "CMN_TGETBCK"
BREAK
CASE FV_DEVIN_CAR
sGetInString = "FC2_GODCAR2"
BREAk
ENDSWITCH
BREAK
ENDSWITCH
IF bDoneGotoSpeech
OR currentMissionStage <> STAGE_GET_TO_CLIFF
IF DO_MISSION_GOD_TEXT(sGetInString)
bShouldDoGetInText = FALSE
iGetInTextStage[currentPlayer]++
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
IF NOT bBuddyGroupOK
// lamar is not group member
ENDIF
IF NOT bAllOK
IF NOT bSavedBanter
IF STORE_BANTER()
KILL_ANY_CONVERSATION()
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
// have all hits succeeded
FUNC BOOL HAVE_ALL_HITS_SUCCEEDED()
BOOL bAllDone = TRUE
INT i
REPEAT 3 i
IF NOT g_bFinale3BHitSuccessful[i]
bAllDone = FALSE
ENDIF
ENDREPEAT
RETURN bAllDone
ENDFUNC
// get correct string for switch text
FUNC STRING GET_STRING_FOR_SWITCH_PROMPT()
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
// michael
CASE CHAR_MICHAEL
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_TREVOR]
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_FRANKLIN]
RETURN "FC2_SWTF"
ELSE
RETURN "FC2_SWT"
ENDIF
ELSE
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_FRANKLIN]
RETURN "FC2_SWF"
ENDIF
ENDIF
BREAK
// franklin
CASE CHAR_FRANKLIN
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_TREVOR]
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_MICHAEL]
RETURN "FC2_SWMT"
ELSE
RETURN "FC2_SWT"
ENDIF
ELSE
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_MICHAEL]
RETURN "FC2_SWM"
ENDIF
ENDIF
BREAK
// trevor
CASE CHAR_TREVOR
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_MICHAEL]
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_FRANKLIN]
RETURN "FC2_SWMF"
ELSE
RETURN "FC2_SWM"
ENDIF
ELSE
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_FRANKLIN]
RETURN "FC2_SWF"
ENDIF
ENDIF
BREAK
ENDSWITCH
RETURN "BADSTRING"
ENDFUNC
// ask who to assassinate next
FUNC BOOL DO_WHO_NEXT_QUESTION_SPEECH()
STRING sString
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
// michael
CASE CHAR_MICHAEL
IF HAVE_ALL_HITS_SUCCEEDED()
sString = "FINC1_WF"
ELSE
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_TREVOR]
sString = "FINC1_WF"
ELSE
sString = "FINC1_WT"
ENDIF
ENDIF
BREAK
// franklin
CASE CHAR_FRANKLIN
IF HAVE_ALL_HITS_SUCCEEDED()
sString = "FINC1_WM"
ELSE
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_TREVOR]
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_MICHAEL]
sString = "FINC1_WT"
ELSE
sString = "FINC1_WM"
ENDIF
ELSE
sString = "FINC1_WT"
ENDIF
ENDIF
BREAK
// trevor
CASE CHAR_TREVOR
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_MICHAEL]
sString = "FINC1_WF"
ELSE
sString = "FINC1_WM"
ENDIF
BREAK
ENDSWITCH
RETURN DO_MISSION_SPEECH(sString)
ENDFUNC
// answer who to assassinate next
FUNC BOOL DO_WHO_NEXT_ANSWER_SPEECH()
STRING sString
IF NOT HAVE_ALL_HITS_SUCCEEDED()
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
// michael
CASE CHAR_MICHAEL
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_TREVOR]
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_FRANKLIN]
sString = "FINC1_NFT"
ELSE
sString = "FINC1_NT"
ENDIF
ELSE
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_FRANKLIN]
sString = "FINC1_NF"
ENDIF
ENDIF
BREAK
// franklin
CASE CHAR_FRANKLIN
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_TREVOR]
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_MICHAEL]
sString = "FINC1_NTM"
ELSE
sString = "FINC1_NT"
ENDIF
ELSE
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_MICHAEL]
sString = "FINC1_NM"
ENDIF
ENDIF
BREAK
// trevor
CASE CHAR_TREVOR
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_MICHAEL]
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_FRANKLIN]
sString = "FINC1_NFM"
ELSE
sString = "FINC1_NM"
ENDIF
ELSE
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_FRANKLIN]
sString = "FINC1_NF"
ENDIF
ENDIF
BREAK
ENDSWITCH
ELSE
sString = "FINC1_ND"
ENDIF
RETURN DO_MISSION_SPEECH(sString)
ENDFUNC
// handle create hits
PROC HANDLE_CREATE_HITS(BOOL bAllowDelete)
INT i
REPEAT 3 i
enumCharacterList thisChar = INT_TO_ENUM(enumCharacterList, i)
VECTOR vHitPos
SWITCH thisChar
CASE CHAR_MICHAEL
vHitPos = GET_FINALE_VECTOR(FINVEC_REC)
BREAK
CASE CHAR_FRANKLIN
vHitPos = GET_FINALE_VECTOR(FINVEC_CLUB)
BREAK
CASE CHAR_TREVOR
vHitPos = GET_FINALE_VECTOR(FINVEC_GONDOLA)
BREAK
ENDSWITCH
SWITCH createHitStage[thisChar]
CASE CREATE_HIT_STAGE_NOT_STARTED
IF NOT g_bFinale3BHitSuccessful[thisChar]
IF currentMissionStage = STAGE_GET_TO_HIT
OR thisChar = GET_CURRENT_PLAYER_PED_ENUM()
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vHitPos, <<300,300,300>>, FALSE, FALSE)
IF thisChar <> CHAR_FRANKLIN
OR GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
// request the assets
SWITCH thisChar
CASE CHAR_MICHAEL
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_STRETCH))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_GANGSTER))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_GANGSTER_CAR))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_STRETCH_PHONE))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_BASKETBALL))
//ADD_MODEL_REQUEST(ENUM_TO_INT(FM_STRETCH_CAR))
ADD_ANIM_DICT_REQUEST(F_ANIM_DICT_GANGSTERS)
ADD_ANIM_DICT_REQUEST(F_ANIM_DICT_GANGSTERS_PHONE)
ADD_ANIM_DICT_REQUEST(F_ANIM_DICT_REACT_INTRO)
ADD_ANIM_DICT_REQUEST(F_ANIM_DICT_REACT_FLEE)
//ADD_ANIM_DICT_REQUEST(F_ANIM_DICT_GANGSTERS_BBALL)
ADD_WAYPOINT_REQUEST(1-1)
ADD_WAYPOINT_REQUEST(2-1)
ADD_WAYPOINT_REQUEST(3-1)
BREAK
CASE CHAR_FRANKLIN
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_CHENG_SR))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_CHENG_JR))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_TRIAD))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_TRIAD_BOSS_CAR))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_TRIAD_ESCORT_CAR))
ADD_ANIM_DICT_REQUEST(F_ANIM_DICT_TRIADS_INTO_CARS)
// ADD_ANIM_DICT_REQUEST(F_ANIM_DICT_TRIADS_IDLE)
ADD_WAYPOINT_REQUEST(4-1)
BREAK
CASE CHAR_TREVOR
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_STEVE))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_CAMERAMAN))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_BYSTANDER))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_COP))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_CAMERA))
ADD_ANIM_DICT_REQUEST(F_ANIM_DICT_STEVE_FILMING)
ADD_ANIM_DICT_REQUEST(F_ANIM_DICT_STEVE_SPEECH)
ADD_ANIM_DICT_REQUEST(F_ANIM_DICT_STEVE_REACT)
ADD_ANIM_DICT_REQUEST(F_ANIM_DICT_STEVE_DEATH)
ADD_ANIM_DICT_REQUEST(F_ANIM_DICT_CAMERAMAN_REACT)
ADD_ANIM_DICT_REQUEST(F_ANIM_DICT_WHEEL_BYSTANDERS)
ADD_SFX_REQUEST(F_SFX_STEVE_DEATH)
BREAK
ENDSWITCH
createHitStage[thisChar] = CREATE_HIT_STAGE_WAITING
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE CREATE_HIT_STAGE_WAITING
IF NOT g_bFinale3BHitSuccessful[thisChar]
IF HAVE_ALL_MODEL_REQUESTS_SUCCEEDED()
AND HAVE_ALL_ANIM_DICT_REQUESTS_SUCCEEDED()
AND HAVE_ALL_WAYPOINT_REQUESTS_SUCCEEDED()
SWITCH thisChar
CASE CHAR_MICHAEL
CREATE_GANGSTERS(currentMissionStage)
BREAK
CASE CHAR_FRANKLIN
CREATE_TRIADS(currentMissionStage)
BREAK
CASE CHAR_TREVOR
CREATE_STEVE()
BREAK
ENDSWITCH
IF bDoFadeInOnHitCreation
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
bDoFadeInOnHitCreation = FALSE
ENDIF
//[MF] Load Death Cam Assets
IF thisChar = CHAR_TREVOR
eSwitchCamState = SWITCH_CAM_REQUEST_ASSETS
HANDLE_SWITCH_CAM_BULLET_CAM(scsSwitchCamBulletCam)
ENDIF
createHitStage[thisChar] = CREATE_HIT_STAGE_DONE
ENDIF
ENDIF
BREAK
CASE CREATE_HIT_STAGE_DONE
IF bAllowDelete
OR GET_CURRENT_PLAYER_PED_ENUM() <> thisChar
IF NOT IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vHitPos, <<350,350,350>>, FALSE, FALSE)
SWITCH thisChar
CASE CHAR_MICHAEL
DELETE_GANGSTERS()
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_STRETCH))
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_GANGSTER))
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_STRETCH_PHONE))
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_BASKETBALL))
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_GANGSTER_CAR))
//CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_STRETCH_CAR))
CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_GANGSTERS)
CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_GANGSTERS_PHONE)
// CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_GANGSTERS_BBALL)
CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_REACT_INTRO)
CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_REACT_FLEE)
CLEAR_WAYPOINT_REQUEST(1-1)
CLEAR_WAYPOINT_REQUEST(2-1)
CLEAR_WAYPOINT_REQUEST(3-1)
BREAK
CASE CHAR_FRANKLIN
DELETE_TRIADS()
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_CHENG_SR))
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_CHENG_JR))
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_TRIAD))
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_TRIAD_BOSS_CAR))
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_TRIAD_ESCORT_CAR))
CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_TRIADS_INTO_CARS)
// CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_TRIADS_IDLE)
CLEAR_WAYPOINT_REQUEST(4-1)
BREAK
CASE CHAR_TREVOR
DELETE_STEVE()
DELETE_WHEEL_BYSTANDERS()
DELETE_PIER_COPS()
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_STEVE))
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_CAMERAMAN))
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_BYSTANDER))
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_CAMERA))
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_COP))
CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_STEVE_FILMING)
CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_STEVE_SPEECH)
CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_STEVE_REACT)
CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_STEVE_DEATH)
CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_CAMERAMAN_REACT)
CLEAR_ANIM_DICT_REQUEST(F_ANIM_DICT_WHEEL_BYSTANDERS)
CLEAR_SFX_REQUEST(F_SFX_STEVE_DEATH)
BREAK
ENDSWITCH
createHitStage[thisChar] = CREATE_HIT_STAGE_NOT_STARTED
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDREPEAT
ENDPROC
// common stuff for cutscene skip
PROC HANDLE_SKIP_CUTSCENE()
IF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED()
AND GET_GAME_TIMER() >= iAllowSkipCutsceneTime + 1000
DO_SCREEN_FADE_OUT(DEFAULT_FADE_TIME)
WHILE NOT IS_SCREEN_FADED_OUT()
WAIT(0)
ENDWHILE
HANG_UP_AND_PUT_AWAY_PHONE()
KILL_ANY_CONVERSATION()
bSkippedCutscene = TRUE
cutsceneStage = F_CUT_STAGE_CLEANUP
ENDIF
ENDPROC
// handle steve state
PROC HANDLE_STEVE_STATE()
IF createHitStage[CHAR_TREVOR] = CREATE_HIT_STAGE_DONE
bPlayerShootingInArea = FALSE
IF IS_PED_SHOOTING_IN_AREA(PLAYER_PED_ID(), <<-1878.22058, -1214.36646, -100.01662>>, <<-1479.24622, -977.38129, 100.11576>>, FALSE)
WEAPON_TYPE currentPlayerWeapon
GET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), currentPlayerWeapon)
IF NOT IS_PED_CURRENT_WEAPON_SILENCED(PLAYER_PED_ID())
AND currentPlayerWeapon <> WEAPONTYPE_STICKYBOMB
AND currentPlayerWeapon <> WEAPONTYPE_GRENADE
AND currentPlayerWeapon <> WEAPONTYPE_SMOKEGRENADE
AND currentPlayerWeapon <> WEAPONTYPE_BZGAS
AND currentPlayerWeapon <> WEAPONTYPE_MOLOTOV
AND currentPlayerWeapon <> WEAPONTYPE_STUNGUN
bPlayerShootingInArea = TRUE
ENDIF
ENDIF
INT i
REPEAT COUNT_OF(STEVE_ENUM) i
STEVE_ENUM thisEnum = INT_TO_ENUM(STEVE_ENUM, i)
IF NOT IS_PED_INJURED(stevePed[thisEnum])
IF NOT bSteveDead[thisEnum]
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(stevePed[i], PLAYER_PED_ID())
#IF IS_DEBUG_BUILD
OR bDEBUG_ForceBulletKillSteve
#ENDIF
IF CAN_ADVANCE_MISSION()
IF thisEnum = STEVE_TARGET
// steve
CREATE_SYNCED_SCENE_ATTACHED_TO_GONDOLA(iSteveSyncScene, FALSE)
TASK_SYNCHRONIZED_SCENE(stevePed[i], iSteveSyncScene, GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_STEVE_DEATH), "Death_Steve", NORMAL_BLEND_IN, NORMAL_BLEND_OUT)
REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(stevePed[i])
ELSE
// cameraman
CREATE_SYNCED_SCENE_ATTACHED_TO_GONDOLA(iCameramanSyncScene, FALSE)
TASK_SYNCHRONIZED_SCENE(stevePed[i], iCameramanSyncScene, GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_STEVE_DEATH), "Death_CamMan", NORMAL_BLEND_OUT, NORMAL_BLEND_OUT)
ENDIF
SET_PED_CAN_BE_TARGETTED(stevePed[i], FALSE)
SET_ENTITY_PROOFS(stevePed[i], TRUE, TRUE, TRUE, TRUE, TRUE)
STOP_PED_SPEAKING(stevePed[i], TRUE)
iAllowGondolaReactTime = GET_GAME_TIMER() + 100
iSteveDeadTime = GET_GAME_TIMER()
bSteveDead[i] = TRUE
IF thisEnum = STEVE_TARGET
IF NOT IS_PED_INJURED(stevePed[i])
IF IS_PED_IN_CURRENT_CONVERSATION(stevePed[i])
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
ENDIF
ENDIF
bSwitchCam_SteveKilledViaExplosion = FALSE
bSwitchCam_SteveKilledViaGrenade = FALSE
IF NOT IS_PED_INJURED(stevePed[STEVE_TARGET])
PRINTSTRING("STEVE = ") PRINTVECTOR(GET_ENTITY_COORDS(stevePed[STEVE_TARGET])) printnl()
IF IS_EXPLOSION_IN_SPHERE(EXP_TAG_DONTCARE, GET_ENTITY_COORDS(stevePed[STEVE_TARGET]), 30.0) //[MF] Any Explosion...
IF IS_EXPLOSION_IN_SPHERE(EXP_TAG_GRENADE, GET_ENTITY_COORDS(stevePed[STEVE_TARGET]), 30.0)//[MF] ...Making a special case for grenades.
OR IS_EXPLOSION_IN_SPHERE(EXP_TAG_GRENADELAUNCHER, GET_ENTITY_COORDS(stevePed[STEVE_TARGET]), 30.0)//[MF] ...Making a special case for grenades.
printstring("here1") printnl()
bSwitchCam_SteveKilledViaGrenade = TRUE
ELIF IS_EXPLOSION_IN_SPHERE(EXP_TAG_BULLET, GET_ENTITY_COORDS(stevePed[STEVE_TARGET]), 30.0)//[MF] ...Provided it isn't a bullet.
OR IS_EXPLOSION_IN_SPHERE(EXP_TAG_VEHICLE_BULLET, GET_ENTITY_COORDS(stevePed[STEVE_TARGET]), 30.0)//[MF] ...Provided it isn't a bullet.
printstring("here2") printnl()
bSwitchCam_SteveKilledViaExplosion = FALSE
ELSE
printstring("here3") printnl()
bSwitchCam_SteveKilledViaExplosion = TRUE
ENDIF
ELSE
printstring("here4") printnl()
bSwitchCam_SteveKilledViaExplosion = FALSE
ENDIF
ELSE
printstring("here5") printnl()
bSwitchCam_SteveKilledViaExplosion = TRUE
ENDIF
ENDIF
ENDIF
#IF IS_DEBUG_BUILD
bDEBUG_ForceBulletKillSteve = FALSE
bDEBUG_ForceExplosionKillSteve = FALSE
#ENDIF
ELSE
SWITCH steveState[thisEnum]
CASE STEVE_STATE_SPEECH
IF thisEnum = STEVE_TARGET
fStoreStevePhase = GET_STEVE_PED_PHASE(thisEnum)
ELSE
SET_SYNCHRONIZED_SCENE_PHASE(iCameramanSyncScene, fStoreStevePhase)
ENDIF
IF GET_STEVE_PED_PHASE(thisEnum) >= 1.0
SET_STEVE_STATE(thisEnum, STEVE_STATE_IDLE)
ENDIF
BREAK
CASE STEVE_STATE_END_FILMING
FLOAT fEndPhase
IF thisEnum = STEVE_TARGET
fEndPhase = 0.98
ELSE
fEndPhase = 0.99
ENDIF
IF GET_STEVE_PED_PHASE(thisEnum) >= fEndPhase
SET_STEVE_STATE(thisEnum, STEVE_STATE_IDLE)
ENDIF
BREAK
CASE STEVE_STATE_REACT
IF GET_STEVE_PED_PHASE(thisEnum) >= 0.98
SET_STEVE_STATE(thisEnum, STEVE_STATE_COWER)
iAllowGondolaReactTime = GET_GAME_TIMER() + 100
ENDIF
BREAK
ENDSWITCH
ENDIF
ENDIF
ENDIF
ENDREPEAT
// handle react
BOOL bReact = FALSE
IF IS_PED_INJURED(stevePed[STEVE_CAMERAMAN])
OR IS_PED_INJURED(stevePed[STEVE_TARGET])
OR bSteveDead[STEVE_TARGET]
OR bSteveDead[STEVE_CAMERAMAN]
bReact = TRUE
ENDIF
IF NOT IS_PED_INJURED(stevePed[STEVE_TARGET])
VECTOR vStevePos = GET_ENTITY_COORDS(stevePed[STEVE_TARGET])
IF IS_SNIPER_BULLET_IN_AREA(vStevePos - <<5,5,5>>, vStevePos + <<5,5,5>>)
OR IS_BULLET_IN_AREA(vStevePos, 5.0)
OR IS_EXPLOSION_IN_AREA(EXP_TAG_DONTCARE, <<-1878.22058, -1214.36646, -100.01662>>, <<-1479.24622, -977.38129, 100.11576>>)
OR bPlayerShootingInArea
OR IS_PROJECTILE_IN_AREA(vStevePos - <<10,10,10>>, vStevePos + <<10,10,10>>)
OR GET_NUMBER_OF_FIRES_IN_RANGE(vStevePos, 10) > 0
OR (GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0 AND currentMissionStage = STAGE_TREVOR_HIT)
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), stevePed[STEVE_TARGET], <<30, 30, 10>>)
bDoSpookedSpeech = TRUE
ENDIF
bDoSeenSpeech = FALSE
bReact = TRUE
ELIF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), stevePed[STEVE_TARGET], <<10,10,6>>)
bDoSeenSpeech = TRUE
bDoSpookedSpeech = TRUE
bReact = TRUE
//ELIF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), <<-1663.9, -1126.9, 30.7>>, <<33,33,33>>)
// fAtWheelTime = fAtWheelTime +@ 1.0
// IF fAtWheelTime >= 10.0
// bDoSpookedSpeech = TRUE
//// bReact = TRUE
// ENDIF
//ELSE
// fAtWheelTime = 0.0
ENDIF
ENDIF
IF bReact
IF steveState[STEVE_TARGET] < STEVE_STATE_REACT
AND NOT bSteveDead[STEVE_TARGET]
SET_STEVE_STATE(STEVE_TARGET, STEVE_STATE_REACT)
iAllowGondolaReactTime = GET_GAME_TIMER() + 100
ENDIF
IF steveState[STEVE_CAMERAMAN] < STEVE_STATE_REACT
AND NOT bSteveDead[STEVE_CAMERAMAN]
SET_STEVE_STATE(STEVE_CAMERAMAN, STEVE_STATE_REACT)
iAllowGondolaReactTime = GET_GAME_TIMER() + 100
ENDIF
IF NOT g_bFinale3BHitSuccessful[CHAR_TREVOR]
IF currentMissionStage = STAGE_GET_TO_HIT
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_TREVOR
bJumpedAheadToTrevorHit = TRUE
SET_MISSION_STAGE(STAGE_TREVOR_HIT, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE)
bShownSteveIntro = TRUE
ELSE
IF bSteveDead[STEVE_TARGET]
MISSION_FAILED(FAIL_WRONG_STEVE_DEAD)
ELSE
MISSION_FAILED(FAIL_WRONG_STEVE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC STORE_ENTITY_POSITION_AND_HEADING(ENTITY_INDEX EntityIndex, VECTOR &vPosition, FLOAT &fHeading)
IF DOES_ENTITY_EXIST(EntityIndex)
IF NOT IS_ENTITY_DEAD(EntityIndex)
vPosition = GET_ENTITY_COORDS(EntityIndex)
fHeading = GET_ENTITY_HEADING(EntityIndex)
ENDIF
ENDIF
ENDPROC
PROC RUN_VEHICLE_WARP_CHECK_BASED_ON_TARGET_VEHICLE(VEHICLE_INDEX VehicleIndex, VEHICLE_INDEX TargetVehicleIndex, VECTOR &vWarpPosition,
FLOAT &fWarpHeading, VECTOR &vLastTargetPosition, FLOAT &fLastTargetHeading,
INT &iWarpTimer, VECTOR vWarpOffset, INT iWarpTimeDelay, FLOAT fWarpDistance, FLOAT fMaxWarpDistance)
IF DOES_ENTITY_EXIST(VehicleIndex)
IF IS_VEHICLE_DRIVEABLE(VehicleIndex)
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(TargetVehicleIndex), vLastTargetPosition) > 20.0
IF vLastTargetPosition.z = 0
STORE_ENTITY_POSITION_AND_HEADING(TargetVehicleIndex, vLastTargetPosition, fLastTargetHeading)
ENDIF
vWarpPosition = vLastTargetPosition //store last target vehicle positon as the new warp position
fWarpHeading = fLastTargetHeading //store last target vehicle heading as the new warp heading
vWarpPosition = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vWarpPosition, fWarpHeading, vWarpOffset)
STORE_ENTITY_POSITION_AND_HEADING(TargetVehicleIndex, vLastTargetPosition, fLastTargetHeading)
ENDIF
IF IS_ENTITY_ON_SCREEN(VehicleIndex)
iWarpTimer = GET_GAME_TIMER()
ELIF GET_GAME_TIMER() - iWarpTimer > iWarpTimeDelay
IF GET_DISTANCE_BETWEEN_ENTITIES(VehicleIndex, TargetVehicleIndex) > fWarpDistance
AND GET_DISTANCE_BETWEEN_ENTITIES(VehicleIndex, TargetVehicleIndex) < fMaxWarpDistance
AND GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(TargetVehicleIndex), vWarpPosition) > 20.0
AND NOT IS_ENTITY_IN_AIR(TargetVehicleIndex)
IF NOT IS_VECTOR_ZERO(vWarpPosition)
IF NOT IS_SPHERE_VISIBLE(vWarpPosition, 3.0)
FLOAT fGroundHeight
GET_GROUND_Z_FOR_3D_COORD(vWarpPosition, fGroundHeight)
IF fGroundHeight > 2
IF vWarpPosition.x < -3068.50586
OR vWarpPosition.x > -2848.35571
OR vWarpPosition.y < -18.83005
OR vWarpPosition.y > 179.83005
CLEAR_AREA_OF_PEDS(vWarpPosition, 1.5)
CLEAR_AREA_OF_VEHICLES(vWarpPosition, 3.0)
SET_ENTITY_COORDS(VehicleIndex, vWarpPosition)
SET_ENTITY_HEADING(VehicleIndex, fWarpHeading)
SET_VEHICLE_ON_GROUND_PROPERLY(VehicleIndex)
FLOAT fTargetSpeed
fTargetSpeed = GET_ENTITY_SPEED(TargetVehicleIndex)
IF fTargetSpeed < 10
fTargetSpeed = 10
ELIF fTargetSpeed > 40
fTargetSpeed = 40
ENDIF
SET_VEHICLE_FORWARD_SPEED(VehicleIndex,fTargetSpeed)
SET_VEHICLE_ENGINE_ON(VehicleIndex, TRUE, TRUE)
iWarpTimer = GET_GAME_TIMER()
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC INTERP_FLOAT_TO_IDEAL(FLOAT &fThisFloat, FLOAT fIdealFloat, FLOAT fInterpSpeed)
IF fThisFloat < fIdealFloat
fThisFloat = fThisFloat +@ fInterpSpeed
IF fThisFloat > fIdealFloat
fThisFloat = fIdealFloat
ENDIF
ELIF fThisFloat > fIdealFloat
fThisFloat = fThisFloat -@ fInterpSpeed
IF fThisFloat < fIdealFloat
fThisFloat = fIdealFloat
ENDIF
ENDIF
ENDPROC
PROC INTERP_VECTOR_TO_IDEAL(VECTOR &vThisVector, VECTOR vIdealVector, FLOAT fInterpSpeed)
INTERP_FLOAT_TO_IDEAL(vThisVector.x, vIdealvector.x, fInterpSpeed)
INTERP_FLOAT_TO_IDEAL(vThisVector.y, vIdealvector.y, fInterpSpeed)
INTERP_FLOAT_TO_IDEAL(vThisVector.z, vIdealvector.z, fInterpSpeed)
ENDPROC
// handle gangster state
PROC HANDLE_GANGSTER_STATE()
IF createHitStage[CHAR_MICHAEL] = CREATE_HIT_STAGE_DONE
INT i
REPEAT NUMBER_STRETCH_CREW i
GANGSTER_ENUM thisGangster = INT_TO_ENUM(GANGSTER_ENUM, i)
IF NOT IS_PED_INJURED(gangsterPed[thisGangster].ped)
// don't allow 1-shotting stretch
IF thisGangster = GANGSTER_STRETCH
SET_PED_RESET_FLAG(gangsterPed[i].ped, PRF_PreventAllMeleeTakedowns, TRUE)
ENDIF
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(gangsterPed[i].ped, PLAYER_PED_ID())
gangsterAggro = GANGSTER_AGGRO_DANGER
ENDIF
SWITCH gangsterPed[thisGangster].state
CASE GANGSTER_STATE_BBALL
IF gangsterAggro = GANGSTER_AGGRO_DANGER
SET_GANGSTER_STATE(thisGangster, GANGSTER_STATE_TO_ACTION_FAST)
ELSE
IF thisGangster = GANGSTER_STRETCH
IF IS_SYNCHRONIZED_SCENE_RUNNING(iGangsterSyncScene)
IF GET_SYNCHRONIZED_SCENE_PHASE(iGangsterSyncScene) >= 0.98
SET_OVERALL_GANGSTER_STATE(GANGSTER_STATE_GATHER_AT_PHONE, FALSE)
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE GANGSTER_STATE_GATHER_AT_PHONE
IF bGangstersFrozen
IF IS_ENTITY_ON_SCREEN(gangsterPed[i].ped)
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), gangsterPed[i].ped, <<85,85,85>>, FALSE, FALSE)
OR IS_PLAYER_FREE_AIMING_AT_ENTITY(PLAYER_ID(), gangsterPed[i].ped)
OR IS_PLAYER_TARGETTING_ENTITY(PLAYER_ID(), gangsterPed[i].ped)
IF IS_TRACKED_PED_VISIBLE(gangsterPed[i].ped)
IF IS_SYNCHRONIZED_SCENE_RUNNING(iGangsterSyncScene)
SET_SYNCHRONIZED_SCENE_RATE(iGangsterSyncScene, 1.0)
ENDIF
bGangstersFrozen = FALSE
ENDIF
ENDIF
ENDIF
ENDIF
IF gangsterAggro = GANGSTER_AGGRO_DANGER
SET_GANGSTER_STATE(thisGangster, GANGSTER_STATE_TO_ACTION_FAST)
ELSE
IF thisGangster = GANGSTER_STRETCH
IF IS_SYNCHRONIZED_SCENE_RUNNING(iGangsterSyncScene)
IF GET_SYNCHRONIZED_SCENE_PHASE(iGangsterSyncScene) >= 0.98
SET_OVERALL_GANGSTER_STATE(GANGSTER_STATE_IDLE, FALSE)
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE GANGSTER_STATE_IDLE
IF gangsterAggro = GANGSTER_AGGRO_DANGER
INT iTimeToReact
SWITCH thisGangster
CASE GANGSTER_STRETCH
iTimeToReact = 0
BREAK
CASE GANGSTER_L
iTimeToReact = 100
BREAK
CASE GANGSTER_M
iTimeToReact = 0
BREAK
CASE GANGSTER_R
iTimeToReact = 300
BREAK
ENDSWITCH
IF GET_GAME_TIMER() >= iGangsterAggroTime + iTimeToReact
SET_GANGSTER_STATE(thisGangster, GANGSTER_STATE_TO_ACTION_FAST)
ENDIF
ELIF gangsterAggro = GANGSTER_AGGRO_SUSPICION
SET_GANGSTER_STATE(thisGangster, GANGSTER_STATE_TO_ACTION_SLOW)
ENDIF
BREAK
CASE GANGSTER_STATE_TO_ACTION_FAST
BOOL bSetStateFromFast
bSetStateFromFast = FALSE
IF IS_ENTITY_PLAYING_ANIM(gangsterPed[thisGangster].ped, GET_ANIM_DICT_FOR_GANGSTER_AI_STATE(thisGangster, GANGSTER_STATE_TO_ACTION_FAST), GET_ANIM_FOR_GANGSTER_AI_STATE(thisGangster, GANGSTER_STATE_TO_ACTION_FAST))
IF GET_ENTITY_ANIM_CURRENT_TIME(gangsterPed[thisGangster].ped, GET_ANIM_DICT_FOR_GANGSTER_AI_STATE(thisGangster, GANGSTER_STATE_TO_ACTION_FAST), GET_ANIM_FOR_GANGSTER_AI_STATE(thisGangster, GANGSTER_STATE_TO_ACTION_FAST)) >= 0.98
bSetStateFromFast = TRUE
ENDIF
ELSE
bSetStateFromFast = TRUE
ENDIF
IF bSetStateFromFast
IF thisGangster = GANGSTER_STRETCH
SET_GANGSTER_STATE(thisGangster, GANGSTER_STATE_COMBAT)
ELSE
SET_GANGSTER_STATE(thisGangster, GANGSTER_STATE_ENTERING_FLEE)
ENDIF
ELSE
IF thisGangster <> GANGSTER_STRETCH
SET_PED_MIN_MOVE_BLEND_RATIO(gangsterPed[thisGangster].ped, PEDMOVE_RUN)
ENDIF
ENDIF
BREAK
CASE GANGSTER_STATE_ENTERING_FLEE
BOOL bSetStateFromFlee
bSetStateFromFlee = FALSE
FLOAT fExitPhase
SWITCH thisGangster
CASE GANGSTER_L
fExitPhase = 0.89
BREAK
CASE GANGSTER_M
fExitPhase = 0.87
BREAK
CASE GANGSTER_R
fExitPhase = 0.93
ENDSWITCH
IF IS_ENTITY_PLAYING_ANIM(gangsterPed[thisGangster].ped, GET_ANIM_DICT_FOR_GANGSTER_AI_STATE(thisGangster, GANGSTER_STATE_ENTERING_FLEE), GET_ANIM_FOR_GANGSTER_AI_STATE(thisGangster, GANGSTER_STATE_ENTERING_FLEE))
IF GET_ENTITY_ANIM_CURRENT_TIME(gangsterPed[thisGangster].ped, GET_ANIM_DICT_FOR_GANGSTER_AI_STATE(thisGangster, GANGSTER_STATE_ENTERING_FLEE), GET_ANIM_FOR_GANGSTER_AI_STATE(thisGangster, GANGSTER_STATE_ENTERING_FLEE)) >= fExitPhase
bSetStateFromFlee = TRUE
ENDIF
ELSE
bSetStateFromFlee = TRUE
ENDIF
IF bSetStateFromFlee
SET_GANGSTER_STATE(thisGangster, GANGSTER_STATE_FLEE)
ELSE
SET_PED_MIN_MOVE_BLEND_RATIO(gangsterPed[thisGangster].ped, PEDMOVE_RUN)
ENDIF
BREAK
CASE GANGSTER_STATE_TO_ACTION_SLOW
BOOL bSetStateFromSlow
bSetStateFromSlow = FALSE
IF IS_ENTITY_PLAYING_ANIM(gangsterPed[thisGangster].ped, GET_ANIM_DICT_FOR_GANGSTER_AI_STATE(thisGangster, GANGSTER_STATE_TO_ACTION_SLOW), GET_ANIM_FOR_GANGSTER_AI_STATE(thisGangster, GANGSTER_STATE_TO_ACTION_SLOW))
IF thisGangster = GANGSTER_STRETCH
IF GET_ENTITY_ANIM_CURRENT_TIME(gangsterPed[thisGangster].ped, GET_ANIM_DICT_FOR_GANGSTER_AI_STATE(thisGangster, GANGSTER_STATE_TO_ACTION_SLOW), GET_ANIM_FOR_GANGSTER_AI_STATE(thisGangster, GANGSTER_STATE_TO_ACTION_SLOW)) >= 0.98
bSetStateFromSlow = TRUE
ENDIF
ELSE
IF GET_ENTITY_ANIM_CURRENT_TIME(gangsterPed[thisGangster].ped, GET_ANIM_DICT_FOR_GANGSTER_AI_STATE(thisGangster, GANGSTER_STATE_TO_ACTION_SLOW), GET_ANIM_FOR_GANGSTER_AI_STATE(thisGangster, GANGSTER_STATE_TO_ACTION_SLOW)) >= 0.85
bSetStateFromSlow = TRUE
ENDIF
ENDIF
ELSE
bSetStateFromSlow = TRUE
ENDIF
IF bSetStateFromSlow
IF thisGangster = GANGSTER_STRETCH
SET_GANGSTER_STATE(thisGangster, GANGSTER_STATE_COMBAT)
ELSE
SET_GANGSTER_STATE(thisGangster, GANGSTER_STATE_FLEE)
ENDIF
ELSE
IF thisGangster <> GANGSTER_STRETCH
SET_PED_MIN_MOVE_BLEND_RATIO(gangsterPed[thisGangster].ped, PEDMOVE_RUN)
ELSE
IF gangsterAggro = GANGSTER_AGGRO_DANGER
SET_GANGSTER_STATE(thisGangster, GANGSTER_STATE_COMBAT)
ENDIF
ENDIF
ENDIF
BREAK
CASE GANGSTER_STATE_FLEE
IF GET_GAME_TIMER() <= iGangsterStateTime[thisGangster] + 2000
SET_PED_MIN_MOVE_BLEND_RATIO(gangsterPed[thisGangster].ped, PEDMOVE_RUN)
SET_PED_MAX_MOVE_BLEND_RATIO(gangsterPed[thisGangster].ped, PEDMOVE_RUN)
ENDIF
IF GET_SCRIPT_TASK_STATUS(gangsterPed[thisGangster].ped, SCRIPT_TASK_FOLLOW_WAYPOINT_ROUTE) = FINISHED_TASK
//IF GET_SCRIPT_TASK_STATUS(gangsterPed[thisGangster], SCRIPT_TASK_GO_STRAIGHT_TO_COORD) = FINISHED_TASK
//IF GET_SCRIPT_TASK_STATUS(gangsterPed[thisGangster], SCRIPT_TASK_SMART_FLEE_PED) = FINISHED_TASK
SET_PED_SPHERE_DEFENSIVE_AREA(gangsterPed[thisGangster].ped, GET_ENTITY_COORDS(gangsterPed[thisGangster].ped), 8.0)
SET_GANGSTER_STATE(thisGangster, GANGSTER_STATE_COMBAT)
ENDIF
BREAK
CASE GANGSTER_STATE_COMBAT
IF GET_SCRIPT_TASK_STATUS(gangsterPed[thisGangster].ped, SCRIPT_TASK_PERFORM_SEQUENCE) = FINISHED_TASK
SET_GANGSTER_STATE(thisGangster, GANGSTER_STATE_COMBAT)
ENDIF
BREAK
ENDSWITCH
ELSE
IF DOES_ENTITY_EXIST(gangsterPed[i].ped)
IF NOT gangsterPed[i].bRegisteredDead
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(gangsterPed[i].ped, PLAYER_PED_ID())
INFORM_MISSION_STATS_OF_INCREMENT(FIN_KILLS)
ENDIF
gangsterPed[i].bRegisteredDead = TRUE
ENDIF
gangsterAggro = GANGSTER_AGGRO_DANGER
IF iGangsterAggroTime < 0
iGangsterAggroTime = GET_GAME_TIMER()
ENDIF
ENDIF
ENDIF
ENDREPEAT
FLOAT fSuspicionRange
IF gangsterPed[GANGSTER_STRETCH].state >= GANGSTER_STATE_IDLE
fSuspicionRange = 15.0
ELSE
fSuspicionRange = 14.0
ENDIF
BOOL bKillConversationForAttack = FALSE
IF IS_BULLET_IN_AREA(<<-202.78033, -1509.74194, 30.61494>>, 8.0)
OR GET_NUMBER_OF_FIRES_IN_RANGE(<<-202.78033, -1509.74194, 30.61494>>, 14) > 0
OR ((IS_PED_SHOOTING(PLAYER_PED_ID()) OR (GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0 AND currentMissionStage = STAGE_MICHAEL_HIT)) AND IS_ENTITY_AT_COORD(PLAYER_PED_ID(), <<-203.88301, -1509.37268, 30.61493>>, <<50,50,50>>, FALSE, FALSE))
OR bGangstersHostileFromAggro
bKillConversationForAttack = TRUE
gangsterAggro = GANGSTER_AGGRO_DANGER
IF iGangsterAggroTime < 0
iGangsterAggroTime = GET_GAME_TIMER()
ENDIF
ELIF ((GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), <<-202.78033, -1509.74194, 30.61494>>) < fSuspicionRange AND NOT bDoneHailStretchSpeech AND gangsterPed[GANGSTER_STRETCH].state >= GANGSTER_STATE_IDLE)
OR (bDoneHailStretchSpeech AND GET_GAME_TIMER() >= iHailStretchSpeechTime + 1000))
IF gangsterPed[GANGSTER_STRETCH].state >= GANGSTER_STATE_IDLE
IF gangsterAggro <> GANGSTER_AGGRO_DANGER
bKillConversationForAttack = TRUE
gangsterAggro = GANGSTER_AGGRO_SUSPICION
IF iGangsterAggroTime < 0
iGangsterAggroTime = GET_GAME_TIMER()
ENDIF
ENDIF
ELSE
bKillConversationForAttack = TRUE
gangsterAggro = GANGSTER_AGGRO_DANGER
IF iGangsterAggroTime < 0
iGangsterAggroTime = GET_GAME_TIMER()
ENDIF
ENDIF
ENDIF
IF bKillConversationForAttack
IF NOT bDoneKillConversationForAttack
bDoneKillConversationForAttack = TRUE
KILL_ANY_CONVERSATION()
ENDIF
ENDIF
// handle stretch accessories
IF DOES_ENTITY_EXIST(gangsterPed[GANGSTER_STRETCH].ped)
//BOOL bPlayingQuickExit = FALSE
//BOOL bPlayingSlowExit = FALSE
//FLOAT fPhase = 0.0
/*
IF NOT IS_PED_INJURED(gangsterPed[GANGSTER_STRETCH])
IF IS_ENTITY_PLAYING_ANIM(gangsterPed[GANGSTER_STRETCH], GET_ANIM_DICT_FOR_GANGSTER_AI_STATE(GANGSTER_STATE_TO_ACTION_FAST), GET_ANIM_FOR_GANGSTER_AI_STATE(GANGSTER_STRETCH, GANGSTER_STATE_TO_ACTION_FAST))
bPlayingQuickExit = TRUE
fPhase = GET_ENTITY_ANIM_CURRENT_TIME(gangsterPed[GANGSTER_STRETCH], GET_ANIM_DICT_FOR_GANGSTER_AI_STATE(GANGSTER_STATE_TO_ACTION_FAST), GET_ANIM_FOR_GANGSTER_AI_STATE(GANGSTER_STRETCH, GANGSTER_STATE_TO_ACTION_FAST))
ENDIF
IF IS_ENTITY_PLAYING_ANIM(gangsterPed[GANGSTER_STRETCH], GET_ANIM_DICT_FOR_GANGSTER_AI_STATE(GANGSTER_STATE_TO_ACTION_SLOW), GET_ANIM_FOR_GANGSTER_AI_STATE(GANGSTER_STRETCH, GANGSTER_STATE_TO_ACTION_SLOW))
bPlayingQuickExit = TRUE
fPhase = GET_ENTITY_ANIM_CURRENT_TIME(gangsterPed[GANGSTER_STRETCH], GET_ANIM_DICT_FOR_GANGSTER_AI_STATE(GANGSTER_STATE_TO_ACTION_SLOW), GET_ANIM_FOR_GANGSTER_AI_STATE(GANGSTER_STRETCH, GANGSTER_STATE_TO_ACTION_SLOW))
ENDIF
ENDIF
*/
IF NOT bRemovedStretchPhone
BOOL bRemoveDelete = FALSE
BOOL bRemoveDetach = FALSE
IF NOT IS_PED_INJURED(gangsterPed[GANGSTER_STRETCH].ped)
IF HAS_ANIM_EVENT_FIRED(gangsterPed[GANGSTER_STRETCH].ped, GET_HASH_KEY("HIDE_PHONE"))
//OR (fPhase >= 0.41 AND bPlayingQuickExit)
bRemoveDelete = TRUE
ELIF IS_PED_RAGDOLL(gangsterPed[GANGSTER_STRETCH].ped)
OR IS_PED_IN_COMBAT(gangsterPed[GANGSTER_STRETCH].ped)
bRemoveDetach = TRUE
ENDIF
ELSE
bRemoveDetach = TRUE
ENDIF
IF bRemoveDelete
IF DOES_ENTITY_EXIST(stretchPhoneObject)
DELETE_OBJECT(stretchPhoneObject)
ENDIF
bRemovedStretchPhone = TRUE
ELIF bRemoveDetach
IF DOES_ENTITY_EXIST(stretchPhoneObject)
DETACH_ENTITY(stretchPhoneObject)
ENDIF
bRemovedStretchPhone = TRUE
ENDIF
ENDIF
IF NOT bDetachedBasketball
BOOL bDetachBall = FALSE
BOOL bApplyForce = FALSE
IF NOT IS_PED_INJURED(gangsterPed[GANGSTER_STRETCH].ped)
IF HAS_ANIM_EVENT_FIRED(gangsterPed[GANGSTER_STRETCH].ped, GET_HASH_KEY("THROW_BBALL"))
bDetachBall = TRUE
bApplyForce = TRUE
/*
IF fPhase >= 0.43 AND bPlayingSlowExit
bDetachBall = TRUE
bApplyForce = TRUE
ELIF fPhase >= 0.55 AND bPlayingQuickExit
bDetachBall = TRUE
*/
ELIF HAS_ANIM_EVENT_FIRED(gangsterPed[GANGSTER_STRETCH].ped, GET_HASH_KEY("DROP_BALL"))
bDetachBall = TRUE
ELIF IS_PED_RAGDOLL(gangsterPed[GANGSTER_STRETCH].ped)
OR IS_PED_IN_COMBAT(gangsterPed[GANGSTER_STRETCH].ped)
OR gangsterPed[GANGSTER_STRETCH].state = GANGSTER_STATE_COMBAT
bDetachBall = TRUE
ENDIF
ELSE
bDetachBall = TRUE
ENDIF
IF bDetachBall
IF DOES_ENTITY_EXIST(basketballObject)
DETACH_ENTITY(basketballObject, FALSE)
IF bApplyForce
APPLY_FORCE_TO_ENTITY_CENTER_OF_MASS(basketballObject, APPLY_TYPE_IMPULSE, <<0,8,4>>, 0, TRUE, TRUE)
ENDIF
ENDIF
bDetachedBasketball = TRUE
ENDIF
ENDIF
IF NOT bGivenGun
//IF fPhase >= 0.61 AND bPlayingQuickExit
IF NOT IS_PED_INJURED(gangsterPed[GANGSTER_STRETCH].ped)
IF HAS_ANIM_EVENT_FIRED(gangsterPed[GANGSTER_STRETCH].ped, GET_HASH_KEY("DRAW_GUN"))
IF NOT IS_PED_INJURED(gangsterPed[GANGSTER_STRETCH].ped)
SET_CURRENT_PED_WEAPON(gangsterPed[GANGSTER_STRETCH].ped, GET_FINALE_WEAPON_TYPE(F_WEAPON_PISTOL), TRUE)
bGivenGun = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
// handle bystander AI
bNearGangster = FALSE
REPEAT COUNT_OF(GANGSTER_ENUM) i
GANGSTER_ENUM thisGangster = INT_TO_ENUM(GANGSTER_ENUM, i)
IF thisGangster <> GANGSTER_STRETCH
IF IS_PED_INJURED(gangsterPed[GANGSTER_STRETCH].ped)
// blip stuff
BOOL bNoBlip = FALSE
IF NOT IS_PED_INJURED(gangsterPed[i].ped)
INT j
REPEAT NUMBER_GANGSTER_VEHICLES j
IF IS_VEHICLE_DRIVEABLE(gangsterVehicle[j])
IF IS_PED_IN_VEHICLE(gangsterPed[i].ped, gangsterVehicle[j])
bNoBlip = TRUE
ENDIF
ENDIF
ENDREPEAT
ENDIF
IF NOT bNoBlip
IF NOT bEscapedArea[CHAR_MICHAEL]
UPDATE_AI_PED_BLIP(gangsterPed[i].ped, gangsterPed[i].blipStruct, -1, NULL, FALSE, FALSE, 320) // 250
ENDIF
ELSE
CLEANUP_AI_PED_BLIP(gangsterPed[i].blipStruct)
ENDIF
ENDIF
ENDIF
IF NOT IS_PED_INJURED(gangsterPed[i].ped)
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), gangsterPed[i].ped, <<250,250,250>>)
bNearGangster = TRUE
ENDIF
IF thisGangster >= GANGSTER_GROUP_CHAT_1// AND thisGangster <= GANGSTER_CAR_CAR_PARK_DRIVER
IF NOT gangsterPed[i].bToCombat
// trigger off aggro
BOOL bAggroed = FALSE
IF IS_PLAYER_TARGETTING_ENTITY(PLAYER_ID(), gangsterPed[i].ped)
OR IS_PLAYER_FREE_AIMING_AT_ENTITY(PLAYER_ID(), gangsterPed[i].ped)
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), gangsterPed[i].ped, <<20,20,4>>)
IF CAN_PED_SEE_HATED_PED(gangsterPed[i].ped, PLAYER_PED_ID())
bDamagedGangster = TRUE
bAggroed = TRUE
ENDIF
ENDIF
ENDIF
IF IS_PED_IN_ANY_VEHICLE(gangsterPed[i].ped)
VEHICLE_INDEX hisVehicle = GET_VEHICLE_PED_IS_IN(gangsterPed[i].ped)
IF NOT IS_ENTITY_DEAD(hisVehicle)
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(hisVehicle, PLAYER_PED_ID())
bDamagedGangster = TRUE
bAggroed = TRUE
ENDIF
ENDIF
ENDIF
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(gangsterPed[i].ped, PLAYER_PED_ID())
bDamagedGangster = TRUE
bAggroed = TRUE
ENDIF
IF bGangstersHostileFromAggro
OR gangsterPed[GANGSTER_STRETCH].state = GANGSTER_STATE_COMBAT
OR g_bFinale3BHitSuccessful[CHAR_MICHAEL]
IF thisGangster < GANGSTER_CAR_ROAD_DRIVER
bAggroed = TRUE
ENDIF
ENDIF
IF bAggroed
bGangstersHostileFromAggro = TRUE
gangsterPed[i].bToCombat = TRUE
ENDIF
// trigger off dealing w/stretch
//IF g_bFinale3BHitSuccessful[CHAR_MICHAEL]
//OR (gangsterPed[GANGSTER_STRETCH].state = GANGSTER_STATE_COMBAT AND GET_GAME_TIMER() >= iSetStretchToCombatTime + 15000)
// put a delay on car peds if stretch was killed so they don't all zoom out right away
IF thisGangster >= GANGSTER_CAR_ROAD_DRIVER
BOOL bCanGoToCombat
bCanGoToCombat = TRUE
INT iCarMayGoTime
SWITCH thisGangster
CASE GANGSTER_CAR_ROAD_DRIVER
iCarMayGoTime = 4000
BREAK
CASE GANGSTER_CAR_ROAD_PASSENGER
iCarMayGoTime = 3000
BREAK
//CASE GANGSTER_CAR_COURT_DRIVER
// iCarMayGoTime = 8000
//BREAK
//CASE GANGSTER_CAR_CAR_PARK_DRIVER
// iCarMayGoTime = 10000
//BREAK
DEFAULT
iCarMayGoTime = 0
BREAK
ENDSWITCH
IF ((GET_GAME_TIMER() <= iStretchDeadTime + iCarMayGoTime)
OR NOT g_bFinale3BHitSuccessful[CHAR_MICHAEL])
AND NOT (gangsterPed[GANGSTER_STRETCH].state = GANGSTER_STATE_COMBAT AND GET_GAME_TIMER() >= iSetStretchToCombatTime + 15000)
bCanGoToCombat = FALSE
ENDIF
IF bCanGoToCombat
gangsterPed[i].bToCombat = TRUE
ELSE
IF NOT IS_PED_HEADTRACKING_ENTITY(gangsterPed[i].ped, PLAYER_PED_ID())
TASK_LOOK_AT_ENTITY(gangsterPed[i].ped, PLAYER_PED_ID(), -1, SLF_WHILE_NOT_IN_FOV)
ENDIF
ENDIF
ENDIF
ELSE
IF NOT g_bFinale3BHitSuccessful[CHAR_MICHAEL]
AND NOT (gangsterPed[GANGSTER_STRETCH].state = GANGSTER_STATE_COMBAT AND GET_GAME_TIMER() >= iSetStretchToCombatTime + 15000)
AND NOT bDamagedGangster
SET_PED_RESET_FLAG(gangsterPed[i].ped, PRF_BlockWeaponFire, TRUE)
ENDIF
INT iGangsterVehicle
iGangsterVehicle = GET_GANGSTER_VEHICLE_FOR_GANGSTER(thisGangster)
IF iGangsterVehicle >= 0
bGangsterVehicleOnGo[iGangsterVehicle] = TRUE
ENDIF
IF gangsterPed[i].iToCombatTime < 0
gangsterPed[i].iToCombatTime = GET_GAME_TIMER()
ENDIF
IF NOT bDoneRevengeForStretchSpeech
IF IS_PED_INJURED(gangsterPed[GANGSTER_STRETCH].ped)
IF GET_GAME_TIMER() >= iStretchDeadTime + 1000
IF NOT bGotRevengeForStretchSpeaker
INT j
INT iClosest = -1
FLOAT fClosestDistance = 99999999.0
REPEAT COUNT_OF(GANGSTER_ENUM) j
IF NOT IS_PED_INJURED(gangsterPed[j].ped)
IF INT_TO_ENUM(GANGSTER_ENUM, j) >= GANGSTER_GROUP_CHAT_1
FLOAT fThisDist = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(gangsterPed[j].ped))
IF fThisDist < fClosestDistance
iClosest = j
fClosestDistance = fThisDist
ENDIF
ENDIF
ENDIF
ENDREPEAT
IF iClosest >= 0
iRevengeForStretchSpeaker = iClosest
ADD_PED_FOR_DIALOGUE(finaleConversation, 5, gangsterPed[iRevengeForStretchSpeaker].ped, "GANGBANGER1")
bGotRevengeForStretchSpeaker = TRUE
ELSE
bGotRevengeForStretchSpeaker = TRUE
bDoneRevengeForStretchSpeech = TRUE
ENDIF
ELSE
IF iRevengeForStretchSpeaker >= 0
IF NOT IS_PED_INJURED(gangsterPed[iRevengeForStretchSpeaker].ped)
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), gangsterPed[iRevengeForStretchSpeaker].ped, <<30,30,6>>)
bDoneRevengeForStretchSpeech = DO_MISSION_SPEECH("FINC1_REVSTR")
ELSE
bDoneRevengeForStretchSpeech = TRUE
ENDIF
ELSE
bDoneRevengeForStretchSpeech = TRUE
ENDIF
ELSE
bDoneRevengeForStretchSpeech = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
IF NOT gangsterPed[i].bAllowLeaveCar
INT iAllowLeaveCarTime
SWITCH thisGangster
CASE GANGSTER_CAR_ROAD_DRIVER
iAllowLeaveCarTime = 5000
BREAK
CASE GANGSTER_CAR_ROAD_PASSENGER
iAllowLeaveCarTime = 3000
BREAK
//CASE GANGSTER_CAR_COURT_DRIVER
// iAllowLeaveCarTime = 5000
//BREAK
//CASE GANGSTER_CAR_CAR_PARK_DRIVER
// iAllowLeaveCarTime = 6000
//BREAK
DEFAULT
iAllowLeaveCarTime = 0
BREAK
ENDSWITCH
IF GET_GAME_TIMER() >= gangsterPed[i].iToCombatTime + iAllowLeaveCarTime
OR IS_ENTITY_AT_ENTITY(gangsterPed[i].ped, PLAYER_PED_ID(), <<15,15,5>>)
OR NOT g_bFinale3BHitSuccessful[CHAR_MICHAEL]
SET_PED_COMBAT_ATTRIBUTES(gangsterPed[i].ped, CA_LEAVE_VEHICLES, TRUE)
gangsterPed[i].bAllowLeaveCar = TRUE
ENDIF
ENDIF
IF NOT IS_PED_IN_COMBAT(gangsterPed[i].ped)
IF GET_SCRIPT_TASK_STATUS(gangsterPed[i].ped, SCRIPT_TASK_START_SCENARIO_IN_PLACE) <> FINISHED_TASK
OR IS_PED_USING_ANY_SCENARIO(gangsterPed[i].ped)
SET_PED_SHOULD_PLAY_IMMEDIATE_SCENARIO_EXIT(gangsterPed[i].ped)
ENDIF
TASK_COMBAT_PED(gangsterPed[i].ped, PLAYER_PED_ID())
ENDIF
ENDIF
ENDIF
ELSE
IF thisGangster >= GANGSTER_GROUP_CHAT_1
bDamagedGangster = TRUE
ENDIF
bGangstersHostileFromAggro = TRUE
ENDIF
ENDREPEAT
// vehicles warp behind you
IF g_bFinale3BHitSuccessful[CHAR_MICHAEL]
REPEAT NUMBER_GANGSTER_VEHICLES i
IF IS_VEHICLE_DRIVEABLE(gangsterVehicle[i])
IF NOT bEscapedArea[CHAR_MICHAEL]
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), gangsterVehicle[i], <<320,320,320>>)
AND NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), gangsterVehicle[i])
AND (NOT IS_PED_INJURED(GET_PED_IN_VEHICLE_SEAT(gangsterVehicle[i], VS_DRIVER))
OR NOT IS_PED_INJURED(GET_PED_IN_VEHICLE_SEAT(gangsterVehicle[i], VS_FRONT_RIGHT))
OR NOT IS_PED_INJURED(GET_PED_IN_VEHICLE_SEAT(gangsterVehicle[i], VS_BACK_LEFT))
OR NOT IS_PED_INJURED(GET_PED_IN_VEHICLE_SEAT(gangsterVehicle[i], VS_BACK_RIGHT)))
IF NOT DOES_BLIP_EXIST(gangsterVehicleBlip[i])
vGangsterVehicleBlipPos[i] = GET_ENTITY_COORDS(gangsterVehicle[i])
gangsterVehicleBlip[i] = CREATE_MISSION_BLIP_FOR_COORD(vGangsterVehicleBlipPos[i])
SET_BLIP_AS_FRIENDLY(gangsterVehicleBlip[i], FALSE)
SET_BLIP_NAME_FROM_TEXT_FILE(gangsterVehicleBlip[i], "BLIP_VEH")
//SHOW_HEIGHT_ON_BLIP(gangsterVehicleBlip[i], FALSE)
ELSE
INTERP_VECTOR_TO_IDEAL(vGangsterVehicleBlipPos[i], GET_ENTITY_COORDS(gangsterVehicle[i]), 50.0)
SET_BLIP_COORDS(gangsterVehicleBlip[i], vGangsterVehicleBlipPos[i])
ENDIF
ELSE
IF DOES_BLIP_EXIST(gangsterVehicleBlip[i])
REMOVE_BLIP(gangsterVehicleBlip[i])
ENDIF
ENDIF
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF bGangsterVehicleOnGo[i]
IF NOT IS_PED_INJURED(GET_PED_IN_VEHICLE_SEAT(gangsterVehicle[i]))
// audio scenes
IF NOT bDoneCarArriveAudioScene
IF IS_ENTITY_AT_ENTITY(gangsterVehicle[i], PLAYER_PED_ID(), <<50,50,50>>)
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_MICHAEL_ENEMY_CAR_ARRIVES)
bDoneCarArriveAudioScene = TRUE
ENDIF
ENDIF
VECTOR vWarpOffset
SWITCH i
CASE 0
vWarpOffset = << -3.0, -4.0, 0.0 >>
BREAK
CASE 1
vWarpOffset = <<3.0,0,0>>
BREAK
CASE 2
vWarpOffset = << 0, 4.0, 0.0 >>
BREAK
ENDSWITCH
RUN_VEHICLE_WARP_CHECK_BASED_ON_TARGET_VEHICLE(gangsterVehicle[i], GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), vGangsterVehicleWarpTarget[i], fGangsterVehicleWarpHeading[i], vGangsterVehicleLastWarpPos[i], fGangsterVehicleLastWarpHeading[i], iGangsterVehicleWarpTimer[i], vWarpOffset, 3000, 45.0, fMaxGangsterWarpVehicleDistance)
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF DOES_BLIP_EXIST(gangsterVehicleBlip[i])
REMOVE_BLIP(gangsterVehicleBlip[i])
ENDIF
ENDIF
ENDREPEAT
ENDIF
// skip stage
IF NOT g_bFinale3BHitSuccessful[CHAR_MICHAEL]
IF currentMissionStage = STAGE_GET_TO_HIT
IF gangsterAggro <> GANGSTER_AGGRO_NOT_AGGROED
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL
bJumpedAheadToMichaelHit = TRUE
SET_MISSION_STAGE(STAGE_MICHAEL_HIT, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE)
ELSE
IF IS_PED_INJURED(gangsterPed[GANGSTER_STRETCH].ped)
MISSION_FAILED(FAIL_WRONG_STRETCH_DEAD)
ELSE
MISSION_FAILED(FAIL_WRONG_STRETCH)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
// handle triad state
PROC HANDLE_TRIAD_STATE()
IF createHitStage[CHAR_FRANKLIN] = CREATE_HIT_STAGE_DONE
INT i
// check triad aggro
REPEAT COUNT_OF(TRIAD_ENUM) i
IF DOES_ENTITY_EXIST(triadPed[i].ped)
IF IS_PED_INJURED(triadPed[i].ped)
BOOL bDamagedByPlayer = HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(triadPed[i].ped, PLAYER_PED_ID())
IF NOT triadPed[i].bRegisteredDead
IF bDamagedByPlayer
INFORM_MISSION_STATS_OF_INCREMENT(FIN_KILLS)
ENDIF
triadPed[i].bRegisteredDead = TRUE
ENDIF
ENDIF
ENDIF
ENDREPEAT
IF NOT bAggroedTriads
IF triadState < TRIAD_STATE_DRIVING_LEAVE_CLUB
IF GET_NUMBER_OF_FIRES_IN_RANGE(<<-3016.44, 89.40, 11.98>>, 15) > 0
OR (IS_PED_SHOOTING(PLAYER_PED_ID()) AND IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-3021.878,79.211,0>>, <<-2995.467,113.063,17.5>>, 100.0))
bAggroedTriads = TRUE
//ELIF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), <<-3016.44, 89.40, 11.98>>, <<6.5,6.5,6.5>>, FALSE, FALSE)
ELIF IS_ENTITY_IN_AREA(PLAYER_PED_ID(), <<-3024.43384, 82.58960, 10.60847>>, <<-3010.13843, 89.91269, 13.99329>>)
OR IS_ENTITY_IN_AREA(PLAYER_PED_ID(), <<-3024.43384, 82.58960, 10.60847>>, <<-3017.87744, 92.78082, 13.99329>>)
//bDoRecognizeSpeech = TRUE
bAggroedTriads = TRUE
ENDIF
ENDIF
REPEAT COUNT_OF(triadVehicle) i
IF IS_VEHICLE_DRIVEABLE(triadVehicle[i])
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID() , triadVehicle[i], <<20,20,20>>, FALSE, FALSE)
IF IS_PED_SHOOTING(PLAYER_PED_ID())
OR GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0
bAggroedTriads = TRUE
ENDIF
ENDIF
IF IS_BULLET_IN_AREA(GET_ENTITY_COORDS(triadVehicle[i]), 10.0)
OR IS_EXPLOSION_IN_AREA(EXP_TAG_DONTCARE, GET_ENTITY_COORDS(triadVehicle[i]) - <<20,20,20>>, GET_ENTITY_COORDS(triadVehicle[i]) + <<20,20,20>>)
bAggroedTriads = TRUE
ENDIF
FLOAT fVehicleSpeed = GET_ENTITY_SPEED(triadVehicle[i])
IF fVehicleSpeed <= 1.0
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(triadVehicle[i], <<0,4,0>>), <<4,4,4>>)
fBlockingTriadTime = fBlockingTriadTime +@ 1.0
IF fBlockingTriadTime >= 1.5
bAggroedTriads = TRUE
ENDIF
ENDIF
ENDIF
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
VEHICLE_INDEX playerVehicle
playerVehicle = GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())
IF NOT IS_ENTITY_DEAD(playerVehicle)
IF IS_ENTITY_TOUCHING_ENTITY(playerVehicle, triadVehicle[i])
AND GET_ENTITY_SPEED(playerVehicle) > 15
AND GET_ENTITY_SPEED(playerVehicle) > fVehicleSpeed - 3
bAggroedTriads = TRUE
ENDIF
ENDIF
ENDIF
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(triadVehicle[i], PLAYER_PED_ID())
bAggroedTriads = TRUE
ENDIF
ELSE
IF DOES_ENTITY_EXIST(triadVehicle[i])
bAggroedTriads = TRUE
ENDIF
ENDIF
ENDREPEAT
REPEAT COUNT_OF(triadPed) i
IF NOT IS_PED_INJURED(triadPed[i].ped)
// don't allow 1-shotting cheng
IF INT_TO_ENUM(TRIAD_ENUM, i) = TRIAD_CHENG_SR
SET_PED_RESET_FLAG(triadPed[i].ped, PRF_PreventAllMeleeTakedowns, TRUE)
ENDIF
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(triadPed[i].ped, PLAYER_PED_ID())
bAggroedTriads = TRUE
ENDIF
ELSE
IF DOES_ENTITY_EXIST(triadPed[i].ped)
bAggroedTriads = TRUE
ENDIF
ENDIF
ENDREPEAT
ENDIF
IF currentMissionStage = STAGE_GET_TO_HIT
AND NOT g_bFinale3BHitSuccessful[CHAR_FRANKLIN]
IF bAggroedTriads
OR NOT bTriadsFrozen
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
bJumpedAheadToFranklinHit = TRUE
SET_MISSION_STAGE(STAGE_FRANKLIN_HIT, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE)
// MISSION_FAILED(FAIL_TRIADS_EARLY)
ELSE
IF IS_PED_INJURED(triadPed[TRIAD_CHENG_SR].ped)
MISSION_FAILED(FAIL_WRONG_TRIADS_DEAD)
ELSE
MISSION_FAILED(FAIL_WRONG_TRIADS)
ENDIF
ENDIF
ENDIF
ENDIF
SWITCH triadState
CASE TRIAD_STATE_IDLE
IF IS_SYNCHRONIZED_SCENE_RUNNING(iTriadSyncScene)
IF currentMissionStage = STAGE_FRANKLIN_HIT
IF NOT IS_PED_INJURED(triadPed[TRIAD_CHENG_SR].ped)
//SET_TRIAD_STATE(TRIAD_STATE_SLAP, FALSE)
SET_TRIAD_STATE(TRIAD_STATE_ENTER_CARS, FALSE)
ENDIF
ENDIF
ENDIF
//IF bAggroedTriads
// SET_TRIAD_STATE(TRIAD_STATE_COMBAT)
//ENDIF
BREAK
CASE TRIAD_STATE_SLAP
IF IS_SYNCHRONIZED_SCENE_RUNNING(iTriadSyncScene)
IF GET_SYNCHRONIZED_SCENE_PHASE(iTriadSyncScene) >= 0.98
SET_TRIAD_STATE(TRIAD_STATE_ENTER_CARS, FALSE)
ENDIF
ENDIF
BREAK
CASE TRIAD_STATE_ENTER_CARS
//IF bAggroedTriads
// SET_TRIAD_STATE(TRIAD_STATE_COMBAT)
IF bTriadsFrozen
REPEAT COUNT_OF(triadPed) i
IF IS_ENTITY_ON_SCREEN(triadPed[i].ped)
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), triadPed[i].ped, <<85,85,85>>, FALSE, FALSE)
OR IS_PLAYER_FREE_AIMING_AT_ENTITY(PLAYER_ID(), triadPed[i].ped)
OR IS_PLAYER_TARGETTING_ENTITY(PLAYER_ID(), triadPed[i].ped)
IF IS_TRACKED_PED_VISIBLE(triadPed[i].ped)
IF IS_SYNCHRONIZED_SCENE_RUNNING(iTriadSyncScene)
SET_SYNCHRONIZED_SCENE_RATE(iTriadSyncScene, 1.0)
ENDIF
PRINTSTRING("unfreeze triads!") PRINTNL()
bTriadsFrozen = FALSE
ENDIF
ENDIF
ENDIF
ENDREPEAT
REPEAT COUNT_OF(TRIAD_VEHICLE_ENUM) i
STRING sAnim
TRIAD_VEHICLE_ENUM thisVehicle
thisVehicle = INT_TO_ENUM(TRIAD_VEHICLE_ENUM, i)
IF IS_VEHICLE_DRIVEABLE(triadVehicle[thisVehicle])
SWITCH thisVehicle
CASE TRIAD_VEHICLE_BOSSES
sAnim = "IG8_WASH"
BREAK
CASE TRIAD_VEHICLE_ESCORT_FRONT
sAnim = "IG8_CAVFRONT"
BREAK
CASE TRIAD_VEHICLE_ESCORT_REAR
sAnim = "IG8_CAVREAR"
BREAK
ENDSWITCH
IF IS_ENTITY_PLAYING_ANIM(triadVehicle[thisVehicle], GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_TRIADS_INTO_CARS), sAnim)
FLOAT fRate
IF bTriadsFrozen
fRate = 0.0
ELSE
fRate = 1.0
ENDIF
SET_ENTITY_ANIM_SPEED(triadVehicle[thisVehicle], GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_TRIADS_INTO_CARS), sAnim, fRate)
ENDIF
ENDIF
ENDREPEAT
ENDIF
IF IS_SYNCHRONIZED_SCENE_RUNNING(iTriadSyncScene)
#IF IS_DEBUG_BUILD
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_NUMPAD2)
SET_SYNCHRONIZED_SCENE_PHASE(iTriadSyncScene, 1.0)
ENDIF
#ENDIF
IF GET_SYNCHRONIZED_SCENE_PHASE(iTriadSyncScene) >= 0.94
OR ARE_ALL_TRIADS_IN_CARS()
SET_TRIAD_STATE(TRIAD_STATE_DRIVING_LEAVE_CLUB)
ENDIF
ENDIF
BREAK
CASE TRIAD_STATE_DRIVING_LEAVE_CLUB
// accelerate out of club
REPEAT COUNT_OF(triadVehicle) i
IF IS_VEHICLE_DRIVEABLE(triadVehicle[i])
IF IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_VEHICLE(triadVehicle[i])
IF bAggroedTriads
VEHICLE_WAYPOINT_PLAYBACK_OVERRIDE_SPEED(triadVehicle[i], 45.0)
ELSE
FLOAT fSpeed
fSpeed = 18
IF INT_TO_ENUM(TRIAD_VEHICLE_ENUM, i) = TRIAD_VEHICLE_BOSSES
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT])
IF IS_ENTITY_AT_ENTITY(triadVehicle[i], triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT], <<10,10,10>>, FALSE, FALSE)
fSpeed = 14
ENDIF
ENDIF
ELIF INT_TO_ENUM(TRIAD_VEHICLE_ENUM, i) = TRIAD_VEHICLE_ESCORT_REAR
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_BOSSES])
IF IS_ENTITY_AT_ENTITY(triadVehicle[i], triadVehicle[TRIAD_VEHICLE_BOSSES], <<10,10,10>>, FALSE, FALSE)
fSpeed = 16
ENDIF
ENDIF
ENDIF
VEHICLE_WAYPOINT_PLAYBACK_OVERRIDE_SPEED(triadVehicle[i], fSpeed)
ENDIF
ENDIF
ENDIF
ENDREPEAT
IF bAggroedTriads
HANDLE_TRIAD_DRIVEBYS()
ENDIF
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT])
VECTOR vFrontCarPos
vFrontCarPos = GET_ENTITY_COORDS(triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT])
IF vFrontCarPos.y > 160
SET_TRIAD_STATE(TRIAD_STATE_DRIVING_WANDER)
ENDIF
ELSE
SET_TRIAD_STATE(TRIAD_STATE_DRIVING_ESCAPE)
ENDIF
BREAK
CASE TRIAD_STATE_DRIVING_WANDER
IF bAggroedTriads
SET_TRIAD_STATE(TRIAD_STATE_DRIVING_ESCAPE)
ELSE
IF NOT bDoneTriadsWander
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT])
IF IS_ENTITY_AT_COORD(triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT], vTriadDriveCoords, <<24,24,24>>, FALSE, FALSE)
SET_TRIAD_STATE(TRIAD_STATE_DRIVING_WANDER)
ENDIF
ENDIF
ENDIF
/*
// FLOAT fDistanceToSecondCar
FLOAT fDistanceToThirdCar
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT])
AND IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_ESCORT_REAR])
AND IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_BOSSES])
AND NOT IS_PED_INJURED(triadPed[TRIAD_ESCORT_REAR_DRIVER].ped)
// fDistanceToSecondCar = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT]), GET_ENTITY_COORDS(triadVehicle[TRIAD_VEHICLE_BOSSES]))
fDistanceToThirdCar = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT]), GET_ENTITY_COORDS(triadVehicle[TRIAD_VEHICLE_ESCORT_REAR]))
IF fDistanceToThirdCar >= 25
SET_DRIVE_TASK_CRUISE_SPEED(triadPed[TRIAD_ESCORT_REAR_DRIVER].ped, 17 )
ELSE
SET_DRIVE_TASK_CRUISE_SPEED(triadPed[TRIAD_ESCORT_REAR_DRIVER].ped, 16 )
ENDIF
ENDIF
*/
ENDIF
BREAK
CASE TRIAD_STATE_DRIVING_ESCAPE
IF NOT bDoneFrontCarFollow
IF GET_GAME_TIMER() >= iTriadsEscapeTime + 7000
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT])
AND IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_BOSSES])
AND NOT IS_PED_INJURED(triadPed[TRIAD_ESCORT_FRONT_DRIVER].ped)
TASK_VEHICLE_MISSION(triadPed[TRIAD_ESCORT_FRONT_DRIVER].ped, triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT], triadVehicle[TRIAD_VEHICLE_BOSSES], MISSION_FOLLOW, 35.0, DRIVINGMODE_AVOIDCARS, -1, -1)
ENDIF
bDoneFrontCarFollow = TRUE
ENDIF
ENDIF
HANDLE_TRIAD_DRIVEBYS()
BREAK
CASE TRIAD_STATE_CHASE_DOWN_PLAYER
//HANDLE_TRIAD_DRIVEBYS()
BREAK
ENDSWITCH
IF triadState <> TRIAD_STATE_CHASE_DOWN_PLAYER
IF bTriadsMustChasePlayer
SET_TRIAD_STATE(TRIAD_STATE_CHASE_DOWN_PLAYER)
ENDIF
ENDIF
// handle combat / flee on foot
IF bAggroedTriads
bNearTriad = FALSE
REPEAT COUNT_OF(TRIAD_ENUM) i
IF IS_PED_INJURED(triadPed[TRIAD_CHENG_SR].ped)
// blip stuff
BOOL bNoBlip = FALSE
IF NOT IS_PED_INJURED(triadPed[i].ped)
INT j
REPEAT COUNT_OF(TRIAD_VEHICLE_ENUM) j
IF IS_VEHICLE_DRIVEABLE(triadVehicle[j])
IF IS_PED_IN_VEHICLE(triadPed[i].ped, triadVehicle[j])
bNoBlip = TRUE
ENDIF
ENDIF
ENDREPEAT
ENDIF
IF NOT bNoBlip
IF NOT bEscapedArea[CHAR_FRANKLIN]
UPDATE_AI_PED_BLIP(triadPed[i].ped, triadPed[i].blipStruct, -1, NULL, FALSE, FALSE, 320)//250)
ENDIF
ELSE
CLEANUP_AI_PED_BLIP(triadPed[i].blipStruct)
ENDIF
ENDIF
TRIAD_ENUM thisTriad
thisTriad = INT_TO_ENUM(TRIAD_ENUM, i)
IF NOT IS_PED_INJURED(triadPed[thisTriad].ped)
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), triadPed[thisTriad].ped, <<250,250,250>>)
bNearTriad = TRUE
ENDIF
//IF thisTriad = TRIAD_CHENG_SR
// printstring("here1") printnl()
//ENDIF
IF NOT triadPed[thisTriad].bInCombat
BOOL bCanGoToCombat
bCanGoToCombat = FALSE
IF IS_SYNCHRONIZED_SCENE_RUNNING(iTriadSyncScene)
IF GET_SYNCHRONIZED_SCENE_PHASE(iTriadSyncScene) <= GET_TRIAD_MUST_ENTER_VEHICLE_PHASE(thisTriad)
bCanGoToCombat = TRUE
ENDIF
ELSE
IF NOT IS_PED_IN_ANY_VEHICLE(triadPed[thisTriad].ped)
bCanGoToCombat = TRUE
ELSE
VEHICLE_INDEX thisVeh
thisVeh = GET_VEHICLE_PED_IS_USING(triadPed[thisTriad].ped)
IF NOT IS_VEHICLE_DRIVEABLE(thisVeh)
bCanGoToCombat = TRUE
ELSE
FLOAT fInVehicleSpeed = GET_ENTITY_SPEED(thisVeh)
IF triadState = TRIAD_STATE_CHASE_DOWN_PLAYER
bCanGoToCombat = TRUE
ENDIF
PED_INDEX thisDriver
thisDriver = GET_PED_IN_VEHICLE_SEAT(thisVeh, VS_DRIVER)
IF IS_PED_INJURED(thisDriver)
AND fInVehicleSpeed < 2.0
bCanGoToCombat = TRUE
ENDIF
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), thisVeh)
bCanGoToCombat = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
IF bCanGoToCombat
triadPed[thisTriad].bInCombat = TRUE
ENDIF
ELSE
//IF thisTriad = TRIAD_CHENG_SR
// IF GET_SCRIPT_TASK_STATUS(triadPed[thisTriad].ped, SCRIPT_TASK_PERFORM_SEQUENCE) = FINISHED_TASK
// CLEAR_SEQUENCE_TASK(sequence)
// OPEN_SEQUENCE_TASK(sequence)
// TASK_LEAVE_ANY_VEHICLE(NULL)
// TASK_COWER(NULL)
// CLOSE_SEQUENCE_TASK(sequence)
// TASK_PERFORM_SEQUENCE(triadPed[thisTriad].ped, sequence)
// bTriadsMustChasePlayer = TRUE
// ENDIF
//ELIF thisTriad = TRIAD_CHENG_JR
// IF GET_SCRIPT_TASK_STATUS(triadPed[thisTriad].ped, SCRIPT_TASK_SMART_FLEE_PED) = FINISHED_TASK
// TASK_SMART_FLEE_PED(triadPed[thisTriad].ped, PLAYER_PED_ID(), 1000, -1)
// ENDIF
//ELSE
IF NOT IS_PED_IN_COMBAT(triadPed[i].ped)
SET_PED_COMBAT_ATTRIBUTES(triadPed[i].ped, CA_USE_VEHICLE, TRUE)
SET_PED_COMBAT_ATTRIBUTES(triadPed[i].ped, CA_CAN_COMMANDEER_VEHICLES, TRUE)
SET_PED_COMBAT_MOVEMENT(triadPed[i].ped, CM_WILLADVANCE)
SET_PED_COMBAT_ATTRIBUTES(triadPed[i].ped, CA_CAN_CHARGE, TRUE)
SET_PED_COMBAT_ATTRIBUTES(triadPed[i].ped, CA_JUST_FOLLOW_VEHICLE, TRUE)
TASK_COMBAT_PED(triadPed[thisTriad].ped, PLAYER_PED_ID())
ENDIF
//ENDIF
ENDIF
ENDIF
ENDREPEAT
ENDIF
// vehicles warp behind you
IF triadState = TRIAD_STATE_CHASE_DOWN_PLAYER
IF NOT bEscapedArea[CHAR_FRANKLIN]
REPEAT COUNT_OF(TRIAD_VEHICLE_ENUM) i
IF IS_VEHICLE_DRIVEABLE(triadVehicle[i])
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), triadVehicle[i], <<320,320,320>>)
AND NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), triadVehicle[i])
AND (NOT IS_PED_INJURED(GET_PED_IN_VEHICLE_SEAT(triadVehicle[i], VS_DRIVER))
OR NOT IS_PED_INJURED(GET_PED_IN_VEHICLE_SEAT(triadVehicle[i], VS_FRONT_RIGHT))
OR NOT IS_PED_INJURED(GET_PED_IN_VEHICLE_SEAT(triadVehicle[i], VS_BACK_LEFT))
OR NOT IS_PED_INJURED(GET_PED_IN_VEHICLE_SEAT(triadVehicle[i], VS_BACK_RIGHT)))
IF NOT DOES_BLIP_EXIST(triadVehicleBlip[i])
vTriadVehicleBlipPos[i] = GET_ENTITY_COORDS(triadVehicle[i])
triadVehicleBlip[i] = CREATE_MISSION_BLIP_FOR_COORD(vTriadVehicleBlipPos[i])
SET_BLIP_AS_FRIENDLY(triadVehicleBlip[i], FALSE)
SET_BLIP_NAME_FROM_TEXT_FILE(triadVehicleBlip[i], "BLIP_VEH")
//SHOW_HEIGHT_ON_BLIP(triadVehicleBlip[i], FALSE)
ELSE
INTERP_VECTOR_TO_IDEAL(vTriadVehicleBlipPos[i], GET_ENTITY_COORDS(triadVehicle[i]), 50.0)
SET_BLIP_COORDS(triadVehicleBlip[i], vTriadVehicleBlipPos[i])
ENDIF
ELSE
IF DOES_BLIP_EXIST(triadVehicleBlip[i])
REMOVE_BLIP(triadVehicleBlip[i])
ENDIF
ENDIF
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF NOT IS_PED_INJURED(GET_PED_IN_VEHICLE_SEAT(triadVehicle[i]))
VECTOR vWarpOffset
SWITCH i
CASE 0
vWarpOffset = << -3.0, 3.0, 0.0 >>
BREAK
CASE 1
vWarpOffset = <<0.0,-2.5,0>>
BREAK
CASE 2
vWarpOffset = << 3.0, 2.0, 0.0 >>
BREAK
ENDSWITCH
RUN_VEHICLE_WARP_CHECK_BASED_ON_TARGET_VEHICLE(triadVehicle[i], GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), vTriadVehicleWarpTarget[i], fTriadVehicleWarpHeading[i], vTriadVehicleLastWarpPos[i], fTriadVehicleLastWarpHeading[i], iTriadVehicleWarpTimer[i], vWarpOffset, 3000, 45.0, fMaxTriadWarpVehicleDistance)
ENDIF
ENDIF
ELSE
IF DOES_BLIP_EXIST(triadVehicleBlip[i])
REMOVE_BLIP(triadVehicleBlip[i])
ENDIF
ENDIF
ENDREPEAT
ENDIF
ENDIF
ENDIF
ENDPROC
// common hit functions
PROC DO_COMMON_HIT_FUNCTIONS()
HANDLE_CREATE_HITS(currentMissionStage = STAGE_GET_TO_HIT)
HANDLE_WHEEL_BYSTANDERS()
HANDLE_STEVE_STATE()
IF NOT bRunningCutscene
CONVERT_STEVE_TO_GONDOLA()
HANDLE_PIER_COPS()
HANDLE_GANGSTER_STATE()
HANDLE_TRIAD_STATE()
IF currentMissionStage < STAGE_PICKUP_DEVIN
UPDATE_JOURNEYS_TO_HITS()
ENDIF
ENDIF
ENDPROC
FUNC BOOL IS_PLAYER_AT_HIT_POS()
//IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_PLAYER_DRIVE_TARGET(GET_CURRENT_PLAYER_PED_ENUM()), <<LOCATE_SIZE_ANY_MEANS,LOCATE_SIZE_ANY_MEANS,LOCATE_SIZE_HEIGHT>>)
// RETURN TRUE
//ENDIF
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-196.270, -1515.160, 29.620>>, <<-226.520, -1490.690, 33.000>>, 75.000)
RETURN TRUE
ENDIF
BREAK
CASE CHAR_TREVOR
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-1695.534, -1156.338, 12.000>>, <<-1574.942, -1012.826, 15.000>>, 52.000)
OR IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-1728.331, -1128.913, 12.000>>, <<-1661.748, -1049.736, 15.000>>, 55.000)
OR IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-1741.410, -1116.077, 12.000>>, <<-1792.803, -1177.224, 15.000>>, 18.000)
OR IS_ENTITY_AT_COORD(PLAYER_PED_ID(), <<-1609.10461, -1012.95776, 12.01757>>, <<10,10,3>>)
RETURN TRUE
ENDIF
BREAK
CASE CHAR_FRANKLIN
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-3007.114, 114.438, 10.000>>, <<-3038.896, 85.495, 17.500>>, 25.000)
OR IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-3042.929, 114.960, 10.000>>, <<-2973.122, 58.090, 15.000>>, 40.000)
RETURN TRUE
ELSE
IF NOT IS_PED_INJURED(triadPed[TRIAD_CHENG_SR].ped)
IF (IS_TRACKED_PED_VISIBLE(triadPed[TRIAD_CHENG_SR].ped) AND IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), triadPed[TRIAD_CHENG_SR].ped, <<100, 100, 100>>, FALSE, FALSE))
OR IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), triadPed[TRIAD_CHENG_SR].ped, <<50, 50, 100>>)
RETURN TRUE
ENDIF
ENDIF
ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
// get to the hit
PROC DO_STAGE_GET_TO_HIT()
enumCharacterList currentPlayer = GET_CURRENT_PLAYER_PED_ENUM()
DO_COMMON_HIT_FUNCTIONS()
IF NOT bRunningCutscene
IF NOT bUnblockedGPS[GET_CURRENT_PLAYER_PED_ENUM()]
IF freeHotswapData.state = FREE_HOTSWAP_STATE_SELECTING
IF IS_ENTITY_IN_AREA(PLAYER_PED_ID(), GET_MIN_GPS_BLOCK_AREA_COORDS(GET_CURRENT_PLAYER_PED_ENUM()), GET_MAX_GPS_BLOCK_AREA_COORDS(GET_CURRENT_PLAYER_PED_ENUM()), FALSE, FALSE)
SET_GPS_DISABLED_ZONE(<<0,0,0>>, <<0,0,0>>)
//bHitStagingPoint[GET_CURRENT_PLAYER_PED_ENUM()] = TRUE
bUnblockedGPS[GET_CURRENT_PLAYER_PED_ENUM()] = TRUE
ENDIF
ENDIF
ENDIF
IF currentMissionStage = STAGE_GET_TO_HIT
IF NOT bDoneOnlyYourTargetSpeech
IF bShownGotoText[currentPlayer]
IF freeHotswapData.state = FREE_HOTSWAP_STATE_SELECTING
IF currentPlayer <> CHAR_MICHAEL
IF NOT g_bFinale3BHitSuccessful[CHAR_TREVOR]
AND NOT g_bFinale3BHitSuccessful[CHAR_MICHAEL]
AND NOT g_bFinale3BHitSuccessful[CHAR_FRANKLIN]
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", TRUE)
bDoneOnlyYourTargetSpeech = DO_MISSION_SPEECH("FINC1_STARGS")
IF bDoneOnlyYourTargetSpeech
REPLAY_RECORD_BACK_FOR_TIME(5.0, 7.0, REPLAY_IMPORTANCE_HIGHEST)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF freeHotswapData.state = FREE_HOTSWAP_STATE_SELECTING
IF NOT bDoneOnlyYourTargetReplySpeech
IF currentPlayer = CHAR_FRANKLIN
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", TRUE)
bDoneOnlyYourTargetReplySpeech = DO_MISSION_SPEECH("FINC1_FENCM")
ELIF currentPlayer = CHAR_TREVOR
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", TRUE)
bDoneOnlyYourTargetReplySpeech = DO_MISSION_SPEECH("FINC1_TENCM")
ENDIF
ENDIF
// handle calls for each ped - rework this when get a few more
IF currentPlayer = CHAR_FRANKLIN
IF NOT bDoneFranklinCallLamar
IF (IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_PLAYER_HIT_TARGET(currentPlayer), <<3000,3000,3000>>, FALSE, FALSE)
OR iForceLamarCallTime >=0 AND GET_GAME_TIMER() >= iForceLamarCallTime)
AND NOT IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_PLAYER_HIT_TARGET(currentPlayer), <<600,600,600>>, FALSE, FALSE)
IF NOT IS_MESSAGE_BEING_DISPLAYED()
and not is_any_conversation_ongoing_or_queued()
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", FALSE)
REMOVE_PED_FOR_DIALOGUE(finaleConversation, 3)
ADD_PED_FOR_DIALOGUE(finaleConversation, 3, NULL, "LAMAR")
bDoneFranklinCallLamar = PLAYER_CALL_CHAR_CELLPHONE(finaleConversation, CHAR_LAMAR, "FINC1AU", "FINC1_LCALL5", CONV_PRIORITY_HIGH)
endif
ENDIF
ENDIF
ELIF currentPlayer = CHAR_TREVOR
IF NOT bDoneTrevorCallRon
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_PLAYER_HIT_TARGET(currentPlayer), <<3000,3000,3000>>, FALSE, FALSE)
AND NOT IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_PLAYER_HIT_TARGET(currentPlayer), <<600,600,600>>, FALSE, FALSE)
IF NOT IS_MESSAGE_BEING_DISPLAYED()
and not is_any_conversation_ongoing_or_queued()
IF GET_GAME_TIMER() >= iTrevorCallRonTime
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", FALSE)
REMOVE_PED_FOR_DIALOGUE(finaleConversation, 3)
ADD_PED_FOR_DIALOGUE(finaleConversation, 3, NULL, "nervousron")
bDoneTrevorCallRon = PLAYER_CALL_CHAR_CELLPHONE(finaleConversation, CHAR_RON, "CHATCAU", "CHATC_RON06", CONV_PRIORITY_HIGH)
ENDIF
ELSE
iTrevorCallRonTime = GET_GAME_TIMER() + 3000
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
bDoneOnlyYourTargetReplySpeech = TRUE
ENDIF
ENDIF
IF NOT bCutsceneWaitStarted
IF CAN_DO_FREE_HOTSWAP()
HANDLE_FREE_HOTSWAP()
ENDIF
IF freeHotswapData.state = FREE_HOTSWAP_STATE_SELECTING
IF HANDLE_GET_TO_LOCATION(FALSE, FALSE, FALSE)
IF NOT DOES_BLIP_EXIST(gotoBlip)
REMOVE_ALL_BLIPS()
REMOVE_MISSION_TEXT(FALSE)
gotoBlip = CREATE_MISSION_BLIP_FOR_COORD(GET_PLAYER_HIT_TARGET(currentPlayer), TRUE)
IF DOES_BLIP_EXIST(gotoBlip)
SET_BLIP_SCALE(gotoBlip, BLIP_SIZE_PED)
SET_BLIP_COLOUR(gotoBlip, BLIP_COLOUR_RED)
SET_BLIP_ROUTE_COLOUR(gotoBlip, BLIP_COLOUR_RED)
SET_BLIP_NAME_FROM_TEXT_FILE(gotoBlip, "BLIP_270")
ENDIF
ENDIF
// IF iWanted = 0
IF NOT bShownGotoText[currentPlayer]
IF driveToHitState[currentPlayer] <> DRIVE_TO_HIT_STATE_DONE
STRING sGotoText
SWITCH currentPlayer
CASE CHAR_MICHAEL
sGotoText = "FC2_KILLSTR"
BREAK
CASE CHAR_FRANKLIN
sGotoText = "FC2_KILLTRI"
BREAK
CASE CHAR_TREVOR
sGotoText = "FC2_KILLSTE"
BREAK
ENDSWITCH
bShownGotoText[currentPlayer] = DO_MISSION_GOD_TEXT(sGotoText)
ENDIF
ENDIF
IF createHitStage[currentPlayer] = CREATE_HIT_STAGE_DONE
IF IS_PLAYER_AT_HIT_POS()
SWITCH currentPlayer
CASE CHAR_MICHAEL
bJumpedAheadToMichaelHit = TRUE
SET_MISSION_STAGE(STAGE_MICHAEL_HIT, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE)
BREAK
CASE CHAR_TREVOR
bJumpedAheadToTrevorHit = TRUE
SET_MISSION_STAGE(STAGE_TREVOR_HIT, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE)
BREAK
CASE CHAR_FRANKLIN
bJumpedAheadToFranklinHit = TRUE
SET_MISSION_STAGE(STAGE_FRANKLIN_HIT, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE)
BREAK
ENDSWITCH
ENDIF
ENDIF
ENDIF
//ENDIF
ENDIF
ELSE
PREVENT_WANTED_LEVEL_FOR_CUTSCENE()
ENDIF
ENDIF
ELSE
ENDIF
ENDPROC
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
// steve intro cut
PROC DO_STEVE_INTRO_CUTSCENE()
SET_ALL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID())
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_TREVOR_CAR])
SET_FORCE_HD_VEHICLE(finaleVehicle[FV_TREVOR_CAR], TRUE)
ENDIF
SWITCH cutsceneStage
CASE F_CUT_STAGE_INIT
//SET_MISSION_CUTSCENE(TRUE)
iFinaleCutsceneTime = GET_GAME_TIMER()
IF NOT IS_PED_INJURED(stevePed[STEVE_TARGET])
REGISTER_ENTITY_FOR_CUTSCENE(stevePed[STEVE_TARGET], "Steve_FBI", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
IF NOT IS_PED_INJURED(stevePed[STEVE_CAMERAMAN])
REGISTER_ENTITY_FOR_CUTSCENE(stevePed[STEVE_CAMERAMAN], "Grip_beside_director", CU_ANIMATE_EXISTING_SCRIPT_ENTITY) // Grip_beside_director
ENDIF
IF DOES_ENTITY_EXIST(cameraObject)
DETACH_ENTITY(cameraObject)
REGISTER_ENTITY_FOR_CUTSCENE(cameraObject, "film_crew_Camera", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
// backup vehicle player is in
hitCutsceneVehicle = NULL
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
hitCutsceneVehicle = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
ELSE
vHitStorePos = GET_ENTITY_COORDS(PLAYER_PED_ID())
fHitRot = GET_ENTITY_HEADING(PLAYER_PED_ID())
ENDIF
trevorVolume = STREAMVOL_CREATE_FRUSTUM(GET_ENTITY_COORDS(PLAYER_PED_ID()), CONVERT_ROTATION_TO_DIRECTION_VECTOR(<<0, 0.0, GET_ENTITY_HEADING(PLAYER_PED_ID())>>), 500, FLAG_MAPDATA)
ADD_ANIM_DICT_REQUEST(F_ANIM_DICT_STEVE_SPEECH)
START_CUTSCENE()
SET_CUTSCENE_FADE_VALUES(FALSE, FALSE, FALSE, FALSE)
cutsceneStage = F_CUT_STAGE_RUNNING
BREAK
CASE F_CUT_STAGE_RUNNING
IF NOT bClearedForCutscene
IF IS_CUTSCENE_PLAYING()
SET_MISSION_MOCAP_CUTSCENE()
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
CLEAR_TIMECYCLE_MODIFIER()
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_TREVOR_FOCUS_ON_WHEEL)
//KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
RESET_CUSTOM_CHASE_HINT_CAM_INTERP_IN_TIME(localChaseHintCamStruct)
FORCE_CHASE_HINT_CAM(localChaseHintCamStruct, FALSE)
// clear the area
IF DOES_ENTITY_EXIST(gondolaObject[STEVE_GONDOLA])
CLEAR_AREA(GET_ENTITY_COORDS(gondolaObject[STEVE_GONDOLA]), 30, TRUE)
ENDIF
CLEAR_AREA_OF_PROJECTILES(GET_ENTITY_COORDS(PLAYER_PED_ID()), 8)
STOP_FIRE_IN_RANGE(GET_ENTITY_COORDS(PLAYER_PED_ID()), 8)
REMOVE_PARTICLE_FX_IN_RANGE(GET_ENTITY_COORDS(PLAYER_PED_ID()), 8)
IF NOT IS_ENTITY_DEAD(hitCutsceneVehicle)
SET_ENTITY_COORDS(hitCutsceneVehicle, GET_ENTITY_COORDS(hitCutsceneVehicle))
SET_ENTITY_HEADING(hitCutsceneVehicle, GET_ENTITY_HEADING(hitCutsceneVehicle))
ENDIF
IF IS_SCREEN_FADED_OUT()
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
ENDIF
STOP_VEHICLE_FIRE(hitCutsceneVehicle)
bClearedForCutscene = TRUE
ENDIF
ENDIF
INT iCutsceneTime
BOOL bCamOn
SWITCH iCamViewCount
CASE 0
iCutsceneTime = 5503
bCamOn = TRUE
BREAK
CASE 1
iCutsceneTime = 10892
bCamOn = FALSE
BREAK
CASE 2
iCutsceneTime = 14101
bCamOn = TRUE
BREAK
CASE 3
iCutsceneTime = 21858
bCamOn = FALSE
BREAK
CASE 4
iCutsceneTime = 25354
bCamOn = TRUE
BREAK
ENDSWITCH
IF iCamViewCount < 5
IF GET_CUTSCENE_TIME() >= iCutsceneTime
IF bCamOn
SET_TIMECYCLE_MODIFIER("scanline_cam_cheap")
ELSE
CLEAR_TIMECYCLE_MODIFIER()
ENDIF
iCamViewCount++
ENDIF
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Steve_FBI")
SET_STEVE_STATE(STEVE_TARGET, STEVE_STATE_FILMING)
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Grip_beside_director")
SET_STEVE_STATE(STEVE_CAMERAMAN, STEVE_STATE_FILMING)
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("film_crew_Camera")
ATTACH_CAMERA_TO_CAMERAMAN()
ENDIF
IF CAN_SET_EXIT_STATE_FOR_CAMERA()
IF IS_VEHICLE_DRIVEABLE(hitCutsceneVehicle)
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), hitCutsceneVehicle)
SET_VEHICLE_ON_GROUND_PROPERLY(hitCutsceneVehicle)
ELSE
SET_ENTITY_COORDS_NO_OFFSET(PLAYER_PED_ID(), vHitStorePos)
SET_ENTITY_HEADING(PLAYER_PED_ID(), fHitRot)
CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID())
FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID())
ENDIF
IF STREAMVOL_IS_VALID(trevorVolume)
STREAMVOL_DELETE(trevorVolume)
ENDIF
bJumpedAheadToTrevorHit = FALSE
bStartedWheel = TRUE
CLEAR_TIMECYCLE_MODIFIER()
SET_MISSION_CUTSCENE(FALSE)
iCamViewCount = 0
bShownSteveIntro = TRUE
ENDIF
#IF IS_DEBUG_BUILD
DEBUG_SKIP_MOCAP()
#ENDIF
BREAK
CASE F_CUT_STAGE_CLEANUP
BREAK
ENDSWITCH
ENDPROC
// trevor snipe
PROC DO_TREVOR_SNIPE_CUTSCENE()
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_TREVOR_CAR])
SET_FORCE_HD_VEHICLE(finaleVehicle[FV_TREVOR_CAR], TRUE)
ENDIF
SWITCH cutsceneStage
CASE F_CUT_STAGE_INIT
SET_MISSION_CUTSCENE(TRUE)
fCachedPlayerHeading = GET_ENTITY_HEADING(PLAYER_PED_ID())
IF NOT bSwitchCam_SteveKilledViaExplosion
AND NOT bSwitchCam_SteveKilledViaGrenade
SET_CAM_ACTIVE(reactionCam, TRUE)
RENDER_SCRIPT_CAMS(TRUE, NOT bSuppressBulletCam)
REPLAY_START_EVENT(REPLAY_IMPORTANCE_HIGHEST)
// CREATE_CAM_ATTACHED_TO_GONDOLA()
ENDIF
IF bSuppressBulletCam
IF NOT IS_PED_INJURED(stevePed[STEVE_TARGET])
CREATE_SYNCED_SCENE_ATTACHED_TO_GONDOLA(iSteveSyncScene, FALSE)
TASK_SYNCHRONIZED_SCENE(stevePed[STEVE_TARGET], iSteveSyncScene, GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_STEVE_DEATH), "Death_Steve", INSTANT_BLEND_IN, NORMAL_BLEND_OUT)
FORCE_PED_AI_AND_ANIMATION_UPDATE(stevePed[STEVE_TARGET])
ENDIF
// cameraman
IF steveState[STEVE_CAMERAMAN] <> STEVE_STATE_DEAD
SET_STEVE_STATE(STEVE_CAMERAMAN, STEVE_STATE_REACT, TRUE)
ENDIF
ENDIF
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_TREVOR_KILL_CAM)
//SET_STEVE_STATE(STEVE_CAMERAMAN, STEVE_STATE_REACT, TRUE)
trevorVolume = STREAMVOL_CREATE_FRUSTUM(GET_ENTITY_COORDS(PLAYER_PED_ID()), CONVERT_ROTATION_TO_DIRECTION_VECTOR(<<0, 0.0, GET_ENTITY_HEADING(PLAYER_PED_ID())>>), 500, FLAG_MAPDATA)
bDoneFlash = FALSE
iFinaleCutsceneTime = GET_GAME_TIMER()
IF NOT bSwitchCam_SteveKilledViaExplosion
AND NOT bSwitchCam_SteveKilledViaGrenade
cutsceneStage = F_CUT_STAGE_RUNNING
ELSE
cutsceneStage = F_CUT_STAGE_CLEANUP
ENDIF
BREAK
CASE F_CUT_STAGE_RUNNING
SET_ENTITY_HEADING(PLAYER_PED_ID(), fCachedPlayerHeading)
IF NOT IS_PED_INJURED(stevePed[STEVE_CAMERAMAN])
AND NOT bSteveDead[STEVE_CAMERAMAN]
IF NOT bDoneCameramanSpeech
bDoneCameramanSpeech = DO_MISSION_SPEECH("FINC1_SHOT")
ENDIF
ENDIF
IF GET_GAME_TIMER() >= (iFinaleCutsceneTime + 5800)
OR (bSteveDead[STEVE_CAMERAMAN] AND GET_GAME_TIMER() >= (iFinaleCutsceneTime + 2500))
IF NOT bSkippedCutscene
cutsceneStage = F_CUT_STAGE_CLEANUP
ENDIF
ENDIF
IF NOT bDoneFlash
IF GET_CAM_VIEW_MODE_FOR_CONTEXT(GET_CAM_ACTIVE_VIEW_MODE_CONTEXT()) = CAM_VIEW_MODE_FIRST_PERSON
IF GET_GAME_TIMER() >= iFinaleCutsceneTime + 5500
ANIMPOSTFX_PLAY("CamPushInNeutral", 0, FALSE)
PLAY_SOUND_FRONTEND(-1, "1st_Person_Transition", "PLAYER_SWITCH_CUSTOM_SOUNDSET")
bDoneFlash = TRUE
ENDIF
ENDIF
ENDIF
IF NOT bSkippedCutscene
IF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED()
AND GET_GAME_TIMER() >= iAllowSkipCutsceneTime + 1000
DO_SCREEN_FADE_OUT(DEFAULT_FADE_TIME)
bSkippedCutscene = TRUE
ENDIF
ELSE
IF IS_SCREEN_FADED_OUT()
HANG_UP_AND_PUT_AWAY_PHONE()
KILL_ANY_CONVERSATION()
cutsceneStage = F_CUT_STAGE_CLEANUP
ENDIF
ENDIF
BREAK
CASE F_CUT_STAGE_CLEANUP
REPLAY_STOP_EVENT()
IF bSkippedCutscene
ENDIF
INT i
REPEAT NUMBER_PIER_COPS i
IF NOT IS_PED_INJURED(copPed[i])
SET_PED_ACCURACY(copPed[i], 0)
ENDIF
ENDREPEAT
IF STREAMVOL_IS_VALID(trevorVolume)
STREAMVOL_DELETE(trevorVolume)
ENDIF
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_TREVOR_KILL_CAM)
iResetCopAccuracyTime = GET_GAME_TIMER() + 3000
SET_MISSION_CUTSCENE(FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, DEFAULT_PED_CAM_INTERP_TIME, TRUE)
SET_POLICE_IGNORE_PLAYER(PLAYER_ID(), TRUE)
BREAK
ENDSWITCH
ENDPROC
PROC DO_STEVE_LIGHT()
IF DOES_ENTITY_EXIST(cameraObject)
VECTOR vFront
VECTOR vSide
VECTOR vUp
VECTOR vPos
GET_ENTITY_MATRIX(cameraObject, vSide, vFront, vUp, vPos)
//SET_ENTITY_VISIBLE(cameraObject, FALSE)
VECTOR vDrawPos = vPos + (vFront * 0.165) + (vSide * 0.169)
DRAW_SHADOWED_SPOT_LIGHT(vDrawPos, vFront, 255, 255, 255, 4, 0.2, 20, 25, 2.5, 0)
ENDIF
ENDPROC
// trevor hit stage
PROC DO_STAGE_TREVOR_HIT
DO_COMMON_HIT_FUNCTIONS()
SET_ALL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID())
INT i
IF NOT bRunningCutscene
IF NOT g_bFinale3BHitSuccessful[CHAR_TREVOR]
IF createHitStage[CHAR_TREVOR] = CREATE_HIT_STAGE_DONE
IF NOT bShownSteveIntro
AND GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 0
/*
IF bDoneReadySpeech[CHAR_TREVOR]
AND GET_GAME_TIMER() >= iTrevorReadySpeechTime + 1400
IF NOT bCheckedInVehicle
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
bWasInVehicle = TRUE
ELSE
bWasInVehicle = FALSE
ENDIF
bCheckedInVehicle = TRUE
ENDIF
IF bCheckedInVehicle
AND bWasInVehicle
AND NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF NOT bKilledHintCamForLeaveVehicle
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
bKilledHintCamForLeaveVehicle = TRUE
ENDIF
ELSE
SET_CUSTOM_CHASE_HINT_CAM_INTERP_IN_TIME(localChaseHintCamStruct, 4000)
FORCE_CHASE_HINT_CAM(localChaseHintCamStruct, TRUE)
DISABLE_CONTROL_ACTION(CAMERA_CONTROL, INPUT_LOOK_LR)
DISABLE_CONTROL_ACTION(CAMERA_CONTROL, INPUT_LOOK_UD)
CONTROL_COORD_CHASE_HINT_CAM_ANY_MEANS(localChaseHintCamStruct, <<-1663.7, -1120.0, 43.3>>)
ENDIF
ENDIF
*/
IF createHitStage[CHAR_TREVOR] = CREATE_HIT_STAGE_DONE
HANDLE_STREAMING_MOCAP("fin_c2_mcs_1", <<-1664.34277, -1125.82056, 12.23751>>, 1000, 2000)
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
IF NOT IS_PED_INJURED(stevePed[STEVE_TARGET])
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Steve_FBI", stevePed[STEVE_TARGET])
ENDIF
IF NOT IS_PED_INJURED(stevePed[STEVE_CAMERAMAN])
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Grip_beside_director", stevePed[STEVE_CAMERAMAN])
ENDIF
ENDIF
IF CAN_PLAYER_START_CUTSCENE()
AND CAN_ADVANCE_MISSION()
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF steveState[STEVE_TARGET] <> STEVE_STATE_REACT
AND steveState[STEVE_TARGET] <> STEVE_STATE_COWER
IF bDoneReadySpeech[CHAR_TREVOR]
IF HAS_CUTSCENE_LOADED_WITH_FAILSAFE()
bDoShotSteveCutscene = FALSE
bRunningCutscene = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF bDoneWheelCamHelp
IF NOT bDoneDontGetCloseHelp
IF steveState[STEVE_TARGET] <> STEVE_STATE_REACT
AND steveState[STEVE_TARGET] <> STEVE_STATE_COWER
bDoneDontGetCloseHelp = DO_MISSION_HELP_TEXT("FC2_STVHLP")
ENDIF
ENDIF
ENDIF
SWITCH steveSpeechState
CASE STEVE_SPEECH_STATE_NOT_STARTED
IF createHitStage[CHAR_TREVOR] = CREATE_HIT_STAGE_DONE
INIT_SYNCH_SCENE_AUDIO_WITH_ENTITY("FIN_C2_MCS_1", stevePed[STEVE_TARGET])
steveSpeechState = STEVE_SPEECH_STATE_PREPARING
ENDIF
BREAK
CASE STEVE_SPEECH_STATE_PREPARING
IF PREPARE_SYNCHRONIZED_AUDIO_EVENT("FIN_C2_MCS_1", 0)
IF steveState[STEVE_TARGET] < STEVE_STATE_REACT
SET_STEVE_STATE(STEVE_TARGET, STEVE_STATE_SPEECH)
SET_STEVE_STATE(STEVE_CAMERAMAN, STEVE_STATE_SPEECH)
// camera
CREATE_MISSION_ANIM_CAM(FALSE, FALSE)
PLAY_SYNCHRONIZED_CAM_ANIM(animCam, iSteveSyncScene, "FIN_C2_MCS_1_CAM", GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_STEVE_SPEECH))
PLAY_SYNCHRONIZED_AUDIO_EVENT(iSteveSyncScene)
ENDIF
steveSpeechState = STEVE_SPEECH_STATE_DONE
ENDIF
BREAK
ENDSWITCH
ENDIF
IF steveState[STEVE_TARGET] = STEVE_STATE_SPEECH
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_MELEE_ATTACK_HEAVY)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_MELEE_ATTACK_LIGHT)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_MELEE_ATTACK_ALTERNATE)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_CIN_CAM)
ENDIF
// handle the camera view
IF bShownSteveIntro
IF IS_SYNCHRONIZED_SCENE_RUNNING(iSteveSyncScene)
AND steveState[STEVE_TARGET] = STEVE_STATE_SPEECH
BOOL bCamOn
FLOAT fStevePhase = GET_SYNCHRONIZED_SCENE_PHASE(iSteveSyncScene)
FLOAT fDoPhase
//PRINTSTRING("steve phase = ") PRINTFLOAT(fStevePhase) PRINTNL()
IF fStevePhase >= 0.3
bAllowWheelTopSpeed = TRUE
ENDIF
IF iCamViewCount < 4
SWITCH iCamViewCount
CASE 0
fDoPhase = 0
bCamOn = TRUE
BREAK
CASE 1
fDoPhase = 0.3405
bCamOn = FALSE
BREAK
CASE 2
fDoPhase = 0.5027
bCamOn = TRUE
BREAK
CASE 3
fDoPhase = 0.711
bCamOn = FALSE
BREAK
ENDSWITCH
IF fStevePhase >= fDoPhase
bShouldDoCamView = bCamOn
iCamViewCount++
ENDIF
ENDIF
ELSE
bShouldDoCamView = FALSE
ENDIF
IF g_bBrowserVisible
iBrowserTime = GET_GAME_TIMER()
ENDIF
IF NOT bUsingWheelCam
IF DOES_CAM_EXIST(animCam)
AND IS_SYNCHRONIZED_SCENE_RUNNING(iSteveSyncScene)
AND steveState[STEVE_TARGET] = STEVE_STATE_SPEECH
IF steveSpeechState = STEVE_SPEECH_STATE_DONE
IF NOT bDoneWheelCamHelp
bDoneWheelCamHelp = DO_MISSION_HELP_TEXT("FC2_WHLHLP")
IF bDoneWheelCamHelp
REPLAY_RECORD_BACK_FOR_TIME(5.0, 10.0, REPLAY_IMPORTANCE_HIGHEST)
ENDIF
ENDIF
ENDIF
IF IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_CIN_CAM)
IF GET_GAME_TIMER() >= iBrowserTime + 1000
AND NOT IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_SELECT_WEAPON)
AND NOT IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_AIM)
AND NOT IS_PHONE_ONSCREEN()
AND NOT bLockedOutOfWheelCam
DO_STEVE_LIGHT()
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
WAIT(0)
SET_CAM_ACTIVE(animCam, TRUE)
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_TREVOR_WATCH_STEVE_CAMERA)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
DISPLAY_RADAR(FALSE)
SET_FRONTEND_RADIO_ACTIVE(FALSE)
SET_CINEMATIC_MODE_ACTIVE(FALSE)
REPLAY_START_EVENT(REPLAY_IMPORTANCE_HIGHEST)
bDoneWheelCamHelp = TRUE
bReleasedCamButton = FALSE
bLockIntoWheelCam = FALSE
iWheelCamTime = GET_GAME_TIMER()
bUsingWheelCam = TRUE
ENDIF
ELSE
bLockedOutOfWheelCam = FALSE
ENDIF
ENDIF
ELSE
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("FC2_WHLHLP")
IF GET_GAME_TIMER() >= iClearHelpTime + 1000
CLEAR_HELP(FALSE)
iClearHelpTime = GET_GAME_TIMER()
ENDIF
ENDIF
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_TREVOR_CAR])
SET_FORCE_HD_VEHICLE(finaleVehicle[FV_TREVOR_CAR], TRUE)
ENDIF
BOOL bDisable = FALSE
IF NOT IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_CIN_CAM)
IF NOT bLockIntoWheelCam
IF GET_GAME_TIMER() >= iWheelCamTime + 500
bDisable = TRUE
bLockedOutOfWheelCam = FALSE
ELSE
bLockIntoWheelCam = TRUE
ENDIF
bReleasedCamButton = TRUE
ENDIF
ELSE
IF bReleasedCamButton
bDisable = TRUE
bLockedOutOfWheelCam = TRUE
ENDIF
ENDIF
IF bDisable
OR NOT DOES_CAM_EXIST(animCam)
OR not IS_SYNCHRONIZED_SCENE_RUNNING(iSteveSyncScene)
OR steveState[STEVE_TARGET] <> STEVE_STATE_SPEECH
IF DOES_CAM_EXIST(animCam)
SET_CAM_ACTIVE(animCam, FALSE)
ENDIF
REPLAY_STOP_EVENT()
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_TREVOR_WATCH_STEVE_CAMERA)
RENDER_SCRIPT_CAMS(FALSE, FALSE)
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
DISPLAY_RADAR(TRUE)
CLEAR_TIMECYCLE_MODIFIER()
CLEAR_PRINTS()
SET_FRONTEND_RADIO_ACTIVE(TRUE)
bCamViewTurnedOn = FALSE
bUsingWheelCam = FALSE
ENDIF
ENDIF
IF bUsingWheelCam
IF bCamViewTurnedOn
IF NOT bShouldDoCamView
CLEAR_TIMECYCLE_MODIFIER()
bCamViewTurnedOn = FALSE
ENDIF
ELSE
IF bShouldDoCamView
SET_TIMECYCLE_MODIFIER("scanline_cam_cheap")
bCamViewTurnedOn = TRUE
ENDIF
ENDIF
ENDIF
IF bUsingWheelCam
// spotlight
DO_STEVE_LIGHT()
DISABLE_CELLPHONE_THIS_FRAME_ONLY()
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_AIM)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SELECT_WEAPON)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ATTACK)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ATTACK)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ATTACK2)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_SELECT_NEXT_WEAPON)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_SELECT_PREV_WEAPON)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_SELECT_NEXT_WEAPON)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ATTACK)
ENDIF
ENDIF
IF IS_SYNCHRONIZED_SCENE_RUNNING(iSteveSyncScene)
AND steveState[STEVE_TARGET] = STEVE_STATE_SPEECH
// interrogation subs
FLOAT fSubPhase
STRING sSubLabel
BOOL bIsClear = FALSE
SWITCH iTVSubCount
CASE 0
fSubPhase = 0
sSubLabel = "FC2_SUB1"
BREAK
CASE 1
fSubPhase = 0.032
bIsClear = TRUE
BREAK
CASE 2
fSubPhase = 0.036
sSubLabel = "FC2_SUB2"
BREAK
CASE 3
fSubPhase = 0.095
bIsClear = TRUE
BREAK
CASE 4
fSubPhase = 0.100
sSubLabel = "FC2_SUB3"
BREAK
CASE 5
fSubPhase = 0.165
bIsClear = TRUE
BREAK
CASE 6
fSubPhase = 0.177
sSubLabel = "FC2_SUB4"
BREAK
CASE 7
fSubPhase = 0.234
bIsClear = TRUE
BREAK
CASE 8
fSubPhase = 0.248
sSubLabel = "FC2_SUB5"
BREAK
CASE 9
fSubPhase = 0.305
bIsClear = TRUE
BREAK
CASE 10
fSubPhase = 0.313
sSubLabel = "FC2_SUB6"
BREAK
CASE 11
fSubPhase = 0.326
bIsClear = TRUE
BREAK
CASE 12
fSubPhase = 0.335
sSubLabel = "FC2_SUB7"
BREAK
CASE 13
fSubPhase = 0.339
bIsClear = TRUE
BREAK
CASE 14
fSubPhase = 0.347
sSubLabel = "FC2_SUB8"
BREAK
CASE 15
fSubPhase = 0.359
bIsClear = TRUE
BREAK
CASE 16
fSubPhase = 0.359
sSubLabel = "FC2_SUB9"
BREAK
CASE 17
fSubPhase = 0.375
bIsClear = TRUE
BREAK
CASE 18
fSubPhase = 0.382
sSubLabel = "FC2_SUB10"
BREAK
CASE 19
fSubPhase = 0.408
bIsClear = TRUE
BREAK
CASE 20
fSubPhase = 0.414
sSubLabel = "FC2_SUB11"
BREAK
CASE 21
fSubPhase = 0.440
bIsClear = TRUE
BREAK
CASE 22
fSubPhase = 0.446
sSubLabel = "FC2_SUB12"
BREAK
CASE 23
fSubPhase = 0.451
bIsClear = TRUE
BREAK
CASE 24
fSubPhase = 0.467
sSubLabel = "FC2_SUB13"
BREAK
CASE 25
fSubPhase = 0.473
bIsClear = TRUE
BREAK
CASE 26
fSubPhase = 0.478
sSubLabel = "FC2_SUB14"
BREAK
CASE 27
fSubPhase = 0.502
bIsClear = TRUE
BREAK
CASE 28
fSubPhase = 0.524
sSubLabel = "FC2_SUB15"
BREAK
CASE 29
fSubPhase = 0.594
bIsClear = TRUE
BREAK
CASE 30
fSubPhase = 0.604
sSubLabel = "FC2_SUB16"
BREAK
CASE 31
fSubPhase = 0.665
bIsClear = TRUE
BREAK
CASE 32
fSubPhase = 0.675
sSubLabel = "FC2_SUB17"
BREAK
CASE 33
fSubPhase = 0.688
bIsClear = TRUE
BREAK
CASE 34
fSubPhase = 0.716
sSubLabel = "FC2_SUB18"
BREAK
CASE 35
fSubPhase = 0.723
bIsClear = TRUE
BREAK
CASE 36
fSubPhase = 0.725
sSubLabel = "FC2_SUB19"
BREAK
CASE 37
fSubPhase = 0.738
bIsClear = TRUE
BREAK
CASE 38
fSubPhase = 0.739
sSubLabel = "FC2_SUB20"
BREAK
CASE 39
fSubPhase = 0.746
bIsClear = TRUE
BREAK
CASE 40
fSubPhase = 0.750
sSubLabel = "FC2_SUB21"
BREAK
CASE 41
fSubPhase = 0.763
bIsClear = TRUE
BREAK
CASE 42
fSubPhase = 0.791
sSubLabel = "FC2_SUB22"
BREAK
CASE 43
fSubPhase = 0.803
bIsClear = TRUE
BREAK
CASE 44
fSubPhase = 0.804
sSubLabel = "FC2_SUB23"
BREAK
CASE 45
fSubPhase = 0.837
bIsClear = TRUE
BREAK
CASE 46
fSubPhase = 0.844
sSubLabel = "FC2_SUB24"
BREAK
CASE 47
fSubPhase = 0.853
bIsClear = TRUE
BREAK
CASE 48
fSubPhase = 0.856
sSubLabel = "FC2_SUB25"
BREAK
CASE 49
fSubPhase = 0.868
bIsClear = TRUE
BREAK
CASE 50
fSubPhase = 0.886
sSubLabel = "FC2_SUB26"
BREAK
CASE 51
fSubPhase = 0.910
bIsClear = TRUE
BREAK
CASE 52
fSubPhase = 0.933
sSubLabel = "FC2_SUB27"
BREAK
CASE 53
fSubPhase = 0.95
bIsClear = TRUE
BREAK
ENDSWITCH
IF iTVSubCount < 54
IF GET_SYNCHRONIZED_SCENE_PHASE(iSteveSyncScene) >= fSubPhase
IF IS_SUBTITLE_PREFERENCE_SWITCHED_ON()
IF NOT bIsClear
IF bUsingWheelCam
FORCE_NEXT_MESSAGE_TO_PREVIOUS_BRIEFS_LIST(PREVIOUS_BRIEF_FORCE_DIALOGUE)
PRINT_NOW(sSubLabel, DEFAULT_GOD_TEXT_TIME, 1)
ENDIF
ELSE
IF bUsingWheelCam
CLEAR_PRINTS()
ENDIF
ENDIF
ELSE
IF bUsingWheelCam
CLEAR_PRINTS()
ENDIF
ENDIF
iTVSubCount++
ENDIF
ENDIF
ENDIF
IF NOT bDoneReadySpeech[CHAR_TREVOR]
IF steveState[STEVE_TARGET] < STEVE_STATE_REACT
IF DO_MISSION_SPEECH("FINC1_THR")
TRIGGER_MISSION_MUSIC_EVENT("FINC2_STEVE_START")
bDoneReadySpeech[CHAR_TREVOR] = TRUE
ENDIF
// iTrevorReadySpeechTime = GET_GAME_TIMER()
ELSE
bDoneReadySpeech[CHAR_TREVOR] = TRUE
ENDIF
ELSE
IF NOT bShownDoHitText[CHAR_TREVOR]
IF NOT IS_PED_INJURED(stevePed[STEVE_TARGET])
IF steveSpeechState = STEVE_SPEECH_STATE_DONE
bShownDoHitText[CHAR_TREVOR] = DO_MISSION_GOD_TEXT("FC2_KILLSTE")
ENDIF
ENDIF
ENDIF
ENDIF
// fail for react
IF steveState[STEVE_TARGET] = STEVE_STATE_REACT
OR steveState[STEVE_TARGET] = STEVE_STATE_COWER
IF NOT bSteveDead[STEVE_TARGET]
IF bDoSpookedSpeech
IF NOT bDoneSpookedSpeech
IF bDoSeenSpeech
bDoneSpookedSpeech = DO_MISSION_SPEECH("FINC1_SSETRE")
ELSE
VECTOR vOffsetFromSteve
vOffsetFromSteve = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(stevePed[STEVE_TARGET], GET_ENTITY_COORDS(PLAYER_PED_ID()))
IF vOffsetFromSteve.y > 0
AND vOffsetFromSteve.z > -1
bDoneSpookedSpeech = DO_MISSION_SPEECH("FINC1_SSETRE")
ELSE
bDoneSpookedSpeech = DO_MISSION_SPEECH("FINC1_STPAN")
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
IF NOT IS_PED_INJURED(stevePed[STEVE_TARGET])
BOOL bSpookedFail = FALSE
IF GET_GAME_TIMER() >= iSteveReactTime + 7400 // 5000
bSpookedFail = TRUE
ELSE
IF IS_SYNCHRONIZED_SCENE_RUNNING(iSteveSyncScene)
IF GET_SYNCHRONIZED_SCENE_PHASE(iSteveSyncScene) >= 0.98
bSpookedFail = TRUE
ENDIF
ENDIF
ENDIF
IF bSpookedFail
VECTOR vStevePos = GET_ENTITY_COORDS(stevePed[STEVE_TARGET])
VECTOR vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID())
#IF IS_DEBUG_BUILD
IF NOT bDEBUG_DisableMissionFail
#ENDIF
IF vStevePos.z > vPlayerPos.z + 5
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
MISSION_FAILED(FAIL_STEVE_SPOOKED)
ENDIF
#IF IS_DEBUG_BUILD
ENDIF
#ENDIF
ENDIF
ENDIF
ENDIF
BOOL bKilledSteve = FALSE
REPEAT COUNT_OF(STEVE_ENUM) i
STEVE_ENUM thisSteve = INT_TO_ENUM(STEVE_ENUM, i)
IF DOES_ENTITY_EXIST(stevePed[i])
IF IS_PED_INJURED(stevePed[i])
OR bSteveDead[i]
IF DOES_BLIP_EXIST(steveBlip[i])
REMOVE_BLIP(steveBlip[i])
ENDIF
IF thisSteve = STEVE_TARGET
bKilledSteve = TRUE
eSwitchCamState = SWITCH_CAM_SETUP_SPLINE
iBulletCamTime=iBulletCamTime
IF bSwitchCam_SteveKilledViaExplosion
bDoneBulletCamFlash = FALSE
iBulletCamTime = GET_GAME_TIMER()
WHILE NOT HANDLE_SWITCH_CAM_BULLET_CAM(scsSwitchCamExplosion, TRUE)
IF NOT bDoneBulletCamFlash
IF GET_CAM_VIEW_MODE_FOR_CONTEXT(GET_CAM_ACTIVE_VIEW_MODE_CONTEXT()) = CAM_VIEW_MODE_FIRST_PERSON
IF IS_CAM_ACTIVE(scsSwitchCamExplosion.ciSpline)
IF GET_CAM_SPLINE_PHASE(scsSwitchCamExplosion.ciSpline) >= 0.89
ANIMPOSTFX_PLAY("CamPushInNeutral", 0, FALSE)
PLAY_SOUND_FRONTEND(-1, "1st_Person_Transition", "PLAYER_SWITCH_CUSTOM_SOUNDSET")
PRINTSTRING("start time = ") PRINTINT(GET_GAME_TIMER() - iBulletCamTime) PRINTNL()
bDoneBulletCamFlash = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
#IF IS_DEBUG_BUILD
UPDATE_SPLINE_CAM_WIDGETS(scsSwitchCamExplosion)
#ENDIF
HANDLE_CREATE_WHEEL()
WAIT(0)
ENDWHILE
PRINTSTRING("end time = ") PRINTINT(GET_GAME_TIMER() - iBulletCamTime) PRINTNL()
RENDER_SCRIPT_CAMS(FALSE, FALSE)
bSuppressShotCutscene = TRUE
ELIF bSwitchCam_SteveKilledViaGrenade
bDoneBulletCamFlash = FALSE
iBulletCamTime = GET_GAME_TIMER()
WHILE NOT HANDLE_SWITCH_CAM_BULLET_CAM(scsSwitchCamGrenade, TRUE)
IF NOT bDoneBulletCamFlash
IF GET_CAM_VIEW_MODE_FOR_CONTEXT(GET_CAM_ACTIVE_VIEW_MODE_CONTEXT()) = CAM_VIEW_MODE_FIRST_PERSON
IF IS_CAM_ACTIVE(scsSwitchCamGrenade.ciSpline)
IF GET_CAM_SPLINE_PHASE(scsSwitchCamGrenade.ciSpline) >= 0.89
ANIMPOSTFX_PLAY("CamPushInNeutral", 0, FALSE)
PLAY_SOUND_FRONTEND(-1, "1st_Person_Transition", "PLAYER_SWITCH_CUSTOM_SOUNDSET")
PRINTSTRING("start time = ") PRINTINT(GET_GAME_TIMER() - iBulletCamTime) PRINTNL()
bDoneBulletCamFlash = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
#IF IS_DEBUG_BUILD
UPDATE_SPLINE_CAM_WIDGETS(scsSwitchCamGrenade)
#ENDIF
HANDLE_CREATE_WHEEL()
WAIT(0)
ENDWHILE
PRINTSTRING("end time = ") PRINTINT(GET_GAME_TIMER() - iBulletCamTime) PRINTNL()
RENDER_SCRIPT_CAMS(FALSE, FALSE)
bSuppressShotCutscene = TRUE
ELSE
IF NOT bSetDoBulletCam
IF NOT IS_PED_INJURED(stevePed[STEVE_TARGET])
VECTOR vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID())
VECTOR vStevePos = GET_ENTITY_COORDS(stevePed[STEVE_TARGET])
IF GET_DISTANCE_BETWEEN_COORDS(vPlayerPos, vStevePos) < 5
bSuppressBulletCam = TRUE
ELSE
bSuppressBulletCam = FALSE
ENDIF
ENDIF
bSetDoBulletCam = TRUE
ENDIF
IF NOT bSuppressBulletCam
WHILE NOT HANDLE_SWITCH_CAM_BULLET_CAM(scsSwitchCamBulletCam, TRUE)
#IF IS_DEBUG_BUILD
UPDATE_SPLINE_CAM_WIDGETS(scsSwitchCamBulletCam)
#ENDIF
HANDLE_CREATE_WHEEL()
WAIT(0)
ENDWHILE
ENDIF
IF NOT IS_PED_INJURED(stevePed[STEVE_CAMERAMAN])
AND NOT bSteveDead[STEVE_CAMERAMAN]
DO_TREVOR_SNIPE_CUTSCENE()
ELSE
RENDER_SCRIPT_CAMS(FALSE, FALSE)
bSuppressShotCutscene = TRUE
ENDIF
ENDIF
ENDIF
ELSE
IF thisSteve = STEVE_TARGET
IF NOT DOES_BLIP_EXIST(steveBlip[i])
steveBlip[i] = CREATE_MISSION_BLIP_FOR_PED(stevePed[i], TRUE)
ENDIF
IF NOT bBeenCloseToSteve
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), stevePed[i], <<150,150,150>>)
bBeenCloseToSteve = TRUE
ELIF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), stevePed[i], <<330,330,330>>)
MISSION_FAILED(FAIL_ABANDONED_STEVE)
ENDIF
ELSE
IF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), stevePed[i], <<210,210,210>>, FALSE, FALSE)
MISSION_FAILED(FAIL_ABANDONED_STEVE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
IF bKilledSteve
AND GET_GAME_TIMER() >= iSteveDeadTime + 120
IF DOES_ENTITY_EXIST(stevePed[STEVE_TARGET])
PED_BONETAG damageBone
IF GET_PED_LAST_DAMAGE_BONE(stevePed[STEVE_TARGET], damageBone)
IF damageBone = BONETAG_HEAD
INFORM_STAT_SYSTEM_OF_BOOL_STAT_HAPPENED(FIN_HAINES_HEADSHOT)
ENDIF
ENDIF
ENDIF
IF CAN_ADVANCE_MISSION()
REPLAY_RECORD_BACK_FOR_TIME(10.0, 15.0, REPLAY_IMPORTANCE_HIGHEST)
INFORM_MISSION_STATS_OF_INCREMENT(FIN_KILLS)
sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_TREVOR] = TRUE
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_TREVOR_KILL_STEVE)
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_TREVOR_FOCUS_ON_WHEEL)
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_TREVOR_WATCH_STEVE_CAMERA)
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_TREVOR_KILL_CAM)
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
CLEAR_TIMECYCLE_MODIFIER()
g_bFinale3BHitSuccessful[CHAR_TREVOR] = TRUE
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) < 2
SET_WANTED_LEVEL_DIFFICULTY(PLAYER_ID(), 0)
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 2)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
ENDIF
IF NOT bSuppressShotCutscene
IF NOT IS_PED_INJURED(stevePed[STEVE_CAMERAMAN])
AND NOT bSteveDead[STEVE_CAMERAMAN]
bDoShotSteveCutscene = TRUE
bRunningCutscene = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF NOT bResetCopAccuracy
IF GET_GAME_TIMER() >= iResetCopAccuracyTime
REPEAT NUMBER_PIER_COPS i
IF NOT IS_PED_INJURED(copPed[i])
SET_PED_ACCURACY(copPed[i], 40)
ENDIF
ENDREPEAT
PLAY_POLICE_REPORT("SCRIPTED_SCANNER_REPORT_FIN_C2_01", 0.0)
SET_POLICE_IGNORE_PLAYER(PLAYER_ID(), FALSE)
bResetCopAccuracy = TRUE
ENDIF
ENDIF
IF NOT bEscapedArea[CHAR_TREVOR]
IF IS_THIS_PRINT_BEING_DISPLAYED("FC2_KILLSTE")
REMOVE_MISSION_TEXT(FALSE, TRUE, FALSE)
ENDIF
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 0
RESET_WANTED_LEVEL_DIFFICULTY(PLAYER_ID())
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
TRIGGER_MISSION_MUSIC_EVENT("FINC2_STEVE_DONE_FOOT")
ELSE
TRIGGER_MISSION_MUSIC_EVENT("FINC2_STEVE_DONE")
ENDIF
bEscapedArea[CHAR_TREVOR] = TRUE
ELSE
IF NOT bShownEscapePrompt[CHAR_TREVOR]
IF DO_MISSION_GOD_TEXT("LOSE_WANTED")
bShownEscapePrompt[CHAR_TREVOR] = TRUE
TRIGGER_MISSION_MUSIC_EVENT("FINC2_STEVE_LOSE_COPS")
ENDIF
ENDIF
ENDIF
ELSE
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 0
OR freeHotswapData.state <> FREE_HOTSWAP_STATE_SELECTING
IF IS_THIS_PRINT_BEING_DISPLAYED("LOSE_WANTED")
REMOVE_MISSION_TEXT(FALSE, TRUE, FALSE)
ENDIF
bShownLoseWantedPrompt = FALSE
IF NOT bTaskedCopsToWander
REPEAT NUMBER_PIER_COPS i
IF NOT IS_PED_INJURED(copPed[i])
TASK_WANDER_STANDARD(copPed[i])
ENDIF
ENDREPEAT
bTaskedCopsToWander = TRUE
ENDIF
IF NOT bDoneHitSuccessfulSpeech[CHAR_TREVOR]
bDoneHitSuccessfulSpeech[CHAR_TREVOR] = DO_MISSION_SPEECH("FINC1_TDH")
ELSE
IF NOT bDoneWhoNextQuestionSpeech
IF HAVE_ALL_HITS_SUCCEEDED()
bDoneWhoNextQuestionSpeech = TRUE
ELSE
bDoneWhoNextQuestionSpeech = DO_WHO_NEXT_QUESTION_SPEECH()
ENDIF
ELSE
IF HAVE_ALL_HITS_SUCCEEDED()
SET_MISSION_STAGE(STAGE_PICKUP_DEVIN, FALSE, FALSE)
ELSE
IF NOT bDoneWhoNextAnswerSpeech
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", TRUE)
bDoneWhoNextAnswerSpeech = DO_WHO_NEXT_ANSWER_SPEECH()
ELSE
IF NOT bShownSwitchPrompt
IF freeHotswapData.state = FREE_HOTSWAP_STATE_SELECTING
bShownSwitchPrompt = DO_MISSION_GOD_TEXT(GET_STRING_FOR_SWITCH_PROMPT())
ENDIF
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_MICHAEL]
IF sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_FRANKLIN]
DO_MISSION_HINT(SELECTOR_PED_MICHAEL)
ENDIF
ELIF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_FRANKLIN]
DO_MISSION_HINT(SELECTOR_PED_FRANKLIN)
ENDIF
ENDIF
IF CAN_DO_FREE_HOTSWAP()
HANDLE_FREE_HOTSWAP()
ENDIF
ENDIF
//IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
//ENDIF
ENDIF
ENDIF
ENDIF
ELSE
bTaskedCopsToWander = FALSE
IF NOT bShownLoseWantedPrompt
bShownLoseWantedPrompt = DO_MISSION_GOD_TEXT("LOSE_WANTED")
ENABLE_DISPATCH_SERVICE(DT_POLICE_AUTOMOBILE, TRUE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_VEHICLE_REQUEST, TRUE)
SET_CREATE_RANDOM_COPS(TRUE)
ENDIF
bShownSwitchPrompt = FALSE
ENDIF
ENDIF
IF CAN_ADVANCE_MISSION()
BOOL bDeleteTrevor = FALSE
IF freeHotswapData.state = FREE_HOTSWAP_STATE_SELECTING
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
OR GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL
SET_MISSION_STAGE(STAGE_GET_TO_HIT, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE)
bDeleteTrevor = TRUE
ENDIF
ENDIF
IF bDeleteTrevor
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_TREVOR_CAR])
SET_PED_INTO_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], finaleVehicle[FV_TREVOR_CAR])
SET_ENTITY_COORDS(finaleVehicle[FV_TREVOR_CAR], GET_PLAYER_HIDE_POS(CHAR_TREVOR))
FREEZE_ENTITY_POSITION(finaleVehicle[FV_TREVOR_CAR], TRUE)
ELSE
SET_ENTITY_COORDS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], GET_PLAYER_HIDE_POS(CHAR_TREVOR))
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF bDoShotSteveCutscene
DO_TREVOR_SNIPE_CUTSCENE()
ELSE
DO_STEVE_INTRO_CUTSCENE()
ENDIF
ENDIF
IF DOES_BLIP_EXIST(gotoBlip)
REMOVE_BLIP(gotoBlip)
ENDIF
ENDPROC
// michael hit stage
PROC DO_STAGE_MICHAEL_HIT
DO_COMMON_HIT_FUNCTIONS()
SET_ALL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID())
INT i
IF NOT bRunningCutscene
IF NOT bDoneAttackStretchMusic
IF gangsterAggro > GANGSTER_AGGRO_NOT_AGGROED
TRIGGER_MISSION_MUSIC_EVENT("FINC2_STRETCH_SHOT")
bDoneAttackStretchMusic = TRUE
ENDIF
ENDIF
IF GET_GAME_TIMER() < iResetPlayerCameraControlTime
DISABLE_CONTROL_ACTION(CAMERA_CONTROL, INPUT_LOOK_LR)
DISABLE_CONTROL_ACTION(CAMERA_CONTROL, INPUT_LOOK_UD)
ENDIF
IF NOT bDoneInstanceHintShooting
IF gangsterAggro > GANGSTER_AGGRO_NOT_AGGROED
SET_INSTANCE_PRIORITY_HINT(INSTANCE_HINT_SHOOTING)
bDoneInstanceHintShooting = TRUE
ENDIF
ENDIF
BOOL bShouldHeadlookStretch = FALSE
IF gangsterPed[GANGSTER_STRETCH].state < GANGSTER_STATE_COMBAT
AND NOT bGangstersHostileFromAggro
IF NOT IS_PED_INJURED(gangsterPed[GANGSTER_STRETCH].ped)
bShouldHeadlookStretch = TRUE
ENDIF
ENDIF
IF bShouldHeadlookStretch
IF NOT IS_PED_HEADTRACKING_ENTITY(PLAYER_PED_ID(), gangsterPed[GANGSTER_STRETCH].ped)
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), gangsterPed[GANGSTER_STRETCH].ped, -1, SLF_WHILE_NOT_IN_FOV)
ENDIF
ELSE
IF NOT IS_PED_INJURED(gangsterPed[GANGSTER_STRETCH].ped)
IF IS_PED_HEADTRACKING_ENTITY(PLAYER_PED_ID(), gangsterPed[GANGSTER_STRETCH].ped)
TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
ENDIF
ELSE
IF NOT bClearedLookAtForKilledStretch
TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
bClearedLookAtForKilledStretch = TRUE
ENDIF
ENDIF
ENDIF
IF NOT g_bFinale3BHitSuccessful[CHAR_MICHAEL]
IF createHitStage[CHAR_MICHAEL] = CREATE_HIT_STAGE_DONE
IF NOT bDoneReadySpeech[CHAR_MICHAEL]
//IF NOT bJumpedAheadToMichaelHit
IF gangsterAggro = GANGSTER_AGGRO_NOT_AGGROED
AND NOT bKilledSpeechForHail
IF bDonePhoneIntroSpeech
IF DO_MISSION_SPEECH("FINC1_MHR")
bDoneReadySpeech[CHAR_MICHAEL] = TRUE
ENDIF
ENDIF
ELSE
bDoneReadySpeech[CHAR_MICHAEL] = TRUE
ENDIF
ELSE
IF NOT bShownDoHitText[CHAR_MICHAEL]
AND NOT bKilledSpeechForHail
bShownDoHitText[CHAR_MICHAEL] = DO_MISSION_GOD_TEXT("FC2_KILLSTR")
ENDIF
ENDIF
// stretch
BOOL bKilledStretch = FALSE
REPEAT COUNT_OF(GANGSTER_ENUM) i
GANGSTER_ENUM thisGangster = INT_TO_ENUM(GANGSTER_ENUM, i)
IF DOES_ENTITY_EXIST(gangsterPed[i].ped)
IF IS_PED_INJURED(gangsterPed[i].ped)
IF thisGangster = GANGSTER_STRETCH
IF DOES_BLIP_EXIST(stretchBlip)
REMOVE_BLIP(stretchBlip)
ENDIF
bKilledStretch = TRUE
ENDIF
ELSE
IF thisGangster = GANGSTER_STRETCH
// update if stretch is in a vehicle
BOOL bStretchCar = IS_STRETCH_IN_CAR()
IF CAN_ADVANCE_MISSION()
IF bStretchCar
IF NOT bCacheStretchInCar
OR NOT DOES_BLIP_EXIST(stretchBlip)
IF DOES_BLIP_EXIST(stretchBlip)
REMOVE_BLIP(stretchBlip)
ENDIF
CREATE_MISSION_BLIP_FOR_STRETCH(TRUE)
ENDIF
ELSE
IF bCacheStretchInCar
OR NOT DOES_BLIP_EXIST(stretchBlip)
IF DOES_BLIP_EXIST(stretchBlip)
REMOVE_BLIP(stretchBlip)
ENDIF
CREATE_MISSION_BLIP_FOR_STRETCH(FALSE)
ENDIF
ENDIF
ENDIF
bCacheStretchInCar = bStretchCar
// fail if lost
BOOL bFailForLostStretch = FALSE
FLOAT fFailDist
IF NOT bCacheStretchInCar
fFailDist = 150.0
ELSE
fFailDist = 300.0
ENDIF
UPDATE_CHASE_BLIP(stretchBlip, gangsterPed[i].ped, fFailDist)
IF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), gangsterPed[i].ped, <<fFailDist,fFailDist,fFailDist>>, FALSE, FALSE)
bFailForLostStretch = TRUE
ENDIF
IF bFailForLostStretch
IF DOES_BLIP_EXIST(stretchBlip)
REMOVE_BLIP(stretchBlip)
ENDIF
MISSION_FAILED(FAIL_LOST_STRETCH)
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
IF NOT IS_PED_INJURED(gangsterPed[GANGSTER_STRETCH].ped)
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), gangsterPed[GANGSTER_STRETCH].ped, <<35, 35, 35>>, FALSE, FALSE)
IF NOT bDoneHailStretchSpeech
IF gangsterAggro = GANGSTER_AGGRO_DANGER
bDoneHailStretchSpeech = TRUE
ELSE
//IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), gangsterPed[GANGSTER_STRETCH], <<19,19,19>>, FALSE, FALSE)
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(gangsterPed[GANGSTER_STRETCH].ped)) < 17.0
AND gangsterPed[GANGSTER_STRETCH].state >= GANGSTER_STATE_IDLE
IF NOT bKilledSpeechForHail
KILL_ANY_CONVERSATION()
bKilledSpeechForHail = TRUE
ENDIF
IF DO_MISSION_SPEECH("FINC1_MCOMB", TRUE)
iHailStretchSpeechTime = GET_GAME_TIMER()
bDoneHailStretchSpeech = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
IF gangsterAggro <> GANGSTER_AGGRO_NOT_AGGROED
IF NOT bDoneStretchToCombatSpeech
IF bDoneHailStretchSpeech
bShownDoHitText[CHAR_MICHAEL] = TRUE
bDoneStretchToCombatSpeech = DO_MISSION_SPEECH("FINC1_SGCOMB", TRUE)
ENDIF
ELSE
IF NOT bDoneCowardlySpeech
IF NOT IS_PED_INJURED(gangsterPed[GANGSTER_M].ped)
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), gangsterPed[GANGSTER_M].ped, <<30,30,6>>)
bDoneCowardlySpeech = DO_MISSION_SPEECH("FINC1_COWARD")
ELSE
bDoneCowardlySpeech = TRUE
ENDIF
ELSE
bDoneCowardlySpeech = TRUE
ENDIF
ELSE
IF NOT bDoneDisloyalSpeech
IF IS_PED_INJURED(gangsterPed[GANGSTER_L].ped)
AND IS_PED_INJURED(gangsterPed[GANGSTER_M].ped)
AND IS_PED_INJURED(gangsterPed[GANGSTER_R].ped)
bDoneDisloyalSpeech = DO_MISSION_SPEECH("FINC_MSTRET")
IF bDoneDisloyalSpeech
REPLAY_RECORD_BACK_FOR_TIME(4.0, 8.0, REPLAY_IMPORTANCE_HIGHEST)
ENDIF
ELSE
bDoneDisloyalSpeech = DO_MISSION_SPEECH("FINC1_DISL")
ENDIF
ELSE
//IF NOT bDoneMichaelShootSpeech
// IF IS_PED_SHOOTING(PLAYER_PED_ID())
// bDoneMichaelShootSpeech = DO_MISSION_SPEECH("FINC1_MCOMB")
// ENDIF
//ENDIF
IF NOT bDoneStretchThreatenSpeech
IF DO_MISSION_SPEECH("FINC1_SICOMB")
bDoneStretchThreatenSpeech = TRUE
iNextRandomSpeechTime = GET_GAME_TIMER() + 12000
ENDIF
ELSE
DO_RANDOM_SPEECH("FINC1_SATT", 12000, 16000)
ENDIF
ENDIF
ENDIF
IF NOT bDoneStretchOrderSpeech
IF gangsterPed[GANGSTER_STRETCH].state = GANGSTER_STATE_COMBAT AND GET_GAME_TIMER() >= iSetStretchToCombatTime + 12000
IF DO_MISSION_SPEECH("FINC1_SORDER")
bDoneStretchOrderSpeech = TRUE
iNextRandomSpeechTime = GET_GAME_TIMER() + 7000
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF NOT bDoneHailStretchSpeech
IF NOT bDonePhoneIntroSpeech
IF gangsterPed[GANGSTER_STRETCH].state >= GANGSTER_STATE_GATHER_AT_PHONE
bDonePhoneIntroSpeech = DO_MISSION_SPEECH("FINC1_SPHINT")//, FALSE, 9, TRUE)
ENDIF
ELSE
IF gangsterPed[GANGSTER_STRETCH].state = GANGSTER_STATE_IDLE
IF GET_RANDOM_INT_IN_RANGE(0,2) = 0
IF iGangsterBanterCount < 3
IF DO_RANDOM_SPEECH("FINC1_LPHONE")
iGangsterBanterCount++
ENDIF
ENDIF
ELSE
IF iStretchBanterCount < 4
IF DO_RANDOM_SPEECH("FINC1_IG6")
iStretchBanterCount++
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
IF bKilledStretch
IF DOES_ENTITY_EXIST(gangsterPed[GANGSTER_STRETCH].ped)
IF HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON(gangsterPed[GANGSTER_STRETCH].ped, WEAPONTYPE_INVALID, GENERALWEAPON_TYPE_ANYMELEE)
INFORM_STAT_SYSTEM_OF_BOOL_STAT_HAPPENED(FIN_STRETCH_STRONGARM)
ENDIF
ENDIF
IF CAN_ADVANCE_MISSION()
//REPEAT NUMBER_GANGSTER_VEHICLES i
// IF DOES_ENTITY_EXIST(gangsterVehicle[i])
/// SET_VEHICLE_AS_NO_LONGER_NEEDED(gangsterVehicle[i])
// ENDIF
//ENDREPEAT
IF g_bFinale3BHitSuccessful[CHAR_MICHAEL] = FALSE
REPLAY_RECORD_BACK_FOR_TIME(4.0, 8.0, REPLAY_IMPORTANCE_HIGHEST)
ENDIF
iStretchDeadTime = GET_GAME_TIMER()
SET_INSTANCE_PRIORITY_HINT(INSTANCE_HINT_NONE)
sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_MICHAEL] = TRUE
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_MICHAEL_KILL_STRETCH)
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_MICHAEL_KILL_BALLAS)
fMaxGangsterWarpVehicleDistance = 230.0
g_bFinale3BHitSuccessful[CHAR_MICHAEL] = TRUE
ENDIF
ENDIF
ENDIF
ELSE
fMaxGangsterWarpVehicleDistance = fMaxGangsterWarpVehicleDistance -@ 0.4
IF fMaxGangsterWarpVehicleDistance < 0
fMaxGangsterWarpVehicleDistance = 0
ENDIF
IF NOT bEscapedArea[CHAR_MICHAEL]
IF IS_THIS_PRINT_BEING_DISPLAYED("FC2_KILLSTR")
REMOVE_MISSION_TEXT(FALSE, TRUE, FALSE)
ENDIF
IF NOT bNearGangster
bEscapedArea[CHAR_MICHAEL] = TRUE
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_MICHAEL_KILL_BALLAS)
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_MICHAEL_ENEMY_CAR_ARRIVES)
// get rid of gangsters
REPEAT COUNT_OF(GANGSTER_ENUM) i
CLEANUP_AI_PED_BLIP(gangsterPed[i].blipStruct)
IF DOES_ENTITY_EXIST(gangsterPed[i].ped)
IF NOT IS_PED_INJURED(gangsterPed[i].ped)
TASK_SMART_FLEE_PED(gangsterPed[i].ped, PLAYER_PED_ID(), 1000, -1)
ENDIF
SET_PED_AS_NO_LONGER_NEEDED(gangsterPed[i].ped)
ENDIF
ENDREPEAT
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
TRIGGER_MISSION_MUSIC_EVENT("FINC2_STRETCH_DONE_FOOT")
ELSE
TRIGGER_MISSION_MUSIC_EVENT("FINC2_STRETCH_DONE")
ENDIF
REMOVE_ALL_BLIPS()
ELSE
IF NOT bShownEscapePrompt[CHAR_MICHAEL]
IF bDoneRevengeForStretchSpeech
bShownEscapePrompt[CHAR_MICHAEL] = DO_MISSION_GOD_TEXT("FC2_ESCHOOD")
ENDIF
ENDIF
ENDIF
ELSE
IF IS_THIS_PRINT_BEING_DISPLAYED("FC2_ESCHOOD")
REMOVE_MISSION_TEXT(FALSE, TRUE, FALSE)
ENDIF
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 0
OR freeHotswapData.state <> FREE_HOTSWAP_STATE_SELECTING
IF IS_THIS_PRINT_BEING_DISPLAYED("LOSE_WANTED")
REMOVE_MISSION_TEXT(FALSE, TRUE, FALSE)
ENDIF
bShownLoseWantedPrompt = FALSE
IF NOT bDoneHitSuccessfulSpeech[CHAR_MICHAEL]
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
bDoneHitSuccessfulSpeech[CHAR_MICHAEL] = DO_MISSION_SPEECH("FINC1_MDH")
ELSE
IF NOT bDoneWhoNextQuestionSpeech
bDoneWhoNextQuestionSpeech = DO_WHO_NEXT_QUESTION_SPEECH()
ELSE
IF NOT bDoneWhoNextAnswerSpeech
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", TRUE)
bDoneWhoNextAnswerSpeech = DO_WHO_NEXT_ANSWER_SPEECH()
ELSE
IF NOT bShownSwitchPrompt
IF freeHotswapData.state = FREE_HOTSWAP_STATE_SELECTING
bShownSwitchPrompt = DO_MISSION_GOD_TEXT(GET_STRING_FOR_SWITCH_PROMPT())
ENDIF
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_TREVOR]
IF sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_FRANKLIN]
DO_MISSION_HINT(SELECTOR_PED_TREVOR)
ENDIF
ELIF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_FRANKLIN]
DO_MISSION_HINT(SELECTOR_PED_FRANKLIN)
ENDIF
ENDIF
IF CAN_DO_FREE_HOTSWAP()
HANDLE_FREE_HOTSWAP()
ENDIF
ENDIF
IF sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_TREVOR]
IF HAVE_ALL_HITS_SUCCEEDED()
DO_MISSION_HINT(SELECTOR_PED_TREVOR)
SET_SELECTOR_PED_PRIORITY(sSelectorPeds, SELECTOR_PED_TREVOR, SELECTOR_PED_MICHAEL, SELECTOR_PED_FRANKLIN)
sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_TREVOR] = FALSE
ENDIF
ENDIF
//IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
//IF freeHotswapData.state <> FREE_HOTSWAP_STATE_SELECTING
//ENDIF
ENDIF
ENDIF
ELSE
IF NOT bShownLoseWantedPrompt
bShownLoseWantedPrompt = DO_MISSION_GOD_TEXT("LOSE_WANTED")
ENABLE_DISPATCH_SERVICE(DT_POLICE_AUTOMOBILE, TRUE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_VEHICLE_REQUEST, TRUE)
SET_CREATE_RANDOM_COPS(TRUE)
ENDIF
bShownSwitchPrompt = FALSE
ENDIF
ENDIF
ENDIF
IF CAN_ADVANCE_MISSION()
IF bRecordAdvance = FALSE
REPLAY_RECORD_BACK_FOR_TIME(4.0, 8.0, REPLAY_IMPORTANCE_HIGHEST)
bRecordAdvance = TRUE
ENDIF
BOOL bDeleteMichael = FALSE
IF freeHotswapData.state = FREE_HOTSWAP_STATE_SELECTING
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
SET_MISSION_STAGE(STAGE_GET_TO_HIT, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE)
bDeleteMichael = TRUE
ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_TREVOR
IF g_bFinale3BHitSuccessful[CHAR_TREVOR]
SET_MISSION_STAGE(STAGE_PICKUP_DEVIN)
bDeleteMichael = TRUE
ELSE
SET_MISSION_STAGE(STAGE_GET_TO_HIT, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE)
bDeleteMichael = TRUE
ENDIF
ENDIF
IF bDeleteMichael
IF DOES_ENTITY_EXIST(sSelectorPeds.pedID[SELECTOR_PED_MICHAEL])
SET_PLAYER_PED_WITH_HEADSET(CHAR_MICHAEL, FALSE)
STORE_PLAYER_PED_VARIATIONS(sSelectorPeds.pedID[SELECTOR_PED_MICHAEL], TRUE)
DELETE_PED(sSelectorPeds.pedID[SELECTOR_PED_MICHAEL])
ADD_PED_FOR_DIALOGUE(finaleConversation, 0, NULL, "MICHAEL")
ENDIF
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_MICHAEL))
IF DOES_ENTITY_EXIST(finaleVehicle[FV_MICHAEL_CAR])
DELETE_VEHICLE(finaleVehicle[FV_MICHAEL_CAR])
ENDIF
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_MICHAEL_CAR))
ENDIF
ENDIF
ENDIF
ENDIF
IF DOES_BLIP_EXIST(gotoBlip)
REMOVE_BLIP(gotoBlip)
ENDIF
ENDPROC
// franklin hit stage
PROC DO_STAGE_FRANKLIN_HIT
DO_COMMON_HIT_FUNCTIONS()
//SET_ALL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID())
IF NOT bRunningCutscene
IF NOT bRestoredVehicleDensity
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
IF GET_GAME_TIMER() >= iStageStartTime + 20000
//OR triadState = TRIAD_STATE_COMBAT
OR triadState = TRIAD_STATE_DRIVING_WANDER
OR triadState = TRIAD_STATE_DRIVING_ESCAPE
bRestoredVehicleDensity = TRUE
ENDIF
ELSE
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.4)
ENDIF
IF NOT bDoneAttackChengMusic
IF bAggroedTriads
TRIGGER_MISSION_MUSIC_EVENT("FINC2_CHENG_SHOT")
bDoneAttackChengMusic = TRUE
ENDIF
ENDIF
CONTROL_PED_CHASE_HINT_CAM_IN_VEHICLE(localChaseHintCamStruct, triadPed[TRIAD_CHENG_SR].ped)
IF NOT bRestoredTriadHealth
IF GET_GAME_TIMER() >= iStageStartTime + 10000
SET_TRIADS_BADASS(FALSE)
bRestoredTriadHealth = TRUE
ENDIF
ENDIF
// cheng jr curse
IF bAggroedTriads
IF NOT IS_PED_INJURED(triadPed[TRIAD_CHENG_JR].ped)
IF GET_GAME_TIMER() >= iNextChengJrCurseTime
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF GET_RANDOM_INT_IN_RANGE(0,2) = 0
PLAY_PED_AMBIENT_SPEECH(triadPed[TRIAD_CHENG_JR].ped, "GENERIC_CURSE_HIGH", SPEECH_PARAMS_FORCE_SHOUTED)
//printstring("play cheng jr curse high") printnl()
ELSE
PLAY_PED_AMBIENT_SPEECH(triadPed[TRIAD_CHENG_JR].ped, "GENERIC_FUCK_YOU", SPEECH_PARAMS_FORCE_SHOUTED)
//printstring("play cheng jr f you") printnl()
ENDIF
iNextChengJrCurseTime = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(10000, 14000)
ELSE
iNextChengJrCurseTime = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(4000, 6000)
ENDIF
ENDIF
ENDIF
ENDIF
IF NOT g_bFinale3BHitSuccessful[CHAR_FRANKLIN]
IF createHitStage[CHAR_FRANKLIN] = CREATE_HIT_STAGE_DONE
IF NOT bDoneChengLeaveSpeech
//bDoneChengLeaveSpeech = TRUE
IF createHitStage[CHAR_FRANKLIN] = CREATE_HIT_STAGE_DONE
IF bAggroedTriads
bDoneChengLeaveSpeech = TRUE
ELSE
IF triadState = TRIAD_STATE_ENTER_CARS
AND NOT bTriadsFrozen
IF NOT IS_PED_INJURED(triadPed[TRIAD_CHENG_SR].ped)
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), triadPed[TRIAD_CHENG_SR].ped, <<40,40,10>>, FALSE, FALSE)
bDoneChengLeaveSpeech = DO_MISSION_SPEECH("FINC1_CHLEA", FALSE, 11)
ELSE
bDoneChengLeaveSpeech = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF NOT bDoneReadySpeech[CHAR_FRANKLIN]
IF NOT bAggroedTriads
IF DO_MISSION_SPEECH("FINC1_FHR")
bDoneReadySpeech[CHAR_FRANKLIN] = TRUE
ENDIF
ELSE
bDoneReadySpeech[CHAR_FRANKLIN] = TRUE
ENDIF
ELSE
IF NOT bShownDoHitText[CHAR_FRANKLIN]
bShownDoHitText[CHAR_FRANKLIN] = DO_MISSION_GOD_TEXT("FC2_KILLTRI")
IF bShownDoHitText[CHAR_FRANKLIN]
REPLAY_RECORD_BACK_FOR_TIME(0.0, 10.0)
ENDIF
ENDIF
ENDIF
ENDIF
BOOL bKilledCheng = FALSE
INT i
REPEAT COUNT_OF(TRIAD_ENUM) i
TRIAD_ENUM thisTriad = INT_TO_ENUM(TRIAD_ENUM, i)
IF DOES_ENTITY_EXIST(triadPed[i].ped)
IF IS_PED_INJURED(triadPed[i].ped)
IF thisTriad = TRIAD_CHENG_SR
IF DOES_BLIP_EXIST(chengBlip)
REMOVE_BLIP(chengBlip)
ENDIF
bKilledCheng = TRUE
ENDIF
ELSE
IF thisTriad = TRIAD_CHENG_SR
// update if cheng is in a vehicle
BOOL bChengCar = IS_CHENG_IN_CAR()
IF CAN_ADVANCE_MISSION()
IF bChengCar
IF NOT bCacheChengInCar
OR NOT DOES_BLIP_EXIST(chengBlip)
IF DOES_BLIP_EXIST(chengBlip)
REMOVE_BLIP(chengBlip)
ENDIF
CREATE_MISSION_BLIP_FOR_CHENG(TRUE)
ENDIF
ELSE
IF bCacheChengInCar
OR NOT DOES_BLIP_EXIST(chengBlip)
IF DOES_BLIP_EXIST(chengBlip)
REMOVE_BLIP(chengBlip)
ENDIF
CREATE_MISSION_BLIP_FOR_CHENG(FALSE)
ENDIF
ENDIF
ENDIF
bCacheChengInCar = bChengCar
// fail if lost
BOOL bFailForLostCheng = FALSE
//FLOAT fFailDist
//IF NOT bCacheChengInCar
//fFailDist = 150.0
//ELSE
// fFailDist = 300.0
//ENDIF
UPDATE_CHASE_BLIP(chengBlip, triadPed[i].ped, 300)
IF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), triadPed[i].ped, <<300,300,300>>, FALSE, FALSE)
bFailForLostCheng = TRUE
ENDIF
IF bFailForLostCheng
IF DOES_BLIP_EXIST(chengBlip)
REMOVE_BLIP(chengBlip)
ENDIF
MISSION_FAILED(FAIL_LOST_CHENG)
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
IF bAggroedTriads
IF triadState = TRIAD_STATE_DRIVING_ESCAPE
OR triadState = TRIAD_STATE_DRIVING_LEAVE_CLUB
IF NOT IS_PED_INJURED(triadPed[TRIAD_CHENG_SR].ped)
AND NOT IS_PED_INJURED(triadPed[TRIAD_BOSSES_DRIVER].ped)
IF NOT bDoneChengEscapeSpeech
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), triadPed[TRIAD_CHENG_SR].ped, <<40,40,10>>, FALSE, FALSE)
IF DO_MISSION_SPEECH("FINC1_CHHIT")
bDoneChengEscapeSpeech = TRUE
SET_NEXT_RANDOM_SPEECH_TIME(8000)
ENDIF
ENDIF
ENDIF
ENDIF
//ELSE
//IF bDoRecognizeSpeech
// IF NOT bDoneRecognizeSpeech
// bDoneRecognizeSpeech = DO_MISSION_SPEECH("FINC1_TRRF")
// ENDIF
//ENDIF
ENDIF
BOOL bCanDoChengSpeech = FALSE
IF NOT IS_PED_INJURED(triadPed[TRIAD_CHENG_SR].ped)
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), triadPed[TRIAD_CHENG_SR].ped, <<25,25,10>>, FALSE, FALSE)
bCanDoChengSpeech = TRUE
ENDIF
IF NOT bDoneMySonDeadSpeech
IF IS_PED_INJURED(triadPed[TRIAD_CHENG_JR].ped)
IF bCanDoChengSpeech
bDoneMySonDeadSpeech = DO_MISSION_SPEECH("FINC1_CHCD")
ELSE
bDoneMySonDeadSpeech = TRUE
ENDIF
ENDIF
ENDIF
IF bCanDoChengSpeech
IF IS_PED_IN_ANY_VEHICLE(triadPed[TRIAD_CHENG_SR].ped)
IF NOT IS_PED_INJURED(triadPed[TRIAD_BOSSES_DRIVER].ped)
IF GET_RANDOM_INT_IN_RANGE(0,2) = 0
DO_RANDOM_SPEECH("FINC1_CHGF")
ELSE
DO_RANDOM_SPEECH("FINC1_CHCS")
ENDIF
ELSE
IF NOT IS_PED_INJURED(triadPed[TRIAD_BOSSES_FR].ped)
DO_RANDOM_SPEECH("FINC1_CHGF")
ENDIF
ENDIF
ELSE
DO_RANDOM_SPEECH("FINC1_CHSF")
ENDIF
ENDIF
ENDIF
ENDIF
IF bKilledCheng
IF DOES_ENTITY_EXIST(triadPed[TRIAD_CHENG_SR].ped)
IF HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON(triadPed[TRIAD_CHENG_SR].ped, GET_FINALE_WEAPON_TYPE(F_WEAPON_STICKY_BOMB))
INFORM_STAT_SYSTEM_OF_BOOL_STAT_HAPPENED(FIN_CHENG_BOMBER)
ENDIF
ENDIF
IF CAN_ADVANCE_MISSION()
sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_FRANKLIN] = TRUE
SET_TRIAD_STATE(TRIAD_STATE_CHASE_DOWN_PLAYER)
fMaxTriadWarpVehicleDistance = 230.0
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_FRANKLIN_KILL_CHENG)
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_FRANKLIN_ESCAPE_TRIADS)
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_BOSSES])
REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(triadVehicle[TRIAD_VEHICLE_BOSSES])
ENDIF
REPLAY_RECORD_BACK_FOR_TIME(12.0, 8.0)
g_bFinale3BHitSuccessful[CHAR_FRANKLIN] = TRUE
ENDIF
ENDIF
ENDIF
ELSE
fMaxTriadWarpVehicleDistance = fMaxTriadWarpVehicleDistance -@ 0.40
IF fMaxTriadWarpVehicleDistance < 0
fMaxTriadWarpVehicleDistance = 0
ENDIF
IF IS_THIS_PRINT_BEING_DISPLAYED("FC2_KILLTRI")
REMOVE_MISSION_TEXT(FALSE, TRUE, FALSE)
ENDIF
IF NOT bDoneGotChengSpeech
bDoneGotChengSpeech = DO_MISSION_SPEECH("FINC1_FKILCH")
ENDIF
IF NOT bEscapedArea[CHAR_FRANKLIN]
INT i
IF NOT bNearTriad
// get rid of triads
REPEAT COUNT_OF(TRIAD_ENUM) i
CLEANUP_AI_PED_BLIP(triadPed[i].blipStruct)
IF DOES_ENTITY_EXIST(triadPed[i].ped)
IF NOT IS_PED_INJURED(triadPed[i].ped)
TASK_SMART_FLEE_PED(triadPed[i].ped, PLAYER_PED_ID(), 1000, -1)
ENDIF
SET_PED_AS_NO_LONGER_NEEDED(triadPed[i].ped)
ENDIF
ENDREPEAT
REPEAT COUNT_OF(TRIAD_VEHICLE_ENUM) i
IF DOES_BLIP_EXIST(triadVehicleBlip[i])
REMOVE_BLIP(triadVehicleBlip[i])
ENDIF
ENDREPEAT
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT])
REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(triadVehicle[TRIAD_VEHICLE_ESCORT_FRONT])
ENDIF
IF IS_VEHICLE_DRIVEABLE(triadVehicle[TRIAD_VEHICLE_ESCORT_REAR])
REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(triadVehicle[TRIAD_VEHICLE_ESCORT_REAR])
ENDIF
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
TRIGGER_MISSION_MUSIC_EVENT("FINC2_CHENG_DONE_FOOT")
ELSE
TRIGGER_MISSION_MUSIC_EVENT("FINC2_CHENG_DONE")
ENDIF
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_FRANKLIN_ESCAPE_TRIADS)
bEscapedArea[CHAR_FRANKLIN] = TRUE
ELSE
IF NOT bShownEscapePrompt[CHAR_FRANKLIN]
IF bDoneGotChengSpeech
bShownEscapePrompt[CHAR_FRANKLIN] = DO_MISSION_GOD_TEXT("FC2_ESCTRI")
ENDIF
ENDIF
ENDIF
ELSE
IF IS_THIS_PRINT_BEING_DISPLAYED("FC2_ESCTRI")
REMOVE_MISSION_TEXT(FALSE, TRUE, FALSE)
ENDIF
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 0
OR freeHotswapData.state <> FREE_HOTSWAP_STATE_SELECTING
IF IS_THIS_PRINT_BEING_DISPLAYED("LOSE_WANTED")
REMOVE_MISSION_TEXT(FALSE, TRUE, FALSE)
ENDIF
bShownLoseWantedPrompt = FALSE
IF NOT bDoneHitSuccessfulSpeech[CHAR_FRANKLIN]
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
bDoneHitSuccessfulSpeech[CHAR_FRANKLIN] = DO_MISSION_SPEECH("FINC1_FDH")
ELSE
IF NOT bDoneWhoNextQuestionSpeech
bDoneWhoNextQuestionSpeech = DO_WHO_NEXT_QUESTION_SPEECH()
ELSE
IF NOT bDoneWhoNextAnswerSpeech
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", TRUE)
bDoneWhoNextAnswerSpeech = DO_WHO_NEXT_ANSWER_SPEECH()
ELSE
IF NOT bShownSwitchPrompt
IF freeHotswapData.state = FREE_HOTSWAP_STATE_SELECTING
bShownSwitchPrompt = DO_MISSION_GOD_TEXT(GET_STRING_FOR_SWITCH_PROMPT())
ENDIF
IF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_TREVOR]
IF sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_MICHAEL]
DO_MISSION_HINT(SELECTOR_PED_TREVOR)
ENDIF
ELIF NOT sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_MICHAEL]
DO_MISSION_HINT(SELECTOR_PED_MICHAEL)
ENDIF
ENDIF
//IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
//IF freeHotswapData.state <> FREE_HOTSWAP_STATE_SELECTING
IF CAN_DO_FREE_HOTSWAP()
HANDLE_FREE_HOTSWAP()
ENDIF
ENDIF
IF sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_TREVOR]
IF HAVE_ALL_HITS_SUCCEEDED()
DO_MISSION_HINT(SELECTOR_PED_TREVOR)
SET_SELECTOR_PED_PRIORITY(sSelectorPeds, SELECTOR_PED_TREVOR, SELECTOR_PED_MICHAEL, SELECTOR_PED_FRANKLIN)
sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_TREVOR] = FALSE
ENDIF
ENDIF
//ENDIF
ENDIF
ENDIF
ELSE
IF NOT bShownLoseWantedPrompt
bShownLoseWantedPrompt = DO_MISSION_GOD_TEXT("LOSE_WANTED")
ENABLE_DISPATCH_SERVICE(DT_POLICE_AUTOMOBILE, TRUE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_VEHICLE_REQUEST, TRUE)
SET_CREATE_RANDOM_COPS(TRUE)
ENDIF
bShownSwitchPrompt = FALSE
ENDIF
ENDIF
ENDIF
IF CAN_ADVANCE_MISSION()
BOOL bDeleteFranklin = FALSE
IF freeHotswapData.state = FREE_HOTSWAP_STATE_SELECTING
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL
SET_MISSION_STAGE(STAGE_GET_TO_HIT, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE)
bDeleteFranklin = TRUE
ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_TREVOR
IF g_bFinale3BHitSuccessful[CHAR_TREVOR]
SET_MISSION_STAGE(STAGE_PICKUP_DEVIN)
bDeleteFranklin = TRUE
ELSE
SET_MISSION_STAGE(STAGE_GET_TO_HIT, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE)
bDeleteFranklin = TRUE
ENDIF
ENDIF
IF bDeleteFranklin
IF DOES_ENTITY_EXIST(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
SET_PLAYER_PED_WITH_HEADSET(CHAR_FRANKLIN, FALSE)
STORE_PLAYER_PED_VARIATIONS(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], TRUE)
DELETE_PED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
ENDIF
ADD_PED_FOR_DIALOGUE(finaleConversation, 2, NULL, "FRANKLIN")
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_FRANKLIN))
IF DOES_ENTITY_EXIST(finaleVehicle[FV_FRANKLIN_CAR])
DELETE_VEHICLE(finaleVehicle[FV_FRANKLIN_CAR])
ENDIF
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_FRANKLIN_BIKE))
ENDIF
ENDIF
ENDIF
ENDIF
IF DOES_BLIP_EXIST(gotoBlip)
REMOVE_BLIP(gotoBlip)
ENDIF
ENDPROC
FUNC BOOL IS_PLAYER_IN_DRIVEWAY_OUTSIDE()
RETURN IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-2557.69922, 1913.67993, 167.86884>>, <<-2549.76709, 1909.98010, 171.51650>>, 6.86)
ENDFUNC
PROC HANDLE_MERRYWEATHER()
// merryweather
//FLOAT fStealthNoise = GET_PLAYER_CURRENT_STEALTH_NOISE(PLAYER_ID())
//PRINTSTRING("stealth noise = ") PRINTFLOAT(fStealthNoise) PRINTNL()
BOOL bFiringWeapon = FALSE
IF IS_PED_SHOOTING_IN_AREA(PLAYER_PED_ID(), <<-2659.44458, 1841.31934, 134.24051>>, <<-2536.53149, 1949.55786, 180.48360>>, FALSE)
WEAPON_TYPE currentPlayerWeapon
GET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), currentPlayerWeapon)
IF NOT IS_PED_CURRENT_WEAPON_SILENCED(PLAYER_PED_ID())
AND currentPlayerWeapon <> WEAPONTYPE_STICKYBOMB
AND currentPlayerWeapon <> WEAPONTYPE_GRENADE
AND currentPlayerWeapon <> WEAPONTYPE_SMOKEGRENADE
AND currentPlayerWeapon <> WEAPONTYPE_BZGAS
AND currentPlayerWeapon <> WEAPONTYPE_MOLOTOV
AND currentPlayerWeapon <> WEAPONTYPE_STUNGUN
bFiringWeapon = TRUE
ENDIF
ENDIF
BOOL bExplosion = FALSE
IF IS_EXPLOSION_IN_AREA(EXP_TAG_DONTCARE, <<-2659.44458, 1841.31934, 134.24051>>, <<-2536.53149, 1949.55786, 180.48360>>)
IF devinHideReason = DEVIN_HIDE_REASON_NONE
devinHideReason = DEVIN_HIDE_REASON_EXPLOSION
ENDIF
bExplosion = TRUE
ENDIF
BOOL bInVehicle = FALSE
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
bInVehicle = TRUE
ENDIF
bTrespassing = FALSE
IF IS_ENTITY_IN_AREA(PLAYER_PED_ID(), <<-2604.26440, 1859.12488, 161.8173>>, <<-2553.18677, 1938.96106, 180.04288>>)
OR IS_ENTITY_IN_AREA(PLAYER_PED_ID(), <<-2650.52051, 1860.73572, 159.95520>>, <<-2605.26001, 1924.88574, 180.04638>>)
IF NOT IS_PLAYER_IN_DRIVEWAY_OUTSIDE()
bTrespassing = TRUE
IF bInVehicle
bGeneralMerryweatherAlert = TRUE
ENDIF
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0
IF currentMissionStage = STAGE_PICKUP_DEVIN
MISSION_FAILED(FAIL_POLICE_DEVIN)
ENDIF
bGeneralMerryweatherAlert = TRUE
ENDIF
ENDIF
ENDIF
IF iMerryweatherForceAlertTime >= 0
IF GET_GAME_TIMER() >= iMerryweatherForceAlertTime + 3000
bGeneralMerryweatherAlert = TRUE
ENDIF
ENDIF
iGuardsAlive = 0
INT i
REPEAT COUNT_OF(MERRYWEATHER_ENUM) i
MERRYWEATHER_ENUM thisMerryweather = INT_TO_ENUM(MERRYWEATHER_ENUM, i)
//BOOL bForceBlip = FALSE
IF NOT IS_PED_INJURED(merryweatherPed[i].ped)
iGuardsAlive++
IF NOT bGeneralMerryWeatherAlert
//IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), merryweatherPed[i].ped, <<25,25,25>>)
//OR IS_TRACKED_PED_VISIBLE(merryweatherPed[i].ped)
// bForceBlip = TRUE
//ENDIF
SET_PED_RESET_FLAG(merryweatherPed[i].ped, PRF_ForceInjuryAfterStunned, TRUE)
ENDIF
IF IS_PED_SHOOTING(merryweatherPed[i].ped)
OR bDoneMerryweatherCombatSpeech1
bGeneralMerryweatherAlert = TRUE
ENDIF
// can see?
IF NOT merryweatherPed[i].bIsAlerted
//IF iMerryweatherLOSCheck = i
IF bTrespassing
IF merryweatherPed[i].iSeenTime < 0
IF CAN_PED_SEE_HATED_PED(merryweatherPed[i].ped, PLAYER_PED_ID())
merryweatherPed[i].iSeenTime = GET_GAME_TIMER()
ENDIF
ELSE
IF GET_GAME_TIMER() >= merryweatherPed[i].iSeenTime + 2000
IF NOT IS_PED_BEING_STEALTH_KILLED(merryweatherPed[i].ped)
IF CAN_PED_SEE_HATED_PED(merryweatherPed[i].ped, PLAYER_PED_ID())
bDoSpottedSpeech = TRUE
iMerryweatherSpeaker1 = i
merryweatherPed[i].bIsAlerted = TRUE
ELIF GET_GAME_TIMER() >= merryweatherPed[i].iSeenTime + 3000
merryweatherPed[i].iSeenTime = -1
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
//ENDIF
IF NOT bDoSpottedSpeech
IF bTrespassing
IF CAN_PED_HEAR_PLAYER(PLAYER_ID(), merryweatherPed[i].ped)
IF NOT IS_PED_BEING_STEALTH_KILLED(merryweatherPed[i].ped)
printstring("heard by ") printint(i) printnl()
bDoSpottedSpeech = TRUE
iMerryweatherSpeaker1 = i
//IF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), merryweatherPed[i].ped, <<12,12,5>>)
// bHeard = TRUE
//ENDIF
merryweatherPed[i].bIsAlerted = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
VECTOR vMerryweatherPos = GET_ENTITY_COORDS(merryweatherPed[i].ped)
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(merryweatherPed[i].ped, PLAYER_PED_ID())
IF NOT IS_PED_BEING_STEALTH_KILLED(merryweatherPed[i].ped)
IF devinHideReason = DEVIN_HIDE_REASON_NONE
devinHideReason = DEVIN_HIDE_REASON_GUARD_SHOT
ENDIF
merryweatherPed[i].bIsAlerted = TRUE
ENDIF
ELIF IS_SNIPER_BULLET_IN_AREA(vMerryweatherPos - <<2,2,2>>, vMerryweatherPos + <<2,2,2>>)
OR IS_BULLET_IN_AREA(vMerryweatherPos, 2.0)
OR IS_PROJECTILE_IN_AREA(vMerryweatherPos - <<15,15,15>>, vMerryweatherPos + <<15,15,15>>)
OR GET_NUMBER_OF_FIRES_IN_RANGE(vMerryweatherPos, 30) > 0
IF iMerryweatherForceAlertTime < 0
iMerryweatherForceAlertTime = GET_GAME_TIMER()
ENDIF
merryweatherPed[i].bIsAlerted = TRUE
ENDIF
IF bFiringWeapon
OR bExplosion
OR bGeneralMerryweatherAlert
bGeneralMerryweatherAlert = TRUE
merryweatherPed[i].bIsAlerted = TRUE
ENDIF
ELSE
IF iGuardsAliveLastFrame = 1
IF thisMerryweather = MERRYWEATHER_IN_GARAGE
IF NOT IS_TRACKED_PED_VISIBLE(merryweatherPed[i].ped)
AND NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), merryweatherPed[i].ped, <<40,40,40>>)
APPLY_DAMAGE_TO_PED(merryweatherPed[i].ped, 1000, TRUE)
ENDIF
ENDIF
ENDIF
// temp kill if fell off house
VECTOR vPedCoords = GET_ENTITY_COORDS(merryweatherPed[i].ped)
IF vPedCoords.z < 159.0
APPLY_DAMAGE_TO_PED(merryweatherPed[i].ped, 1000, TRUE)
ENDIF
IF merryweatherPed[i].aiState <> MERRYWEATHER_AI_COMBAT
SET_PED_SEEING_RANGE(merryweatherPed[i].ped, 60)
merryweatherPed[i].aiState = MERRYWEATHER_AI_COMBAT
ENDIF
ENDIF
SWITCH merryweatherPed[i].aiState
CASE MERRYWEATHER_AI_PATROL
SWITCH merryweatherPed[i].patrolState
CASE MERRYWEATHER_PATROL_WAIT_1
CASE MERRYWEATHER_PATROL_WAIT_2
IF GET_GAME_TIMER() >= merryweatherPed[i].iNextPatrolTime
STRING sWaypointRec
SWITCH thisMerryweather
CASE MERRYWEATHER_DRIVE
IF merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_WAIT_1
sWaypointRec = "finc25"
ELSE
sWaypointRec = "finc26"
ENDIF
BREAK
CASE MERRYWEATHER_WALKWAY_1
IF merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_WAIT_1
sWaypointRec = "finc27"
ELSE
sWaypointRec = "finc28"
ENDIF
BREAK
CASE MERRYWEATHER_WALKWAY_2
IF merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_WAIT_1
sWaypointRec = "finc29"
ELSE
sWaypointRec = "finc210"
ENDIF
BREAK
CASE MERRYWEATHER_VIEWING_PLATFORM
IF merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_WAIT_1
sWaypointRec = "finc211"
ELSE
sWaypointRec = "finc212"
ENDIF
BREAK
CASE MERRYWEATHER_PATROL_COURTYARD
IF merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_WAIT_1
sWaypointRec = "finc213"
ELSE
sWaypointRec = "finc214"
ENDIF
BREAK
CASE MERRYWEATHER_OVERLOOK_POOL
IF merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_WAIT_1
sWaypointRec = "finc215"
ELSE
sWaypointRec = "finc216"
ENDIF
BREAK
CASE MERRYWEATHER_OVERLOOK_SEA
IF merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_WAIT_1
sWaypointRec = "finc217"
ELSE
sWaypointRec = "finc218"
ENDIF
BREAK
ENDSWITCH
TASK_FOLLOW_WAYPOINT_RECORDING(merryweatherPed[i].ped, sWaypointRec, 1, EWAYPOINT_TURN_TO_FACE_WAYPOINT_HEADING_AT_END)
IF merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_WAIT_1
merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_ROUTE_1
ELSE
merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_ROUTE_2
ENDIF
ENDIF
BREAK
CASE MERRYWEATHER_PATROL_ROUTE_1
CASE MERRYWEATHER_PATROL_ROUTE_2
IF NOT IS_WAYPOINT_PLAYBACK_GOING_ON_FOR_PED(merryweatherPed[i].ped)
INT iWaitTime
SWITCH thisMerryweather
CASE MERRYWEATHER_DRIVE
IF merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_ROUTE_1
iWaitTime = 15000
ELSE
iWaitTime = 10000
ENDIF
BREAK
CASE MERRYWEATHER_WALKWAY_1
IF merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_ROUTE_1
iWaitTime = 8000
ELSE
iWaitTime = 7000
ENDIF
BREAK
CASE MERRYWEATHER_WALKWAY_2
IF merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_ROUTE_1
iWaitTime = 10000
ELSE
iWaitTime = 9000
ENDIF
BREAK
CASE MERRYWEATHER_VIEWING_PLATFORM
IF merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_ROUTE_1
iWaitTime = 7000
ELSE
iWaitTime = 12000
ENDIF
BREAK
CASE MERRYWEATHER_PATROL_COURTYARD
IF merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_ROUTE_1
iWaitTime = 11000
ELSE
iWaitTime = 9000
ENDIF
BREAK
CASE MERRYWEATHER_OVERLOOK_POOL
IF merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_ROUTE_1
iWaitTime = 8000
ELSE
iWaitTime = 8000
ENDIF
BREAK
CASE MERRYWEATHER_OVERLOOK_SEA
IF merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_ROUTE_1
iWaitTime = 9000
ELSE
iWaitTime = 11000
ENDIF
BREAK
ENDSWITCH
IF bRunningCutscene
iWaitTime = 3000
ENDIF
merryweatherPed[i].iNextPatrolTime = GET_GAME_TIMER() + iWaitTime
IF merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_ROUTE_1
merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_WAIT_2
ELSE
merryweatherPed[i].patrolState = MERRYWEATHER_PATROL_WAIT_1
ENDIF
ENDIF
BREAK
ENDSWITCH
BREAK
CASE MERRYWEATHER_AI_COMBAT
IF NOT merryweatherPed[i].bDoneCharge
FLOAT fAllowChargeTime
BOOL bIncrementCharge
bIncrementCharge = FALSE
SWITCH thisMerryweather
CASE MERRYWEATHER_DRIVE
bIncrementCharge = TRUE
fAllowChargeTime = 0.0
BREAK
CASE MERRYWEATHER_IN_GARAGE
bIncrementCharge = TRUE
fAllowChargeTime = 5.0
BREAK
CASE MERRYWEATHER_WALKWAY_1
CASE MERRYWEATHER_WALKWAY_2
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), merryWeatherPed[i].ped, <<20,20,20>>)
OR bPlayerNearDeck
bIncrementCharge = TRUE
fAllowChargeTime = 4.0
ENDIF
BREAK
CASE MERRYWEATHER_OVERLOOK_POOL
CASE MERRYWEATHER_OVERLOOK_SEA
CASE MERRYWEATHER_VIEWING_PLATFORM
CASE MERRYWEATHER_PATROL_COURTYARD
IF bPlayerNearDeck
bIncrementCharge = TRUE
fAllowChargeTime = 2.0
ENDIF
BREAK
ENDSWITCH
IF bIncrementCharge
merryweatherPed[i].fToChargeTimer = merryweatherPed[i].fToChargeTimer +@ 1.0
IF merryweatherPed[i].fToChargeTimer >= fAllowChargeTime
REMOVE_PED_DEFENSIVE_AREA(merryweatherPed[i].ped)
SET_PED_COMBAT_MOVEMENT(merryweatherPed[i].ped, CM_WILLADVANCE)
SET_PED_COMBAT_ATTRIBUTES(merryweatherPed[i].ped, CA_CAN_CHARGE, TRUE)
//PRINTSTRING("setting charge flag ") PRINTINT(i) PRINTNL()
merryweatherPed[i].bDoneCharge = TRUE
ENDIF
ENDIF
ENDIF
IF NOT IS_PED_IN_COMBAT(merryweatherPed[i].ped)
IF GET_SCRIPT_TASK_STATUS(merryweatherPed[i].ped, SCRIPT_TASK_START_SCENARIO_IN_PLACE) <> FINISHED_TASK
OR IS_PED_USING_ANY_SCENARIO(merryweatherPed[i].ped)
SET_PED_SHOULD_PLAY_IMMEDIATE_SCENARIO_EXIT(merryweatherPed[i].ped)
ENDIF
TASK_COMBAT_PED(merryweatherPed[i].ped, PLAYER_PED_ID())
ENDIF
BREAK
ENDSWITCH
ENDIF
IF currentMissionStage = STAGE_DEVINS_HOUSE
UPDATE_AI_PED_BLIP(merryweatherPed[i].ped, merryweatherPed[i].blipStruct, -1, NULL, FALSE, FALSE, 100)
ENDIF
ENDREPEAT
iGuardsAliveLastFrame = iGuardsAlive
ENDPROC
// come back to seeing projectiles and fires.
// fix trespass area
// common stuff for devin house
PROC DO_COMMON_DEVINS_HOUSE()
IF NOT IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_FINALE_VECTOR(FINVEC_PICKUP), <<300,300,300>>, FALSE, FALSE)
MISSION_FAILED(FAIL_ABANDONED_DEVIN)
ENDIF
//FREEZE_POSITION_OF_CLOSEST_OBJECT_OF_TYPE (<<-2645.96, 1872.59, 159.15>>, 0.2, PROP_PATIO_LOUNGER1, TRUE)
// devin
IF DOES_ENTITY_EXIST(devinPed)
IF currentMissionStage = STAGE_DEVINS_HOUSE
IF NOT DOES_BLIP_EXIST(devinBlip)
//IF iGuardsAlive = 0 OR NOT bGeneralMerryweatherAlert
devinBlip = CREATE_MISSION_BLIP_FOR_PED(devinPed, FALSE)
IF DOES_BLIP_EXIST(devinBlip)
SET_BLIP_NAME_FROM_TEXT_FILE(devinBlip, "BLIP_108")
ENDIF
//ENDIF
//ELSE
//IF bGeneralMerryweatherAlert
//AND iGuardsAlive > 0
// IF DOES_BLIP_EXIST(devinBlip)
// REMOVE_BLIP(devinBlip)
// ENDIF
//ENDIF
ENDIF
ENDIF
//PRINTSTRING("here1") PRINTNL()
IF IS_PED_INJURED(devinPed)
//PRINTSTRING("here2") PRINTNL()
MISSION_FAILED(FAIL_DEVIN_DEAD)
IF DOES_ENTITY_EXIST(boxObject)
IF IS_ENTITY_PLAYING_ANIM(boxObject, GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_DEVIN_AND_BOX), "LOUNGE_OUTRO_BOX")
STOP_ENTITY_ANIM(boxObject, "LOUNGE_OUTRO_BOX", GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_DEVIN_AND_BOX), INSTANT_BLEND_OUT)
ENDIF
ENDIF
IF DOES_ENTITY_EXIST(tabletObject)
IF NOT bStoppedTabletAnim
BOOL bStopAnim = FALSE
IF IS_SYNCHRONIZED_SCENE_RUNNING(iSyncScene)
IF devinIntoBoxState = DEVIN_INTO_BOX_STATE_NOT_STARTED
bStopAnim = TRUE
ELSE
IF GET_SYNCHRONIZED_SCENE_PHASE(iSyncScene) >= 0.172
bStopAnim = TRUE
ENDIF
ENDIF
IF bStopAnim
STOP_SYNCHRONIZED_ENTITY_ANIM(tabletObject, INSTANT_BLEND_OUT, TRUE)
APPLY_FORCE_TO_ENTITY_CENTER_OF_MASS(tabletObject, APPLY_TYPE_IMPULSE, <<0,0.0,-0.1>>, 0, TRUE, TRUE)
ENDIF
ENDIF
bStoppedTabletAnim = TRUE
ENDIF
ENDIF
ELSE
SWITCH devinIntoBoxState
CASE DEVIN_INTO_BOX_STATE_NOT_STARTED
BOOL bDoIntoBox
bDoIntoBox = FALSE
IF bGeneralMerryweatherAlert
bDoIntoBox = TRUE
ELIF IS_ENTITY_IN_AREA(PLAYER_PED_ID(), <<-2659.05225, 1859.63245, 158.29218>>, <<-2627.70313, 1874.20886, 194.41885>>)
OR (IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-2646.42847, 1867.55750, 159.24397>>, <<-2629.00220, 1882.91931, 162.44397>>, 15.25)
AND NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-2627.60547, 1874.13611, 157.05910>>, <<-2619.10693, 1880.35229, 161.9.00262>>, 2.9))
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF devinHideReason = DEVIN_HIDE_REASON_NONE
devinHideReason = DEVIN_HIDE_REASON_SEE_VEHICLE
ENDIF
ELSE
IF devinHideReason = DEVIN_HIDE_REASON_NONE
devinHideReason = DEVIN_HIDE_REASON_SEE_TREVOR
ENDIF
ENDIF
bDoIntoBox = TRUE
ENDIF
IF bDoIntoBox
//iDevinIntoBoxTime = GET_GAME_TIMER()
iSyncScene = CREATE_SYNCHRONIZED_SCENE(<<-2645.961, 1872.599, 159.153>>, <<0, 0, 102.44>>)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncScene, FALSE)
SET_SYNCHRONIZED_SCENE_HOLD_LAST_FRAME(iSyncScene, TRUE)
TASK_LOOK_AT_ENTITY(devinPed, PLAYER_PED_ID(), -1, SLF_WHILE_NOT_IN_FOV, SLF_LOOKAT_VERY_HIGH)
TASK_SYNCHRONIZED_SCENE(devinPed, iSyncScene, GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_DEVIN_AND_BOX), "LOUNGE_OUTRO_DEV", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_USE_PHYSICS | SYNCED_SCENE_DONT_INTERRUPT)
PLAY_SYNCHRONIZED_ENTITY_ANIM(boxObject, iSyncScene, "LOUNGE_OUTRO_BOX", GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_DEVIN_AND_BOX), NORMAL_BLEND_IN)
PLAY_SYNCHRONIZED_ENTITY_ANIM(tabletObject, iSyncScene, "LOUNGE_OUTRO_TAB", GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_DEVIN_AND_BOX), NORMAL_BLEND_IN)
devinIntoBoxState = DEVIN_INTO_BOX_STATE_RUNNING
ENDIF
BREAK
CASE DEVIN_INTO_BOX_STATE_RUNNING
IF NOT bDoneDevinHideSpeech
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), devinPed, <<23,23,8>>)
STRING sSpeech
SWITCH devinHideReason
CASE DEVIN_HIDE_REASON_NONE
sSpeech = "FINC1_DEVSND"
BREAK
CASE DEVIN_HIDE_REASON_SEE_TREVOR
sSpeech = "FINC1_DEVTRV"
BREAK
CASE DEVIN_HIDE_REASON_SEE_VEHICLE
sSpeech = "FINC1_DEVWRD"
BREAK
CASE DEVIN_HIDE_REASON_EXPLOSION
sSpeech = "FINC1_DEVHID"
BREAK
CASE DEVIN_HIDE_REASON_GUARD_SHOT
sSpeech = "FINC1_DEVSHO"
BREAK
ENDSWITCH
bDoneDevinHideSpeech = DO_MISSION_SPEECH(sSpeech)
ENDIF
ELSE
bGeneralMerryweatherAlert = TRUE
ENDIF
IF IS_SYNCHRONIZED_SCENE_RUNNING(iSyncScene)
IF NOT bBlockedDevinRagdoll
IF GET_SYNCHRONIZED_SCENE_PHASE(iSyncScene) >= 0.639
SET_PED_CAN_RAGDOLL(devinPed, FALSE)
SET_PED_CONFIG_FLAG(devinPed, PCF_ForceRagdollUponDeath, FALSE)
bBlockedDevinRagdoll = TRUE
ENDIF
ENDIF
IF GET_SYNCHRONIZED_SCENE_PHASE(iSyncScene) >= 1.0
devinIntoBoxState = DEVIN_INTO_BOX_STATE_DONE
ENDIF
ELSE
devinIntoBoxState = DEVIN_INTO_BOX_STATE_DONE
ENDIF
BREAK
CASE DEVIN_INTO_BOX_STATE_DONE
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), devinPed, <<10,10,2>>)
IF iDevinSpeechInBoxStage < 8
IF GET_GAME_TIMER() >= iNextDevinSpeechInBoxTime
IF DO_MISSION_SPEECH("FINC1_FNEBOX", FALSE, iDevinSpeechInBoxStage)
iDevinSpeechInBoxStage++
iNextDevinSpeechInBoxTime = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(8000, 12000)
ENDIF
ENDIF
ENDIF
//DO_RANDOM_SPEECH("FINC1_DHIDDN", 10000, 16000)
ENDIF
IF DOES_ENTITY_EXIST(boxObject)
IF IS_ENTITY_ON_FIRE(boxObject)
APPLY_DAMAGE_TO_PED(devinPed, 1000, TRUE)
ENDIF
ENDIF
BREAK
ENDSWITCH
IF IS_PED_RAGDOLL(devinPed)
APPLY_DAMAGE_TO_PED(devinPed, 1000, TRUE)
ENDIF
ENDIF
ENDIF
HANDLE_MERRYWEATHER()
ENDPROC
// do house cutscene
PROC DO_HOUSE_CUTSCENE()
HIDE_HUD_AND_RADAR_THIS_FRAME()
SWITCH cutsceneStage
CASE F_CUT_STAGE_INIT
INT i
VECTOR vPos
FLOAT fRot
STRING sRec
INT iInitNode
INT iPause
BOOL bDoWalk
BOOL bStraightTo
VECTOR vStraightToTarget
MERRYWEATHER_ENUM thisMerryweather
REPEAT COUNT_OF(MERRYWEATHER_ENUM) i
thisMerryweather = INT_TO_ENUM(MERRYWEATHER_ENUM, i)
IF NOT IS_PED_INJURED(merryWeatherPed[i].ped)
bDoWalk = TRUE
bStraightTo = FALSE
iPause = -1
SWITCH thisMerryweather
CASE MERRYWEATHER_IN_GARAGE
bDoWalk = FALSE
BREAK
CASE MERRYWEATHER_DRIVE
vPos = <<-2574.57056, 1894.40845, 166.29906>>
fRot = 33.8
sRec = "finc26"
iInitNode = 2
BREAK
CASE MERRYWEATHER_WALKWAY_1
vPos = <<-2568.41895, 1879.07727, 162.69603>>
fRot = -170.8
sRec = "finc27"
iPause = 0
iInitNode = 8
BREAK
CASE MERRYWEATHER_WALKWAY_2
vPos = <<-2580.29614, 1863.36658, 162.69443>>
fRot = 93.9
sRec = "finc210"
iInitNode = 0
BREAK
CASE MERRYWEATHER_OVERLOOK_POOL
vPos = <<-2624.39111, 1878.72400, 162.42613>>
fRot = -57.5
sRec = "finc215"
iPause = 0
iInitNode = 3
BREAK
CASE MERRYWEATHER_OVERLOOK_SEA
vPos = <<-2604.30078, 1898.96936, 166.30452>>
fRot = 91.9
sRec = "finc218"
iInitNode = 7
iPause = 0
BREAK
CASE MERRYWEATHER_VIEWING_PLATFORM
vPos = <<-2607.85083, 1878.90344, 162.42644>>
fRot = 129.1
iPause = 1200
bStraightTo = TRUE
vStraightToTarget = <<-2614.57959, 1872.55859, 166.30370>>
BREAK
CASE MERRYWEATHER_PATROL_COURTYARD
vPos = <<-2643.20776, 1872.86743, 159.15184>>//<<-2605.13745, 1878.95667, 166.30421>>
fRot = -114.6
iPause = 7200
bStraightTo = TRUE
vStraightToTarget = <<-2637.02002, 1869.96338, 159.15202>>
BREAK
ENDSWITCH
IF bDoWalk
CLEAR_PED_TASKS_IMMEDIATELY(merryWeatherPed[i].ped)
SET_ENTITY_COORDS(merryWeatherPed[i].ped, vPos)
SET_ENTITY_HEADING(merryweatherPed[i].ped, fRot)
CLEAR_SEQUENCE_TASK(sequence)
OPEN_SEQUENCE_TASK(sequence)
IF iPause >= 0
TASK_PAUSE(NULL, iPause)
ELSE
FORCE_PED_MOTION_STATE(merryWeatherPed[i].ped, MS_ON_FOOT_WALK, TRUE, FAUS_CUTSCENE_EXIT)
ENDIF
IF NOT bStraightTo
TASK_FOLLOW_WAYPOINT_RECORDING(NULL, sRec, iInitNode, EWAYPOINT_TURN_TO_FACE_WAYPOINT_HEADING_AT_END)
ELSE
TASK_GO_STRAIGHT_TO_COORD(NULL, vStraightToTarget, PEDMOVE_WALK)
ENDIF
CLOSE_SEQUENCE_TASK(sequence)
TASK_PERFORM_SEQUENCE(merryWeatherPed[i].ped, sequence)
ENDIF
ENDIF
ENDREPEAT
IF NOT IS_PED_INJURED(devinPed)
AND NOT IS_PED_INJURED(merryWeatherPed[MERRYWEATHER_PATROL_COURTYARD].ped)
TASK_LOOK_AT_ENTITY(devinPed, merryWeatherPed[MERRYWEATHER_PATROL_COURTYARD].ped, -1, SLF_WHILE_NOT_IN_FOV, SLF_LOOKAT_VERY_HIGH)
TASK_LOOK_AT_ENTITY(merryWeatherPed[MERRYWEATHER_PATROL_COURTYARD].ped, devinPed, -1, SLF_WHILE_NOT_IN_FOV, SLF_LOOKAT_VERY_HIGH)
ENDIF
CLEAR_AREA_OF_PROJECTILES(GET_ENTITY_COORDS(PLAYER_PED_ID()), 8)
STOP_FIRE_IN_RANGE(GET_ENTITY_COORDS(PLAYER_PED_ID()), 8)
REMOVE_PARTICLE_FX_IN_RANGE(GET_ENTITY_COORDS(PLAYER_PED_ID()), 8)
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_DEVINS_HOUSE_OVERVIEW)
TRIGGER_MISSION_MUSIC_EVENT("FINC2_OUTSIDE_DEVINS")
SET_MISSION_CUTSCENE(TRUE)
INFORM_MISSION_STATS_SYSTEM_OF_INGAME_CUTSCENE_START()
REMOVE_ALL_BLIPS()
DO_MISSION_GOD_TEXT("FC2_PLC1", TRUE, TRUE)
CREATE_CAM_FOR_FINALE_SHOT(FIN_SHOT_HOUSE_1, TRUE, 8000)
bRecreatedDevinVolume = FALSE
bDoneFlash = FALSE
REPLAY_RECORD_BACK_FOR_TIME(8.0, 0.0, REPLAY_IMPORTANCE_HIGHEST)
REPLAY_START_EVENT(REPLAY_IMPORTANCE_HIGHEST)
iFinaleCutsceneTime = GET_GAME_TIMER()
cutsceneStage = F_CUT_STAGE_RUNNING
BREAK
CASE F_CUT_STAGE_RUNNING
OVERRIDE_LODSCALE_THIS_FRAME(1.0)
SWITCH houseOverviewShot
CASE HOUSE_OVERVIEW_SHOT_1
IF NOT bRecreatedDevinVolume
IF GET_GAME_TIMER() >= iFinaleCutsceneTime + 100
IF STREAMVOL_IS_VALID(devinVolume)
STREAMVOL_DELETE(devinVolume)
ENDIF
devinVolume = STREAMVOL_CREATE_FRUSTUM(<<-2636.0, 1881.8, 160.1>>, CONVERT_ROTATION_TO_DIRECTION_VECTOR(<<1.9, 0.0, 137.1>>), 20, FLAG_MAPDATA)
bRecreatedDevinVolume = TRUE
ENDIF
ENDIF
IF GET_GAME_TIMER() >= iFinaleCutsceneTime + 8000
CREATE_CAM_FOR_FINALE_SHOT(FIN_SHOT_HOUSE_2, TRUE, 6000)
REMOVE_MISSION_TEXT()
iFinaleCutsceneTime = GET_GAME_TIMER()
bRecreatedDevinVolume = FALSE
houseOverviewShot = HOUSE_OVERVIEW_SHOT_3
ENDIF
SET_FORCE_OBJECT_THIS_FRAME(<<-2642.32153, 1870.60242, 159.31302>>, 10)
BREAK
//CASE HOUSE_OVERVIEW_SHOT_2
//
// IF GET_GAME_TIMER() >= iFinaleCutsceneTime + 6000
// CREATE_CAM_FOR_FINALE_SHOT(FIN_SHOT_HOUSE_3, TRUE, 5000)
// REMOVE_MISSION_TEXT()
// iFinaleCutsceneTime = GET_GAME_TIMER()
// houseOverviewShot = HOUSE_OVERVIEW_SHOT_3
/// ENDIF
//BREAK
CASE HOUSE_OVERVIEW_SHOT_3
IF NOT bRecreatedDevinVolume
IF GET_GAME_TIMER() >= iFinaleCutsceneTime + 100
IF STREAMVOL_IS_VALID(devinVolume)
STREAMVOL_DELETE(devinVolume)
ENDIF
devinVolume = STREAMVOL_CREATE_FRUSTUM(GET_ENTITY_COORDS(PLAYER_PED_ID()), CONVERT_ROTATION_TO_DIRECTION_VECTOR(<<0, 0.0, GET_ENTITY_HEADING(PLAYER_PED_ID())>>), 20, FLAG_MAPDATA)
bRecreatedDevinVolume = TRUE
ENDIF
ENDIF
IF NOT bDoneDevinToGuardSpeech
bDoneDevinToGuardSpeech = DO_MISSION_SPEECH("FINC1_DGUARD")
ENDIF
IF NOT bDoneFlash
IF GET_CAM_VIEW_MODE_FOR_CONTEXT(GET_CAM_ACTIVE_VIEW_MODE_CONTEXT()) = CAM_VIEW_MODE_FIRST_PERSON
IF GET_GAME_TIMER() >= iFinaleCutsceneTime + 4700
ANIMPOSTFX_PLAY("CamPushInNeutral", 0, FALSE)
PLAY_SOUND_FRONTEND(-1, "1st_Person_Transition", "PLAYER_SWITCH_CUSTOM_SOUNDSET")
bDoneFlash = TRUE
ENDIF
ENDIF
ENDIF
IF GET_GAME_TIMER() >= iFinaleCutsceneTime + 5000
cutsceneStage = F_CUT_STAGE_CLEANUP
ENDIF
BREAK
ENDSWITCH
HANDLE_SKIP_CUTSCENE()
BREAK
CASE F_CUT_STAGE_CLEANUP
IF NOT IS_PED_INJURED(devinPed)
AND NOT IS_PED_INJURED(merryWeatherPed[MERRYWEATHER_PATROL_COURTYARD].ped)
TASK_CLEAR_LOOK_AT(devinPed)
TASK_CLEAR_LOOK_AT(merryWeatherPed[MERRYWEATHER_PATROL_COURTYARD].ped)
ENDIF
IF STREAMVOL_IS_VALID(devinVolume)
STREAMVOL_DELETE(devinVolume)
ENDIF
REPLAY_STOP_EVENT()
CREATE_MERRYWEATHER(FALSE)
INFORM_MISSION_STATS_SYSTEM_OF_INGAME_CUTSCENE_END()
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_DEVINS_HOUSE_OVERVIEW)
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_KIDNAP_DEVIN_STEALTH)
SET_MISSION_CUTSCENE(FALSE)
SET_MISSION_STAGE(STAGE_DEVINS_HOUSE)
BREAK
ENDSWITCH
ENDPROC
// pickup devin stage
PROC DO_STAGE_PICKUP_DEVIN()
INT iWanted = GET_PLAYER_WANTED_LEVEL(PLAYER_ID())
IF NOT bRunningCutscene
HANDLE_CREATE_HITS(TRUE) // getting rid of last hit
// create devin
SWITCH createDevinHouseStage
CASE CREATE_DEVIN_HOUSE_STAGE_NOT_STARTED
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_FINALE_VECTOR(FINVEC_PICKUP), <<200,200,200>>, FALSE, FALSE)
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_DEVIN))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_DEVIN_CAR))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_MERRYWEATHER))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_BOX))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_BOX_COLLISION))
ADD_MODEL_REQUEST(ENUM_TO_INT(FM_TABLET))
ADD_WEAPON_REQUEST(F_WEAPON_MERRYWEATHER_RIFLE)
ADD_WEAPON_REQUEST(F_WEAPON_MERRYWEATHER_SHOTGUN)
ADD_ANIM_DICT_REQUEST(F_ANIM_DICT_DEVIN_AND_BOX)
ADD_WAYPOINT_REQUEST(5-1)
ADD_WAYPOINT_REQUEST(6-1)
ADD_WAYPOINT_REQUEST(7-1)
ADD_WAYPOINT_REQUEST(8-1)
ADD_WAYPOINT_REQUEST(9-1)
ADD_WAYPOINT_REQUEST(10-1)
ADD_WAYPOINT_REQUEST(11-1)
ADD_WAYPOINT_REQUEST(12-1)
ADD_WAYPOINT_REQUEST(13-1)
ADD_WAYPOINT_REQUEST(14-1)
ADD_WAYPOINT_REQUEST(15-1)
ADD_WAYPOINT_REQUEST(16-1)
ADD_WAYPOINT_REQUEST(17-1)
ADD_WAYPOINT_REQUEST(18-1)
createDevinHouseStage = CREATE_DEVIN_HOUSE_STAGE_WAITING
ENDIF
BREAK
CASE CREATE_DEVIN_HOUSE_STAGE_WAITING
IF HAVE_ALL_MODEL_REQUESTS_SUCCEEDED()
AND HAVE_ALL_ANIM_DICT_REQUESTS_SUCCEEDED()
AND HAVE_ALL_WEAPON_REQUESTS_SUCCEEDED()
AND HAVE_ALL_WAYPOINT_REQUESTS_SUCCEEDED()
CREATE_DEVIN_HOUSE()
createDevinHouseStage = CREATE_DEVIN_HOUSE_STAGE_DONE
ENDIF
BREAK
CASE CREATE_DEVIN_HOUSE_STAGE_DONE
DO_COMMON_DEVINS_HOUSE()
IF bGeneralMerryweatherAlert
OR devinIntoBoxState > DEVIN_INTO_BOX_STATE_NOT_STARTED
OR bTrespassing
IF CAN_ADVANCE_MISSION()
IF STREAMVOL_IS_VALID(devinVolume)
STREAMVOL_DELETE(devinVolume)
ENDIF
REMOVE_ALL_BLIPS()
SET_MISSION_STAGE(STAGE_DEVINS_HOUSE)
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_KIDNAP_DEVIN_STEALTH)
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_KIDNAP_DEVIN_ALERT)
TRIGGER_MISSION_MUSIC_EVENT("FINC2_OUTSIDE_DEVINS")
TRIGGER_MISSION_MUSIC_EVENT("FINC2_ALERTED")
ENDIF
ENDIF
BREAK
ENDSWITCH
IF currentMissionStage = STAGE_PICKUP_DEVIN
BOOL bIsInHeliAtHouse = FALSE
IF IS_PED_SITTING_IN_ANY_VEHICLE(PLAYER_PED_ID())
VEHICLE_INDEX playerVehicle = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
IF IS_VEHICLE_DRIVEABLE(playerVehicle)
IF IS_THIS_MODEL_A_HELI(GET_ENTITY_MODEL(playerVehicle))
IF IS_ENTITY_IN_AREA(PLAYER_PED_ID(), <<-2679.9, 1793.3, 137.7>>, <<2468.1, 1976.0, 252.7>>)
bIsInHeliAtHouse = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
IF NOT bCutsceneWaitStarted
AND NOT bIsInHeliAtHouse
IF HANDLE_GET_TO_LOCATION(FALSE, FALSE, TRUE)
IF NOT DOES_BLIP_EXIST(gotoBlip)
REMOVE_ALL_BLIPS()
REMOVE_MISSION_TEXT(FALSE)
gotoBlip = CREATE_MISSION_BLIP_FOR_COORD(GET_FINALE_VECTOR(FINVEC_PICKUP), TRUE)
ENDIF
IF NOT bShownGodText
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
bShownGodText = DO_MISSION_GOD_TEXT("FC2_GODEV")
ENDIF
ENDIF
IF NOT STREAMVOL_IS_VALID(devinVolume)
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_FINALE_VECTOR(FINVEC_PICKUP), <<50,50,50>>)
devinVolume = STREAMVOL_CREATE_FRUSTUM(<<-2711.9, 1910.3, 175.9>>, CONVERT_ROTATION_TO_DIRECTION_VECTOR(<<-1.4, 0.0, -102.8>>), 200, FLAG_MAPDATA)
ENDIF
ELSE
IF NOT IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_FINALE_VECTOR(FINVEC_PICKUP), <<75,75,75>>)
STREAMVOL_DELETE(devinVolume)
ENDIF
ENDIF
IF iWanted = 0
IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_FINALE_VECTOR(FINVEC_PICKUP), <<1,1,LOCATE_SIZE_HEIGHT>>, TRUE)
IF IS_PLAYER_IN_DRIVEWAY_OUTSIDE()
AND createDevinHouseStage = CREATE_DEVIN_HOUSE_STAGE_DONE
AND CAN_PLAYER_START_CUTSCENE()
iAllowLaunchCutsceneTime = GET_GAME_TIMER() + DEFAULT_CAR_STOPPING_TO_CUTSCENE
bCutsceneWaitStarted = TRUE
ENDIF
ENDIF
ENDIF
ELSE
BOOL bAdvance = TRUE
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF IS_VEHICLE_DRIVEABLE(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()))
bAdvance = BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), 8)
ENDIF
ENDIF
IF bAdvance
OR bIsInHeliAtHouse
IF GET_GAME_TIMER() >= iAllowLaunchCutsceneTime
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF CAN_ADVANCE_MISSION()
bRunningCutscene = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
DO_HOUSE_CUTSCENE()
ENDIF
ENDPROC
// do house cutscene
PROC DO_KIDNAP_CUTSCENE()
SWITCH cutsceneStage
CASE F_CUT_STAGE_INIT
LOCK_AUTOMATIC_DOOR_OPEN(AUTODOOR_DEVIN_GATE_L, TRUE)
LOCK_AUTOMATIC_DOOR_OPEN(AUTODOOR_DEVIN_GATE_R, TRUE)
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
REGISTER_ENTITY_FOR_CUTSCENE(PLAYER_PED_ID(), "Trevor", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
IF NOT IS_PED_INJURED(devinPed)
REGISTER_ENTITY_FOR_CUTSCENE(devinPed, "DEVIN", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_DEVIN_CAR])
ELSE
IF DOES_ENTITY_EXIST(finaleVehicle[FV_DEVIN_CAR])
DELETE_VEHICLE(finaleVehicle[FV_DEVIN_CAR])
CLEAR_AREA(GET_FINALE_VECTOR(FINVEC_DEVIN_CAR_INIT), 5.0, TRUE)
FINALE_CREATE_VEHICLE(STAGE_GET_TO_CLIFF, FV_DEVIN_CAR, GET_FINALE_VECTOR(FINVEC_DEVIN_CAR_INIT), DEVIN_CAR_INIT_ROT, TRUE, TRUE, FALSE, TRUE, FALSE)
ENDIF
ENDIF
REGISTER_ENTITY_FOR_CUTSCENE(finaleVehicle[FV_DEVIN_CAR], "TORNADO", CU_ANIMATE_EXISTING_SCRIPT_ENTITY, DUMMY_MODEL_FOR_SCRIPT, CEO_IS_CASCADE_SHADOW_FOCUS_ENTITY_DURING_EXIT)
IF DOES_ENTITY_EXIST(boxObject)
REGISTER_ENTITY_FOR_CUTSCENE(boxObject, "p_devin_box_01_s", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
TRIGGER_MISSION_MUSIC_EVENT("FINC2_WE_GOT_HIM")
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_KIDNAP_DEVIN_STEALTH)
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_KIDNAP_DEVIN_ALERT)
START_CUTSCENE(CUTSCENE_SUPPRESS_FP_TRANSITION_FLASH)
bDoneFlash = FALSE
REPLAY_START_EVENT(REPLAY_IMPORTANCE_HIGHEST)
iFinaleCutsceneTime = GET_GAME_TIMER()
cutsceneStage = F_CUT_STAGE_RUNNING
BREAK
CASE F_CUT_STAGE_RUNNING
IF NOT bClearedForCutscene
IF IS_CUTSCENE_PLAYING()
// clear the area
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA_WITH_SIZE_LIMIT(<<-2550.60352, 1909.27344, 167.02940>>, <<-2558.10767, 1912.69250, 172.87531>>, 0.7, <<-2551.91, 1909.08, 168.88>>, 57.85, GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR(), TRUE, FALSE, TRUE)
IF DOES_ENTITY_EXIST(boxCollisionObject)
DELETE_OBJECT(boxCollisionObject)
ENDIF
SET_MISSION_MOCAP_CUTSCENE()
CLEAR_AREA(<<-2649.05884, 1872.45435, 159.72034>>, 8, TRUE)
CLEAR_AREA_OF_PROJECTILES(<<-2649.05884, 1872.45435, 159.72034>>, 12)
STOP_FIRE_IN_RANGE(<<-2649.05884, 1872.45435, 159.72034>>, 12)
REMOVE_PARTICLE_FX_IN_RANGE(<<-2649.05884, 1872.45435, 159.72034>>, 12)
IF IS_SCREEN_FADED_OUT()
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
ENDIF
bClearedForCutscene = TRUE
ENDIF
ENDIF
IF NOT bDoneFlash
IF GET_FOLLOW_VEHICLE_CAM_VIEW_MODE() = CAM_VIEW_MODE_FIRST_PERSON
IF GET_CUTSCENE_TIME() >= GET_CUTSCENE_TOTAL_DURATION() - 300
ANIMPOSTFX_PLAY("CamPushInNeutral", 0, FALSE)
PLAY_SOUND_FRONTEND(-1, "1st_Person_Transition", "PLAYER_SWITCH_CUSTOM_SOUNDSET")
bDoneFlash = TRUE
ENDIF
ENDIF
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Tornado")
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_DEVIN_CAR])
printstring("shut all doors") printnl()
SHUT_ALL_VEHICLE_DOORS(finaleVehicle[FV_DEVIN_CAR])
bSetTornadoOutOfCut = TRUE
ENDIF
ELSE
IF NOT bSetTornadoOutOfCut
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_DEVIN_CAR])
SET_VEHICLE_USE_CUTSCENE_WHEEL_COMPRESSION(finaleVehicle[FV_DEVIN_CAR])
ENDIF
ENDIF
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Trevor")
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_DEVIN_CAR])
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_DEVIN_CAR])
ENDIF
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Devin")
IF DOES_ENTITY_EXIST(devinPed)
DELETE_PED(devinPed)
ENDIF
ENDIF
IF CAN_SET_EXIT_STATE_FOR_CAMERA()
INT i
REPEAT COUNT_OF(MERRYWEATHER_ENUM) i
IF DOES_ENTITY_EXIST(merryWeatherPed[i].ped)
IF IS_PED_INJURED(merryWeatherPed[i].ped)
SET_PED_AS_NO_LONGER_NEEDED(merryWeatherPed[i].ped)
ELSE
DELETE_PED(merryWeatherPed[i].ped)
ENDIF
ENDIF
ENDREPEAT
IF DOES_ENTITY_EXIST(boxObject)
DELETE_OBJECT(boxObject)
ENDIF
IF DOES_ENTITY_EXIST(boxCollisionObject)
DELETE_OBJECT(boxCollisionObject)
ENDIF
REPLAY_STOP_EVENT()
SET_MISSION_CUTSCENE(FALSE)
SET_MISSION_STAGE(STAGE_GET_TO_CLIFF)
ENDIF
BREAK
CASE F_CUT_STAGE_CLEANUP
BREAK
ENDSWITCH
ENDPROC
FUNC INT GET_CLOSEST_MERRYWEATHER_PED()
INT i
INT iClosest = -1
FLOAT fClosestDistance = 9999999
REPEAT COUNT_OF(MERRYWEATHER_ENUM) i
IF i <> 1
AND i <> iMerryweatherSpeaker1
AND i <> iMerryweatherSpeaker2
IF NOT IS_PED_INJURED(merryweatherPed[i].ped)
FLOAT fThisDistance = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(merryweatherPed[i].ped), FALSE)
IF fThisDistance < fClosestDistance
fClosestDistance = fThisDistance
iClosest = i
ENDIF
ENDIF
ENDIF
ENDREPEAT
RETURN iClosest
ENDFUNC
// devin's house stage
PROC DO_STAGE_DEVINS_HOUSE()
SET_ALL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID())
IF NOT bRunningCutscene
DO_COMMON_DEVINS_HOUSE()
IF NOT bPlayerNearDeck
INT i
IF IS_ENTITY_IN_AREA(PLAYER_PED_ID(), <<-2654.7, 1861.9, 159.30399>>, <<-2602.7, 1925.2, 168.7>>)
OR IS_ENTITY_IN_AREA(PLAYER_PED_ID(), <<-2604.20654, 1859.18201, 164.80421>>, <<-2598.30151, 1905.65698, 168.7>>)
REPEAT COUNT_OF(MERRYWEATHER_ENUM) i
IF NOT IS_PED_INJURED(merryweatherPed[i].ped)
SET_PED_COMBAT_RANGE(merryweatherPed[i].ped, CR_NEAR)
SET_PED_COMBAT_ATTRIBUTES(merryweatherPed[i].ped, CA_DISABLE_SEEK_DUE_TO_LINE_OF_SIGHT, FALSE)
ENDIF
ENDREPEAT
printstring("set up on merryweather") printnl()
bPlayerNearDeck = TRUE
ENDIF
ENDIF
IF NOT bGeneralMerryweatherAlert
IF NOT bDoneKidnapDevinText
bDoneKidnapDevinText = DO_MISSION_GOD_TEXT("FC2_KIDDEV")
ENDIF
ELSE
IF NOT bDoneKillGuardsText
BOOL bDoGodText = FALSE
IF bSetMerryweatherSpeaker1
IF IS_PED_INJURED(merryWeatherPed[iMerryweatherSpeaker1].ped)
OR bDoneMerryweatherCombatSpeech1
OR GET_GAME_TIMER() >= iAssignedSpeakerTime + 1200
bDoGodText = TRUE
ENDIF
ENDIF
IF bDoGodText
IF IS_THIS_PRINT_BEING_DISPLAYED("FC2_KIDDEV")
REMOVE_MISSION_TEXT(FALSE, TRUE, FALSE)
ENDIF
bDoneKillGuardsText = DO_MISSION_GOD_TEXT("FC2_KILLGUA")
ENDIF
ELSE
IF NOT bRepeatedKidnapDevinText
IF iGuardsAlive = 0
bRepeatedKidnapDevinText = DO_MISSION_GOD_TEXT("FC2_KIDDEV")
ENDIF
ENDIF
ENDIF
ENDIF
IF NOT bDoneAlertedCue
IF bGeneralMerryweatherAlert
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_KIDNAP_DEVIN_STEALTH)
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_KIDNAP_DEVIN_ALERT)
bDoneAlertedCue = TRIGGER_MISSION_MUSIC_EVENT("FINC2_ALERTED")
ENDIF
ELSE
IF NOT bDoneKilledAllCue
IF iGuardsAlive = 0
bDoneKilledAllCue = TRIGGER_MISSION_MUSIC_EVENT("FINC2_ALL_DEAD")
ENDIF
ENDIF
ENDIF
IF bGeneralMerryweatherAlert
IF iGuardsAlive > 0
IF GET_RANDOM_INT_IN_RANGE(0,2) = 0
DO_RANDOM_SPEECH("FINC1_TRECOM", 10000, 16000)
ELSE
DO_RANDOM_SPEECH("FINC1_DEVIN", 10000, 16000)
ENDIF
ENDIF
ENDIF
IF NOT bSetMerryweatherSpeaker1
IF bDoSpottedSpeech
OR bGeneralMerryweatherAlert
IF IS_THIS_PRINT_BEING_DISPLAYED("FC2_KIDDEV")
REMOVE_MISSION_TEXT(FALSE, TRUE, FALSE)
ENDIF
ENDIF
IF NOT IS_MESSAGE_BEING_DISPLAYED()
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF bDoSpottedSpeech
OR bGeneralMerryweatherAlert
IF iMerryweatherSpeaker1 < 0
iMerryweatherSpeaker1 = GET_CLOSEST_MERRYWEATHER_PED()
ENDIF
IF iMerryweatherSpeaker1 >= 0
IF NOT IS_PED_INJURED(merryweatherPed[iMerryweatherSpeaker1].ped)
ADD_PED_FOR_DIALOGUE(finaleConversation, 7, merryweatherPed[iMerryweatherSpeaker1].ped, "MERRYGUARD2")
printstring("assigned speaker!") printnl()
iAssignedSpeakerTime = GET_GAME_TIMER()
bSetMerryweatherSpeaker1 = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF NOT bDoneMerryweatherCombatSpeech1
IF NOT IS_PED_INJURED(merryweatherPed[iMerryweatherSpeaker1].ped)
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), merryweatherPed[iMerryweatherSpeaker1].ped, <<27,27,5>>)
IF NOT bFlipMerryweatherDialogue
bDoneMerryweatherCombatSpeech1 = DO_MISSION_SPEECH("FINC1_MW2")
ELSE
bDoneMerryweatherCombatSpeech1 = DO_MISSION_SPEECH("FINC1_MW5")
ENDIF
iMerryweatherCombatSpeechTime = GET_GAME_TIMER()
ENDIF
ENDIF
ELSE
IF NOT bDoneMerryweatherCombatSpeech2
IF NOT IS_PED_INJURED(merryweatherPed[iMerryweatherSpeaker1].ped)
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), merryweatherPed[iMerryweatherSpeaker1].ped, <<27,27,5>>)
IF GET_GAME_TIMER() >= iMerryweatherCombatSpeechTime + 8000
IF NOT bFlipMerryweatherDialogue
bDoneMerryweatherCombatSpeech2 = DO_MISSION_SPEECH("FINC1_MW3")
ELSE
bDoneMerryweatherCombatSpeech2 = DO_MISSION_SPEECH("FINC1_MW6")
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
IF bGeneralMerryweatherAlert
IF NOT bSetMerryweatherSpeaker2
IF bSetMerryweatherSpeaker1
IF GET_GAME_TIMER() >= iAssignedSpeakerTime + 45000
OR iGuardsAlive < 4
IF IS_PED_INJURED(merryweatherPed[iMerryweatherSpeaker1].ped)
IF NOT IS_MESSAGE_BEING_DISPLAYED()
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
iMerryweatherSpeaker2 = GET_CLOSEST_MERRYWEATHER_PED()
IF iMerryweatherSpeaker2 >= 0
ADD_PED_FOR_DIALOGUE(finaleConversation, 7, merryweatherPed[iMerryweatherSpeaker2].ped, "MERRYGUARD2")
bSetMerryweatherSpeaker2 = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF NOT IS_PED_INJURED(merryweatherPed[iMerryweatherSpeaker2].ped)
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), merryweatherPed[iMerryweatherSpeaker2].ped, <<27,27,5>>)
IF NOT bDoneMerryweatherCombatSpeech3
IF NOT bFlipMerryweatherDialogue
bDoneMerryweatherCombatSpeech3 = DO_MISSION_SPEECH("FINC1_MW6")
ELSE
bDoneMerryweatherCombatSpeech3 = DO_MISSION_SPEECH("FINC1_MW3")
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
IF NOT IS_PED_INJURED(devinPed)
IF iGuardsAlive = 0
HANDLE_STREAMING_MOCAP("fin_c2_mcs_5", <<-2648.75684, 1872.55396, 159.15071>>, 50, 75)
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
IF NOT IS_PED_INJURED(devinPed)
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Devin", devinPed)
SET_CUTSCENE_PED_COMPONENT_VARIATION("Devin", PED_COMP_SPECIAL, 0, 0, CS_DEVIN)
ENDIF
ENDIF
IF NOT bCutsceneWaitStarted
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), devinPed, <<3.5,3.5,2.5>>)
AND devinIntoBoxState = DEVIN_INTO_BOX_STATE_DONE
AND NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON)
bCutsceneWaitStarted = TRUE
ENDIF
ELSE
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF HAS_CUTSCENE_LOADED_WITH_FAILSAFE()
bRunningCutscene = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
DO_KIDNAP_CUTSCENE()
ENDIF
ENDPROC
PROC START_MISSION_CREDITS()
SET_CREDITS_ACTIVE(TRUE)
SET_CREDITS_FADE_OUT_WITH_SCREEN(FALSE)
START_AUDIO_SCENE("END_CREDITS_SCENE")
SET_GAME_PAUSES_FOR_STREAMING(FALSE)
bStartedCreditsRoll = TRUE
ENDPROC
// cleanup cliff cutscene
PROC CLEANUP_CLIFF_CUTSCENE()
INT i
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
DETACH_ENTITY(PLAYER_PED_ID())
ENDIF
REPEAT 3 i
IF DOES_ENTITY_EXIST(sSelectorPeds.pedID[i])
DELETE_PED(sSelectorPeds.pedID[i])
ENDIF
ENDREPEAT
IF DOES_ENTITY_EXIST(devinPed)
DELETE_PED(devinPed)
ENDIF
REPEAT COUNT_OF(finaleVehicle) i
IF DOES_ENTITY_EXIST(finaleVehicle[i])
DELETE_VEHICLE(finaleVehicle[i])
ENDIF
ENDREPEAT
IF bSkippedCutscene
ENDIF
CREATE_MISSION_STATIC_CAM(staticCam)
SET_CAM_COORD(staticCam, <<-1573.8031, 5160.5732, 20.7951>>)
SET_CAM_ROT(staticCam, <<5.9980, -0.0062, 83.9225>>)
SET_CAM_FOV(staticCam, 40.000000)
CREATE_MISSION_STATIC_CAM(interpCam)
SET_CAM_COORD(interpCam, <<-1573.8031, 5160.5732, 20.7951>>)
SET_CAM_ROT(interpCam,<<5.9980, -0.0062, 83.9225>>)
SET_CAM_FOV(interpCam, 40.000000)
SHAKE_CAM(interpCam, "HAND_SHAKE", 0.15)
SET_CAM_ACTIVE_WITH_INTERP(interpCam, staticCam, 2000)
//SET_MISSION_CUTSCENE(FALSE)
iCreditsStartTime = GET_GAME_TIMER()
cliffStage = CLIFF_STAGE_BEGIN_CREDITS
IF NOT bStartedCreditsRoll
WHILE NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT)
WAIT(0)
ENDWHILE
START_MISSION_CREDITS()
ENDIF
IF IS_SCREEN_FADED_OUT()
OR IS_SCREEN_FADING_OUT()
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
ENDIF
ENDPROC
CONST_FLOAT OVER_EDGE_X -1588.87
// do cliff cutscene
PROC DO_CLIFF_CUTSCENE()
PED_INDEX michaelPed = GET_MICHAEL_PED()
PED_INDEX trevorPed = GET_TREVOR_PED()
PED_INDEX franklinPed = GET_FRANKLIN_PED()
SET_ALL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID())
SWITCH cutsceneStage
CASE F_CUT_STAGE_INIT
SET_MISSION_CUTSCENE(TRUE)
/*
CREATE_MISSION_STATIC_CAM(staticCam)
DETACH_CAM(staticCam)
STOP_CAM_POINTING(staticCam)
VECTOR vGameCamCoord
vGameCamCoord = GET_GAMEPLAY_CAM_COORD()
VECTOR vGameCamRot
vGameCamRot = GET_GAMEPLAY_CAM_ROT()
FLOAT fGameCamFOV
fGameCamFOV = GET_GAMEPLAY_CAM_FOV()
SET_CAM_COORD(staticCam, vGameCamCoord)
SET_CAM_ROT(staticCam, vGameCamRot)
SET_CAM_FOV(staticCam, fGameCamFOV)
CREATE_MISSION_STATIC_CAM(interpCam)
SET_CAM_COORD(interpCam, vGameCamCoord + <<0,0,5>> )
SET_CAM_ROT(interpCam, <<70, vGameCamRot.y, vGameCamRot.z>>)
SET_CAM_FOV(interpCam, fGameCamFOV)
SET_CAM_ACTIVE_WITH_INTERP(interpCam, staticCam, 7000)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
*/
//CLEAR_SFX_REQUEST(F_SFX_DEVIN_BANGING)
// iSyncScene = CREATE_SYNCHRONIZED_SCENE(<<-1586.885, 5164.080, 18.547>>, <<0,0,-24.000>>)
// CREATE_MISSION_ANIM_CAM()
// PLAY_SYNCHRONIZED_CAM_ANIM(animCam, iSyncScene, "lead_in_to_fin_ext_p1_cam", GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_CLIFF_CAM))
// SET_SYNCHRONIZED_SCENE_HOLD_LAST_FRAME(iSyncScene, TRUE)
//WATER_OVERRIDE_SET_SHOREWAVEAMPLITUDE(100.0)
//WATER_OVERRIDE_SET_SHOREWAVEMINAMPLITUDE(100.0)
//WATER_OVERRIDE_SET_SHOREWAVEMAXAMPLITUDE(100.0)
WATER_OVERRIDE_SET_SHOREWAVEAMPLITUDE(0)
WATER_OVERRIDE_SET_SHOREWAVEMINAMPLITUDE(0)
WATER_OVERRIDE_SET_SHOREWAVEMAXAMPLITUDE(0)
WATER_OVERRIDE_SET_OCEANNOISEMINAMPLITUDE(0)
WATER_OVERRIDE_SET_OCEANWAVEAMPLITUDE(0)
WATER_OVERRIDE_SET_OCEANWAVEMINAMPLITUDE(0)
WATER_OVERRIDE_SET_OCEANWAVEMAXAMPLITUDE(0)
WATER_OVERRIDE_SET_RIPPLEBUMPINESS(0)
WATER_OVERRIDE_SET_RIPPLEMINBUMPINESS(0)
WATER_OVERRIDE_SET_RIPPLEMAXBUMPINESS(0)
WATER_OVERRIDE_SET_RIPPLEDISTURB(0)
WATER_OVERRIDE_SET_STRENGTH(0.1)
printstring("setting shore wave") printnl()
CREATE_CAM_FOR_FINALE_SHOT(FIN_SHOT_CLIFFS, TRUE, 8000)
CASCADE_SHADOWS_SET_CASCADE_BOUNDS_SCALE(0.6)
CASCADE_SHADOWS_ENABLE_ENTITY_TRACKER(FALSE)
CASCADE_SHADOWS_ENABLE_FREEZER(FALSE) //#1439834
TRIGGER_MUSIC_EVENT("FIN1_RADIO_FADE")
g_bFinaleCreditsPlaylistStarted = FALSE
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
CLEAR_AREA(<<-1577.77246, 5157.83252, 18.7777>>, 5, TRUE)
CLEAR_AREA_OF_PROJECTILES(<<-1577.77246, 5157.83252, 18.7777>>, 12)
STOP_FIRE_IN_RANGE(<<-1577.77246, 5157.83252, 18.7777>>, 12)
REMOVE_PARTICLE_FX_IN_RANGE(<<-1577.77246, 5157.83252, 18.7777>>, 12)
CLEAR_AREA_OF_PEDS(<<-1577.77246, 5157.83252, 18.7777>>, 120.0)
CLEAR_AREA_OF_VEHICLES(<<-1577.77246, 5157.83252, 18.7777>>, 120.0)
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_DEVIN_CAR])
SET_ENTITY_COORDS(finaleVehicle[FV_DEVIN_CAR], <<-1577.77246, 5157.83252, 18.7777>>)
SET_ENTITY_HEADING(finaleVehicle[FV_DEVIN_CAR], 3.2)
SET_VEHICLE_ON_GROUND_PROPERLY(finaleVehicle[FV_DEVIN_CAR])
SET_VEHICLE_ENGINE_ON(finaleVehicle[FV_DEVIN_CAR], FALSE, FALSE)
SET_VEHICLE_FORWARD_SPEED(finaleVehicle[FV_DEVIN_CAR], 0.0)
ENDIF
iFinaleCutsceneTime = GET_GAME_TIMER()
IF IS_SCREEN_FADED_OUT()
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
ENDIF
cutsceneStage = F_CUT_STAGE_RUNNING
BREAK
CASE F_CUT_STAGE_RUNNING
SWITCH cliffStage
CASE CLIFF_STAGE_PAN_UP
SET_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
SET_SCENARIO_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.0, 0.0)
HANDLE_STREAMING_MOCAP("fin_ext_p1", GET_FINALE_VECTOR(FINVEC_CLIFF), DEFAULT_CUTSCENE_LOAD_DIST, DEFAULT_CUTSCENE_UNLOAD_DIST)
IF IS_SCREEN_FADED_OUT()
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
ENDIF
IF GET_GAME_TIMER() >= iFinaleCutsceneTime + 8500
IF DO_TIMELAPSE(SP_MISSION_FINALE_C2, sTimelapse, TRUE, FALSE, TRUE, TRUE)
WHILE NOT HAS_CUTSCENE_LOADED_WITH_FAILSAFE()
SET_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
SET_SCENARIO_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.0, 0.0)
WAIT(0)
ENDWHILE
SET_PLAYER_PED_WITH_HEADSET(CHAR_MICHAEL, FALSE)
SET_PLAYER_PED_WITH_HEADSET(CHAR_TREVOR, FALSE)
SET_PLAYER_PED_WITH_HEADSET(CHAR_FRANKLIN, FALSE)
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_DEVIN_CAR])
SET_VEHICLE_LIGHTS(finaleVehicle[FV_DEVIN_CAR], FORCE_VEHICLE_LIGHTS_ON)
REGISTER_ENTITY_FOR_CUTSCENE(finaleVehicle[FV_DEVIN_CAR], "Trevor_Cliff_Car", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
IF NOT IS_PED_INJURED(trevorPed)
REGISTER_ENTITY_FOR_CUTSCENE(trevorPed, "Trevor", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
IF NOT IS_PED_INJURED(michaelPed)
REGISTER_ENTITY_FOR_CUTSCENE(michaelPed, "Michael", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ELSE
REGISTER_ENTITY_FOR_CUTSCENE(michaelPed, "Michael", CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_MICHAEL))
ENDIF
IF NOT IS_PED_INJURED(franklinPed)
REGISTER_ENTITY_FOR_CUTSCENE(franklinPed, "Franklin", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ELSE
REGISTER_ENTITY_FOR_CUTSCENE(franklinPed, "Franklin", CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, GET_MODEL_FOR_FINALE_MODEL_ENUM(FM_FRANKLIN))
ENDIF
REGISTER_ENTITY_FOR_CUTSCENE(devinPed, "Devin", CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, CS_DEVIN)
/*
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_MICHAEL_CAR])
IF GET_ENTITY_MODEL(finaleVehicle[FV_MICHAEL_CAR]) = TAILGATER
REGISTER_ENTITY_FOR_CUTSCENE(finaleVehicle[FV_MICHAEL_CAR], "Michaels_car", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
ENDIF
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_FRANKLIN_CAR])
IF GET_ENTITY_MODEL(finaleVehicle[FV_FRANKLIN_CAR]) = BAGGER
REGISTER_ENTITY_FOR_CUTSCENE(finaleVehicle[FV_FRANKLIN_CAR], "Franklin_Bike", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
ENDIF
*/
REPLAY_START_EVENT(REPLAY_IMPORTANCE_HIGHEST)
START_CUTSCENE(CUTSCENE_SUPPRESS_FP_TRANSITION_FLASH)
SET_CUTSCENE_FADE_VALUES(FALSE, FALSE, FALSE, FALSE)
cliffStage = CLIFF_STAGE_ARRIVE
ENDIF
ENDIF
BREAK
CASE CLIFF_STAGE_ARRIVE
IF NOT bClearedForCutscene
IF IS_CUTSCENE_PLAYING()
SET_TODS_CUTSCENE_RUNNING(sTimelapse, FALSE)
// clear the area
SET_MISSION_MOCAP_CUTSCENE()
IF bForcePassOnShitskip
IF IS_SCREEN_FADED_OUT()
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
ENDIF
ELSE
IF IS_SCREEN_FADED_OUT()
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
ENDIF
ENDIF
SET_PLAYER_PED_WITH_HEADSET(CHAR_TREVOR, FALSE)
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_DRIVE_TO_OCEAN)
CLEAR_AREA(GET_FINALE_VECTOR(FINVEC_CLIFF), 12, TRUE)
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_MICHAEL_CAR])
SET_VEHICLE_DOOR_CONTROL(finaleVehicle[FV_MICHAEL_CAR], SC_DOOR_FRONT_LEFT, DT_DOOR_INTACT, 0.0)
ENDIF
STOP_VEHICLE_FIRE(finaleVehicle[FV_DEVIN_CAR])
SET_ENTITY_PROOFS(finaleVehicle[FV_DEVIN_CAR], FALSE, FALSE, FALSE, FALSE, FALSE)
bClearedForCutscene = TRUE
ENDIF
ENDIF
// get Devin
IF NOT DOES_ENTITY_EXIST(devinPed)
IF DOES_ENTITY_EXIST(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Devin"))
devinPed = GET_PED_INDEX_FROM_ENTITY_INDEX(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Devin"))
ENDIF
ENDIF
IF NOT DOES_ENTITY_EXIST(sSelectorPeds.pedID[SELECTOR_PED_MICHAEL])
IF DOES_ENTITY_EXIST(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Michael"))
sSelectorPeds.pedID[SELECTOR_PED_MICHAEL] = GET_PED_INDEX_FROM_ENTITY_INDEX(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Michael"))
ENDIF
ENDIF
IF NOT DOES_ENTITY_EXIST(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
IF DOES_ENTITY_EXIST(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Franklin"))
sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN] = GET_PED_INDEX_FROM_ENTITY_INDEX(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Franklin"))
ENDIF
ENDIF
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_DEVIN_CAR])
VECTOR vPos
VECTOR vRot
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Trevor")
IF NOT IS_PED_INJURED(trevorPed)
UPDATE_CHAR_PUSH_CAR_POS_AND_ROT(trevorPed, CHAR_TREVOR, vPos, vRot, 0)
ATTACH_ENTITY_TO_ENTITY(trevorPed, finaleVehicle[FV_DEVIN_CAR], GET_ENTITY_BONE_INDEX_BY_NAME(finaleVehicle[FV_DEVIN_CAR], "seat_dside_f"), vPos, vRot)
ANIM_DATA none
ANIM_DATA animDataBlend1
animDataBlend1.type = APT_SINGLE_ANIM
animDataBlend1.anim0 = GET_PUSH_CAR_ANIM_FOR_CHAR(CHAR_TREVOR)
animDataBlend1.dictionary0 = GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_PUSH_CAR)
animDataBlend1.phase0 = 0.0
animDataBlend1.rate0 = 0.0
animDataBlend1.flags = AF_LOOPING
TASK_SCRIPTED_ANIMATION(trevorPed, animDataBlend1, none, none, INSTANT_BLEND_DURATION, INSTANT_BLEND_DURATION)
ANIM_DATA animDataBlend2
animDataBlend2.type = APT_SINGLE_ANIM
animDataBlend2.anim0 = "PushCar_waitIdle_additive_T"
animDataBlend2.dictionary0 = GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_PUSH_CAR)
animDataBlend2.phase0 = 0.0
animDataBlend2.rate0 = 1.0
animDataBlend2.flags = AF_LOOPING | AF_ADDITIVE | AF_SECONDARY
TASK_SCRIPTED_ANIMATION(trevorPed, animDataBlend2, none, none, INSTANT_BLEND_DURATION, INSTANT_BLEND_DURATION)
//TASK_PLAY_ANIM(trevorPed, GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_PUSH_CAR), GET_PUSH_CAR_ANIM_FOR_CHAR(CHAR_TREVOR), INSTANT_BLEND_IN, INSTANT_BLEND_OUT, -1, AF_LOOPING)
FORCE_PED_AI_AND_ANIMATION_UPDATE(trevorPed)
ENDIF
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Michael")
IF NOT IS_PED_INJURED(michaelPed)
UPDATE_CHAR_PUSH_CAR_POS_AND_ROT(michaelPed, CHAR_MICHAEL, vPos, vRot, 0)
ATTACH_ENTITY_TO_ENTITY(michaelPed, finaleVehicle[FV_DEVIN_CAR], GET_ENTITY_BONE_INDEX_BY_NAME(finaleVehicle[FV_DEVIN_CAR], "seat_dside_f"), vPos, vRot)
ANIM_DATA none
ANIM_DATA animDataBlend1
animDataBlend1.type = APT_SINGLE_ANIM
animDataBlend1.anim0 = GET_PUSH_CAR_ANIM_FOR_CHAR(CHAR_MICHAEL)
animDataBlend1.dictionary0 = GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_PUSH_CAR)
animDataBlend1.phase0 = 0.0
animDataBlend1.rate0 = 0.0
animDataBlend1.flags = AF_LOOPING
TASK_SCRIPTED_ANIMATION(michaelPed, animDataBlend1, none, none, INSTANT_BLEND_DURATION, INSTANT_BLEND_DURATION)
ANIM_DATA animDataBlend2
animDataBlend2.type = APT_SINGLE_ANIM
animDataBlend2.anim0 = "PushCar_waitIdle_additive_M"
animDataBlend2.dictionary0 = GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_PUSH_CAR)
animDataBlend2.phase0 = 0.0
animDataBlend2.rate0 = 1.0
animDataBlend2.flags = AF_LOOPING | AF_ADDITIVE | AF_SECONDARY
TASK_SCRIPTED_ANIMATION(michaelPed, animDataBlend2, none, none, INSTANT_BLEND_DURATION, INSTANT_BLEND_DURATION)
//TASK_PLAY_ANIM(michaelPed, GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_PUSH_CAR), GET_PUSH_CAR_ANIM_FOR_CHAR(CHAR_MICHAEL), INSTANT_BLEND_IN, INSTANT_BLEND_OUT, -1, AF_LOOPING)
FORCE_PED_AI_AND_ANIMATION_UPDATE(michaelPed)
ENDIF
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Franklin")
IF NOT IS_PED_INJURED(franklinPed)
UPDATE_CHAR_PUSH_CAR_POS_AND_ROT(franklinPed, CHAR_FRANKLIN, vPos, vRot, 0)
ATTACH_ENTITY_TO_ENTITY(franklinPed, finaleVehicle[FV_DEVIN_CAR], GET_ENTITY_BONE_INDEX_BY_NAME(finaleVehicle[FV_DEVIN_CAR], "seat_dside_f"), vPos, vRot)
ANIM_DATA none
ANIM_DATA animDataBlend1
animDataBlend1.type = APT_SINGLE_ANIM
animDataBlend1.anim0 = GET_PUSH_CAR_ANIM_FOR_CHAR(CHAR_FRANKLIN)
animDataBlend1.dictionary0 = GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_PUSH_CAR)
animDataBlend1.phase0 = 0.0
animDataBlend1.rate0 = 0.0
animDataBlend1.flags = AF_LOOPING
TASK_SCRIPTED_ANIMATION(franklinPed, animDataBlend1, none, none, INSTANT_BLEND_DURATION, INSTANT_BLEND_DURATION)
ANIM_DATA animDataBlend2
animDataBlend2.type = APT_SINGLE_ANIM
animDataBlend2.anim0 = "PushCar_waitIdle_additive_F"
animDataBlend2.dictionary0 = GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_PUSH_CAR)
animDataBlend2.phase0 = 0.0
animDataBlend2.rate0 = 1.0
animDataBlend2.flags = AF_LOOPING | AF_ADDITIVE | AF_SECONDARY
TASK_SCRIPTED_ANIMATION(franklinPed, animDataBlend2, none, none, INSTANT_BLEND_DURATION, INSTANT_BLEND_DURATION)
//TASK_PLAY_ANIM(franklinPed, GET_FINALE_ANIM_DICT_AS_STRING(F_ANIM_DICT_PUSH_CAR), GET_PUSH_CAR_ANIM_FOR_CHAR(CHAR_FRANKLIN), INSTANT_BLEND_IN, INSTANT_BLEND_OUT, -1, AF_LOOPING)
FORCE_PED_AI_AND_ANIMATION_UPDATE(franklinPed)
ENDIF
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Trevor_Cliff_Car")
SET_VEHICLE_DOOR_SHUT(finaleVehicle[FV_DEVIN_CAR], SC_DOOR_BOOT)
SET_VEHICLE_ON_GROUND_PROPERLY(finaleVehicle[FV_DEVIN_CAR])
PLAY_SOUND_FROM_ENTITY(iPushCarSoundID, "CAR_WHEELS", finaleVehicle[FV_DEVIN_CAR], "FINALE_C2_SOUNDS")
ENDIF
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Michaels_car")
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Franklin_Bike")
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Devin")
IF DOES_ENTITY_EXIST(devinPed)
DELETE_PED(devinPed)
ENDIF
ENDIF
IF CAN_SET_EXIT_STATE_FOR_CAMERA()
REPLAY_STOP_EVENT()
PAUSE_CLOCK(TRUE)
CREATE_CAMERA_ATTACHED_TO_CAR()
PRINT_HELP_FOREVER("FC2_PUSHHLP")
DO_MISSION_GOD_TEXT("FC2_KILLDEV")
START_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_PUSH_CAR)
RESET_ADAPTATION()
IF WAS_CUTSCENE_SKIPPED()
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
ENDIF
mocapStreamingStage = MOCAP_STREAMING_STAGE_REQUEST
iFinaleCutsceneTime = GET_GAME_TIMER()
iNextDevinBangOnTrunkTime = GET_GAME_TIMER() + 2000
SET_MULTIHEAD_SAFE(FALSE) //B* 2262843: Disable blinders in the 'push car' scene
cliffStage = CLIFF_STAGE_PUSH_CAR
ENDIF
#IF IS_DEBUG_BUILD
DEBUG_SKIP_MOCAP()
#ENDIF
BREAK
CASE CLIFF_STAGE_PUSH_CAR
ALLOW_ALTERNATIVE_SCRIPT_CONTROLS_LAYOUT(PLAYER_CONTROL)
INT iLX, iLY, iRX, iRY
GET_CONTROL_VALUE_OF_ANALOGUE_STICKS(iLX, iLY, iRX, iRY)
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_DEVIN_CAR])
VECTOR vIdealCamCoord
vIdealCamCoord = GET_IDEAL_CAR_CAM_POSITION()
vActualCamCoord += (vIdealCamCoord - vActualCamCoord) * (5 * GET_FRAME_TIME()) //7.5
vActualCamCoord.z = 20.3
SET_CAM_COORD(staticCam, vActualCamCoord)
VECTOR vCarPos
vCarPos = GET_ENTITY_COORDS(finaleVehicle[FV_DEVIN_CAR])
IF (iLY < -100 AND NOT IS_USING_KEYBOARD_AND_MOUSE(PLAYER_CONTROL))
OR (IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_MOVE_UP_ONLY) AND IS_USING_KEYBOARD_AND_MOUSE(PLAYER_CONTROL))
AND vCarPos.x > OVER_EDGE_X
// sound
IF NOT bDonePushCarSound
IF GET_GAME_TIMER() >= iPushCarSoundTime
PLAY_SOUND_FROM_ENTITY(-1, "Car_Push_Flex", finaleVehicle[FV_DEVIN_CAR], "FINALE_C2_SOUNDS")
SWITCH GET_RANDOM_INT_IN_RANGE(0,3)
CASE 0
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
PLAY_PAIN(PLAYER_PED_ID(), AUD_DAMAGE_REASON_CLIMB_SMALL, 0)
ENDIF
BREAK
CASE 1
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_MICHAEL])
PLAY_PAIN(sSelectorPeds.pedID[SELECTOR_PED_MICHAEL], AUD_DAMAGE_REASON_CLIMB_SMALL, 0)
ENDIF
BREAK
CASE 2
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
PLAY_PAIN(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], AUD_DAMAGE_REASON_CLIMB_SMALL, 0)
ENDIF
BREAK
ENDSWITCH
iPushCarSoundTime = GET_GAME_TIMER() + 1500
ENDIF
bDonePushCarSound = TRUE
ENDIF
fPushCarForce = fPushCarForce +@ 1.20//2.5
IF fPushCarForce > MAX_PUSH_CAR_FORCE
fPushCarForce = MAX_PUSH_CAR_FORCE
ENDIF
fPushAnimSpeed = fPushAnimSpeed +@ 1.0
IF fPushAnimSpeed > 1.0
fPushAnimSpeed = 1.0
ENDIF
APPLY_FORCE_TO_ENTITY(finaleVehicle[FV_DEVIN_CAR], APPLY_TYPE_FORCE, <<0,fPushCarForce,0>>, <<0,0,0>>, 0, TRUE, TRUE, TRUE)
ELSE
bDonePushCarSound = FALSE
fPushCarForce = fPushCarForce -@ 1.5
IF fPushCarForce < MIN_PUSH_CAR_FORCE
fPushCarForce = MIN_PUSH_CAR_FORCE
ENDIF
fPushAnimSpeed = fPushAnimSpeed -@ 1.0
IF fPushAnimSpeed < 0.0
fPushAnimSpeed = 0.0
ENDIF
ENDIF
//handle anim speeds
IF NOT IS_PED_INJURED(michaelPed)
SET_ANIM_RATE(michaelPed, fPushAnimSpeed, AF_PRIORITY_LOW)
ENDIF
IF NOT IS_PED_INJURED(trevorPed)
SET_ANIM_RATE(trevorPed, fPushAnimSpeed, AF_PRIORITY_LOW)
ENDIF
IF NOT IS_PED_INJURED(franklinPed)
SET_ANIM_RATE(franklinPed, fPushAnimSpeed, AF_PRIORITY_LOW)
ENDIF
// do bumping
IF GET_GAME_TIMER() >= iNextDevinBangOnTrunkTime
PLAY_SOUND_FROM_ENTITY(-1, "FINALE_C2_DEVIN_INSIDE_TRUNK_MASTER", finaleVehicle[FV_DEVIN_CAR])
PRINTSTRING("do devin bang!") PRINTNL()
iNextDevinBangOnTrunkTime = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(4000, 8000)
ENDIF
IF NOT IS_CUTSCENE_PLAYING()
HANDLE_STREAMING_MOCAP("fin_ext_p2", <<-1584.70, 5163.71, 18.56>>, DEFAULT_CUTSCENE_LOAD_DIST, DEFAULT_CUTSCENE_UNLOAD_DIST)
ENDIF
IF GET_GAME_TIMER() >= iFinaleCutsceneTime + 1000
IF vCarPos.x < OVER_EDGE_X
#IF IS_DEBUG_BUILD
OR IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J)
#ENDIF
IF HAS_CUTSCENE_LOADED_WITH_FAILSAFE()
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_DEVIN_CAR])
REGISTER_ENTITY_FOR_CUTSCENE(finaleVehicle[FV_DEVIN_CAR], "Trevor_Cliff_Car", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_MICHAEL_CAR])
IF GET_ENTITY_MODEL(finaleVehicle[FV_MICHAEL_CAR]) = TAILGATER
REGISTER_ENTITY_FOR_CUTSCENE(finaleVehicle[FV_MICHAEL_CAR], "Michaels_car", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
ENDIF
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_FRANKLIN_CAR])
IF GET_ENTITY_MODEL(finaleVehicle[FV_FRANKLIN_CAR]) = BAGGER
REGISTER_ENTITY_FOR_CUTSCENE(finaleVehicle[FV_FRANKLIN_CAR], "Franklin_Bike", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
ENDIF
IF NOT IS_PED_INJURED(trevorPed)
DETACH_ENTITY(trevorPed)
REGISTER_ENTITY_FOR_CUTSCENE(trevorPed, "Trevor", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
IF NOT IS_PED_INJURED(michaelPed)
DETACH_ENTITY(michaelPed)
REGISTER_ENTITY_FOR_CUTSCENE(michaelPed, "Michael", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
IF NOT IS_PED_INJURED(franklinPed)
DETACH_ENTITY(franklinPed)
REGISTER_ENTITY_FOR_CUTSCENE(franklinPed, "Franklin", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
STOP_SOUND(iPushCarSoundID)
CLEAR_HELP()
iFinaleCutsceneTime = GET_GAME_TIMER()
bSkippedCutscene = FALSE
bClearedForCutscene = FALSE
REPLAY_RECORD_BACK_FOR_TIME(5.0, 0.0, REPLAY_IMPORTANCE_HIGHEST)
REPLAY_START_EVENT(REPLAY_IMPORTANCE_HIGHEST)
START_CUTSCENE(CUTSCENE_SUPPRESS_FP_TRANSITION_FLASH)
SET_CUTSCENE_FADE_VALUES(FALSE, FALSE, FALSE, FALSE)
REQUEST_ADDITIONAL_TEXT("CREDIT", MISSION_TEXT_SLOT)
cliffStage = CLIFF_STAGE_AFTERMATH
ENDIF
ENDIF
ENDIF
ELSE
REQUEST_ADDITIONAL_TEXT("CREDIT", MISSION_TEXT_SLOT)
CLEANUP_CLIFF_CUTSCENE()
ENDIF
BREAK
CASE CLIFF_STAGE_AFTERMATH
IF WAS_CUTSCENE_SKIPPED()
bSkippedCutscene = TRUE
ENDIF
IF NOT bClearedForCutscene
IF IS_CUTSCENE_PLAYING()
STOP_FINALE_AUDIO_SCENE(FINALE_AUDIO_SCENE_PUSH_CAR)
IF IS_SCREEN_FADED_OUT()
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
ENDIF
bClearedForCutscene = TRUE
ENDIF
ENDIF
IF NOT g_bFinaleCreditsPlaylistStarted
IF GET_CUTSCENE_TIME() >= 71400
printstring("play finale credits")
PLAY_END_CREDITS_MUSIC(TRUE)
SET_MOBILE_RADIO_ENABLED_DURING_GAMEPLAY(TRUE)
SET_MOBILE_PHONE_RADIO_STATE(TRUE)
SET_RADIO_TO_STATION_NAME("RADIO_01_CLASS_ROCK")
SET_CUSTOM_RADIO_TRACK_LIST("RADIO_01_CLASS_ROCK", "END_CREDITS_SAVE_MICHAEL_TREVOR", TRUE)
DISABLE_CONTROL_ACTION(FRONTEND_CONTROL, INPUT_SKIP_CUTSCENE)
g_bFinaleCreditsPlaylistStarted = TRUE
ENDIF
ELSE
DISABLE_CONTROL_ACTION(FRONTEND_CONTROL, INPUT_SKIP_CUTSCENE)
ENDIF
IF NOT bStartedCreditsRoll
IF GET_CUTSCENE_TIME() >= 90583
REPLAY_PREVENT_RECORDING_AND_UI_THIS_FRAME()
IF HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT)
REPLAY_STOP_EVENT()
START_MISSION_CREDITS()
ENDIF
ENDIF
ELSE
//REPLAY_PREVENT_RECORDING_AND_UI_THIS_FRAME()
ENDIF
IF NOT bAwardedAchievement
IF GET_CUTSCENE_TIME() >= 95600
AWARD_ACHIEVEMENT_FOR_MISSION(ACH04) // To live or die in los santos
bAwardedAchievement = TRUE
ENDIF
ENDIF
//IF NOT bDoneEndSceneFadeout
//IF GET_CUTSCENE_TIME() >= 91300
//IF NOT IS_SCREEN_FADING_OUT()
//AND NOT IS_SCREEN_FADED_OUT()
// DO_SCREEN_FADE_OUT(5000)
//ENDIF
// bDoneEndSceneFadeout = TRUE
//ENDIF
//ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Trevor")
//CLEANUP_CLIFF_CUTSCENE()
ENDIF
IF CAN_SET_EXIT_STATE_FOR_CAMERA()
REPLAY_STOP_EVENT()
CLEANUP_CLIFF_CUTSCENE()
ENDIF
#IF IS_DEBUG_BUILD
DEBUG_SKIP_MOCAP()
#ENDIF
BREAK
CASE CLIFF_STAGE_BEGIN_CREDITS
REPLAY_PREVENT_RECORDING_AND_UI_THIS_FRAME()
IF GET_GAME_TIMER() >= iCreditsStartTime + 45000
DO_SCREEN_FADE_OUT(5000)
WHILE NOT IS_SCREEN_FADED_OUT()
WAIT(0)
ENDWHILE
MISSION_PASSED()
ENDIF
BREAK
ENDSWITCH
BREAK
CASE F_CUT_STAGE_CLEANUP
BREAK
ENDSWITCH
ENDPROC
// get to cliff stage
PROC DO_STAGE_GET_TO_CLIFF()
INT iWanted = GET_PLAYER_WANTED_LEVEL(PLAYER_ID())
REPLAY_DISABLE_CAMERA_MOVEMENT_THIS_FRAME()
IF NOT bForcePassOnShitskip
IF NOT bDoneGotoSpeech
IF GET_GAME_TIMER() >= iStageStartTime + 10000
bDoneGotoSpeech = DO_MISSION_SPEECH("FINC1_TGD")
ENDIF
ENDIF
ELSE
bDoneGotoSpeech = TRUE
ENDIF
IF NOT bRunningCutscene
HANDLE_STREAMING_MOCAP("fin_ext_p1", GET_FINALE_VECTOR(FINVEC_CLIFF), DEFAULT_CUTSCENE_LOAD_DIST, DEFAULT_CUTSCENE_UNLOAD_DIST)
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
// REMEMBER TO CHANGE INGAME VARS IF THIS CHANGES
//SET_CUTSCENE_PED_COMPONENT_VARIATION("Devin", PED_COMP_HEAD, 0, 1, CS_DEVIN)
///SET_CUTSCENE_PED_COMPONENT_VARIATION("Devin", PED_COMP_SPECIAL2, 1, 0, CS_DEVIN)
//SET_CUTSCENE_PED_COMPONENT_VARIATION("Devin", PED_COMP_TORSO, 0, 1, CS_DEVIN) //0,1
//SET_CUTSCENE_PED_COMPONENT_VARIATION("Devin", PED_COMP_LEG, 2, 0, CS_DEVIN) //2,0
//SET_CUTSCENE_PED_COMPONENT_VARIATION("Devin", PED_COMP_SPECIAL, 0, 0, CS_DEVIN) //2,0
SET_CUTSCENE_PED_COMPONENT_VARIATION("Devin", PED_COMP_HEAD, 0, 1, CS_DEVIN)
SET_CUTSCENE_PED_COMPONENT_VARIATION("Devin", PED_COMP_SPECIAL, 0, 0, CS_DEVIN)
SET_CUTSCENE_PED_COMPONENT_VARIATION("Devin", PED_COMP_DECL, 1, 0, CS_DEVIN)
SET_CUTSCENE_PED_COMPONENT_VARIATION("Devin", PED_COMP_SPECIAL2, 1, 0, CS_DEVIN)
SET_CUTSCENE_PED_COMPONENT_VARIATION("Devin", PED_COMP_FEET, 0, 0, CS_DEVIN)
SET_CUTSCENE_PED_COMPONENT_VARIATION("Devin", PED_COMP_LEG, 4, 0, CS_DEVIN)
SET_CUTSCENE_PED_COMPONENT_VARIATION("Devin", PED_COMP_TORSO, 5, 0, CS_DEVIN)
SET_CUTSCENE_PED_COMPONENT_VARIATION("Devin", PED_COMP_JBIB, 0, 0, CS_DEVIN)
ENDIF
IF NOT bSetDevinRadio
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_DEVIN_CAR])
IF GET_IS_VEHICLE_ENGINE_RUNNING(finaleVehicle[FV_DEVIN_CAR])
bSetDevinRadio = TRIGGER_MISSION_MUSIC_EVENT("FINC2_DEVINS_CAR_RADIO")
ENDIF
ENDIF
ENDIF
IF NOT bRemovedTrevorCar
IF DOES_ENTITY_EXIST(finaleVehicle[FV_TREVOR_CAR])
IF IS_ENTITY_DEAD(finaleVehicle[FV_TREVOR_CAR])
OR NOT IS_ENTITY_DEAD(finaleVehicle[FV_TREVOR_CAR])
IF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), finaleVehicle[FV_TREVOR_CAR], <<300,300,300>>, FALSE, FALSE)
SET_VEHICLE_AS_NO_LONGER_NEEDED(finaleVehicle[FV_TREVOR_CAR])
CLEAR_MODEL_REQUEST(ENUM_TO_INT(FM_TREVOR_CAR))
bRemovedTrevorCar = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
IF NOT bCutsceneWaitStarted
IF HANDLE_GET_TO_LOCATION(TRUE, FALSE, TRUE)
IF bDoDevinBangOnTrunk
IF GET_GAME_TIMER() >= iNextDevinBangOnTrunkTime
OR (GET_GAME_TIMER() >= iNextAdditionalBangOnTrunkTime AND bDoDevinAdditionalBangOnTrunk)
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_DEVIN_CAR])
PLAY_SOUND_FROM_ENTITY(-1, "FINALE_C2_DEVIN_INSIDE_TRUNK_MASTER", finaleVehicle[FV_DEVIN_CAR])
PRINTSTRING("do devin bang!") PRINTNL()
ENDIF
IF bDoDevinAdditionalBangOnTrunk
AND GET_GAME_TIMER() < iNextDevinBangOnTrunkTime
bDoDevinAdditionalBangOnTrunk = FALSE
ELSE
bDoDevinAdditionalBangOnTrunk = FALSE
bDoDevinBangOnTrunk = FALSE
ENDIF
ENDIF
ENDIF
IF bDoneNearlyThereSpeech
ELSE
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), <<-1576.90857, 5159.75195, 18.79768>>, <<100,100,25>>)
bDoneNearlyThereSpeech = DO_MISSION_SPEECH("FINC1_DEVARR")
ENDIF
SWITCH devinBootSpeechState
CASE DEVIN_BOOT_SPEECH_STATE_WAKE_UP
IF GET_GAME_TIMER() >= iNextDevinBootSpeechTime
IF DO_MISSION_SPEECH("FINC1_DEVWAK")
bDoDevinBangOnTrunk = TRUE
iNextDevinBangOnTrunkTime = GET_GAME_TIMER() + 8200
devinBootSpeechState = DEVIN_BOOT_SPEECH_STATE_LET_ME_OUT
iNextDevinBootSpeechTime = GET_GAME_TIMER() + 7000
ENDIF
ENDIF
BREAK
CASE DEVIN_BOOT_SPEECH_STATE_LET_ME_OUT
IF GET_GAME_TIMER() >= iNextDevinBootSpeechTime
IF DO_MISSION_SPEECH("FINC1_DHIDDN")
devinBootSpeechState = DEVIN_BOOT_SPEECH_STATE_SHUT_UP
iNextDevinBootSpeechTime = GET_GAME_TIMER() + 4000
ENDIF
ENDIF
BREAK
CASE DEVIN_BOOT_SPEECH_STATE_SHUT_UP
IF GET_GAME_TIMER() <= iNextDevinBootSpeechTime
IF DO_MISSION_SPEECH("FINC2_SHUTUP")
bDoDevinBangOnTrunk = TRUE
iNextDevinBangOnTrunkTime = GET_GAME_TIMER() + 9000
devinBootSpeechState = DEVIN_BOOT_SPEECH_STATE_BANTER
iNextDevinBootSpeechTime = GET_GAME_TIMER() + 20000
ENDIF
ELSE
bDoDevinBangOnTrunk = TRUE
iNextDevinBangOnTrunkTime = GET_GAME_TIMER() + 9000
devinBootSpeechState = DEVIN_BOOT_SPEECH_STATE_BANTER
iNextDevinBootSpeechTime = GET_GAME_TIMER() + 20000
ENDIF
BREAK
CASE DEVIN_BOOT_SPEECH_STATE_BANTER
IF GET_GAME_TIMER() >= iNextDevinBootSpeechTime
IF DO_MISSION_SPEECH("FINC1_DEVTAK")
devinBootSpeechState = DEVIN_BOOT_SPEECH_STATE_YOU_DEAD
ENDIF
ENDIF
BREAK
CASE DEVIN_BOOT_SPEECH_STATE_YOU_DEAD
IF bSavedBanter
IF RESTORE_BANTER()
bSavedBanter = FALSE
ENDIF
ENDIF
IF GET_GAME_TIMER() >= iNextDevinBootSpeechTime
IF DO_MISSION_SPEECH("FINC1_DEAD")
bDoDevinBangOnTrunk = TRUE
iNextDevinBangOnTrunkTime = GET_GAME_TIMER() + 3500
devinBootSpeechState = DEVIN_BOOT_SPEECH_STATE_WAITING
iNextDevinBootSpeechTime = GET_GAME_TIMER() + 8000
ENDIF
ENDIF
BREAK
CASE DEVIN_BOOT_SPEECH_STATE_WAITING
IF GET_GAME_TIMER() >= iNextDevinBootSpeechTime
devinBootSpeechState = DEVIN_BOOT_SPEECH_STATE_THREAT
ENDIF
BREAK
CASE DEVIN_BOOT_SPEECH_STATE_THREAT
IF DO_MISSION_SPEECH("FINC1_BOOT")
devinBootSpeechState = DEVIN_BOOT_SPEECH_STATE_REPLY
ENDIF
BREAK
CASE DEVIN_BOOT_SPEECH_STATE_REPLY
IF DO_MISSION_SPEECH("FINC2_SHUTUP")
iNextDevinBootSpeechTime = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(20000, 30000)
bDoDevinBangOnTrunk = TRUE
bDoDevinAdditionalBangOnTrunk = TRUE
INT iBangMod
SWITCH GET_RANDOM_INT_IN_RANGE(0,6)
CASE 0
iBangMod = -3000
BREAK
CASE 1
iBangMod = -2500
BREAK
CASE 2
iBangMod = -2000
BREAK
CASE 3
iBangMod = -1500
BREAK
CASE 4
iBangMod = -1000
BREAK
CASE 5
iBangMod = 500
BREAK
ENDSWITCH
iNextDevinBangOnTrunkTime = iNextDevinBootSpeechTime + iBangMod
iNextAdditionalBangOnTrunkTime = iNextDevinBangOnTrunkTime - GET_RANDOM_INT_IN_RANGE(10000, 15000)
devinBootSpeechState = DEVIN_BOOT_SPEECH_STATE_WAITING
ENDIF
BREAK
ENDSWITCH
ENDIF
IF NOT DOES_BLIP_EXIST(gotoBlip)
REPLAY_RECORD_BACK_FOR_TIME(5.0, 10.0, REPLAY_IMPORTANCE_HIGHEST)
REMOVE_ALL_BLIPS()
REMOVE_MISSION_TEXT(FALSE)
gotoBlip = CREATE_MISSION_BLIP_FOR_COORD(GET_FINALE_VECTOR(FINVEC_CLIFF), TRUE)
ENDIF
//IF iWanted = 0
IF NOT bForcePassOnShitskip
IF NOT bShownGodText
bShownGodText = DO_MISSION_GOD_TEXT("FC2_GORES")
ENDIF
ENDIF
IF CAN_ADVANCE_MISSION()
IF IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()))
AND IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_FINALE_VECTOR(FINVEC_CLIFF), <<LOCATE_SIZE_ANY_MEANS,LOCATE_SIZE_ANY_MEANS,LOCATE_SIZE_HEIGHT>>, TRUE)
AND iWanted = 0
//SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON)
SET_ENTITY_PROOFS(finaleVehicle[FV_DEVIN_CAR], TRUE, TRUE, TRUE, TRUE, TRUE)
PREVENT_WANTED_LEVEL_FOR_CUTSCENE()
REMOVE_ALL_BLIPS()
KILL_ANY_CONVERSATION()
iCutsceneTriggerTime = GET_GAME_TIMER()
bCutsceneWaitStarted = TRUE
ENDIF
ENDIF
//ENDIF
ELSE
IF devinBootSpeechState >= DEVIN_BOOT_SPEECH_STATE_WAITING
devinBootSpeechState = DEVIN_BOOT_SPEECH_STATE_WAITING
IF GET_GAME_TIMER() >= iNextDevinBootSpeechTime
iNextDevinBootSpeechTime = GET_GAME_TIMER() + 5000
ENDIF
ENDIF
ENDIF
// handle devin reaction to damaging vehicle
INT iCurrentCarHealth = GET_ENTITY_HEALTH(finaleVehicle[FV_DEVIN_CAR])
IF devinBootSpeechState >= DEVIN_BOOT_SPEECH_STATE_SHUT_UP
IF NOT bTriggeredDevinDamageReaction
IF iCurrentCarHealth < iCachedCarHealth
IF GET_GAME_TIMER() >= iNextCheckCarHealthTime
iNextCheckCarHealthTime = GET_GAME_TIMER() + 800
bTriggeredDevinDamageReaction = TRUE
ENDIF
ENDIF
iCachedCarHealth = iCurrentCarHealth
ELSE
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_DEVIN_CAR])
IF DO_MISSION_SPEECH("FINC1_DEVCRA")
bTriggeredDevinDamageReaction = FALSE
iCachedCarHealth = iCurrentCarHealth
iNextCheckCarHealthTime = GET_GAME_TIMER() + 12000
ELSE
IF GET_GAME_TIMER() >= iNextCheckCarHealthTime
iCachedCarHealth = iCurrentCarHealth
bTriggeredDevinDamageReaction = FALSE
ENDIF
ENDIF
ELSE
iCachedCarHealth = iCurrentCarHealth
bTriggeredDevinDamageReaction = FALSE
ENDIF
ENDIF
ELSE
iCachedCarHealth = iCurrentCarHealth
bTriggeredDevinDamageReaction = FALSE
ENDIF
ELSE
PREVENT_WANTED_LEVEL_FOR_CUTSCENE()
IF BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), 10)
IF GET_GAME_TIMER() >= iCutsceneTriggerTime + DEFAULT_CAR_STOPPING_TO_CUTSCENE
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF CAN_ADVANCE_MISSION()
REPLAY_RECORD_BACK_FOR_TIME(10.0, 5.0, REPLAY_IMPORTANCE_HIGHEST)
bRunningCutscene = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
DO_CLIFF_CUTSCENE()
ENDIF
ENDPROC
PROC HANDLE_STATS
// handle vehicle stats
BOOL bSetVehicleStatsNull = FALSE
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
VEHICLE_INDEX currentVehicle = GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())
IF DOES_ENTITY_EXIST(currentVehicle)
INFORM_MISSION_STATS_OF_DAMAGE_WATCH_ENTITY(currentVehicle, FIN_CAR_DAMAGE)
INFORM_MISSION_STATS_OF_SPEED_WATCH_ENTITY(currentVehicle, FIN_MAX_SPEED)
ELSE
bSetVehicleStatsNull = TRUE
ENDIF
ELSE
bSetVehicleStatsNull = TRUE
ENDIF
IF bSetVehicleStatsNull
INFORM_MISSION_STATS_OF_DAMAGE_WATCH_ENTITY(NULL, FIN_CAR_DAMAGE)
INFORM_MISSION_STATS_OF_SPEED_WATCH_ENTITY(NULL, FIN_MAX_SPEED)
ENDIF
// damage stat
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
INFORM_MISSION_STATS_OF_DAMAGE_WATCH_ENTITY(PLAYER_PED_ID(), FIN_DAMAGE)
ENDIF
// sticky bomb stats
IF IS_PED_SHOOTING(PLAYER_PED_ID())
WEAPON_TYPE weapon
GET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), weapon)
IF weapon = GET_FINALE_WEAPON_TYPE(F_WEAPON_STICKY_BOMB)
INFORM_MISSION_STATS_OF_INCREMENT(FIN_STICKY_BOMBS_USED)
ENDIF
ENDIF
ENDPROC
// debug only
#IF IS_DEBUG_BUILD
// create widgets
PROC CREATE_FINALE_WIDGETS()
finaleWidgets = START_WIDGET_GROUP("Finale 3")
RBCamPosWidget = ADD_TEXT_WIDGET("Cam Position")
RBCamRotWidget = ADD_TEXT_WIDGET("Cam Rotation")
ADD_WIDGET_FLOAT_SLIDER("Cam FOV", fRBDebugCamFOV, 0, 80, 1.0)
ADD_WIDGET_BOOL("Do Dump", bRBDebugCamDoDump)
//ADD_WIDGET_FLOAT_SLIDER("Wheel rot", fWheelRotation, 0, 360, 1.0)
//ADD_WIDGET_FLOAT_SLIDER("Gondola Radius", fGondolaRadius, 0, 50, 1.0)
//ADD_WIDGET_VECTOR_SLIDER("Wheel pos", vWheelPos, -6000, 6000, 0.1)
ADD_WIDGET_BOOL("Done Trevor Hit", g_bFinale3BHitSuccessful[CHAR_TREVOR])
ADD_WIDGET_BOOL("Done Michael Hit", g_bFinale3BHitSuccessful[CHAR_MICHAEL])
ADD_WIDGET_BOOL("Done Franklin Hit", g_bFinale3BHitSuccessful[CHAR_FRANKLIN])
// CREATE_SWITCH_CAM_SCRIPT_SPECIFIC_WIDGETS()
STOP_WIDGET_GROUP()
// SETUP_SPLINE_CAM_NODE_ARRAY_KILL_STEVE_BULLET_CAM(scsSwitchCamBulletCam, PLAYER_PED_ID(), stevePed[STEVE_TARGET])
// CREATE_SPLINE_CAM_WIDGETS(scsSwitchCamBulletCam, "Trevor", "Steve", finaleWidgets)
//
// SETUP_SPLINE_CAM_NODE_ARRAY_KILL_STEVE_EXPLOSION_CAM(scsSwitchCamExplosion, PLAYER_PED_ID(), stevePed[STEVE_TARGET])
// CREATE_SPLINE_CAM_WIDGETS(scsSwitchCamExplosion, "Trevor", "Steve Explosion", finaleWidgets)
//
// SETUP_SPLINE_CAM_NODE_ARRAY_KILL_STEVE_GRENADE_CAM(scsSwitchCamGrenade, PLAYER_PED_ID(), stevePed[STEVE_TARGET])
// CREATE_SPLINE_CAM_WIDGETS(scsSwitchCamGrenade, "Trevor", "Steve Grenade", finaleWidgets)
ENDPROC
// setup the debug menu
PROC SETUP_FINALE_DEBUG_MENU()
stageMenu[0].sTxtLabel = GET_DESCRIPTION_FOR_STAGE_AS_STRING(STAGE_GET_TO_HIT)
stageMenu[1].sTxtLabel = "Cutscene FIN_C2_MCS_1"
stageMenu[2].sTxtLabel = "Cutscene FIN_C2_MCS_2"
stageMenu[3].sTxtLabel = "Cutscene FIN_C2_MCS_3"
stageMenu[1].bSelectable = FALSE
stageMenu[2].bSelectable = FALSE
stageMenu[3].bSelectable = FALSE
stageMenu[4].sTxtLabel = GET_DESCRIPTION_FOR_STAGE_AS_STRING(STAGE_TREVOR_HIT)
stageMenu[5].sTxtLabel = GET_DESCRIPTION_FOR_STAGE_AS_STRING(STAGE_MICHAEL_HIT)
stageMenu[6].sTxtLabel = GET_DESCRIPTION_FOR_STAGE_AS_STRING(STAGE_FRANKLIN_HIT)
stageMenu[7].sTxtLabel = GET_DESCRIPTION_FOR_STAGE_AS_STRING(STAGE_PICKUP_DEVIN)
stageMenu[8].sTxtLabel = GET_DESCRIPTION_FOR_STAGE_AS_STRING(STAGE_DEVINS_HOUSE)
stageMenu[9].sTxtLabel = "Cutscene FIN_C2_MCS_4"
stageMenu[9].bSelectable = FALSE
stageMenu[10].sTxtLabel = GET_DESCRIPTION_FOR_STAGE_AS_STRING(STAGE_GET_TO_CLIFF)
stageMenu[11].sTxtLabel = "Cutscene FIN_EXT"
stageMenu[11].bSelectable = FALSE
//REPEAT MAX_SKIP_MENU_LENGTH i
//ENDREPEAT
ENDPROC
PROC DEBUG_REPOSITION_AT_START()
SET_ENTITY_COORDS(PLAYER_PED_ID(), GET_FINALE_VECTOR(FINVEC_PLAYER_INIT))
SET_ENTITY_HEADING(PLAYER_PED_ID(), PLAYER_INIT_ROT)
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
ENDPROC
// debug skips
PROC DO_DEBUG_SKIPS()
// mission pass S
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S)
bThoroughCleanup = TRUE
MISSION_PASSED()
ENDIF
// mission failed F
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F)
MISSION_FAILED(FAIL_DEVIN_DEAD)
ENDIF
// skip stage J
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J)
IF NOT bRunningCutscene
AND hotswapStage <> MISSION_HOTSWAP_STAGE_DO_SPLINE_CAM
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
INT i
SWITCH currentMissionStage
CASE STAGE_GET_TO_HIT
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_TREVOR
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_TREVOR_CAR])
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_TREVOR_CAR])
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_TREVOR_CAR])
ENDIF
SET_ENTITY_COORDS(finaleVehicle[FV_TREVOR_CAR], <<-1604.01392, -1019.51410, 12.05970>>)
ELSE
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-1604.01392, -1019.51410, 12.05970>>)
ENDIF
BREAK
CASE CHAR_MICHAEL
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_MICHAEL_CAR])
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_MICHAEL_CAR])
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_MICHAEL_CAR])
ENDIF
SET_ENTITY_COORDS(finaleVehicle[FV_MICHAEL_CAR], <<-202.33813, -1484.84021, 30.33375>>)
ELSE
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-202.33813, -1484.84021, 30.33375>>)
ENDIF
BREAK
CASE CHAR_FRANKLIN
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_FRANKLIN_CAR])
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_FRANKLIN_CAR])
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_FRANKLIN_CAR])
ENDIF
SET_ENTITY_COORDS(finaleVehicle[FV_FRANKLIN_CAR], GET_FINALE_VECTOR(FINVEC_CLUB))
ELSE
SET_ENTITY_COORDS(PLAYER_PED_ID(), GET_FINALE_VECTOR(FINVEC_CLUB))
ENDIF
BREAK
ENDSWITCH
BREAK
CASE STAGE_TREVOR_HIT
IF NOT g_bFinale3BHitSuccessful[CHAR_TREVOR]
IF NOT IS_PED_INJURED(stevePed[STEVE_TARGET])
FORCE_CHASE_HINT_CAM(localChaseHintCamStruct, FALSE)
RESET_CUSTOM_CHASE_HINT_CAM_INTERP_IN_TIME(localChaseHintCamStruct)
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
APPLY_DAMAGE_TO_PED(stevePed[STEVE_TARGET], 1000, TRUE)
g_bFinale3BHitSuccessful[CHAR_TREVOR] = TRUE
sSelectorPeds.bBlockSelectorPed[SELECTOR_PED_TREVOR] = TRUE
ENDIF
ELSE
IF NOT g_bFinale3BHitSuccessful[CHAR_MICHAEL]
OR g_bFinale3BHitSuccessful[CHAR_FRANKLIN]
sSelectorPeds.eNewSelectorPed = SELECTOR_PED_MICHAEL
bDebugJSkip = TRUE
ELSE
sSelectorPeds.eNewSelectorPed = SELECTOR_PED_FRANKLIN
bDebugJSkip = TRUE
ENDIF
ENDIF
BREAK
CASE STAGE_MICHAEL_HIT
IF NOT g_bFinale3BHitSuccessful[CHAR_MICHAEL]
REPEAT COUNT_OF(GANGSTER_ENUM) i
IF NOT IS_PED_INJURED(gangsterPed[i].ped)
APPLY_DAMAGE_TO_PED(gangsterPed[i].ped, 1000, TRUE)
ENDIF
ENDREPEAT
ELSE
IF NOT g_bFinale3BHitSuccessful[CHAR_TREVOR]
OR g_bFinale3BHitSuccessful[CHAR_FRANKLIN]
sSelectorPeds.eNewSelectorPed = SELECTOR_PED_TREVOR
bDebugJSkip = TRUE
ELSE
sSelectorPeds.eNewSelectorPed = SELECTOR_PED_FRANKLIN
bDebugJSkip = TRUE
ENDIF
ENDIF
BREAK
CASE STAGE_FRANKLIN_HIT
IF NOT g_bFinale3BHitSuccessful[CHAR_FRANKLIN]
REPEAT COUNT_OF(TRIAD_ENUM) i
IF NOT IS_PED_INJURED(triadPed[i].ped)
APPLY_DAMAGE_TO_PED(triadPed[i].ped, 1000, TRUE)
ENDIF
ENDREPEAT
ELSE
IF NOT g_bFinale3BHitSuccessful[CHAR_TREVOR]
OR g_bFinale3BHitSuccessful[CHAR_MICHAEL]
sSelectorPeds.eNewSelectorPed = SELECTOR_PED_TREVOR
bDebugJSkip = TRUE
ELSE
sSelectorPeds.eNewSelectorPed = SELECTOR_PED_MICHAEL
bDebugJSkip = TRUE
ENDIF
ENDIF
BREAK
CASE STAGE_PICKUP_DEVIN
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_TREVOR_CAR])
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_TREVOR_CAR])
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_TREVOR_CAR])
ELSE
SET_ENTITY_COORDS(finaleVehicle[FV_TREVOR_CAR], GET_FINALE_VECTOR(FINVEC_TREVOR_CAR_AT_PICKUP))
SET_ENTITY_HEADING(finaleVehicle[FV_TREVOR_CAR], TREVOR_CAR_AT_PICKUP_ROT)
ENDIF
ENDIF
BREAK
CASE STAGE_DEVINS_HOUSE
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-2649.05884, 1872.45435, 159.72034>>)
REPEAT COUNT_OF(MERRYWEATHER_ENUM) i
IF NOT IS_PED_INJURED(merryweatherPed[i].ped)
APPLY_DAMAGE_TO_PED(merryweatherPed[i].ped, 1000, TRUE)
ENDIF
ENDREPEAT
BREAK
CASE STAGE_GET_TO_CLIFF
IF IS_VEHICLE_DRIVEABLE(finaleVehicle[FV_DEVIN_CAR])
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_DEVIN_CAR])
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), finaleVehicle[FV_DEVIN_CAR])
ELSE
SET_ENTITY_COORDS(finaleVehicle[FV_DEVIN_CAR], GET_FINALE_VECTOR(FINVEC_CLIFF))
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDIF
ENDIF
ENDIF
// previous stage P
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P)
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
AND hotswapStage <> MISSION_HOTSWAP_STAGE_DO_SPLINE_CAM
AND NOT bRunningCutscene
DO_SCREEN_FADE_OUT(500)
WHILE NOT IS_SCREEN_FADED_OUT()
WAIT(0)
ENDWHILE
TRIGGER_MUSIC_EVENT("FINC2_FAIL")
COMMON_MISSION_CLEAR()
SWITCH currentMissionStage
CASE STAGE_GET_TO_HIT
DEBUG_REPOSITION_AT_START()
SET_MISSION_STAGE(STAGE_GET_TO_HIT, TRUE)
bIsNaturalSkipToGetToHits = FALSE
BREAK
CASE STAGE_TREVOR_HIT
DEBUG_REPOSITION_AT_START()
SET_MISSION_STAGE(STAGE_GET_TO_HIT, TRUE)
bIsNaturalSkipToGetToHits = FALSE
BREAK
CASE STAGE_MICHAEL_HIT
SET_MISSION_STAGE(STAGE_TREVOR_HIT, TRUE)
BREAK
CASE STAGE_FRANKLIN_HIT
SET_MISSION_STAGE(STAGE_MICHAEL_HIT, TRUE)
BREAK
CASE STAGE_PICKUP_DEVIN
SET_MISSION_STAGE(STAGE_FRANKLIN_HIT, TRUE)
BREAK
CASE STAGE_DEVINS_HOUSE
SET_MISSION_STAGE(STAGE_PICKUP_DEVIN, TRUE)
BREAK
CASE STAGE_GET_TO_CLIFF
SET_MISSION_STAGE(STAGE_DEVINS_HOUSE, TRUE)
BREAK
ENDSWITCH
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
SET_ENTITY_PROOFS(PLAYER_PED_ID(), FALSE, FALSE, FALSE, FALSE, FALSE)
ENDIF
DO_SCREEN_FADE_IN(500)
ENDIF
ENDIF
// stage menu
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
AND hotswapStage <> MISSION_HOTSWAP_STAGE_DO_SPLINE_CAM
AND NOT bRunningCutscene
IF LAUNCH_MISSION_STAGE_MENU(stageMenu, iMenuMissionStage)
DO_SCREEN_FADE_OUT(500)
WHILE NOT IS_SCREEN_FADED_OUT()
WAIT(0)
ENDWHILE
TRIGGER_MUSIC_EVENT("FINC2_FAIL")
COMMON_MISSION_CLEAR()
// convert debug stage to mission stage
MISSION_STAGE_ENUM setStage
SWITCH iMenuMissionStage
CASE 0
DEBUG_REPOSITION_AT_START()
setStage = STAGE_GET_TO_HIT
bIsNaturalSkipToGetToHits = FALSE
BREAK
CASE 4
setStage = STAGE_TREVOR_HIT
BREAK
CASE 5
setStage = STAGE_MICHAEL_HIT
BREAK
CASE 6
setStage = STAGE_FRANKLIN_HIT
BREAK
CASE 7
setStage = STAGE_PICKUP_DEVIN
BREAK
CASE 8
setStage = STAGE_DEVINS_HOUSE
BREAK
CASE 10
setStage = STAGE_GET_TO_CLIFF
BREAK
ENDSWITCH
SET_MISSION_STAGE(setStage, TRUE)
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
SET_ENTITY_PROOFS(PLAYER_PED_ID(), FALSE, FALSE, FALSE, FALSE, FALSE)
ENDIF
DO_SCREEN_FADE_IN(500)
ENDIF
ENDIF
ENDPROC
// there must be an easier way to do this
PROC FORMAT_FLOAT_FOR_RB_CAM_DUMP(FLOAT fInputFloat, INT &iBeforeDec, INT &iAfterDec)
IF fInputFloat >= 0
iBeforeDec = FLOOR(fInputFloat)
ELSE
iBeforeDec = CEIL(fInputFloat)
ENDIF
fInputFloat -= iBeforeDec
fInputFloat *= 100
IF fInputFloat < 0
fInputFloat *= (-1)
ENDIF
IF fInputFloat < 10
fInputFloat *= 10
ENDIF
iAfterDec = FLOOR(fInputFloat)
ENDPROC
// dump the cam coords to a widget
PROC DO_RB_DEBUG_CAM_DUMP()
IF bRBDebugCamDoDump
CAMERA_INDEX tempCam = GET_DEBUG_CAM()
vRBDebugCamPos = GET_CAM_COORD(tempCam)
vRBDebugCamRot = GET_CAM_ROT(tempCam)
fRBDebugCamFOV = GET_CAM_FOV(tempCam)
TEXT_LABEL_63 tPos
TEXT_LABEL_63 tRot
INT iBefore, iAfter
// fill position
tPos = "<<"
FORMAT_FLOAT_FOR_RB_CAM_DUMP(vRBDebugCamPos.x, iBefore, iAfter)
tPos += iBefore
tPos += "."
tPos += iAfter
tPos += ", "
FORMAT_FLOAT_FOR_RB_CAM_DUMP(vRBDebugCamPos.y, iBefore, iAfter)
tPos += iBefore
tPos += "."
tPos += iAfter
tPos += ", "
FORMAT_FLOAT_FOR_RB_CAM_DUMP(vRBDebugCamPos.z, iBefore, iAfter)
tPos += iBefore
tPos += "."
tPos += iAfter
tPos += ">>"
// fill rotation
tRot = "<<"
FORMAT_FLOAT_FOR_RB_CAM_DUMP(vRBDebugCamRot.x, iBefore, iAfter)
tRot += iBefore
tRot += "."
tRot += iAfter
tRot += ", "
FORMAT_FLOAT_FOR_RB_CAM_DUMP(vRBDebugCamRot.y, iBefore, iAfter)
tRot += iBefore
tRot += "."
tRot += iAfter
tRot += ", "
FORMAT_FLOAT_FOR_RB_CAM_DUMP(vRBDebugCamRot.z, iBefore, iAfter)
tRot += iBefore
tRot += "."
tRot += iAfter
tRot += ">>"
// set widgets
SET_CONTENTS_OF_TEXT_WIDGET(RBCamPosWidget, tPos)
SET_CONTENTS_OF_TEXT_WIDGET(RBCamRotWidget, tRot)
bRBDebugCamDoDump = FALSE
ENDIF
ENDPROC
PROC HANDLE_SWITCH_CAM_SCRIPT_SPECIFIC_WIDGETS()
IF IS_BUTTON_JUST_PRESSED(PAD1, DPADLEFT)
bDEBUG_SwitchCamJumpToKillSteve = TRUE
ENDIF
IF bDEBUG_SwitchCamJumpToKillSteve
DELETE_VEHICLE(finaleVehicle[FV_TREVOR_CAR])
DELETE_VEHICLE(finaleVehicle[FV_FRANKLIN_CAR])
DELETE_PED(stevePed[0])
DELETE_PED(stevePed[1])
createHitStage[CREATE_HIT_STAGE_DONE] = CREATE_HIT_STAGE_NOT_STARTED
SET_MISSION_STAGE(STAGE_TREVOR_HIT, TRUE)
bDEBUG_SwitchCamJumpToKillSteve = FALSE
bSteveDead[0] = FALSE
bSteveDead[1] = FALSE
ENDIF
IF bDEBUG_ForceBulletKillSteve
IF DOES_ENTITY_EXIST(stevePed[0])
SHOOT_SINGLE_BULLET_BETWEEN_COORDS((GET_ENTITY_COORDS(stevePed[0]) + <<0.0, 0.0, 3.0>>), GET_ENTITY_COORDS(stevePed[0]), 100, TRUE)
ENDIF
ENDIF
IF bDEBUG_ForceExplosionKillSteve
IF DOES_ENTITY_EXIST(stevePed[0])
bSwitchCam_SteveKilledViaExplosion = FALSE
ADD_OWNED_EXPLOSION(PLAYER_PED_ID(), GET_ENTITY_COORDS(stevePed[0]), EXP_TAG_ROCKET)
ENDIF
ENDIF
IF bDEBUG_BloodFX_Tester
START_PARTICLE_FX_NON_LOOPED_ON_ENTITY("scr_finale2_blood_entry", PLAYER_PED_ID(), vSwitchCam_BloodSpurtLoc, vSwitchCam_BloodSpurtRot, fSwitchCam_StartBloodSpurtScale)
WAIT(1500)
ENDIF
CLEAR_PLAYER_WANTED_LEVEL(PLAYER_ID())
SET_POLICE_IGNORE_PLAYER(PLAYER_ID(), TRUE)
ENDPROC
#ENDIF
// main script
SCRIPT
SET_MISSION_FLAG(TRUE)
IF HAS_FORCE_CLEANUP_OCCURRED()
Mission_Flow_Mission_Force_Cleanup()
MISSION_CLEANUP()
ENDIF
#IF IS_DEBUG_BUILD
CREATE_FINALE_WIDGETS()
SETUP_FINALE_DEBUG_MENU()
#ENDIF
//ADD_SCENARIO_BLOCKING_AREA(<<-4000,-4000,-4000>>, <<4000,4000,4000>>)
bShownSwitchPrompt = bShownSwitchPrompt
taskStatus = taskStatus
//INFORM_MISSION_STATS_OF_MISSION_START_FINALE_3()
WHILE TRUE
REPLAY_CHECK_FOR_EVENT_THIS_FRAME("SaveMichaelAndTrevorP2")
IF INIT_MISSION()
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
// do streaming for next stage
DO_STREAMING_FOR_NEXT_MISSION_STAGE(FALSE)
// do fail checks
HANDLE_MISSION_FAIL_STATE()
// handle wheel
HANDLE_CREATE_WHEEL()
// handle stats
HANDLE_STATS()
// handle audio scenes
HANDLE_AUDIO_SCENES()
// run appropriate stage
SWITCH currentMissionStage
CASE STAGE_GET_TO_HIT
DO_STAGE_GET_TO_HIT()
BREAK
CASE STAGE_TREVOR_HIT
DO_STAGE_TREVOR_HIT()
BREAK
CASE STAGE_FRANKLIN_HIT
DO_STAGE_FRANKLIN_HIT()
BREAK
CASE STAGE_MICHAEL_HIT
DO_STAGE_MICHAEL_HIT()
BREAK
CASE STAGE_PICKUP_DEVIN
DO_STAGE_PICKUP_DEVIN()
BREAK
CASE STAGE_DEVINS_HOUSE
DO_STAGE_DEVINS_HOUSE()
BREAK
CASE STAGE_GET_TO_CLIFF
DO_STAGE_GET_TO_CLIFF()
BREAK
ENDSWITCH
ENDIF
#IF IS_DEBUG_BUILD
IF CAN_ADVANCE_MISSION()
DO_DEBUG_SKIPS()
ENDIF
// UPDATE_SPLINE_CAM_WIDGETS(scsSwitchCamBulletCam)
// UPDATE_SPLINE_CAM_WIDGETS(scsSwitchCamExplosion)
// UPDATE_SPLINE_CAM_WIDGETS(scsSwitchCamGrenade)
// HANDLE_SWITCH_CAM_SCRIPT_SPECIFIC_WIDGETS()
DO_RB_DEBUG_CAM_DUMP()
#ENDIF
ENDIF
WAIT(0)
ENDWHILE
ENDSCRIPT