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

10429 lines
387 KiB
Python
Executable File

//
// Author: Matthew Booton Date: 31/05/10
//
//
//
// Car Steal Heist
//
// The player loads the stolen cars onto a truck, defends the
// truck as it's driven to the docks, and loads any intact cars │
// onto a container ship.
//
//
//
//Compile out Title Update changes to header functions.
//Must be before includes.
//CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R.
USING "rage_builtins.sch"
USING "globals.sch"
USING "commands_audio.sch"
USING "commands_camera.sch"
USING "commands_clock.sch"
USING "commands_debug.sch"
USING "commands_fire.sch"
USING "commands_graphics.sch"
USING "commands_hud.sch"
USING "commands_misc.sch"
USING "commands_object.sch"
USING "commands_pad.sch"
USING "commands_ped.sch"
USING "commands_physics.sch"
USING "commands_player.sch"
USING "commands_script.sch"
USING "commands_streaming.sch"
USING "commands_task.sch"
USING "commands_vehicle.sch"
USING "commands_interiors.sch"
USING "commands_recording.sch"
USING "building_control_public.sch"
USING "carsteal_public.sch"
USING "dialogue_public.sch"
USING "emergency_call.sch"
USING "model_enums.sch"
USING "script_ped.sch"
USING "script_player.sch"
USING "script_misc.sch"
USING "script_blips.sch"
USING "selector_public.sch"
USING "shop_public.sch"
USING "locates_public.sch"
USING "replay_public.sch"
USING "cutscene_public.sch"
USING "mission_stat_public.sch"
USING "CompletionPercentage_public.sch"
USING "vehicle_gen_public.sch"
USING "taxi_functions.sch"
USING "jb700_gadgets.sch"
USING "area_checks.sch"
USING "spline_cam_edit.sch"
USING "push_in_public.sch"
// total should not exceed 225
CONST_INT TOTAL_NUMBER_OF_TRAFFIC_CARS 60
CONST_INT TOTAL_NUMBER_OF_PARKED_CARS 20
CONST_INT TOTAL_NUMBER_OF_SET_PIECE_CARS 10
// total should not exceed 12
CONST_INT MAX_NUMBER_OF_TRAFFIC_CARS_PLAYING_BACK 12
CONST_INT MAX_NUMBER_OF_SET_PIECE_CARS_PLAYING_BACK 5
// this should be fine
CONST_INT MAX_NUMBER_OF_PARKED_CARS_PLAYING_BACK 10
USING "traffic.sch"
#IF IS_DEBUG_BUILD
USING "shared_debug.sch"
USING "script_debug.sch"
USING "select_mission_stage.sch"
USING "scripted_cam_editor_public.sch"
#ENDIF
ENUM MISSION_STAGE
STAGE_START_PHONECALL,
STAGE_COLLECT_FINAL_CAR,
STAGE_GET_IN_TRUCK_CUTSCENE,
STAGE_GO_TO_DROP_OFF,
STAGE_COPS_ARRIVE,
STAGE_ESCORT_TRUCK,
STAGE_MEET_MOLLY,
STAGE_END_CUTSCENE
ENDENUM
ENUM FAILED_REASON
FAILED_GENERIC = 0,
FAILED_KILLED_FRANKLIN,
FAILED_KILLED_TREVOR,
FAILED_DESTROYED_CAR,
FAILED_DESTROYED_TRUCK,
FAILED_DESTROYED_SOME_CARS,
FAILED_DESTROYED_ALL_CARS,
FAILED_CAR_STUCK,
FAILED_TRUCK_STUCK,
FAILED_TRAILER_DETACHED,
FAILED_TRAILER_ABANDONED,
FAILED_LEFT_FRANKLIN,
FAILED_LAMAR_DIED,
FAILED_LEFT_LAMAR,
FAILED_LEFT_TREVOR,
FAILED_LEFT_TREVOR_AND_LAMAR,
FAILED_LEFT_FRANKLIN_AND_LAMAR,
FAILED_MOLLY_DIED,
FAILED_LEFT_MOLLY,
FAILED_LED_COPS_TO_CARS,
FAILED_LED_COPS_TO_MONROE,
FAILED_MOLLYS_CAR_DESTROYED,
FAILED_TRAILER_FELL_OFF,
FAILED_LED_COPS_TO_TRUCK,
FAILED_FRANKLIN_FELL_OFF,
FAILED_ABANDONED_CAR,
FAILED_SPOOKED_MOLLY
ENDENUM
ENUM SECTION_STAGE
SECTION_STAGE_SETUP = 0,
SECTION_STAGE_RUNNING,
SECTION_STAGE_CLEANUP,
SECTION_STAGE_SKIP
ENDENUM
ENUM FRANKLIN_TRUCK_ANIM_STAGE
TRUCK_IDLE,
TRUCK_ACCEL,
TRUCK_DECEL,
TRUCK_LEFT_INTRO,
TRUCK_LEFT,
TRUCK_LEFT_OUTRO,
TRUCK_RIGHT_INTRO,
TRUCK_RIGHT,
TRUCK_RIGHT_OUTRO
ENDENUM
ENUM MOLLY_STATE
MOLLY_STATE_IN_CAR,
MOLLY_STATE_LEAVING_CAR,
MOLLY_STATE_IDLE,
MOLLY_STATE_ANNOYED
ENDENUM
STRUCT MISSION_PED
PED_INDEX ped //Ped index
BLIP_INDEX blip //Personal blip
INT iEvent //Event tracker: used for organising more complex behaviour for this ped.
BOOL bHasTask
ENDSTRUCT
STRUCT STOLEN_CAR
VEHICLE_INDEX veh
BLIP_INDEX blip
VECTOR vTruckOffset
VECTOR vTruckRotation
INT iDeathTimer
INT iCarrec
INT iEvent
INT iForceTimer
BOOL bInContainer
BOOL bFinishedSliding
BOOL bPlaybackStarted
BOOL bIsLocked
FLOAT fPlaybackStartTime
FLOAT fSlideAccel
MODEL_NAMES model
ENDSTRUCT
STRUCT CAR_TRANSPORTER
VEHICLE_INDEX vehFront
VEHICLE_INDEX vehBack
BLIP_INDEX blip
ENDSTRUCT
STRUCT CAR_GADGET_DATA
INT iForceTimer
INT iForceDirection
INT iCutsceneTimer
INT iCutsceneEvent
VECTOR vCamPos
VECTOR vCamLookatPos
VECTOR vPos
VEHICLE_INDEX vehClosest
ENDSTRUCT
BOOL bIsJumpingDirectlyToStage = FALSE
BOOL bCreatedAssistedRoute = FALSE
BOOL bCustomGPSActive = FALSE
BOOL bDontUseCustomGPS = FALSE
BOOL bMissionFailed = FALSE
//BOOL bRestartedWaypoint = FALSE
BOOL bSkippedMocap = FALSE
BOOL bLamarKnockedOutOfLeanAnim = FALSE
BOOL bTrevorKnockedOver = FALSE
BOOL bTruckAnimIsUpToDate = FALSE
BOOL bAlreadyPrintedWantedLevelText = FALSE
BOOL bTaxiDropoffSet = FALSE
BOOL bShitSkippedIntoFinalCar = FALSE
BOOL bUseTrailerMode = FALSE
BOOL bClimbCamActive = FALSE
BOOL bFranklinTruckClimbActive = FALSE
BOOl bUsedACheckpoint = FALSE
BOOL bCopsTriggered = FALSE
BOOL bPlayedTrevorGreetingAnim = FALSE
BOOL bPlayerIsCloseToMolly = FALSE
BOOL bMollyGameplayHintActive = FALSE
BOOL bClearedCarsDuringCutscene = FALSE
BOOL bCleanedUpSwitchCams = FALSE
BOOL bFranklinSwitchRecordingStarted = FALSE
BOOL bFranklinSwitchRecordingTimeSkipped = FALSE
BOOL bTruckDoorOpenSoundPlayed = FALSE
BOOL bTruckDoorCloseSoundPlayed = FALSE
CONST_INT CARREC_CHASE_TRIGGER 1
CONST_INT CARREC_CHASE_TRIGGER_TRAILER 2
CONST_INT CARREC_TRUCK_FINAL_CUTSCENE 100
CONST_INT CARREC_TRUCK_ESCORT 10
CONST_INT ASSISTED_ROUTE_CRANE_TOP 1
CONST_INT CHECKPOINT_MEET_TREVOR 1
CONST_INT CHECKPOINT_GO_TO_GAS 2
CONST_INT CHECKPOINT_COPS_ARRIVE 3
CONST_INT CHECKPOINT_LOSE_COPS 4
CONST_INT NUM_CHASE_COP_CARS 7
CONST_INT COP_STATE_IDLE 0
CONST_INT COP_STATE_ESCORT_TRUCK 1
CONST_INT COP_STATE_CHASE_TRUCK_DRIVER 2
CONST_INT COP_STATE_CHASE_TRUCK_PASSENGER 3
CONST_INT COP_STATE_PASSENGER_DRIVE_BY 4
CONST_INT COP_STATE_COMBAT_ON_FOOT 5
CONST_INT COP_STATE_ENTER_COP_CAR 6
INT iCurrentEvent = 0
INT iCurrentMusicEvent = 0
INT iMusicEventTimer = 0
INT iTriggeredTextHashes[60]
INT iChosenCar = 3 //JB700
INT iSpikeTimer = 0
INT iOilSlickTimer = 0
INT iTruckSetupStage = 0
INT iTruckSetupTimer = 0
INT iTrevorWaitAnimsTimer = 0
INT iSyncSceneOnTruck = 0
INT iSyncSceneOnTruck2 = 0
INT iSyncSceneStartCar = 0
INT iTruckAccelTimer = 0
INT iTruckBrakeTimer = 0
INT iTruckLeftTurnTimer = 0
INT iTruckRightTurnTimer = 0
INT iCopsDialoguePauseTimer = 0
INT iTruckClimbEvent = 0
INT iTruckClimbTimer = 0
INT iCopsTrashEvent = 0
INT iCopsLostTimer = 0
INT iTrevorDriveEvent = 0
INT iNumChaseCopCarsCreated = 0
INT iTruckAwkwardSilenceTimer = 0
INT iTrevorTruckHornTimer = 0
INT iFranklinClimbDialogueTimer = 0
INT iFranklinCopsShoutTimer = 0
INT iNumTimesPlayedCopsWarn1 = 0
INT iNumTimesPlayedCopsWarn2 = 0
INT iNumTimesPlayedCopsWarn3 = 0
INT iNumTimesPlayedCopsWarn4 = 0
INT iChaseDialogueTimer = 0
INT iNumChaseLamarLinesPlayed = 0
INT iChaseHelperTimer = 0
INT iFranklinFailTimer = 0
INT iFranklinDetachFailTimer = 0
INT iCurrentCopBeingTrackedForDialogue = 0
INT iTrailerFailTimer = 0
INT iInitialDriverConvoTimer = 0
INT iPrevClosestNode = -1
INT iTruckWaitDialogueTimer = 0
INT iMollySyncScene = -1
INT iNumTimesPlayedUnhookDialogue = 0
INT iNumTimesPlayedRehookDialogue = 0
INT iNumTimesPlayedUnhookReminder = 0
INT iUnhookReminderTimer = 0
INT iNumMollyWarnings = 0
INT iMollyWarningTimer = 0
INT iNumTrevorReminders = 0
INT iTrevorReminderTimer = 0
INT iNumLamarMonroeDamageLines = 0
INT iLamarMonroeDamageTimer = 0
INT iFranklinShotByCopsTimer = 0
INT iNumFranklinShootTruckLines = 0
INT iNumFranklinBashTruckLines = 0
INT iNumFranklinStingTruckLines = 0
INT iFranklinAttackTruckTimer = 0
INT iMollyGameplayHintTimer = 0
INT iEscortTimer = 0
INT iTruckAndTrailerAlignTimer = 0
INT iReplayCameraWarpTimer = 0 //Fix for bug 2229446
CONST_FLOAT SPREADER_START_OFFSET -15.4
CONST_FLOAT AUDIO_TRIGGER_THRESHOLD 0.01
CONST_FLOAT TRUCK_EDGE -10.0
FLOAT fTruckStartHeading = 221.0246//220.3509//300.6628
FLOAT fTrevorStartHeading = 47.0949
FLOAT fAnimTime = 0.0
//FLOAT fPlayersSpeedAtSpikeStart = 0.0
FLOAT fPrevTruckSpeed = 0.0
FLOAT fCurrentCopSpawnOffset = -50.0
FLOAT fGasStationCarHeading = 154.5624
FLOAT fTimeLamarSpentOnScreen = 0.0
VECTOR vTruckStartPos = <<517.0918, -1327.6111, 28.2764>>//<<495.1359, -1319.4722, 28.1978>>
VECTOR vBackOfTruck = <<508.1402, -1316.7883, 30.2369>>//<<498.5837, -1320.5707, 28.2745>>
VECTOR vTrevorStartPos = <<520.1395, -1326.7764, 28.3382>>
//VECTOR vGasStation = <<268.6948, -1292.9253, 28.2409>>
VECTOR vDropOffPos = <<1566.4338, 6463.4258, 23.1910>>//<<1731.9172, 6396.2090, 33.8157>>
VECTOR vPathNodesMinPos
VECTOR vPathNodesMaxPos
VECTOR vCountrysideCopPos = <<-2197.7756, 4265.8936, 47.3056>>
VECTOR vGasStationCarPos = <<1576.9301, 6451.7017, 24.0479>>
//VECTOR vTruckEscortDocksPos = <<858.3986, -2931.3560, 4.9009>>
VECTOR vSparksOffsetRight = <<0.75, -10.85, -1.0>>
VECTOR vSparksOffsetLeft = <<-0.75, -10.85, -1.0>>
VECTOR vSparksRotation
VECTOR vSparksLightColour = << 255, 100, 10 >>
VECTOR vSparksLightRange = << 0.6, 0.5, 0.0 >>
VECTOR vSparksLightOffset = << 0.0, -0.08, 0.05 >>
INT iLeftLightOnTimer, iLeftLightOffTimer
INT iRightLightOnTimer, iRightLightOffTimer
STRING strCarrec = "MattCarHeist"
STRING strWaypointTruckRoute = "carsteal5_10"
STRING strWaypointRouteEnd = "carsteal5_11"
//STRING strWaypointFinalCutscene = "carsteal5_20"
STRING strTruckWaitAnims = "misscarstealfinale"
STRING strFailLabel = ""
STRING strCarClimbAnims2 = "misscarstealfinalecar_5_ig_8"
STRING strCarClimbAnims = "misscarstealfinalecar_5_ig_6"
STRING strTruckIdleAnims = "misscarstealfinalecar_5_ig_3"
STRING strTruckCopsIntroAnims = "misscarstealfinalecar_5_ig_4"
STRING strGetInCarAnims = "misscarstealfinalecar_5_ig_1"
STRING strDriveOffTrailerAnims = "misscarstealfinalecar_5_ig_10_switch"
STRING strMollyAnims = "misscarsteal4leadinout"
STRING strTruckSitAnims = "veh@truck@ps@base"
STRING strSleepingAnims = "misscarsteal4asleep"
STRING strSleepingEyeAnims = "FACIALS@P_M_ONE@BASE"
STRING strCamShakeAnims = "shake_cam_all@"
BOOL bCurrentConversationInterrupted
TEXT_LABEL_23 CurrentConversationRoot
TEXT_LABEL_23 CurrentConversationLabel
BLIP_INDEX blipCurrentDestination
BLIP_INDEX blipBuddy
CAMERA_INDEX camSwitch
CAMERA_INDEX camCutscene
CAMERA_INDEX camInterp
CAMERA_INDEX camAttach
OBJECT_INDEX objSpikes[3]
BOOL bSpikeSparks[3]
VEHICLE_INDEX vehFranklinCar
VEHICLE_INDEX vehOilSlickTest
VEHICLE_INDEX vehMollyCar
VEHICLE_INDEX vehGasStationCar
VEHICLE_INDEX vehReplayHelper
VEHICLE_INDEX vehChaseCops[NUM_CHASE_COP_CARS]
PED_INDEX pedOilSlickTest
PED_INDEX pedSpikeHelper
PED_INDEX pedDevin
PED_INDEX pedMolly
PED_INDEX pedMollyDriver
SHAPETEST_INDEX shapetestSpikes
SCENARIO_BLOCKING_INDEX sbiChase[5]
//GROUP_INDEX groupPlayer
STOLEN_CAR sStolenCars[6]
CAR_TRANSPORTER sTruck
MISSION_PED sLamar
MISSION_PED sChaseCops[NUM_CHASE_COP_CARS * 2]
LOCATES_HEADER_DATA sLocatesData
PUSH_IN_DATA sPushInData
CAR_GADGET_DATA sSpikes[10]
JB700_GADGET_DATA sCarGadgets
MODEL_NAMES modelTruckFront = PACKER
MODEL_NAMES modelTruckBack = TR4//TR2
MODEL_NAMES modelSpikes = PROP_TYRE_SPIKE_01
MODEL_NAMES modelCop = S_M_Y_SHERIFF_01//S_M_Y_COP_01
MODEL_NAMES modelCopCar = SHERIFF //POLICE
MODEL_NAMES modelMolly = IG_MOLLY
MODEL_NAMES modelMollyCar = FELON
MODEL_NAMES modelMollyDriver = A_M_Y_BUSINESS_02
MODEL_NAMES modelGasStationCar = ORACLE2
MISSION_STAGE eMissionStage = STAGE_START_PHONECALL
SECTION_STAGE eSectionStage = SECTION_STAGE_SETUP
FRANKLIN_TRUCK_ANIM_STAGE eTruckAnimStage = TRUCK_IDLE
MOLLY_STATE eMollyState = MOLLY_STATE_IDLE
SELECTOR_PED_STRUCT sSelectorPeds
SELECTOR_CAM_STRUCT sSelectorCamera
structPedsForConversation sConversationPeds
CHASE_HINT_CAM_STRUCT localChaseHintCamStruct
//push in variables
BOOL bPushInAttached = TRUE
BOOL bPushInAttachStartCam = FALSE
FLOAT fPushInStartPhase = 0.8
FLOAT fPushInStartDistance = 1.0
INT iPushInInterpTime = 1000
INT iPushInCutTime = 900
INT iPushInFXTime = 600
INT iPushInSpeedUpTime = 500
FLOAT fPushInSpeedUpProportion = 0.25
BOOL bPushInDoColourFlash = FALSE
//============================== CAR STEAL 4 SWITCH CAM =====================================================================================
//Merged from shelved changelist for B*985432, see Scott Penman for any questions.
ENUM CARSTEAL4_SWITCH_CAM_STATE
SWITCH_CAM_IDLE,
SWITCH_CAM_WAIT_BEFORE_SPLINE1,
SWITCH_CAM_START_SPLINE1,
SWITCH_CAM_PLAYING_SPLINE1,
SWITCH_CAM_FIRST_PERSON_PUSH,
SWITCH_CAM_RETURN_TO_GAMEPLAY
ENDENUM
SWITCH_CAM_STRUCT scsTruckToCar
BOOL bSwitchedToFranklin = FALSE
BOOL bFranklinSwitchAnimStarted = FALSE
BOOL bCarWheelsSmokeStarted = FALSE
BOOL bTrailerRampReleased = FALSE
BOOL bCarForcedOnTrailerStarted = FALSE
BOOL bCarForcedOnTrailerStopped = FALSE
BOOL bCarStartedReversing = FALSE
BOOL bCarHasTouchedDown = FALSE
BOOL bCarOnAllWheelsTimerStarted = FALSE
BOOL bPlayerControlGivenEarly = FALSE
BOOL bMusicEventChanged = FALSE
BOOL bWhooshStarted = FALSE
BOOL bWhooshFinished = FALSE
BOOL bSwitchFX0Started = FALSE
BOOL bSwitchFX1Started = FALSE
BOOL bSwitchFX2Started = FALSE
BOOL bGroundImpactShakeStarted = FALSE
BOOL bShortTransitionInStarted = FALSE
FLOAT fSwitchFrankAnimPhase = 0.125
FLOAT fCarWheelsSmokeStartPhase = 0.10
FLOAT fTrailerRampReleasedPhase = 0.08
FLOAT fCarStartedReversingPhase = 0.25
FLOAT fTouchdownSafetyPhase = 0.72
FLOAT fPlayerControlGivenPhase = 0.725 //0.70
FLOAT fTruckToCarGPCamHeading = 0.0
FLOAT fTruckToCarGPCamPitch = 0.0
FLOAT fWhooshStartPhase = 0.0
FLOAT fWhooshStopPhase = 0.3
FLOAT fSwitchFX1StartPhase = 0.0
FLOAT fSwitchFX2StartPhase = 0.245
FLOAT fTruckSpeedLimited = 30.000
FLOAT fClearOfTrailerDistance = 100.000
FLOAT fStartTouchdownCamPhase = 0.0
FLOAT fStartTouchdownCarSpeed = 0.0
INT iScrapeSound
INT iWhooshSound = 0
INT iCarOnAllWheelsThreshold = 250
VECTOR vCarRollRotMaxLimits = <<15.0, 10.0, 0.0>>
VECTOR vCarRollRotMinLimits = <<-5.0, -10.0, 0.0>>
VECTOR vApplyForceVector = <<0.0, -40.0, 0.0>>
VECTOR vWheelSmokeBackLeftOffset = <<-0.750, -0.800, 1.000>>
VECTOR vWheelSmokeRot = <<0.0, 0.0, 180.0>>
CARSTEAL4_SWITCH_CAM_STATE eSwitchCamState = SWITCH_CAM_IDLE
PROC DRAW_FLICKERING_LIGHT(VECTOR vPosition, VECTOR vColour, FLOAT fRange, FLOAT fIntensity, INT &iOffTimer, INT &iOnTimer,
INT iMinOnTime, INT iMaxOnTime, INT iMinOffTime, INT iMaxOffTime)
IF GET_GAME_TIMER() - iOffTimer > 0
IF iOnTimer = 0
iOnTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(iMinOnTime, iMaxOnTime)
ELSE
DRAW_LIGHT_WITH_RANGE(vPosition, FLOOR(vColour.x), FLOOR(vColour.y), FLOOR(vColour.z), fRange, fIntensity)
IF GET_GAME_TIMER() - iOnTimer > 0
iOffTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(iMinOffTime, iMaxOffTime)
iOnTimer = 0
ENDIF
ENDIF
ENDIF
ENDPROC
PROC CAR_COLLISION_OFF()
CDEBUG3LN(DEBUG_MISSION, "CAR_COLLISION_OFF")
IF DOES_ENTITY_EXIST(sStolenCars[iChosenCar].veh)
IF NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
SET_ENTITY_COLLISION(sStolenCars[iChosenCar].veh, FALSE)
ENDIF
ENDIF
ENDPROC
PROC CAR_COLLISION_ON()
CDEBUG3LN(DEBUG_MISSION, "CAR_COLLISION_ON")
IF DOES_ENTITY_EXIST(sStolenCars[iChosenCar].veh)
IF NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
SET_ENTITY_COLLISION(sStolenCars[iChosenCar].veh, TRUE)
ENDIF
ENDIF
ENDPROC
PROC SET_TRAILER_GATE_DOWN()
CDEBUG3LN(DEBUG_MISSION, "SET_TRAILER_GATE_DOWN")
IF DOES_ENTITY_EXIST(sTruck.vehBack)
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
CDEBUG3LN(DEBUG_MISSION, "Trailer Gate Down...")
SET_VEHICLE_DOORS_LOCKED(sTruck.vehBack, VEHICLELOCK_UNLOCKED)
SET_VEHICLE_DOOR_OPEN(sTruck.vehBack, SC_DOOR_BOOT, FALSE)
ENDIF
ENDIF
ENDPROC
PROC UPDATE_FORCE_TRUCK_SPEED()
//CDEBUG3LN(DEBUG_MISSION, "UPDATE_FORCE_TRUCK_SPEED")
IF DOES_ENTITY_EXIST(sTruck.vehFront)
IF NOT IS_ENTITY_DEAD(sTruck.vehFront)
IF GET_ENTITY_SPEED(sTruck.vehFront) > fTruckSpeedLimited
SET_VEHICLE_FORWARD_SPEED(sTruck.vehFront, fTruckSpeedLimited)
ENDIF
ENDIF
ENDIF
ENDPROC
PROC DETACH_CAR()
CDEBUG3LN(DEBUG_MISSION, "DETACH_CAR")
IF DOES_ENTITY_EXIST(sTruck.vehBack)
AND DOES_ENTITY_EXIST(sStolenCars[iChosenCar].veh)
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
AND NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
//DETACH_ENTITY(sStolenCars[iChosenCar].veh, FALSE, FALSE)
DETACH_ENTITY(sStolenCars[iChosenCar].veh, TRUE, FALSE)
ENDIF
ENDIF
ENDPROC
PROC UPDATE_CAR_FORCED_ON_TRAILER()
CDEBUG3LN(DEBUG_MISSION, "UPDATE_CAR_FORCED_ON_TRAILER")
IF DOES_ENTITY_EXIST(sTruck.vehBack)
AND DOES_ENTITY_EXIST(sStolenCars[iChosenCar].veh)
AND DOES_ENTITY_EXIST(sStolenCars[0].veh)
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
AND NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
AND NOT IS_ENTITY_DEAD(sStolenCars[0].veh)
VECTOR vCarRot = GET_ENTITY_ROTATION(sStolenCars[0].veh) //This car has the same attach rotation, so can use it to grab the current rotation needed.
SET_ENTITY_ROTATION(sStolenCars[iChosenCar].veh, vCarRot)
SET_ENTITY_COORDS_NO_OFFSET(sStolenCars[iChosenCar].veh, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehBack, sStolenCars[iChosenCar].vTruckOffset))
ENDIF
ENDIF
ENDPROC
PROC CAR_WHEELS_SMOKE()
CDEBUG3LN(DEBUG_MISSION, "CAR_WHEELS_SMOKE")
IF DOES_ENTITY_EXIST(sStolenCars[iChosenCar].veh)
IF NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
START_PARTICLE_FX_NON_LOOPED_ON_ENTITY("scr_carsteal4_wheel_burnout", sStolenCars[iChosenCar].veh, vWheelSmokeBackLeftOffset, vWheelSmokeRot)
IF REQUEST_SCRIPT_AUDIO_BANK("CAR_STEAL_4")
PLAY_SOUND_FROM_ENTITY(-1, "CAR_STEAL_4_BURNOUT", sStolenCars[iChosenCar].veh, "CAR_STEAL_4_SOUNDSET")
#IF IS_DEBUG_BUILD
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Playing sound CAR_STEAL_4_BURNOUT.")
#ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC CAR_REVERSE_OFF_TRAILER()
CDEBUG3LN(DEBUG_MISSION, "CAR_REVERSE_OFF_TRAILER")
IF DOES_ENTITY_EXIST(sStolenCars[iChosenCar].veh)
IF NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
PED_INDEX piCarDriver
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[iChosenCar].veh)
piCarDriver = PLAYER_PED_ID()
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(piCarDriver, FALSE)
ELSE
piCarDriver = sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN]
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(piCarDriver, TRUE)
ENDIF
IF DOES_ENTITY_EXIST(sTruck.vehBack)
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
FLOAT fTrailerSpeed = GET_ENTITY_SPEED(sTruck.vehBack)
SET_VEHICLE_FORWARD_SPEED(sStolenCars[iChosenCar].veh, fTrailerSpeed)
ENDIF
ENDIF
/*IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxWheelSmoke)
STOP_PARTICLE_FX_LOOPED(ptfxWheelSmoke)
ENDIF*/
APPLY_FORCE_TO_ENTITY(sStolenCars[iChosenCar].veh, APPLY_TYPE_EXTERNAL_FORCE, vApplyForceVector, (<<0.0, 0.0, 0.0>>), 0, TRUE, TRUE, TRUE)
IF DOES_ENTITY_EXIST(piCarDriver)
IF NOT IS_ENTITY_DEAD(piCarDriver)
//CLEAR_PED_TASKS(piCarDriver)
//TASK_VEHICLE_TEMP_ACTION(piCarDriver, sStolenCars[iChosenCar].veh, TEMPACT_REVERSE_STRAIGHT_HARD, 2000)
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC UPDATE_REVERSE_OFF_TRAILER()
CDEBUG3LN(DEBUG_MISSION, "UPDATE_REVERSE_OFF_TRAILER")
IF DOES_ENTITY_EXIST(sStolenCars[iChosenCar].veh)
IF NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
PED_INDEX piCarDriver
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[iChosenCar].veh)
piCarDriver = PLAYER_PED_ID()
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(piCarDriver, FALSE)
ELSE
piCarDriver = sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN]
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(piCarDriver, TRUE)
ENDIF
APPLY_FORCE_TO_ENTITY(sStolenCars[iChosenCar].veh, APPLY_TYPE_EXTERNAL_FORCE, vApplyForceVector, (<<0.0, 0.0, 0.0>>), 0, TRUE, TRUE, TRUE)
IF GET_SCRIPT_TASK_STATUS(piCarDriver, SCRIPT_TASK_VEHICLE_TEMP_ACTION) != PERFORMING_TASK
IF DOES_ENTITY_EXIST(piCarDriver)
IF NOT IS_ENTITY_DEAD(piCarDriver)
//CLEAR_PED_TASKS(piCarDriver)
//TASK_VEHICLE_TEMP_ACTION(piCarDriver, sStolenCars[iChosenCar].veh, TEMPACT_REVERSE_STRAIGHT_HARD, 5000)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC LIMIT_CAR_ROTATIONS()
//CDEBUG3LN(DEBUG_MISSION, "LIMIT_CAR_ROTATIONS")
IF DOES_ENTITY_EXIST(sStolenCars[iChosenCar].veh)
IF NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
//Prevent car from rolling too much
VECTOR vCarRot = GET_ENTITY_ROTATION(sStolenCars[iChosenCar].veh)
//CDEBUG3LN(DEBUG_MISSION, "vCarRot X: ", vCarRot.x, " Y: ", vCarRot.y, " Z: ", vCarRot.z)
BOOL bRotLimitHit = FALSE
IF vCarRot.x > vCarRollRotMaxLimits.x
vCarRot.x = vCarRollRotMaxLimits.x
bRotLimitHit = TRUE
ELIF vCarRot.x < vCarRollRotMinLimits.x
vCarRot.x = vCarRollRotMinLimits.x
bRotLimitHit = TRUE
ENDIF
IF vCarRot.y > vCarRollRotMaxLimits.y
vCarRot.y = vCarRollRotMaxLimits.y
bRotLimitHit = TRUE
ELIF vCarRot.y < vCarRollRotMinLimits.y
vCarRot.y = vCarRollRotMinLimits.y
bRotLimitHit = TRUE
ENDIF
IF bRotLimitHit
//CDEBUG3LN(DEBUG_MISSION, "Forcing car rotations...")
SET_ENTITY_ROTATION(sStolenCars[iChosenCar].veh, vCarRot)
ENDIF
ENDIF
ENDIF
ENDPROC
PROC CAR_START_FOLLOWING()
CDEBUG3LN(DEBUG_MISSION, "CAR_START_FOLLOWING")
IF DOES_ENTITY_EXIST(sStolenCars[iChosenCar].veh)
AND DOES_ENTITY_EXIST(sTruck.vehFront)
IF NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
AND NOT IS_ENTITY_DEAD(sTruck.vehFront)
PED_INDEX piCarDriver
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[iChosenCar].veh)
piCarDriver = PLAYER_PED_ID()
ELSE
piCarDriver = sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN]
ENDIF
//FLOAT fSpeed = GET_ENTITY_SPEED(sTruck.vehFront)
IF DOES_ENTITY_EXIST(piCarDriver)
IF NOT IS_ENTITY_DEAD(piCarDriver)
CLEAR_PED_TASKS(piCarDriver)
//TASK_VEHICLE_ESCORT(piCarDriver, sStolenCars[iChosenCar].veh, sTruck.vehFront, VEHICLE_ESCORT_REAR, 15.0, DRIVINGMODE_PLOUGHTHROUGH, -5.0, DEFAULT, DEFAULT)
//TASK_VEHICLE_DRIVE_TO_COORD(piCarDriver, sStolenCars[iChosenCar].veh, vDropOffPos, fSpeed, DRIVINGSTYLE_NORMAL, modelTruckFront, DF_DontSteerAroundPlayerPed, 10.0, 20.0)
TASK_VEHICLE_TEMP_ACTION(piCarDriver, sStolenCars[iChosenCar].veh, TEMPACT_GOFORWARD, 5000)
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC UPDATE_CAR_FOLLOWING()
//CDEBUG3LN(DEBUG_MISSION, "UPDATE_CAR_FOLLOWING")
IF DOES_ENTITY_EXIST(sStolenCars[iChosenCar].veh)
AND DOES_ENTITY_EXIST(sTruck.vehFront)
IF NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
AND NOT IS_ENTITY_DEAD(sTruck.vehFront)
PED_INDEX piCarDriver
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[iChosenCar].veh)
piCarDriver = PLAYER_PED_ID()
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(piCarDriver, FALSE)
ELSE
piCarDriver = sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN]
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(piCarDriver, TRUE)
ENDIF
IF GET_SCRIPT_TASK_STATUS(piCarDriver, SCRIPT_TASK_VEHICLE_MISSION) != PERFORMING_TASK
//FLOAT fSpeed = GET_ENTITY_SPEED(sTruck.vehFront)
IF DOES_ENTITY_EXIST(piCarDriver)
IF NOT IS_ENTITY_DEAD(piCarDriver)
CLEAR_PED_TASKS(piCarDriver)
TASK_VEHICLE_ESCORT(piCarDriver, sStolenCars[iChosenCar].veh, sTruck.vehFront, VEHICLE_ESCORT_REAR, 15.0, DRIVINGMODE_PLOUGHTHROUGH, -5.0, DEFAULT, DEFAULT)
//TASK_VEHICLE_DRIVE_TO_COORD(piCarDriver, sStolenCars[iChosenCar].veh, vDropOffPos, fSpeed, DRIVINGSTYLE_NORMAL, modelTruckFront, DF_DontSteerAroundPlayerPed, 10.0, 20.0)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC INIT_UPDATE_CAR_FOLLOW_INTERP_VARS(FLOAT fCamPhase)
CDEBUG3LN(DEBUG_MISSION, "INIT_UPDATE_CAR_FOLLOW_INTERP_VARS")
fStartTouchdownCamPhase = fCamPhase
IF DOES_ENTITY_EXIST(sStolenCars[iChosenCar].veh)
AND DOES_ENTITY_EXIST(sTruck.vehFront)
IF NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
AND NOT IS_ENTITY_DEAD(sTruck.vehFront)
VECTOR vCarSpeed = GET_ENTITY_SPEED_VECTOR(sStolenCars[iChosenCar].veh, TRUE)
fStartTouchdownCarSpeed = vCarSpeed.y
fStartTouchdownCarSpeed = fStartTouchdownCarSpeed
ENDIF
ENDIF
ENDPROC
PROC UPDATE_CAR_FOLLOW_TRUCK(FLOAT fCamPhase)
//CDEBUG3LN(DEBUG_MISSION, "UPDATE_CAR_FOLLOW_TRUCK")
IF DOES_ENTITY_EXIST(sStolenCars[iChosenCar].veh)
AND DOES_ENTITY_EXIST(sTruck.vehFront)
IF NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
AND NOT IS_ENTITY_DEAD(sTruck.vehFront)
VECTOR vTruckSpeed = GET_ENTITY_SPEED_VECTOR(sTruck.vehFront, TRUE)
VECTOR vCarSpeed = GET_ENTITY_SPEED_VECTOR(sStolenCars[iChosenCar].veh, TRUE)
FLOAT fAlpha = CLAMP((fCamPhase - fStartTouchdownCamPhase) * (1 / ABSF(1 - fStartTouchdownCamPhase)), 0.0, 1.0)
FLOAT fSpeed = LERP_FLOAT(vCarSpeed.y, vTruckSpeed.y, fAlpha)
IF (fSpeed - vCarSpeed.y) > 1.0
fSpeed = vCarSpeed.y + 1.0
ELIF (fSpeed - vCarSpeed.y) < 1.0
fSpeed = vCarSpeed.y - 1.0
ENDIF
//CDEBUG3LN(DEBUG_MISSION, "fAlpha: ", fAlpha, "Speed: ", fSpeed)
SET_VEHICLE_FORWARD_SPEED(sStolenCars[iChosenCar].veh, fSpeed)
ENDIF
ENDIF
ENDPROC
FUNC BOOL IS_CAR_CLEAR_OF_TRAILER()
//CDEBUG3LN(DEBUG_MISSION, "IS_CAR_CLEAR_OF_TRAILER")
IF DOES_ENTITY_EXIST(sStolenCars[iChosenCar].veh)
AND DOES_ENTITY_EXIST(sTruck.vehBack)
IF NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
AND NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF VDIST2(GET_ENTITY_COORDS(sStolenCars[iChosenCar].veh), GET_ENTITY_COORDS(sTruck.vehBack)) > fClearOfTrailerDistance
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL HAS_CAR_TOUCHED_DOWN(SWITCH_CAM_STRUCT &thisSwitchCam)
//CDEBUG3LN(DEBUG_MISSION, "HAS_CAR_TOUCHED_DOWN")
IF DOES_ENTITY_EXIST(sStolenCars[iChosenCar].veh)
IF NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
IF IS_CAR_CLEAR_OF_TRAILER()
AND IS_VEHICLE_ON_ALL_WHEELS(sStolenCars[iChosenCar].veh)
IF NOT bCarOnAllWheelsTimerStarted
IF NOT bGroundImpactShakeStarted
SHAKE_CAM(thisSwitchCam.ciSpline, "SMALL_EXPLOSION_SHAKE", 0.15)
bGroundImpactShakeStarted = TRUE
ENDIF
IF NOT bSwitchFX2Started
fSwitchFX2StartPhase = fSwitchFX2StartPhase
//IF fCamPhase >= fSwitchFX2StartPhase
CDEBUG3LN(DEBUG_MISSION, "FX2 Started...")
ANIMPOSTFX_PLAY("SwitchSceneFranklin", 0, FALSE)
bSwitchFX2Started = TRUE
//ENDIF
ENDIF
IF NOT bWhooshFinished
fWhooshStopPhase = fWhooshStopPhase
//IF fCamPhase > fWhooshStopPhase
STOP_SOUND(iWhooshSound)
bWhooshFinished = TRUE
//ENDIF
ENDIF
SETTIMERB(0)
bCarOnAllWheelsTimerStarted = TRUE
ELSE
IF TIMERB() > iCarOnAllWheelsThreshold
RETURN TRUE
ENDIF
ENDIF
ELSE
SETTIMERB(0)
bCarOnAllWheelsTimerStarted = FALSE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
PROC SETUP_SPLINE_CAM_NODE_ARRAY_TRUCK_TO_CAR(SWITCH_CAM_STRUCT &thisSwitchCam, VEHICLE_INDEX truck, VEHICLE_INDEX car)
CDEBUG3LN(DEBUG_MISSION, "SETUP_SPLINE_CAM_NODE_ARRAY_TRUCK_TO_CAR")
IF NOT thisSwitchCam.bInitialized
//--- Start of Cam Data ---
thisSwitchCam.nodes[0].SwitchCamType = SWITCH_CAM_OLD_SYSTEM
thisSwitchCam.nodes[0].iForceCamPointAtEntityIndex = -1
thisSwitchCam.nodes[0].bIsGameplayCamCopy = FALSE
thisSwitchCam.nodes[0].iNodeTime = 0
thisSwitchCam.nodes[0].vNodePos = <<-0.7917, 2.2113, 0.6422>>
thisSwitchCam.nodes[0].vWorldPosLookAt = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[0].fNodeOffsetDist = 0.0000
thisSwitchCam.nodes[0].fNodeVerticleOffset = 0.0000
thisSwitchCam.nodes[0].bAttachToOriginPed = FALSE
thisSwitchCam.nodes[0].vNodeDir = <<-0.2027, -0.0921, 0.2221>>
thisSwitchCam.nodes[0].bPointAtEntity = TRUE
thisSwitchCam.nodes[0].bPointAtOffsetIsRelative = TRUE
thisSwitchCam.nodes[0].bAttachOffsetIsRelative = TRUE
thisSwitchCam.nodes[0].fNodeFOV = 40.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_MEDIUM
thisSwitchCam.nodes[0].fNodeCamShake = 0.2000
thisSwitchCam.nodes[0].iCamEaseType = 0
thisSwitchCam.nodes[0].fCamEaseScaler = 0.0000
thisSwitchCam.nodes[0].fCamNodeVelocityScale = 0.0000
thisSwitchCam.nodes[0].bCamEaseForceLinear = FALSE
thisSwitchCam.nodes[0].bCamEaseForceLevel = FALSE
thisSwitchCam.nodes[0].fTimeScale = 0.2000
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_OLD_SYSTEM
thisSwitchCam.nodes[1].iForceCamPointAtEntityIndex = -1
thisSwitchCam.nodes[1].bIsGameplayCamCopy = FALSE
thisSwitchCam.nodes[1].iNodeTime = 300
thisSwitchCam.nodes[1].vNodePos = <<-0.9939, 3.0014, 0.7855>>
thisSwitchCam.nodes[1].vWorldPosLookAt = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[1].fNodeOffsetDist = 0.0000
thisSwitchCam.nodes[1].fNodeVerticleOffset = 0.0000
thisSwitchCam.nodes[1].bAttachToOriginPed = FALSE
thisSwitchCam.nodes[1].vNodeDir = <<-0.2026, -0.0923, 0.2216>>
thisSwitchCam.nodes[1].bPointAtEntity = TRUE
thisSwitchCam.nodes[1].bPointAtOffsetIsRelative = TRUE
thisSwitchCam.nodes[1].bAttachOffsetIsRelative = TRUE
thisSwitchCam.nodes[1].fNodeFOV = 40.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_MEDIUM
thisSwitchCam.nodes[1].fNodeCamShake = 0.2000
thisSwitchCam.nodes[1].iCamEaseType = 0
thisSwitchCam.nodes[1].fCamEaseScaler = 0.0000
thisSwitchCam.nodes[1].fCamNodeVelocityScale = 0.0000
thisSwitchCam.nodes[1].bCamEaseForceLinear = FALSE
thisSwitchCam.nodes[1].bCamEaseForceLevel = FALSE
thisSwitchCam.nodes[1].fTimeScale = 1.0000
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_OLD_SYSTEM
thisSwitchCam.nodes[2].iForceCamPointAtEntityIndex = -1
thisSwitchCam.nodes[2].bIsGameplayCamCopy = FALSE
thisSwitchCam.nodes[2].iNodeTime = 1200
thisSwitchCam.nodes[2].vNodePos = <<-1.0419, 3.1884, 0.8190>>
thisSwitchCam.nodes[2].vWorldPosLookAt = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[2].fNodeOffsetDist = 0.0000
thisSwitchCam.nodes[2].fNodeVerticleOffset = 0.0000
thisSwitchCam.nodes[2].bAttachToOriginPed = FALSE
thisSwitchCam.nodes[2].vNodeDir = <<-0.2029, -0.0924, 0.2218>>
thisSwitchCam.nodes[2].bPointAtEntity = TRUE
thisSwitchCam.nodes[2].bPointAtOffsetIsRelative = TRUE
thisSwitchCam.nodes[2].bAttachOffsetIsRelative = TRUE
thisSwitchCam.nodes[2].fNodeFOV = 40.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_MEDIUM
thisSwitchCam.nodes[2].fNodeCamShake = 0.2000
thisSwitchCam.nodes[2].iCamEaseType = 0
thisSwitchCam.nodes[2].fCamEaseScaler = 0.0000
thisSwitchCam.nodes[2].fCamNodeVelocityScale = 0.0000
thisSwitchCam.nodes[2].bCamEaseForceLinear = FALSE
thisSwitchCam.nodes[2].bCamEaseForceLevel = FALSE
thisSwitchCam.nodes[2].fTimeScale = 0.4000
thisSwitchCam.nodes[2].iTimeScaleEaseType = 0
thisSwitchCam.nodes[2].fTimeScaleEaseScaler = 0.8000
thisSwitchCam.nodes[2].bFlashEnabled = FALSE
thisSwitchCam.nodes[2].SCFE_FlashEffectUsed = SCFE_CODE_FLASH
thisSwitchCam.nodes[2].fMinExposure = 0.0000
thisSwitchCam.nodes[2].fMaxExposure = 0.0000
thisSwitchCam.nodes[2].iRampUpDuration = 0
thisSwitchCam.nodes[2].iRampDownDuration = 0
thisSwitchCam.nodes[2].iHoldDuration = 0
thisSwitchCam.nodes[2].fFlashNodePhaseOffset = 0.0000
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].bIsCamCutNode = TRUE
thisSwitchCam.nodes[4].SwitchCamType = SWITCH_CAM_OLD_SYSTEM
thisSwitchCam.nodes[4].iForceCamPointAtEntityIndex = -1
thisSwitchCam.nodes[4].bIsGameplayCamCopy = FALSE
thisSwitchCam.nodes[4].iNodeTime = 0
thisSwitchCam.nodes[4].vNodePos = <<-1.4945, -4.9765, 0.3261>>
thisSwitchCam.nodes[4].vWorldPosLookAt = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[4].fNodeOffsetDist = 0.0000
thisSwitchCam.nodes[4].fNodeVerticleOffset = 0.0000
thisSwitchCam.nodes[4].bAttachToOriginPed = FALSE
thisSwitchCam.nodes[4].vNodeDir = <<-0.2235, 0.0415, -0.1569>>
thisSwitchCam.nodes[4].bPointAtEntity = TRUE
thisSwitchCam.nodes[4].bPointAtOffsetIsRelative = TRUE
thisSwitchCam.nodes[4].bAttachOffsetIsRelative = TRUE
thisSwitchCam.nodes[4].fNodeFOV = 50.0000
thisSwitchCam.nodes[4].vClonedNodeOffset = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[4].iNodeToClone = 0
thisSwitchCam.nodes[4].NodeTimePostFX_Type = NO_EFFECT
thisSwitchCam.nodes[4].fNodeTimePostFXBlendTime = 0.0000
thisSwitchCam.nodes[4].fNodeTimePostFXTimeOffset = 0.0000
thisSwitchCam.nodes[4].fNodeMotionBlur = 0.0000
thisSwitchCam.nodes[4].NodeCamShakeType = CAM_SHAKE_MEDIUM
thisSwitchCam.nodes[4].fNodeCamShake = 0.2000
thisSwitchCam.nodes[4].iCamEaseType = 0
thisSwitchCam.nodes[4].fCamEaseScaler = 0.0000
thisSwitchCam.nodes[4].fCamNodeVelocityScale = 0.0000
thisSwitchCam.nodes[4].bCamEaseForceLinear = FALSE
thisSwitchCam.nodes[4].bCamEaseForceLevel = FALSE
thisSwitchCam.nodes[4].fTimeScale = 2.0000
thisSwitchCam.nodes[4].iTimeScaleEaseType = 0
thisSwitchCam.nodes[4].fTimeScaleEaseScaler = 0.0000
thisSwitchCam.nodes[4].bFlashEnabled = FALSE
thisSwitchCam.nodes[4].SCFE_FlashEffectUsed = SCFE_CODE_FLASH
thisSwitchCam.nodes[4].fMinExposure = 0.0000
thisSwitchCam.nodes[4].fMaxExposure = 0.0000
thisSwitchCam.nodes[4].iRampUpDuration = 0
thisSwitchCam.nodes[4].iRampDownDuration = 0
thisSwitchCam.nodes[4].iHoldDuration = 0
thisSwitchCam.nodes[4].fFlashNodePhaseOffset = 0.0000
thisSwitchCam.nodes[4].bIsLowDetailNode = FALSE
thisSwitchCam.nodes[4].bUseCustomDOF = FALSE
thisSwitchCam.nodes[4].NodeDOF_Info.fDOF_NearDOF = 0.0000
thisSwitchCam.nodes[4].NodeDOF_Info.fDOF_FarDOF = 0.0000
thisSwitchCam.nodes[4].NodeDOF_Info.fDOF_EffectStrength = 0.0000
thisSwitchCam.nodes[5].SwitchCamType = SWITCH_CAM_OLD_SYSTEM
thisSwitchCam.nodes[5].iForceCamPointAtEntityIndex = -1
thisSwitchCam.nodes[5].bIsGameplayCamCopy = FALSE
thisSwitchCam.nodes[5].iNodeTime = 1000
thisSwitchCam.nodes[5].vNodePos = <<-1.5344, -6.3627, 0.4002>>
thisSwitchCam.nodes[5].vWorldPosLookAt = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[5].fNodeOffsetDist = 0.0000
thisSwitchCam.nodes[5].fNodeVerticleOffset = 0.0000
thisSwitchCam.nodes[5].bAttachToOriginPed = FALSE
thisSwitchCam.nodes[5].vNodeDir = <<0.0236, -0.0150, -0.1142>>
thisSwitchCam.nodes[5].bPointAtEntity = TRUE
thisSwitchCam.nodes[5].bPointAtOffsetIsRelative = TRUE
thisSwitchCam.nodes[5].bAttachOffsetIsRelative = TRUE
thisSwitchCam.nodes[5].fNodeFOV = 50.0000
thisSwitchCam.nodes[5].vClonedNodeOffset = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[5].iNodeToClone = 0
thisSwitchCam.nodes[5].NodeTimePostFX_Type = NO_EFFECT
thisSwitchCam.nodes[5].fNodeTimePostFXBlendTime = 0.0000
thisSwitchCam.nodes[5].fNodeTimePostFXTimeOffset = 0.0000
thisSwitchCam.nodes[5].fNodeMotionBlur = 0.0000
thisSwitchCam.nodes[5].NodeCamShakeType = CAM_SHAKE_MEDIUM
thisSwitchCam.nodes[5].fNodeCamShake = 0.2000
thisSwitchCam.nodes[5].iCamEaseType = 0
thisSwitchCam.nodes[5].fCamEaseScaler = 0.0000
thisSwitchCam.nodes[5].fCamNodeVelocityScale = 0.0000
thisSwitchCam.nodes[5].bCamEaseForceLinear = FALSE
thisSwitchCam.nodes[5].bCamEaseForceLevel = FALSE
thisSwitchCam.nodes[5].fTimeScale = 0.0100
thisSwitchCam.nodes[5].iTimeScaleEaseType = 0
thisSwitchCam.nodes[5].fTimeScaleEaseScaler = 0.0000
thisSwitchCam.nodes[5].bFlashEnabled = FALSE
thisSwitchCam.nodes[5].SCFE_FlashEffectUsed = SCFE_CODE_FLASH
thisSwitchCam.nodes[5].fMinExposure = 0.0000
thisSwitchCam.nodes[5].fMaxExposure = 0.0000
thisSwitchCam.nodes[5].iRampUpDuration = 0
thisSwitchCam.nodes[5].iRampDownDuration = 0
thisSwitchCam.nodes[5].iHoldDuration = 0
thisSwitchCam.nodes[5].fFlashNodePhaseOffset = 0.0000
thisSwitchCam.nodes[5].bIsLowDetailNode = FALSE
thisSwitchCam.nodes[5].bUseCustomDOF = FALSE
thisSwitchCam.nodes[5].NodeDOF_Info.fDOF_NearDOF = 0.0000
thisSwitchCam.nodes[5].NodeDOF_Info.fDOF_FarDOF = 0.0000
thisSwitchCam.nodes[5].NodeDOF_Info.fDOF_EffectStrength = 0.0000
thisSwitchCam.nodes[6].SwitchCamType = SWITCH_CAM_OLD_SYSTEM
thisSwitchCam.nodes[6].iForceCamPointAtEntityIndex = -1
thisSwitchCam.nodes[6].bIsGameplayCamCopy = FALSE
thisSwitchCam.nodes[6].iNodeTime = 600
thisSwitchCam.nodes[6].vNodePos = <<-0.9759, -4.9260, 1.5771>>
thisSwitchCam.nodes[6].vWorldPosLookAt = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[6].fNodeOffsetDist = 0.0000
thisSwitchCam.nodes[6].fNodeVerticleOffset = 0.0000
thisSwitchCam.nodes[6].bAttachToOriginPed = FALSE
thisSwitchCam.nodes[6].vNodeDir = <<-0.2805, 0.0644, 0.0843>>
thisSwitchCam.nodes[6].bPointAtEntity = TRUE
thisSwitchCam.nodes[6].bPointAtOffsetIsRelative = TRUE
thisSwitchCam.nodes[6].bAttachOffsetIsRelative = TRUE
thisSwitchCam.nodes[6].fNodeFOV = 0.0000
thisSwitchCam.nodes[6].vClonedNodeOffset = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[6].iNodeToClone = 0
thisSwitchCam.nodes[6].NodeTimePostFX_Type = NO_EFFECT
thisSwitchCam.nodes[6].fNodeTimePostFXBlendTime = 0.0000
thisSwitchCam.nodes[6].fNodeTimePostFXTimeOffset = 0.0000
thisSwitchCam.nodes[6].fNodeMotionBlur = 0.0000
thisSwitchCam.nodes[6].NodeCamShakeType = CAM_SHAKE_MEDIUM
thisSwitchCam.nodes[6].fNodeCamShake = 0.2000
thisSwitchCam.nodes[6].iCamEaseType = 0
thisSwitchCam.nodes[6].fCamEaseScaler = 0.0000
thisSwitchCam.nodes[6].fCamNodeVelocityScale = 0.0000
thisSwitchCam.nodes[6].bCamEaseForceLinear = FALSE
thisSwitchCam.nodes[6].bCamEaseForceLevel = FALSE
thisSwitchCam.nodes[6].fTimeScale = 2.0000
thisSwitchCam.nodes[6].iTimeScaleEaseType = 0
thisSwitchCam.nodes[6].fTimeScaleEaseScaler = 0.0000
thisSwitchCam.nodes[6].bFlashEnabled = FALSE
thisSwitchCam.nodes[6].SCFE_FlashEffectUsed = SCFE_CODE_FLASH
thisSwitchCam.nodes[6].fMinExposure = 0.0000
thisSwitchCam.nodes[6].fMaxExposure = 0.0000
thisSwitchCam.nodes[6].iRampUpDuration = 0
thisSwitchCam.nodes[6].iRampDownDuration = 0
thisSwitchCam.nodes[6].iHoldDuration = 0
thisSwitchCam.nodes[6].fFlashNodePhaseOffset = 0.0000
thisSwitchCam.nodes[6].bIsLowDetailNode = FALSE
thisSwitchCam.nodes[6].bUseCustomDOF = FALSE
thisSwitchCam.nodes[6].NodeDOF_Info.fDOF_NearDOF = 0.0000
thisSwitchCam.nodes[6].NodeDOF_Info.fDOF_FarDOF = 0.0000
thisSwitchCam.nodes[6].NodeDOF_Info.fDOF_EffectStrength = 0.0000
thisSwitchCam.nodes[7].SwitchCamType = SWITCH_CAM_OLD_SYSTEM
thisSwitchCam.nodes[7].iForceCamPointAtEntityIndex = -1
thisSwitchCam.nodes[7].bIsGameplayCamCopy = FALSE
thisSwitchCam.nodes[7].iNodeTime = 2200
thisSwitchCam.nodes[7].vNodePos = <<-0.4285, -5.1203, 0.8830>>
thisSwitchCam.nodes[7].vWorldPosLookAt = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[7].fNodeOffsetDist = 0.0000
thisSwitchCam.nodes[7].fNodeVerticleOffset = 0.0000
thisSwitchCam.nodes[7].bAttachToOriginPed = FALSE
thisSwitchCam.nodes[7].vNodeDir = <<-0.4801, 0.0052, 0.8198>>
thisSwitchCam.nodes[7].bPointAtEntity = TRUE
thisSwitchCam.nodes[7].bPointAtOffsetIsRelative = TRUE
thisSwitchCam.nodes[7].bAttachOffsetIsRelative = TRUE
thisSwitchCam.nodes[7].fNodeFOV = 0.0000
thisSwitchCam.nodes[7].vClonedNodeOffset = <<0.0000, 0.0000, 0.0000>>
thisSwitchCam.nodes[7].iNodeToClone = 0
thisSwitchCam.nodes[7].NodeTimePostFX_Type = NO_EFFECT
thisSwitchCam.nodes[7].fNodeTimePostFXBlendTime = 0.0000
thisSwitchCam.nodes[7].fNodeTimePostFXTimeOffset = 0.0000
thisSwitchCam.nodes[7].fNodeMotionBlur = 0.0000
thisSwitchCam.nodes[7].NodeCamShakeType = CAM_SHAKE_MEDIUM
thisSwitchCam.nodes[7].fNodeCamShake = 0.2000
thisSwitchCam.nodes[7].iCamEaseType = 0
thisSwitchCam.nodes[7].fCamEaseScaler = 0.0000
thisSwitchCam.nodes[7].fCamNodeVelocityScale = 0.0000
thisSwitchCam.nodes[7].bCamEaseForceLinear = FALSE
thisSwitchCam.nodes[7].bCamEaseForceLevel = FALSE
thisSwitchCam.nodes[7].fTimeScale = 1.0000
thisSwitchCam.nodes[7].iTimeScaleEaseType = 0
thisSwitchCam.nodes[7].fTimeScaleEaseScaler = 0.0000
thisSwitchCam.nodes[7].bFlashEnabled = FALSE
thisSwitchCam.nodes[7].SCFE_FlashEffectUsed = SCFE_CODE_FLASH
thisSwitchCam.nodes[7].fMinExposure = 0.0000
thisSwitchCam.nodes[7].fMaxExposure = 0.0000
thisSwitchCam.nodes[7].iRampUpDuration = 0
thisSwitchCam.nodes[7].iRampDownDuration = 0
thisSwitchCam.nodes[7].iHoldDuration = 0
thisSwitchCam.nodes[7].fFlashNodePhaseOffset = 0.0000
thisSwitchCam.nodes[7].bIsLowDetailNode = FALSE
thisSwitchCam.nodes[7].bUseCustomDOF = FALSE
thisSwitchCam.nodes[7].NodeDOF_Info.fDOF_NearDOF = 0.0000
thisSwitchCam.nodes[7].NodeDOF_Info.fDOF_FarDOF = 0.0000
thisSwitchCam.nodes[7].NodeDOF_Info.fDOF_EffectStrength = 0.0000
thisSwitchCam.iNumNodes = 8
thisSwitchCam.iCamSwitchFocusNode = 0
thisSwitchCam.fSwitchSoundAudioStartPhase = -1.0000
thisSwitchCam.fSwitchSoundAudioEndPhase = -1.0000
thisSwitchCam.bSwitchSoundPlayOpeningPulse = TRUE
thisSwitchCam.bSwitchSoundPlayMoveLoop = TRUE
thisSwitchCam.bSwitchSoundPlayExitPulse = TRUE
thisSwitchCam.bSplineNoSmoothing = FALSE
thisSwitchCam.bAddGameplayCamAsLastNode = TRUE
thisSwitchCam.iGameplayNodeBlendDuration = 1000
//--- End of Cam Data ---
thisSwitchCam.strOutputStructName = "thisSwitchCam"
thisSwitchCam.strOutputFileName = "CameraInfo_CarSteal4_TruckToCar.txt"
thisSwitchCam.strXMLFileName = "CameraInfo_CarSteal4_TruckToCar.xml"
thisSwitchCam.bInitialized = TRUE
ENDIF
thisSwitchCam.viVehicles[0] = truck
thisSwitchCam.viVehicles[1] = car
ENDPROC
PTFX_ID ptfxSparksLeft, ptfxSparksRight
FUNC BOOL HANDLE_TRUCK_TO_CAR_SWITCH_CAM(SWITCH_CAM_STRUCT &thisSwitchCam)
//CDEBUG3LN(DEBUG_MISSION, "HANDLE_TRUCK_TO_CAR_SWITCH_CAM")
INT iCurrentNode
FLOAT fCamPhase
DISABLE_FIRST_PERSON_FLASH_EFFECT_THIS_UPDATE()
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_NEXT_CAMERA)
SWITCH eSwitchCamState
CASE SWITCH_CAM_IDLE
#IF IS_DEBUG_BUILD
DRAW_DEBUG_TEXT_2D("SWITCH_CAM_IDLE", << 0.1, 0.3, 0.0 >>)
#ENDIF
//CDEBUG3LN(DEBUG_MISSION, "eSwitchCamState = SWITCH_CAM_IDLE")
BREAK
CASE SWITCH_CAM_WAIT_BEFORE_SPLINE1
#IF IS_DEBUG_BUILD
DRAW_DEBUG_TEXT_2D("SWITCH_CAM_WAIT_BEFORE_SPLINE1", << 0.1, 0.3, 0.0 >>)
#ENDIF
DISPLAY_HUD(FALSE)
DISPLAY_RADAR(FALSE)
IF NOT bSwitchFX0Started
//IF ( TIMERB() >= 100 )
CDEBUG3LN(DEBUG_MISSION, "FX1 Started...")
ANIMPOSTFX_PLAY("SwitchShortTrevorIn", 0, FALSE)
//PLAY_SOUND_FRONTEND(-1, "HIT_2", "LONG_PLAYER_SWITCH_SOUNDS")
//PLAY_SOUND_FRONTEND(-1, "CAMERA_MOVE", "LONG_PLAYER_SWITCH_SOUNDS")
PLAY_SOUND_FRONTEND(-1, "Hit_Out", "PLAYER_SWITCH_CUSTOM_SOUNDSET")
bSwitchFX0Started = TRUE
//ENDIF
ENDIF
IF ( TIMERB() >= 800 )
SETTIMERB(0)
RESET_PUSH_IN(sPushInData)
FILL_PUSH_IN_DATA(sPushInData, sStolenCars[iChosenCar].veh, CHAR_FRANKLIN, fPushInStartDistance, iPushInInterpTime, iPushInCutTime, iPushInFXTime, iPushInSpeedUpTime, fPushInSpeedUpProportion)
eSwitchCamState = SWITCH_CAM_START_SPLINE1
ENDIF
BREAK
CASE SWITCH_CAM_START_SPLINE1
#IF IS_DEBUG_BUILD
DRAW_DEBUG_TEXT_2D("SWITCH_CAM_START_SPLINE1", << 0.1, 0.3, 0.0 >>)
#ENDIF
CDEBUG3LN(DEBUG_MISSION, "eSwitchCamState = SWITCH_CAM_START_SPLINE1")
DISPLAY_HUD(FALSE)
DISPLAY_RADAR(FALSE)
SET_WIDESCREEN_BORDERS(TRUE, 500)
//Get rid of any cars that could interfere with the switch.
IF DOES_ENTITY_EXIST(sStolenCars[iChosenCar].veh)
IF NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
VECTOR vFranklinsCarPos
vFranklinsCarPos = GET_ENTITY_COORDS(sStolenCars[iChosenCar].veh)
CLEAR_AREA(vFranklinsCarPos, 50.0, TRUE)
CLEAR_AREA_OF_VEHICLES(vFranklinsCarPos, 50.0)
SET_VEHICLE_LIGHTS(sStolenCars[iChosenCar].veh, SET_VEHICLE_LIGHTS_ON)
ENDIF
ENDIF
DESTROY_ALL_CAMS()
SET_CINEMATIC_MODE_ACTIVE(FALSE) //disable cinematic mode if player was in cinematic mode on the truck before the switch
SETUP_SPLINE_CAM_NODE_ARRAY_TRUCK_TO_CAR(thisSwitchCam, sStolenCars[iChosenCar].veh, sStolenCars[iChosenCar].veh)
CREATE_SPLINE_CAM(thisSwitchCam)
SET_CAM_ACTIVE(thisSwitchCam.ciSpline, TRUE)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
UPDATE_FORCE_TRUCK_SPEED()
KILL_CHASE_HINT_CAM(localChaseHintCamStruct) //reset the cinematic camera so that it does not remain after we're done with this switch camera
IF IS_AUDIO_SCENE_ACTIVE("CAR_4_COPS_ARRIVE")
STOP_AUDIO_SCENE("CAR_4_COPS_ARRIVE")
ENDIF
IF NOT IS_AUDIO_SCENE_ACTIVE("CAR_4_REVERSE_OFF_TRUCK")
START_AUDIO_SCENE("CAR_4_REVERSE_OFF_TRUCK")
ENDIF
IF IS_AUDIO_SCENE_ACTIVE("CAR_4_FIRST_PERSON_MUTES_SCENE")
STOP_AUDIO_SCENE("CAR_4_FIRST_PERSON_MUTES_SCENE")
ENDIF
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", TRUE)
IF ( bSwitchFX0Started = FALSE )
//PLAY_SOUND_FRONTEND(-1, "HIT_2", "LONG_PLAYER_SWITCH_SOUNDS")
//PLAY_SOUND_FRONTEND(-1, "CAMERA_MOVE", "LONG_PLAYER_SWITCH_SOUNDS")
PLAY_SOUND_FRONTEND(-1, "Hit_Out", "PLAYER_SWITCH_CUSTOM_SOUNDSET")
ENDIF
SETTIMERA(0)
SETTIMERB(0)
bSwitchedToFranklin = FALSE
bFranklinSwitchAnimStarted = FALSE
bMusicEventChanged = FALSE
bCarWheelsSmokeStarted = FALSE
bTrailerRampReleased = FALSE
bCarForcedOnTrailerStarted = FALSE
bCarForcedOnTrailerStopped = FALSE
bCarStartedReversing = FALSE
bCarHasTouchedDown = FALSE
bPlayerControlGivenEarly = FALSE
bWhooshStarted = FALSE
bWhooshFinished = FALSE
IF ( bSwitchFX0Started = FALSE )
bSwitchFX1Started = FALSE
ELSE
bSwitchFX1Started = TRUE
ENDIF
bSwitchFX2Started = FALSE
bGroundImpactShakeStarted = FALSE
bShortTransitionInStarted = FALSE
REPLAY_RECORD_BACK_FOR_TIME(3, 0.0, REPLAY_IMPORTANCE_HIGH)
eSwitchCamState = SWITCH_CAM_PLAYING_SPLINE1
CDEBUG3LN(DEBUG_MISSION, "eSwitchCamState = SWITCH_CAM_PLAYING_SPLINE1")
FALLTHRU
CASE SWITCH_CAM_PLAYING_SPLINE1
#IF IS_DEBUG_BUILD
DRAW_DEBUG_TEXT_2D("SWITCH_CAM_PLAYING_SPLINE1", << 0.1, 0.3, 0.0 >>)
#ENDIF
//CDEBUG3LN(DEBUG_MISSION, "eSwitchCamState = SWITCH_CAM_PLAYING_SPLINE1")
IF IS_CAM_ACTIVE(thisSwitchCam.ciSpline)
iCurrentNode = iCurrentNode
iCurrentNode = UPDATE_SPLINE_CAM(thisSwitchCam)
fCamPhase = GET_CAM_SPLINE_PHASE(thisSwitchCam.ciSpline)
//UPDATE_FORCE_TRUCK_SPEED()
IF NOT bMusicEventChanged
IF PREPARE_MUSIC_EVENT("CAR4_REVERSE")
TRIGGER_MUSIC_EVENT("CAR4_REVERSE")
bMusicEventChanged = TRUE
ENDIF
ENDIF
IF NOT bWhooshStarted
IF fCamPhase > fWhooshStartPhase
iWhooshSound = GET_SOUND_ID()
PLAY_SOUND_FRONTEND(iWhooshSound, "out", "SHORT_PLAYER_SWITCH_SOUND_SET")
bWhooshStarted = TRUE
ENDIF
ENDIF
IF NOT bShortTransitionInStarted
IF TIMERB() > 200
PLAY_SOUND_FRONTEND(-1, "Short_Transition_In", "PLAYER_SWITCH_CUSTOM_SOUNDSET")
bShortTransitionInStarted = TRUE
ENDIF
ENDIF
IF NOT bSwitchFX1Started
IF fCamPhase >= fSwitchFX1StartPhase
CDEBUG3LN(DEBUG_MISSION, "FX1 Started...")
ANIMPOSTFX_PLAY("SwitchShortTrevorIn", 0, FALSE)
bSwitchFX1Started = TRUE
ENDIF
ENDIF
IF NOT bSwitchedToFranklin
IF GET_CURRENT_PLAYER_PED_ENUM() != CHAR_FRANKLIN
sSelectorPeds.pedID[SELECTOR_PED_TREVOR] = PLAYER_PED_ID()
MAKE_SELECTOR_PED_SELECTION(sSelectorPeds, SELECTOR_PED_FRANKLIN)
TAKE_CONTROL_OF_SELECTOR_PED(sSelectorPeds, TRUE, TRUE, TCF_CLEAR_TASK_INTERRUPT_CHECKS)
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
TASK_VEHICLE_DRIVE_TO_COORD(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], sTruck.vehFront, vDropOffPos, 35.0, DRIVINGSTYLE_NORMAL, modelTruckFront,
DF_DontSteerAroundPlayerPed | DF_UseShortCutLinks, 10.0, 20.0)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], TRUE)
ENDIF
IF DOES_ENTITY_EXIST(PLAYER_PED_ID())
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PLAYER_PED_ID(), TRUE)
CLEAR_PED_TASKS(PLAYER_PED_ID())
TASK_PLAY_ANIM(PLAYER_PED_ID(), strDriveOffTrailerAnims, "ig_10_switch_franklin", NORMAL_BLEND_IN, NORMAL_BLEND_IN, -1)
ENDIF
ENDIF
bSwitchedToFranklin = TRUE
ENDIF
ENDIF
IF NOT bFranklinSwitchAnimStarted
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
IF DOES_ENTITY_EXIST(PLAYER_PED_ID())
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PLAYER_PED_ID(), TRUE)
CLEAR_PED_TASKS(PLAYER_PED_ID())
TASK_PLAY_ANIM(PLAYER_PED_ID(), strDriveOffTrailerAnims, "ig_10_switch_franklin", NORMAL_BLEND_IN, NORMAL_BLEND_IN, -1, DEFAULT, fSwitchFrankAnimPhase)
bFranklinSwitchAnimStarted = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
IF NOT bCarWheelsSmokeStarted
IF fCamPhase > fCarWheelsSmokeStartPhase
CAR_WHEELS_SMOKE()
bCarWheelsSmokeStarted = TRUE
ENDIF
ENDIF
IF NOT bTrailerRampReleased
IF fCamPhase > fTrailerRampReleasedPhase
SET_TRAILER_GATE_DOWN()
ptfxSparksLeft = START_PARTICLE_FX_LOOPED_ON_ENTITY("scr_carsteal4_trailer_scrape", sTruck.vehBack, vSparksOffsetLeft, vSparksRotation )
ptfxSparksRight = START_PARTICLE_FX_LOOPED_ON_ENTITY("scr_carsteal4_trailer_scrape", sTruck.vehBack, vSparksOffsetRight, vSparksRotation )
bTrailerRampReleased = TRUE
ENDIF
ENDIF
IF NOT bCarForcedOnTrailerStarted
DETACH_CAR()
CAR_COLLISION_OFF()
bCarForcedOnTrailerStarted = TRUE
ENDIF
IF NOT bCarForcedOnTrailerStopped
IF bCarForcedOnTrailerStarted
IF fCamPhase > fCarStartedReversingPhase
bCarForcedOnTrailerStopped = TRUE
ELSE
UPDATE_CAR_FORCED_ON_TRAILER()
ENDIF
ENDIF
ENDIF
IF NOT bCarStartedReversing
IF fCamPhase > fCarStartedReversingPhase
CAR_COLLISION_ON()
CAR_REVERSE_OFF_TRAILER()
bCarStartedReversing = TRUE
ENDIF
ENDIF
IF NOT bCarHasTouchedDown
IF bCarStartedReversing
IF fCamPhase > fTouchdownSafetyPhase //saftey fix for bug# 1556193... if car hasn't touched down after regular period stop camera
RENDER_SCRIPT_CAMS(FALSE, TRUE, 2000, FALSE)
bPlayerControlGivenEarly = TRUE
eSwitchCamState = SWITCH_CAM_RETURN_TO_GAMEPLAY
CDEBUG3LN(DEBUG_MISSION, "eSwitchCamState = SWITCH_CAM_RETURN_TO_GAMEPLAY")
ENDIF
IF HAS_CAR_TOUCHED_DOWN(thisSwitchCam)
INIT_UPDATE_CAR_FOLLOW_INTERP_VARS(fCamPhase)
CAR_START_FOLLOWING()
bCarHasTouchedDown = TRUE
ELSE
UPDATE_REVERSE_OFF_TRAILER()
LIMIT_CAR_ROTATIONS()
ENDIF
ENDIF
ENDIF
IF bCarHasTouchedDown
AND NOT bPlayerControlGivenEarly
UPDATE_CAR_FOLLOW_TRUCK(fCamPhase)
//UPDATE_CAR_FOLLOWING()
ENDIF
IF iCurrentNode >= 3 //The cut node
//CDEBUG3LN(DEBUG_MISSION, "Setting gameplay cam heading/pitch")
SET_GAMEPLAY_CAM_RELATIVE_HEADING(fTruckToCarGPCamHeading)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(fTruckToCarGPCamPitch)
ENDIF
IF NOT bPlayerControlGivenEarly
IF bCarHasTouchedDown
AND fCamPhase > fPlayerControlGivenPhase
INT iLeftX, iLeftY, iRightX, iRightY
GET_CONTROL_VALUE_OF_ANALOGUE_STICKS(iLeftX, iLeftY, iRightX, iRightY)
IF iLeftX <> 0 OR iLeftY <> 0 OR iRightX <> 0 OR iRightY <> 0
OR IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_ACCELERATE)
OR IS_DISABLED_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_VEH_ACCELERATE)
OR IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_BRAKE)
OR IS_DISABLED_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_VEH_BRAKE)
IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_IN_VEHICLE) = CAM_VIEW_MODE_FIRST_PERSON
eSwitchCamState = SWITCH_CAM_FIRST_PERSON_PUSH
CDEBUG3LN(DEBUG_MISSION, "eSwitchCamState = SWITCH_CAM_FIRST_PERSON_PUSH")
ELSE
RENDER_SCRIPT_CAMS(FALSE, TRUE, 2000, FALSE)
eSwitchCamState = SWITCH_CAM_RETURN_TO_GAMEPLAY
CDEBUG3LN(DEBUG_MISSION, "eSwitchCamState = SWITCH_CAM_RETURN_TO_GAMEPLAY")
ENDIF
bPlayerControlGivenEarly = TRUE
ENDIF
ENDIF
ENDIF
#IF IS_DEBUG_BUILD
DRAW_DEBUG_TEXT_2D(GET_STRING_FROM_FLOAT(fCamPhase), << 0.1, 0.35, 0.0 >>)
#ENDIF
IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_IN_VEHICLE) = CAM_VIEW_MODE_FIRST_PERSON
IF fCamPhase >= fPushInStartPhase
eSwitchCamState = SWITCH_CAM_FIRST_PERSON_PUSH
ENDIF
ELSE
IF fCamPhase >= 1.0
eSwitchCamState = SWITCH_CAM_RETURN_TO_GAMEPLAY
ENDIF
ENDIF
ENDIF
BREAK
CASE SWITCH_CAM_FIRST_PERSON_PUSH
#IF IS_DEBUG_BUILD
DRAW_DEBUG_TEXT_2D("SWITCH_CAM_FIRST_PERSON_PUSH", << 0.1, 0.3, 0.0 >>)
#ENDIF
IF HANDLE_PUSH_IN(sPushInData, bPushInAttached, DEFAULT, DEFAULT, bPushInAttachStartCam, bPushInDoColourFlash)
eSwitchCamState = SWITCH_CAM_RETURN_TO_GAMEPLAY
ENDIF
BREAK
CASE SWITCH_CAM_RETURN_TO_GAMEPLAY
#IF IS_DEBUG_BUILD
DRAW_DEBUG_TEXT_2D("SWITCH_CAM_RETURN_TO_GAMEPLAY", << 0.1, 0.3, 0.0 >>)
#ENDIF
CDEBUG3LN(DEBUG_MISSION, "eSwitchCamState = SWITCH_CAM_RETURN_TO_GAMEPLAY")
SET_TIME_SCALE(1.0)
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", FALSE)
IF NOT bPlayerControlGivenEarly
IF DOES_CAM_EXIST(thisSwitchCam.ciSpline)
IF IS_CAM_ACTIVE(thisSwitchCam.ciSpline)
DESTROY_CAM(thisSwitchCam.ciSpline)
ENDIF
ENDIF
DESTROY_ALL_CAMS()
RENDER_SCRIPT_CAMS(FALSE, FALSE)
ENDIF
IF DOES_ENTITY_EXIST(PLAYER_PED_ID())
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
CLEAR_PED_TASKS(PLAYER_PED_ID())
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PLAYER_PED_ID(), FALSE)
ENDIF
ENDIF
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
DISPLAY_HUD(TRUE)
DISPLAY_RADAR(TRUE)
SET_WIDESCREEN_BORDERS(FALSE, 500)
REMOVE_ANIM_DICT(strDriveOffTrailerAnims)
REMOVE_ANIM_DICT(strCamShakeAnims)
eSwitchCamState = SWITCH_CAM_IDLE
CDEBUG3LN(DEBUG_MISSION, "eSwitchCamState = SWITCH_CAM_IDLE")
RETURN TRUE
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
//============================== END OF SWITCH CAM ===================================================================================
#IF IS_DEBUG_BUILD
WIDGET_GROUP_ID widgetDebug
TEXT_WIDGET_ID widgetPtfx
BOOL bDebugTestTruckAnims = FALSE
BOOL bDebugRecordTruckAndTrailerForMocap = FALSE
BOOL bDebugPlaybackTruckTrailerForMocap = FALSE
BOOL bDebugPrintTruckAndTrailerPos = FALSE
BOOL bDebugUpdateVehLODs = FALSE
CONST_INT MAX_SKIP_MENU_LENGTH 8
INT iDebugJumpStage = 0
INT iDebugLODDist = 100
MissionStageMenuTextStruct sSkipMenu[MAX_SKIP_MENU_LENGTH]
FLOAT fDebugLODMultiplier = 0.0
PROC CREATE_WIDGETS()
widgetDebug = START_WIDGET_GROUP("Car Steal 5")
ADD_WIDGET_BOOL("Test Truck Anims", bDebugTestTruckAnims)
ADD_WIDGET_INT_SLIDER("iNumChaseCopCarsCreated", iNumChaseCopCarsCreated, 0, 100, 1)
ADD_WIDGET_INT_SLIDER("iCopsTrashEvent", iCopsTrashEvent, 0, 100, 1)
ADD_WIDGET_BOOL("Record truck and trailer for mocap", bDebugRecordTruckAndTrailerForMocap)
ADD_WIDGET_BOOL("Playback truck and trailer for mocap", bDebugPlaybackTruckTrailerForMocap)
ADD_WIDGET_BOOL("Print truck and trailer pos", bDebugPrintTruckAndTrailerPos)
START_WIDGET_GROUP("Debug output")
ADD_WIDGET_INT_READ_ONLY("Trevor drive event", iTrevorDriveEvent)
STOP_WIDGET_GROUP()
START_WIDGET_GROUP("Vehicle LODs")
ADD_WIDGET_BOOL("Update LODs", bDebugUpdateVehLODs)
ADD_WIDGET_FLOAT_SLIDER("LOD multiplier", fDebugLODMultiplier, 0.0, 10.0, 0.1)
ADD_WIDGET_INT_SLIDER("LOD distance", iDebugLODDist, 0, 500, 1)
STOP_WIDGET_GROUP()
ADD_WIDGET_VECTOR_SLIDER("vSparksOffsetLeft", vSparksOffsetLeft, -100.0, 100.0, 0.1)
ADD_WIDGET_VECTOR_SLIDER("vSparksOffsetRight", vSparksOffsetRight, -100.0, 100.0, 0.1)
ADD_WIDGET_VECTOR_SLIDER("vSparksRotation", vSparksRotation, -360.0, 360.0, 1.0)
ADD_WIDGET_VECTOR_SLIDER("vSparksLightOffset", vSparksLightOffset, -10.0, 10.0, 0.1)
ADD_WIDGET_VECTOR_SLIDER("LightColour", vSparksLightColour, 0, 255, 1)
ADD_WIDGET_VECTOR_SLIDER("LightRange", vSparksLightRange, 0, 10, 0.1)
START_WIDGET_GROUP("Push in")
ADD_WIDGET_BOOL("bPushInAttached", bPushInAttached)
ADD_WIDGET_BOOL("bPushInAttachStartCam", bPushInAttachStartCam)
ADD_WIDGET_FLOAT_SLIDER("fPushInStartPhase", fPushInStartPhase, 0.0, 1.0, 0.1)
ADD_WIDGET_FLOAT_SLIDER("fPushInDistance", fPushInStartDistance, 0.0, 10.0, 1.0)
ADD_WIDGET_INT_SLIDER("iPushInInterpTime", iPushInInterpTime, 0, 10000, 100)
ADD_WIDGET_INT_SLIDER("iPushInCutTime", iPushInCutTime, 0, 10000, 100)
ADD_WIDGET_INT_SLIDER("iPushInFXTime", iPushInFXTime, 0, 10000, 100)
ADD_WIDGET_INT_SLIDER("iPushInSpeedUpTime", iPushInSpeedUpTime, 0, 10000, 100)
ADD_WIDGET_FLOAT_SLIDER("fPushInSpeedUpProportion", fPushInSpeedUpProportion, 0.0, 1.0, 0.1)
ADD_WIDGET_BOOL("bPushInDoColourFlash", bPushInDoColourFlash)
STOP_WIDGET_GROUP()
STOP_WIDGET_GROUP()
SET_LOCATES_HEADER_WIDGET_GROUP(widgetDebug)
SET_UBER_PARENT_WIDGET_GROUP(widgetDebug)
SETUP_SPLINE_CAM_NODE_ARRAY_TRUCK_TO_CAR(scsTruckToCar, sStolenCars[iChosenCar].veh, sStolenCars[iChosenCar].veh)
CREATE_SPLINE_CAM_WIDGETS(scsTruckToCar, "Trevor", "JB700", widgetDebug)
ENDPROC
PROC DESTROY_WIDGETS()
IF DOES_TEXT_WIDGET_EXIST(widgetPtfx)
DELETE_TEXT_WIDGET(widgetPtfx)
ENDIF
IF DOES_WIDGET_GROUP_EXIST(widgetDebug)
DELETE_WIDGET_GROUP(widgetDebug)
ENDIF
ENDPROC
FUNC STRING GET_COP_STATE_NAME_FOR_DEBUG(INT iState)
SWITCH iState
CASE COP_STATE_IDLE
RETURN "COP_STATE_IDLE"
BREAK
CASE COP_STATE_ESCORT_TRUCK
RETURN "COP_STATE_ESCORT_TRUCK"
BREAK
CASE COP_STATE_CHASE_TRUCK_DRIVER
RETURN "COP_STATE_CHASE_TRUCK_DRIVER"
BREAK
CASE COP_STATE_CHASE_TRUCK_PASSENGER
RETURN "COP_STATE_CHASE_TRUCK_PASSENGER"
BREAK
CASE COP_STATE_PASSENGER_DRIVE_BY
RETURN "COP_STATE_PASSENGER_DRIVE_BY"
BREAK
CASE COP_STATE_COMBAT_ON_FOOT
RETURN "COP_STATE_COMBAT_ON_FOOT"
BREAK
CASE COP_STATE_ENTER_COP_CAR
RETURN "COP_STATE_ENTER_COP_CAR"
BREAK
DEFAULT
RETURN "COP_STATE_INVALID"
BREAK
ENDSWITCH
RETURN "COP_STATE_INVALID"
ENDFUNC
#ENDIF
FUNC BOOL HAS_LABEL_BEEN_TRIGGERED(STRING strLabel)
INT iHash = GET_HASH_KEY(strLabel)
INT iNumHashes = COUNT_OF(iTriggeredTextHashes)
INT i = 0
REPEAT iNumHashes i
IF iTriggeredTextHashes[i] = iHash
RETURN TRUE
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
PROC SET_LABEL_AS_TRIGGERED(STRING strLabel, BOOL bIsTriggered)
INT iHash = GET_HASH_KEY(strLabel)
INT iNumHashes = COUNT_OF(iTriggeredTextHashes)
INT i = 0
BOOL bQuitLoop = FALSE
WHILE i < iNumHashes AND NOT bQuitLoop
IF bIsTriggered
IF iTriggeredTextHashes[i] = 0
iTriggeredTextHashes[i] = iHash
bQuitLoop = TRUE
#IF IS_DEBUG_BUILD
PRINTLN(GET_THIS_SCRIPT_NAME(), ": SET_LABEL_AS_TRIGGERED(): ", strLabel, " TRUE.")
#ENDIF
ENDIF
ELSE
IF iTriggeredTextHashes[i] = iHash
iTriggeredTextHashes[i] = 0
bQuitLoop = TRUE
#IF IS_DEBUG_BUILD
PRINTLN(GET_THIS_SCRIPT_NAME(), ": SET_LABEL_AS_TRIGGERED(): ", strLabel, " FALSE.")
#ENDIF
ENDIF
ENDIF
i++
ENDWHILE
ENDPROC
PROC CLEAR_TRIGGERED_LABELS()
INT iNumHashes = COUNT_OF(iTriggeredTextHashes)
INT i = 0
REPEAT iNumHashes i
iTriggeredTextHashes[i] = 0
ENDREPEAT
ENDPROC
PROC REMOVE_OBJECT(OBJECT_INDEX &obj, BOOL bForceDelete = FALSE)
IF DOES_ENTITY_EXIST(obj)
IF IS_ENTITY_ATTACHED(obj)
DETACH_ENTITY(obj)
ENDIF
IF bForceDelete
DELETE_OBJECT(obj)
ELSE
SET_OBJECT_AS_NO_LONGER_NEEDED(obj)
ENDIF
ENDIF
ENDPROC
PROC REMOVE_VEHICLE(VEHICLE_INDEX &veh, BOOL bForceDelete = FALSE, BOOL bDoDetach = TRUE)
IF DOES_ENTITY_EXIST(veh)
IF bDoDetach
IF NOT IS_ENTITY_DEAD(veh)
IF IS_ENTITY_ATTACHED(veh)
DETACH_ENTITY(veh)
ENDIF
ENDIF
ENDIF
IF bForceDelete
DELETE_VEHICLE(veh)
ELSE
SET_VEHICLE_AS_NO_LONGER_NEEDED(veh)
ENDIF
ENDIF
ENDPROC
PROC REMOVE_PED(PED_INDEX &ped, BOOL bForceDelete = FALSE, BOOL bKeepTask = FALSE)
IF DOES_ENTITY_EXIST(ped)
IF NOT IS_PED_INJURED(ped)
IF NOT IS_PED_IN_ANY_VEHICLE(ped)
AND NOT IS_PED_GETTING_INTO_A_VEHICLE(ped)
IF IS_ENTITY_ATTACHED_TO_ANY_OBJECT(ped)
OR IS_ENTITY_ATTACHED_TO_ANY_PED(ped)
OR IS_ENTITY_ATTACHED_TO_ANY_VEHICLE(ped)
IF NOT IS_ENTITY_PLAYING_ANIM(ped, strTruckSitAnims, "sit")
AND NOT IS_ENTITY_PLAYING_ANIM(ped, strTruckSitAnims, "die")
DETACH_ENTITY(ped)
ENDIF
ENDIF
FREEZE_ENTITY_POSITION(ped, FALSE)
ENDIF
IF NOT IS_PED_IN_ANY_VEHICLE(ped)
SET_ENTITY_COLLISION(ped, TRUE)
ENDIF
STOP_PED_SPEAKING(ped, FALSE) //added this cleanup, beacause I'm setting franklin to stop speaking when he is asleep
CLEAR_FACIAL_IDLE_ANIM_OVERRIDE(ped)
IF bKeepTask
SET_PED_KEEP_TASK(ped, bKeepTask)
ENDIF
ENDIF
IF bForceDelete
DELETE_PED(ped)
ELSE
SET_PED_AS_NO_LONGER_NEEDED(ped)
ENDIF
ENDIF
ENDPROC
PROC SET_TIME_IN_PLAYBACK_RECORDED_VEHICLE(VEHICLE_INDEX &veh, FLOAT fTime)
IF NOT IS_ENTITY_DEAD(veh)
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(veh)
SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(veh, fTime - GET_TIME_POSITION_IN_RECORDING(veh))
ENDIF
ENDIF
ENDPROC
FUNC FLOAT GET_SCALAR_VELOCITY(VECTOR vVel, BOOL bUseSquareRoot = TRUE)
FLOAT fVel = (vVel.x * vVel.x) + (vVel.y * vVel.y) + (vVel.z * vVel.z)
IF bUseSquareRoot
RETURN SQRT(fVel)
ELSE
RETURN fVel
ENDIF
ENDFUNC
/// PURPOSE:
/// Converges a value towards a given destination, by adding/removing a given amount.
PROC CONVERGE_VALUE(FLOAT &val, FLOAT desiredVal, FLOAT amountToConverge, BOOL adjustForFramerate = FALSE)
IF val != desiredVal
FLOAT convergeAmountThisFrame = amountToConverge
IF adjustForFramerate
convergeAmountThisFrame = 0.0 +@ (amountToConverge * 30.0)
ENDIF
IF val - desiredVal > convergeAmountThisFrame
val -= convergeAmountThisFrame
ELIF val - desiredVal < -convergeAmountThisFrame
val += convergeAmountThisFrame
ELSE
val = desiredVal
ENDIF
ENDIF
ENDPROC
PROC CONVERGE_VALUE_WITH_DECEL(FLOAT &val, FLOAT desiredVal, FLOAT maxVal, FLOAT minAmountToConverge, FLOAT maxAmountToConverge, FLOAT decelRange = 1.0)
IF val != desiredVal
FLOAT valDiff = ABSF(val - desiredVal) / maxVal
FLOAT newConvergeValue = maxAmountToConverge
IF valDiff < decelRange
newConvergeValue = (valDiff / decelRange) * maxAmountToConverge
ENDIF
IF newConvergeValue < minAmountToConverge
newConvergeValue = minAmountToConverge
ENDIF
CONVERGE_VALUE(val, desiredVal, newConvergeValue)
ENDIF
ENDPROC
/// PURPOSE:
/// Converts a rotation vector into a normalised direction vector (basically the direction an entity would move if it moved forward at the current rotation).
/// For example: a rotation of <<0.0, 0.0, 45.0>> gives a direction vector of <<-0.707107, 0.707107, 0.0>>
/// PARAMS:
/// vRot - The rotation vector
/// RETURNS:
/// The direction vector
FUNC VECTOR CONVERT_ROTATION_TO_DIRECTION_VECTOR(VECTOR vRot)
RETURN <<-SIN(vRot.z) * COS(vRot.x), COS(vRot.z) * COS(vRot.x), SIN(vRot.x)>>
ENDFUNC
PROC DO_FADE_OUT_WITH_WAIT(BOOL bHideHud = FALSE)
IF NOT IS_SCREEN_FADED_OUT()
IF NOT IS_SCREEN_FADING_OUT()
DO_SCREEN_FADE_OUT(DEFAULT_FADE_TIME)
ENDIF
WHILE NOT IS_SCREEN_FADED_OUT()
IF bHideHud
HIDE_HUD_AND_RADAR_THIS_FRAME()
ENDIF
WAIT(0)
ENDWHILE
ENDIF
ENDPROC
PROC DO_FADE_IN_WITH_WAIT()
IF NOT IS_SCREEN_FADED_IN()
IF NOT IS_SCREEN_FADING_IN()
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
ENDIF
WHILE NOT IS_SCREEN_FADED_IN()
WAIT(0)
ENDWHILE
ENDIF
ENDPROC
PROC REMOVE_ALL_BLIPS()
IF DOES_BLIP_EXIST(blipCurrentDestination)
REMOVE_BLIP(blipCurrentDestination)
ENDIF
INT i = 0
REPEAT COUNT_OF(sStolenCars) i
IF DOES_BLIP_EXIST(sStolenCars[i].blip)
REMOVE_BLIP(sStolenCars[i].blip)
ENDIF
ENDREPEAT
IF DOES_BLIP_EXIST(sTruck.blip)
REMOVE_BLIP(sTruck.blip)
ENDIF
IF DOES_BLIP_EXIST(blipBuddy)
REMOVE_BLIP(blipBuddy)
ENDIF
IF DOES_BLIP_EXIST(sLamar.blip)
REMOVE_BLIP(sLamar.blip)
ENDIF
ENDPROC
PROC BLOCK_SCENARIOS_FOR_CHASE(BOOL bBlock)
INT i = 0
IF bBlock
IF sbiChase[0] = NULL
sbiChase[0] = ADD_SCENARIO_BLOCKING_AREA(<<-2257.8120, 4221.4644, 0.1865>>, <<-2119.2112, 4336.6172, 54.1865>>)
ENDIF
IF sbiChase[1] = NULL
sbiChase[1] = ADD_SCENARIO_BLOCKING_AREA(<<-470.8388, 5992.0698, 0.8099>>, <<-412.9256, 6094.3013, 38.3099>>)
ENDIF
IF sbiChase[2] = NULL
sbiChase[2] = ADD_SCENARIO_BLOCKING_AREA(<<-107.0392, 6259.4038, 0.2007>>, <<-94.945625,6268.517578, 38.3446>>)
ENDIF
IF sbiChase[3] = NULL
sbiChase[3] = ADD_SCENARIO_BLOCKING_AREA(<<1547.0812, 6406.1392, 0.7764>>, <<1650.0532, 6498.2285, 40.7764>>)
ENDIF
IF sbiChase[4] = NULL
sbiChase[4] = ADD_SCENARIO_BLOCKING_AREA(<<-38.985653,6296.901855, 0.2007>>, <<-25.408390,6308.042969, 38.3446>>)
ENDIF
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<1547.0812, 6406.1392, 0.7764>>, <<1650.0532, 6498.2285, 60.7764>>, FALSE)
SET_SCENARIO_TYPE_ENABLED("WORLD_VEHICLE_POLICE_BIKE", FALSE)
SET_SCENARIO_TYPE_ENABLED("WORLD_VEHICLE_POLICE_CAR", FALSE)
SET_SCENARIO_TYPE_ENABLED("WORLD_VEHICLE_POLICE_NEXT_TO_CAR", FALSE)
ELSE
REPEAT COUNT_OF(sbiChase) i
IF sbiChase[i] != NULL
REMOVE_SCENARIO_BLOCKING_AREA(sbiChase[i])
sbiChase[i] = NULL
ENDIF
ENDREPEAT
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<1547.0812, 6406.1392, 0.7764>>, <<1650.0532, 6498.2285, 60.7764>>, TRUE)
SET_SCENARIO_TYPE_ENABLED("WORLD_VEHICLE_POLICE_BIKE", TRUE)
SET_SCENARIO_TYPE_ENABLED("WORLD_VEHICLE_POLICE_CAR", TRUE)
SET_SCENARIO_TYPE_ENABLED("WORLD_VEHICLE_POLICE_NEXT_TO_CAR", TRUE)
ENDIF
ENDPROC
PROC CALCULATE_PATH_NODES_AREA_FOR_POS(VECTOR vPos)
vPathNodesMinPos = <<0.0, 0.0, 0.0>>
vPathNodesMaxPos = <<0.0, 0.0, 0.0>>
IF vPos.x < vDropOffPos.x
vPathNodesMinPos.x = vPos.x
vPathNodesMaxPos.x = vDropOffPos.x
ELSE
vPathNodesMinPos.x = vDropOffPos.x
vPathNodesMaxPos.x = vPos.x
ENDIF
IF vPos.y < vDropOffPos.y
vPathNodesMinPos.y = vPos.y
vPathNodesMaxPos.y = vDropOffPos.y
ELSE
vPathNodesMinPos.y = vDropOffPos.y
vPathNodesMaxPos.y = vPos.y
ENDIF
IF vPos.z < vDropOffPos.z
vPathNodesMinPos.z = vPos.z
vPathNodesMaxPos.z = vDropOffPos.z
ELSE
vPathNodesMinPos.z = vDropOffPos.z
vPathNodesMaxPos.z = vPos.z
ENDIF
vPathNodesMinPos = vPathNodesMinPos - <<200.0, 200.0, 200.0>>
vPathNodesMaxPos = vPathNodesMaxPos + <<200.0, 200.0, 200.0>>
ENDPROC
///Gets the ped index for a given player ped character, if the character is the player it returns PLAYER_PED_ID(), otherwise it returns the relevant selector ped.
FUNC PED_INDEX GET_PED_INDEX(enumCharacterList eChar)
IF GET_CURRENT_PLAYER_PED_ENUM() = eChar
RETURN PLAYER_PED_ID()
ELSE
RETURN sSelectorPeds.pedID[GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(eChar)]
ENDIF
ENDFUNC
///Checks the three player chars and makes sure they're assigned the correct speakers in dialogue. This is useful for when switches occur, as these
///make current speaker peds invalid.
PROC REASSIGN_PLAYER_CHAR_DIALOGUE_SPEAKERS()
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_MICHAEL])
IF sConversationPeds.PedInfo[0].Index != sSelectorPeds.pedID[SELECTOR_PED_MICHAEL]
ADD_PED_FOR_DIALOGUE(sConversationPeds, 0, sSelectorPeds.pedID[SELECTOR_PED_MICHAEL], "MICHAEL")
ENDIF
ENDIF
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
IF sConversationPeds.PedInfo[1].Index != sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN]
ADD_PED_FOR_DIALOGUE(sConversationPeds, 1, sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], "FRANKLIN")
ENDIF
ENDIF
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
IF sConversationPeds.PedInfo[2].Index != sSelectorPeds.pedID[SELECTOR_PED_TREVOR]
ADD_PED_FOR_DIALOGUE(sConversationPeds, 2, sSelectorPeds.pedID[SELECTOR_PED_TREVOR], "TREVOR")
ENDIF
ENDIF
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL
IF sConversationPeds.PedInfo[0].Index != PLAYER_PED_ID()
ADD_PED_FOR_DIALOGUE(sConversationPeds, 0, PLAYER_PED_ID(), "MICHAEL")
ENDIF
ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
IF sConversationPeds.PedInfo[1].Index != PLAYER_PED_ID()
ADD_PED_FOR_DIALOGUE(sConversationPeds, 1, PLAYER_PED_ID(), "FRANKLIN")
ENDIF
ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_TREVOR
IF sConversationPeds.PedInfo[2].Index != PLAYER_PED_ID()
ADD_PED_FOR_DIALOGUE(sConversationPeds, 2, PLAYER_PED_ID(), "TREVOR")
ENDIF
ENDIF
ENDPROC
FUNC PED_INDEX CREATE_MISSION_PED(MODEL_NAMES model, VECTOR vPos, FLOAT fHeading, REL_GROUP_HASH group,
INT iHealth = 200, INT iArmour = 0, WEAPON_TYPE weapon = WEAPONTYPE_UNARMED, BOOL bIsEnemy = TRUE)
PED_INDEX ped = CREATE_PED(PEDTYPE_MISSION, model, vPos, fHeading)
GIVE_WEAPON_TO_PED(ped, weapon, 100, TRUE)
SET_PED_INFINITE_AMMO(ped, TRUE, weapon)
SET_PED_MAX_HEALTH(ped, iHealth)
SET_ENTITY_HEALTH(ped, iHealth)
ADD_ARMOUR_TO_PED(ped, iArmour)
SET_PED_DIES_WHEN_INJURED(ped, TRUE)
SET_PED_RELATIONSHIP_GROUP_HASH(ped, group)
SET_PED_AS_ENEMY(ped, bIsEnemy)
RETURN ped
ENDFUNC
FUNC INT GET_TRAFFIC_AND_PLAYER_VEHICLE_SEARCH_FLAGS()
RETURN (VEHICLE_SEARCH_FLAG_ALLOW_VEHICLE_OCCUPANTS_TO_BE_PERFORMING_A_SCRIPTED_TASK |
VEHICLE_SEARCH_FLAG_RETURN_MISSION_VEHICLES |
VEHICLE_SEARCH_FLAG_RETURN_RANDOM_VEHICLES |
VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_CONTAINING_A_PLAYER |
VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_CONTAINING_GROUP_MEMBERS |
VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_CONTAINING_A_DEAD_OR_DYING_PED)
ENDFUNC
PROC UPDATE_GAS_STATION_CUSTOM_GPS_ROUTE(BOOL bRouteShouldBeActive)
IF bRouteShouldBeActive
IF NOT bDontUseCustomGPS
INT i = 0
INT iClosestNode = -1
FLOAT fClosestDist = 0.0
VECTOR vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID())
VECTOR vIntermediatePos[12]
vIntermediatePos[0] = <<536.0454, -1421.6314, 28.3560>>
vIntermediatePos[1] = <<473.5091, -1420.0912, 28.3430>>
vIntermediatePos[2] = <<353.3233, -1335.3615, 31.5383>>
vIntermediatePos[3] = <<-2225.3345, -338.3899, 12.4178>>
vIntermediatePos[4] = <<-2726.1013, 2263.6096, 19.3537>>
vIntermediatePos[5] = <<-2694.3357, 2351.5085, 15.9009>>
vIntermediatePos[6] = <<-2654.2808, 2614.4666, 15.6938>>
vIntermediatePos[7] = <<-2585.6885, 3168.4050, 13.2889>>
vIntermediatePos[8] = <<-2567.3921, 3336.4500, 12.5477>>
vIntermediatePos[9] = <<-2028.6205, 4484.0723, 56.0054>>
vIntermediatePos[10] = <<-735.6742, 5510.3154, 34.9960>>
vIntermediatePos[11] = vDropOffPos
//Get the closest node to the player
REPEAT (COUNT_OF(vIntermediatePos) - 1) i
FLOAT fDist = VDIST2(vPlayerPos, vIntermediatePos[i])
IF iClosestNode = -1 OR fDist < fClosestDist
iClosestNode = i
fClosestDist = fDist
ENDIF
ENDREPEAT
//If the closest node is closer to the next node than the player then it's the first node in the route, otherwise it's the next node.
IF VDIST2(vPlayerPos, vIntermediatePos[iClosestNode+1]) < VDIST2(vIntermediatePos[iClosestNode], vIntermediatePos[iClosestNode+1])
iClosestNode = iClosestNode + 1
ENDIF
IF iClosestNode != iPrevClosestNode
AND (fClosestDist > 20000.0 OR iPrevClosestNode = -1)
IF NOT ARE_VECTORS_ALMOST_EQUAL(vDropOffPos, vIntermediatePos[iClosestNode])
SET_BLIP_ALPHA(sLocatesData.LocationBlip, 255) //Blip needs to be brought back in case it was hidden due to trailer detaching.
SET_BLIP_ROUTE(sLocatesData.GPSBlipID, FALSE)
//Build the route starting from the node calculated above.
CLEAR_GPS_MULTI_ROUTE()
START_GPS_MULTI_ROUTE(HUD_COLOUR_OBJECTIVE_ROUTE)
i = iClosestNode
WHILE i < COUNT_OF(vIntermediatePos) - 1
ADD_POINT_TO_GPS_MULTI_ROUTE(vIntermediatePos[i])
i++
ENDWHILE
ADD_POINT_TO_GPS_MULTI_ROUTE(vDropOffPos)
SET_GPS_MULTI_ROUTE_RENDER(TRUE)
bCustomGPSActive = TRUE
ELIF bCustomGPSActive
//If the drop off point is the closest point then we don't need to do the route any more.
SET_GPS_MULTI_ROUTE_RENDER(FALSE)
CLEAR_GPS_MULTI_ROUTE()
bCustomGPSActive = FALSE
ENDIF
ENDIF
VECTOR vAlternateRouteStartPos = <<1618.82, 1168.37, 85.0>>
IF VDIST2(vAlternateRouteStartPos, vPlayerPos) < fClosestDist
IF bCustomGPSActive
SET_GPS_MULTI_ROUTE_RENDER(FALSE)
CLEAR_GPS_MULTI_ROUTE()
bCustomGPSActive = FALSE
ENDIF
//revert to using standard GPS route from locates header, display blip and route
IF DOES_BLIP_EXIST(sLocatesData.LocationBlip)
SET_BLIP_ALPHA(sLocatesData.LocationBlip, 255)
SET_BLIP_ROUTE(sLocatesData.GPSBlipID, TRUE)
ENDIF
bDontUseCustomGPS = TRUE
ENDIF
iPrevClosestNode = iClosestNode
ENDIF
ELSE
IF DOES_BLIP_EXIST(sLocatesData.LocationBlip)
SET_BLIP_ALPHA(sLocatesData.LocationBlip, 0) //Blip needs to be hidden if trailer is detached, as locates will still be active.
SET_BLIP_ROUTE(sLocatesData.GPSBlipID, FALSE)
ENDIF
IF bCustomGPSActive
SET_GPS_MULTI_ROUTE_RENDER(FALSE)
CLEAR_GPS_MULTI_ROUTE()
bCustomGPSActive = FALSE
ENDIF
iPrevClosestNode = -1
bDontUseCustomGPS = FALSE //make sure to reset this flag so the route can be calculated again when trailer is hooked back again
ENDIF
ENDPROC
PROC UPDATE_LAMAR_TRUCK_ANIMS()
IF NOT IS_PED_INJURED(sLamar.ped)
AND NOT IS_ENTITY_DEAD(sTruck.vehFront)
REQUEST_ANIM_DICT(strTruckSitAnims)
IF NOT IS_ENTITY_ATTACHED_TO_ENTITY(sLamar.ped, sTruck.vehFront)
ATTACH_ENTITY_TO_ENTITY(sLamar.ped, sTruck.vehFront, 0, <<0.0, 1.5, 0.85>>, <<0.0, 0.0, 0.0>>)
ENDIF
IF HAS_ANIM_DICT_LOADED(strTruckSitAnims)
IF NOT IS_ENTITY_PLAYING_ANIM(sLamar.ped, strTruckSitAnims, "sit")
TASK_PLAY_ANIM(sLamar.ped, strTruckSitAnims, "sit", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING | AF_NOT_INTERRUPTABLE)
SET_PED_SUFFERS_CRITICAL_HITS(sLamar.ped, FALSE)
SET_PED_CAN_RAGDOLL(sLamar.ped, FALSE)
SET_PED_CONFIG_FLAG(sLamar.ped, PCF_RunFromFiresAndExplosions, FALSE)
SET_PED_CONFIG_FLAG(sLamar.ped, PCF_DisableExplosionReactions, TRUE)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sLamar.ped, TRUE) //block non-temp events, see B*1460213
SET_PED_KEEP_TASK(sLamar.ped, TRUE)
ENDIF
IF GET_ENTITY_HEALTH(sLamar.ped) < 150.0
TASK_PLAY_ANIM(sLamar.ped, strTruckSitAnims, "die", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_HOLD_LAST_FRAME | AF_NOT_INTERRUPTABLE)
SET_ENTITY_HEALTH(sLamar.ped, 0)
ENDIF
ENDIF
ENDIF
ENDPROC
PROC UPDATE_FRANKLINS_TRUCK_ANIMS()
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
AND NOT IS_ENTITY_DEAD(sTruck.vehFront)
FLOAT fTruckSpeed = GET_ENTITY_SPEED(sTruck.vehFront)
INT iLeftX = GET_CONTROL_VALUE(PLAYER_CONTROL, INPUT_MOVE_LR) - 128
IF GET_GAME_TIMER() - iTruckBrakeTimer > 5000
IF (fPrevTruckSpeed - fTruckSpeed > 0.2 AND IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_BRAKE) AND eTruckAnimStage = TRUCK_IDLE)
OR fPrevTruckSpeed - fTruckSpeed > 2.0 //Sudden change e.g. crashing
eTruckAnimStage = TRUCK_DECEL
bTruckAnimIsUpToDate = FALSE
iTruckBrakeTimer = GET_GAME_TIMER()
ENDIF
ENDIF
//Truck is accelerating
IF GET_GAME_TIMER() - iTruckAccelTimer > 5000
IF fTruckSpeed - fPrevTruckSpeed > 0.1 AND eTruckAnimStage = TRUCK_IDLE AND ABSI(iLeftX) < 40
eTruckAnimStage = TRUCK_ACCEL
bTruckAnimIsUpToDate = FALSE
iTruckAccelTimer = GET_GAME_TIMER()
ENDIF
ENDIF
fPrevTruckSpeed = fTruckSpeed
//Turn anims: activate intros if the player presses left/right for a bit.
IF fTruckSpeed > 2.0
IF iLeftX < -40
IF GET_GAME_TIMER() - iTruckRightTurnTimer > 400
AND eTruckAnimStage = TRUCK_IDLE
eTruckAnimStage = TRUCK_RIGHT_INTRO
bTruckAnimIsUpToDate = FALSE
ENDIF
ELSE
iTruckRightTurnTimer = GET_GAME_TIMER()
ENDIF
IF iLeftX > 40
IF GET_GAME_TIMER() - iTruckLeftTurnTimer > 400
AND eTruckAnimStage = TRUCK_IDLE
eTruckAnimStage = TRUCK_LEFT_INTRO
bTruckAnimIsUpToDate = FALSE
ENDIF
ELSE
iTruckLeftTurnTimer = GET_GAME_TIMER()
ENDIF
ELSE
iTruckRightTurnTimer = GET_GAME_TIMER()
iTruckLeftTurnTimer = GET_GAME_TIMER()
ENDIF
//Stop leaning if the player stops pressing left/right
IF eTruckAnimStage = TRUCK_LEFT
IF GET_GAME_TIMER() - iTruckLeftTurnTimer < 400
eTruckAnimStage = TRUCK_LEFT_OUTRO
bTruckAnimIsUpToDate = FALSE
ENDIF
ENDIF
IF eTruckAnimStage = TRUCK_RIGHT
IF GET_GAME_TIMER() - iTruckRightTurnTimer < 400
eTruckAnimStage = TRUCK_RIGHT_OUTRO
bTruckAnimIsUpToDate = FALSE
ENDIF
ENDIF
#IF IS_DEBUG_BUILD
IF bDebugTestTruckAnims
IF IS_BUTTON_JUST_PRESSED(PAD1, SQUARE)
INT iTruckAnimStage = ENUM_TO_INT(eTruckAnimStage) + 1
IF iTruckAnimStage > ENUM_TO_INT(TRUCK_RIGHT_OUTRO)
iTruckAnimStage = 0
ENDIF
eTruckAnimStage = INT_TO_ENUM(FRANKLIN_TRUCK_ANIM_STAGE, iTruckAnimStage)
bTruckAnimIsUpToDate = FALSE
ENDIF
TEXT_LABEL strAnim = ""
strAnim += ENUM_TO_INT(eTruckAnimStage)
//SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
DRAW_DEBUG_TEXT(strAnim, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(PLAYER_PED_ID(), <<0.0, 0.0, 3.0>>))
ENDIF
#ENDIF
//Make sure Franklin is detaches from anything before switching anims.
IF NOT bTruckAnimIsUpToDate
IF IS_ENTITY_ATTACHED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
CLEAR_PED_TASKS_IMMEDIATELY(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
DETACH_ENTITY(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
ENDIF
ENDIF
SWITCH eTruckAnimStage
CASE TRUCK_IDLE
IF NOT bTruckAnimIsUpToDate
iSyncSceneOnTruck = CREATE_SYNCHRONIZED_SCENE(<<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSyncSceneOnTruck, sTruck.vehBack, 0)
TASK_SYNCHRONIZED_SCENE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], iSyncSceneOnTruck, strTruckIdleAnims, "crouchloop", NORMAL_BLEND_IN, NORMAL_BLEND_OUT,
SYNCED_SCENE_USE_PHYSICS | SYNCED_SCENE_DONT_INTERRUPT | SYNCED_SCENE_ON_ABORT_STOP_SCENE,
RBF_BULLET_IMPACT | RBF_VEHICLE_IMPACT | RBF_PLAYER_IMPACT | RBF_EXPLOSION | RBF_WATER_JET | RBF_FALLING | RBF_IMPACT_OBJECT | RBF_PLAYER_BUMP)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneOnTruck, TRUE)
bTruckAnimIsUpToDate = TRUE
ENDIF
BREAK
CASE TRUCK_ACCEL
IF NOT bTruckAnimIsUpToDate
iSyncSceneOnTruck = CREATE_SYNCHRONIZED_SCENE(<<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSyncSceneOnTruck, sTruck.vehBack, 0)
TASK_SYNCHRONIZED_SCENE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], iSyncSceneOnTruck, strTruckIdleAnims, "leanaccel", NORMAL_BLEND_IN, NORMAL_BLEND_OUT,
SYNCED_SCENE_USE_PHYSICS | SYNCED_SCENE_DONT_INTERRUPT,
RBF_BULLET_IMPACT | RBF_VEHICLE_IMPACT | RBF_PLAYER_IMPACT | RBF_EXPLOSION | RBF_WATER_JET | RBF_FALLING | RBF_IMPACT_OBJECT | RBF_PLAYER_BUMP)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneOnTruck, FALSE)
bTruckAnimIsUpToDate = TRUE
ELIF IS_SYNCHRONIZED_SCENE_RUNNING(iSyncSceneOnTruck)
IF GET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneOnTruck) > 0.99
eTruckAnimStage = TRUCK_IDLE
bTruckAnimIsUpToDate = FALSE
ENDIF
ENDIF
BREAK
CASE TRUCK_DECEL
IF NOT bTruckAnimIsUpToDate
iSyncSceneOnTruck = CREATE_SYNCHRONIZED_SCENE(<<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSyncSceneOnTruck, sTruck.vehBack, 0)
TASK_SYNCHRONIZED_SCENE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], iSyncSceneOnTruck, strTruckIdleAnims, "leanbrake", NORMAL_BLEND_IN, NORMAL_BLEND_OUT,
SYNCED_SCENE_USE_PHYSICS | SYNCED_SCENE_DONT_INTERRUPT,
RBF_BULLET_IMPACT | RBF_VEHICLE_IMPACT | RBF_PLAYER_IMPACT | RBF_EXPLOSION | RBF_WATER_JET | RBF_FALLING | RBF_IMPACT_OBJECT | RBF_PLAYER_BUMP)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneOnTruck, FALSE)
bTruckAnimIsUpToDate = TRUE
ELIF IS_SYNCHRONIZED_SCENE_RUNNING(iSyncSceneOnTruck)
IF GET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneOnTruck) > 0.99
eTruckAnimStage = TRUCK_IDLE
bTruckAnimIsUpToDate = FALSE
ENDIF
ENDIF
BREAK
CASE TRUCK_LEFT_INTRO
IF NOT bTruckAnimIsUpToDate
iSyncSceneOnTruck = CREATE_SYNCHRONIZED_SCENE(<<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSyncSceneOnTruck, sTruck.vehBack, 0)
TASK_SYNCHRONIZED_SCENE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], iSyncSceneOnTruck, strTruckIdleAnims, "leanleft_intro", NORMAL_BLEND_IN, NORMAL_BLEND_OUT,
SYNCED_SCENE_USE_PHYSICS | SYNCED_SCENE_DONT_INTERRUPT,
RBF_BULLET_IMPACT | RBF_VEHICLE_IMPACT | RBF_PLAYER_IMPACT | RBF_EXPLOSION | RBF_WATER_JET | RBF_FALLING | RBF_IMPACT_OBJECT | RBF_PLAYER_BUMP)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneOnTruck, FALSE)
bTruckAnimIsUpToDate = TRUE
ELIF IS_SYNCHRONIZED_SCENE_RUNNING(iSyncSceneOnTruck)
IF GET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneOnTruck) > 0.99
eTruckAnimStage = TRUCK_LEFT
bTruckAnimIsUpToDate = FALSE
ENDIF
ENDIF
BREAK
CASE TRUCK_LEFT
IF NOT bTruckAnimIsUpToDate
iSyncSceneOnTruck = CREATE_SYNCHRONIZED_SCENE(<<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSyncSceneOnTruck, sTruck.vehBack, 0)
TASK_SYNCHRONIZED_SCENE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], iSyncSceneOnTruck, strTruckIdleAnims, "leanleft_loop", NORMAL_BLEND_IN, NORMAL_BLEND_OUT,
SYNCED_SCENE_USE_PHYSICS | SYNCED_SCENE_DONT_INTERRUPT,
RBF_BULLET_IMPACT | RBF_VEHICLE_IMPACT | RBF_PLAYER_IMPACT | RBF_EXPLOSION | RBF_WATER_JET | RBF_FALLING | RBF_IMPACT_OBJECT | RBF_PLAYER_BUMP)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneOnTruck, TRUE)
bTruckAnimIsUpToDate = TRUE
ENDIF
BREAK
CASE TRUCK_LEFT_OUTRO
IF NOT bTruckAnimIsUpToDate
iSyncSceneOnTruck = CREATE_SYNCHRONIZED_SCENE(<<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSyncSceneOnTruck, sTruck.vehBack, 0)
TASK_SYNCHRONIZED_SCENE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], iSyncSceneOnTruck, strTruckIdleAnims, "leanleft_outro", NORMAL_BLEND_IN, NORMAL_BLEND_OUT,
SYNCED_SCENE_USE_PHYSICS | SYNCED_SCENE_DONT_INTERRUPT,
RBF_BULLET_IMPACT | RBF_VEHICLE_IMPACT | RBF_PLAYER_IMPACT | RBF_EXPLOSION | RBF_WATER_JET | RBF_FALLING | RBF_IMPACT_OBJECT | RBF_PLAYER_BUMP)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneOnTruck, FALSE)
bTruckAnimIsUpToDate = TRUE
ELIF IS_SYNCHRONIZED_SCENE_RUNNING(iSyncSceneOnTruck)
IF GET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneOnTruck) > 0.99
eTruckAnimStage = TRUCK_IDLE
bTruckAnimIsUpToDate = FALSE
ENDIF
ENDIF
BREAK
CASE TRUCK_RIGHT_INTRO
IF NOT bTruckAnimIsUpToDate
iSyncSceneOnTruck = CREATE_SYNCHRONIZED_SCENE(<<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSyncSceneOnTruck, sTruck.vehBack, 0)
TASK_SYNCHRONIZED_SCENE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], iSyncSceneOnTruck, strTruckIdleAnims, "leanright_intro", NORMAL_BLEND_IN, NORMAL_BLEND_OUT,
SYNCED_SCENE_USE_PHYSICS | SYNCED_SCENE_DONT_INTERRUPT,
RBF_BULLET_IMPACT | RBF_VEHICLE_IMPACT | RBF_PLAYER_IMPACT | RBF_EXPLOSION | RBF_WATER_JET | RBF_FALLING | RBF_IMPACT_OBJECT | RBF_PLAYER_BUMP)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneOnTruck, FALSE)
bTruckAnimIsUpToDate = TRUE
ELIF IS_SYNCHRONIZED_SCENE_RUNNING(iSyncSceneOnTruck)
IF GET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneOnTruck) > 0.99
eTruckAnimStage = TRUCK_RIGHT
bTruckAnimIsUpToDate = FALSE
ENDIF
ENDIF
BREAK
CASE TRUCK_RIGHT
IF NOT bTruckAnimIsUpToDate
iSyncSceneOnTruck = CREATE_SYNCHRONIZED_SCENE(<<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSyncSceneOnTruck, sTruck.vehBack, 0)
TASK_SYNCHRONIZED_SCENE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], iSyncSceneOnTruck, strTruckIdleAnims, "leanright_loop", NORMAL_BLEND_IN, NORMAL_BLEND_OUT,
SYNCED_SCENE_USE_PHYSICS | SYNCED_SCENE_DONT_INTERRUPT,
RBF_BULLET_IMPACT | RBF_VEHICLE_IMPACT | RBF_PLAYER_IMPACT | RBF_EXPLOSION | RBF_WATER_JET | RBF_FALLING | RBF_IMPACT_OBJECT | RBF_PLAYER_BUMP)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneOnTruck, TRUE)
bTruckAnimIsUpToDate = TRUE
ENDIF
BREAK
CASE TRUCK_RIGHT_OUTRO
IF NOT bTruckAnimIsUpToDate
iSyncSceneOnTruck = CREATE_SYNCHRONIZED_SCENE(<<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSyncSceneOnTruck, sTruck.vehBack, 0)
TASK_SYNCHRONIZED_SCENE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], iSyncSceneOnTruck, strTruckIdleAnims, "leanright_outro", NORMAL_BLEND_IN, NORMAL_BLEND_OUT,
SYNCED_SCENE_USE_PHYSICS | SYNCED_SCENE_DONT_INTERRUPT,
RBF_BULLET_IMPACT | RBF_VEHICLE_IMPACT | RBF_PLAYER_IMPACT | RBF_EXPLOSION | RBF_WATER_JET | RBF_FALLING | RBF_IMPACT_OBJECT | RBF_PLAYER_BUMP)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneOnTruck, FALSE)
bTruckAnimIsUpToDate = TRUE
ELIF IS_SYNCHRONIZED_SCENE_RUNNING(iSyncSceneOnTruck)
IF GET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneOnTruck) > 0.99
eTruckAnimStage = TRUCK_IDLE
bTruckAnimIsUpToDate = FALSE
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDIF
IF GET_ENTITY_HEALTH(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN]) < 150
STOP_SYNCHRONIZED_ENTITY_ANIM(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], NORMAL_BLEND_OUT, TRUE)
SET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneOnTruck, -1)
SET_PED_CAN_RAGDOLL(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], TRUE)
SET_PED_TO_RAGDOLL(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], 1000, 7000, TASK_NM_BALANCE)
APPLY_DAMAGE_TO_PED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], GET_ENTITY_HEALTH(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN]) + 50, TRUE)
ENDIF
ENDIF
ENDPROC
PROC UPDATE_FRANKLIN_CLIMBING_FROM_TRUCK_TO_CAR()
//Update Franklin's anims: he climbs into the JB700.
REQUEST_ANIM_DICT(strCarClimbAnims)
REQUEST_ANIM_DICT(strCarClimbAnims2)
REQUEST_ANIM_DICT(strTruckCopsIntroAnims)
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
IF HAS_ANIM_DICT_LOADED(strCarClimbAnims)
AND HAS_ANIM_DICT_LOADED(strCarClimbAnims2)
AND HAS_ANIM_DICT_LOADED(strTruckCopsIntroAnims)
AND NOT IS_ENTITY_DEAD(sTruck.vehBack)
AND NOT IS_ENTITY_DEAD(sTruck.vehFront)
IF IS_SYNCHRONIZED_SCENE_RUNNING(iSyncSceneOnTruck)
fAnimTime = GET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneOnTruck)
ENDIF
IF iTruckClimbEvent > 0
IF NOT HAS_LABEL_BEEN_TRIGGERED("CH_FRANHELP")
IF NOT IS_HELP_MESSAGE_BEING_DISPLAYED()
IF IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), sTruck.vehFront)
IF SAFE_TO_PRINT_CHASE_HINT_CAM_HELP(DEFAULT, DEFAULT, TRUE)
PRINT_HELP("CH_FRANHELP")
SET_LABEL_AS_TRIGGERED("CH_FRANHELP", TRUE)
ENDIF
ENDIF
ENDIF
ELSE
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("CH_FRANHELP")
IF NOT SAFE_TO_PRINT_CHASE_HINT_CAM_HELP(DEFAULT, DEFAULT, TRUE)
OR NOT IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), sTruck.vehFront)
CLEAR_HELP(TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
IF iTruckClimbEvent = 0 //Get out of truck.
IF IS_VEHICLE_ATTACHED_TO_TRAILER(sTruck.vehFront)
STOP_SYNCHRONIZED_ENTITY_ANIM(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], INSTANT_BLEND_OUT, TRUE)
CLEAR_PED_TASKS_IMMEDIATELY(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], TRUE)
IF IS_ENTITY_ATTACHED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
DETACH_ENTITY(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
ENDIF
IF IS_VEHICLE_DRIVEABLE(sStolenCars[iChosenCar].veh)
SET_ENTITY_NO_COLLISION_ENTITY(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], sStolenCars[iChosenCar].veh, FALSE)
ENDIF
//Increase Franklin's health at this stage.
SET_PED_MAX_HEALTH(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], 1800)
SET_ENTITY_HEALTH(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], 1800)
iSyncSceneOnTruck = CREATE_SYNCHRONIZED_SCENE(<<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSyncSceneOnTruck, sTruck.vehFront, GET_ENTITY_BONE_INDEX_BY_NAME(sTruck.vehFront, "seat_pside_f"))
TASK_SYNCHRONIZED_SCENE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], iSyncSceneOnTruck, strCarClimbAnims2, "ig_8_part_01_exit", INSTANT_BLEND_IN, INSTANT_BLEND_OUT,
SYNCED_SCENE_USE_PHYSICS | SYNCED_SCENE_DONT_INTERRUPT,
RBF_BULLET_IMPACT | RBF_VEHICLE_IMPACT | RBF_PLAYER_IMPACT | RBF_EXPLOSION | RBF_WATER_JET | RBF_FALLING | RBF_IMPACT_OBJECT | RBF_PLAYER_BUMP)
FORCE_PED_AI_AND_ANIMATION_UPDATE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
SET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneOnTruck, 0.0)
SET_SYNCHRONIZED_SCENE_RATE(iSyncSceneOnTruck, 1.0)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneOnTruck, FALSE)
PLAY_ENTITY_ANIM(sTruck.vehFront, "ig_8_part_01_exit_door", strCarClimbAnims2, NORMAL_BLEND_IN, FALSE, FALSE)
DESTROY_ALL_CAMS()
camCutscene = CREATE_CAM("DEFAULT_ANIMATED_CAMERA", TRUE)
PLAY_SYNCHRONIZED_CAM_ANIM(camCutscene, iSyncSceneOnTruck, "ig_8_part_01_exit_cam", strCarClimbAnims2)
IF IS_VEHICLE_DRIVEABLE(sStolenCars[2].veh)
AND IS_VEHICLE_DRIVEABLE(sStolenCars[4].veh)
AND IS_VEHICLE_DRIVEABLE(sStolenCars[3].veh)
SET_ENTITY_NO_COLLISION_ENTITY(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], sStolenCars[2].veh, FALSE)
SET_ENTITY_NO_COLLISION_ENTITY(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], sStolenCars[4].veh, FALSE)
SET_ENTITY_NO_COLLISION_ENTITY(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], sStolenCars[3].veh, FALSE)
ENDIF
bTruckDoorOpenSoundPlayed = FALSE
bTruckDoorCloseSoundPlayed = FALSE
bFranklinTruckClimbActive = FALSE
iTruckClimbEvent++
ENDIF
ELIF iTruckClimbEvent = 1 //Go into idle loop
IF bTruckDoorOpenSoundPlayed = FALSE
IF fAnimTime >= 0.050
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
PLAY_VEHICLE_DOOR_OPEN_SOUND(sTruck.vehFront, 1)
ENDIF
bTruckDoorOpenSoundPlayed = TRUE
ENDIF
ENDIF
IF bTruckDoorCloseSoundPlayed = FALSE
IF fAnimTime >= 0.535
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
PLAY_VEHICLE_DOOR_CLOSE_SOUND(sTruck.vehFront, 1)
ENDIF
bTruckDoorCloseSoundPlayed = TRUE
ENDIF
ENDIF
IF fAnimTime >= 1.0
iSyncSceneOnTruck = CREATE_SYNCHRONIZED_SCENE(<<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSyncSceneOnTruck, sTruck.vehFront, GET_ENTITY_BONE_INDEX_BY_NAME(sTruck.vehFront, "seat_pside_f"))
TASK_SYNCHRONIZED_SCENE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], iSyncSceneOnTruck, strCarClimbAnims2, "ig_8_part_02_loop", INSTANT_BLEND_IN, INSTANT_BLEND_OUT,
SYNCED_SCENE_USE_PHYSICS | SYNCED_SCENE_DONT_INTERRUPT,
RBF_BULLET_IMPACT | RBF_VEHICLE_IMPACT | RBF_PLAYER_IMPACT | RBF_EXPLOSION | RBF_WATER_JET | RBF_FALLING | RBF_IMPACT_OBJECT | RBF_PLAYER_BUMP)
SET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneOnTruck, 0.0)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneOnTruck, TRUE)
SET_SYNCHRONIZED_SCENE_RATE(iSyncSceneOnTruck, 1.15)
PLAY_SYNCHRONIZED_CAM_ANIM(camCutscene, iSyncSceneOnTruck, "ig_8_part_02_loop_cam", strCarClimbAnims2)
INIT_SYNCH_SCENE_AUDIO_WITH_ENTITY("CAR_5_IG_6", sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
iTruckAndTrailerAlignTimer = 0
iTruckClimbTimer = GET_GAME_TIMER()
iTruckClimbEvent++
ENDIF
ELIF iTruckClimbEvent = 2 //Once safe do the jump.
BOOL bSafeToClimb
FLOAT fTruckHeading, fTrailerHeading
fTruckHeading = GET_ENTITY_HEADING(sTruck.vehFront)
fTrailerHeading = GET_ENTITY_HEADING(sTruck.vehBack)
#IF IS_DEBUG_BUILD
DRAW_DEBUG_TEXT_ABOVE_ENTITY(sTruck.vehFront, GET_STRING_FROM_FLOAT(fTruckHeading), 1.0)
DRAW_DEBUG_TEXT_ABOVE_ENTITY(sTruck.vehBack, GET_STRING_FROM_FLOAT(fTrailerHeading), 1.0)
#ENDIF
IF ABSF (fTruckHeading - fTrailerHeading) < 10.0
IF iTruckAndTrailerAlignTimer = 0
iTruckAndTrailerAlignTimer = GET_GAME_TIMER()
ELSE
IF GET_GAME_TIMER() - iTruckAndTrailerAlignTimer > 1000
bSafeToClimb = TRUE
ENDIF
ENDIF
ELSE
iTruckAndTrailerAlignTimer = 0
bSafeToClimb = FALSE
ENDIF
IF GET_GAME_TIMER() - iTruckClimbTimer > 500
AND PREPARE_SYNCHRONIZED_AUDIO_EVENT("CAR_5_IG_6", 0)
AND IS_VEHICLE_ATTACHED_TO_TRAILER(sTruck.vehFront) AND bSafeToClimb
iSyncSceneOnTruck = CREATE_SYNCHRONIZED_SCENE(<<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSyncSceneOnTruck, sTruck.vehFront, GET_ENTITY_BONE_INDEX_BY_NAME(sTruck.vehFront, "seat_pside_f"))
TASK_SYNCHRONIZED_SCENE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], iSyncSceneOnTruck, strCarClimbAnims2, "ig_8_part_03_jump", SLOW_BLEND_IN, INSTANT_BLEND_OUT,
SYNCED_SCENE_USE_PHYSICS | SYNCED_SCENE_DONT_INTERRUPT,
RBF_BULLET_IMPACT | RBF_VEHICLE_IMPACT | RBF_PLAYER_IMPACT | RBF_EXPLOSION | RBF_WATER_JET | RBF_FALLING | RBF_IMPACT_OBJECT | RBF_PLAYER_BUMP)
SET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneOnTruck, 0.0)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneOnTruck, FALSE)
SET_SYNCHRONIZED_SCENE_RATE(iSyncSceneOnTruck, 1.15)
PLAY_SYNCHRONIZED_CAM_ANIM(camCutscene, iSyncSceneOnTruck, "ig_8_part_03_jump_cam", strCarClimbAnims2)
iTruckClimbTimer = GET_GAME_TIMER()
iTruckClimbEvent++
ENDIF
ELIF iTruckClimbEvent = 3 //change attachment of the jump from cab to trailer animation
IF fAnimTime >= 0.5
iSyncSceneOnTruck2 = CREATE_SYNCHRONIZED_SCENE(<<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSyncSceneOnTruck2, sTruck.vehBack, 0)
TASK_SYNCHRONIZED_SCENE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], iSyncSceneOnTruck2, strCarClimbAnims2, "ig_8_part_03_jump_alt_trailer", INSTANT_BLEND_IN, INSTANT_BLEND_OUT,
SYNCED_SCENE_USE_PHYSICS | SYNCED_SCENE_DONT_INTERRUPT,
RBF_BULLET_IMPACT | RBF_VEHICLE_IMPACT | RBF_PLAYER_IMPACT | RBF_EXPLOSION | RBF_WATER_JET | RBF_FALLING | RBF_IMPACT_OBJECT | RBF_PLAYER_BUMP)
SET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneOnTruck2, fAnimTime)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneOnTruck2, FALSE)
SET_SYNCHRONIZED_SCENE_RATE(iSyncSceneOnTruck2, 1.15)
FORCE_PED_AI_AND_ANIMATION_UPDATE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], TRUE)
iTruckClimbTimer = GET_GAME_TIMER()
iTruckClimbEvent++
ENDIF
ELIF iTruckClimbEvent = 4 //Start the big climb.
IF fAnimTime >= 1.0
iSyncSceneOnTruck = CREATE_SYNCHRONIZED_SCENE(<<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSyncSceneOnTruck, sTruck.vehBack, 0)
TASK_SYNCHRONIZED_SCENE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], iSyncSceneOnTruck, strTruckCopsIntroAnims, "car_5_ig_4", INSTANT_BLEND_IN, INSTANT_BLEND_OUT,
SYNCED_SCENE_USE_PHYSICS | SYNCED_SCENE_DONT_INTERRUPT | SYNCED_SCENE_ON_ABORT_STOP_SCENE,
RBF_BULLET_IMPACT | RBF_VEHICLE_IMPACT | RBF_PLAYER_IMPACT | RBF_EXPLOSION | RBF_WATER_JET | RBF_FALLING | RBF_IMPACT_OBJECT | RBF_PLAYER_BUMP)
SET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneOnTruck, 0.0)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneOnTruck, FALSE)
SET_SYNCHRONIZED_SCENE_RATE(iSyncSceneOnTruck, 1.15)
PLAY_SYNCHRONIZED_CAM_ANIM(camCutscene, iSyncSceneOnTruck, "car_5_ig_4_cam", strTruckCopsIntroAnims)
iTruckClimbEvent = 50
ENDIF
ELIF iTruckClimbEvent = 50
IF fAnimTime >= 1.0
iSyncSceneOnTruck = CREATE_SYNCHRONIZED_SCENE(<<0.0, 0.0, 0.0>>, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSyncSceneOnTruck, sTruck.vehBack, 0)
TASK_SYNCHRONIZED_SCENE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], iSyncSceneOnTruck, strCarClimbAnims, "car_5_ig_6", INSTANT_BLEND_IN, INSTANT_BLEND_OUT,
SYNCED_SCENE_USE_PHYSICS | SYNCED_SCENE_DONT_INTERRUPT,
RBF_BULLET_IMPACT | RBF_VEHICLE_IMPACT | RBF_PLAYER_IMPACT | RBF_EXPLOSION | RBF_WATER_JET | RBF_FALLING | RBF_IMPACT_OBJECT | RBF_PLAYER_BUMP)
//SET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneOnTruck, 0.0)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneOnTruck, FALSE)
//SET_SYNCHRONIZED_SCENE_RATE(iSyncSceneOnTruck, 1.15)
PLAY_SYNCHRONIZED_CAM_ANIM(camCutscene, iSyncSceneOnTruck, "car_5_ig_6_cam", strCarClimbAnims)
IF IS_VEHICLE_DRIVEABLE(sStolenCars[iChosenCar].veh)
//DETACH_ENTITY(sStolenCars[iChosenCar].veh, FALSE)
//SET_ENTITY_NO_COLLISION_ENTITY(sStolenCars[iChosenCar].veh, sTruck.vehBack, FALSE)
//PLAY_SYNCHRONIZED_ENTITY_ANIM(sStolenCars[iChosenCar].veh, iSyncSceneOnTruck, "car_5_ig_6_car", strCarClimbAnims, INSTANT_BLEND_IN, INSTANT_BLEND_OUT, ENUM_TO_INT(SYNCED_SCENE_DONT_INTERRUPT))
PLAY_ENTITY_ANIM(sStolenCars[iChosenCar].veh, "car_5_ig_6_car", strCarClimbAnims, INSTANT_BLEND_IN, FALSE, FALSE, FALSE, 0.0)
FORCE_ENTITY_AI_AND_ANIMATION_UPDATE(sStolenCars[iChosenCar].veh)
ENDIF
PLAY_SYNCHRONIZED_AUDIO_EVENT(iSyncSceneOnTruck)
bFranklinTruckClimbActive = TRUE
iTruckClimbEvent++
ENDIF
ELIF iTruckClimbEvent = 51
IF IS_VEHICLE_DRIVEABLE(sStolenCars[iChosenCar].veh)
IF IS_ENTITY_PLAYING_ANIM(sStolenCars[iChosenCar].veh, strCarClimbAnims, "car_5_ig_6_car")
//SET_ENTITY_ANIM_SPEED(sStolenCars[iChosenCar].veh, strCarClimbAnims, "car_5_ig_6_car", 1.15)
SET_ENTITY_ANIM_CURRENT_TIME(sStolenCars[iChosenCar].veh, strCarClimbAnims, "car_5_ig_6_car", fAnimTime)
ENDIF
ENDIF
IF fAnimTime >= 1.0
IF IS_VEHICLE_DRIVEABLE(sStolenCars[iChosenCar].veh)
STOP_SYNCHRONIZED_ENTITY_ANIM(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], INSTANT_BLEND_OUT, TRUE)
CLEAR_PED_TASKS_IMMEDIATELY(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
SET_ENTITY_NO_COLLISION_ENTITY(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], sStolenCars[iChosenCar].veh, TRUE)
SET_PED_INTO_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], sStolenCars[iChosenCar].veh)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sStolenCars[iChosenCar].veh, TRUE)
SET_VEHICLE_DOORS_LOCKED(sStolenCars[iChosenCar].veh, VEHICLELOCK_UNLOCKED)
DESTROY_ALL_CAMS()
RENDER_SCRIPT_CAMS(FALSE, FALSE)
KILL_CHASE_HINT_CAM(localChaseHintCamStruct) //reset the cinematic camera struct
bFranklinTruckClimbActive = FALSE
iTruckClimbEvent++
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF GET_ENTITY_HEALTH(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN]) < 150
STOP_SYNCHRONIZED_ENTITY_ANIM(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], NORMAL_BLEND_OUT, TRUE)
SET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneOnTruck, -1)
SET_PED_CAN_RAGDOLL(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], TRUE)
SET_PED_TO_RAGDOLL(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], 1000, 7000, TASK_NM_BALANCE)
APPLY_DAMAGE_TO_PED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], GET_ENTITY_HEALTH(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN]) + 50, TRUE)
ENDIF
ENDIF
ENDPROC
FUNC INT FIND_FREE_OIL_SLICK_SLOT()
INT i = 0
REPEAT COUNT_OF(sSpikes) i
IF sSpikes[i].vPos.x = 0.0
RETURN i
ENDIF
ENDREPEAT
RETURN -1
ENDFUNC
FUNC VEHICLE_INDEX GET_CLOSEST_COP_CAR_FROM_PED(PED_INDEX ped)
VEHICLE_INDEX vehClosestCars[10]
INT iClosest = 0
INT i = 0
FLOAT fClosestDist = 0.0
IF NOT IS_PED_INJURED(ped)
VECTOR vPedPos = GET_ENTITY_COORDS(ped)
GET_PED_NEARBY_VEHICLES(ped, vehClosestCars)
REPEAT COUNT_OF(vehClosestCars) i
IF IS_VEHICLE_DRIVEABLE(vehClosestCars[i])
MODEL_NAMES modelClosestCar = GET_ENTITY_MODEL(vehClosestCars[i])
IF modelClosestCar = POLICE
OR modelClosestCar = SHERIFF
FLOAT fDist = VDIST2(GET_ENTITY_COORDS(vehClosestCars[i]), vPedPos)
IF fDist < fClosestDist OR fClosestDist = 0.0
fClosestDist = fDist
iClosest = i
ENDIF
ENDIF
ENDIF
ENDREPEAT
ENDIF
IF fClosestDist = 0.0
vehClosestCars[iClosest] = NULL
ENDIF
RETURN vehClosestCars[iClosest]
ENDFUNC
/// PURPOSE:
/// Checks if any of the scripted chase cops are at a particular location.
FUNC BOOL IS_SCRIPTED_COP_CAR_AT_COORDS(VECTOR vPos, VECTOR vBounds)
INT i
REPEAT COUNT_OF(vehChaseCops) i
IF NOT IS_ENTITY_DEAD(vehChaseCops[i])
IF IS_ENTITY_AT_COORD(vehChaseCops[i], vPos, vBounds)
RETURN TRUE
ENDIF
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
PROC UPDATE_OIL_SLICKS()
IF IS_VEHICLE_DRIVEABLE(sStolenCars[iChosenCar].veh)
INT i = 0
VECTOR vPlayerPos = GET_ENTITY_COORDS(sStolenCars[iChosenCar].veh)
REQUEST_MODEL(modelSpikes)
REQUEST_SCRIPT_AUDIO_BANK("CAR_THEFT_FINALE")
REQUEST_PTFX_ASSET()
ALLOW_ALTERNATIVE_SCRIPT_CONTROLS_LAYOUT(PLAYER_CONTROL) //fixes spikes input in southpaw controls layout
IF IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[iChosenCar].veh)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_HORN)
//Release an oil slick/spike when instructed.
IF NOT DOES_CAM_EXIST(camCutscene)
AND IS_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_SCRIPT_LS)
AND GET_GAME_TIMER() - iOilSlickTimer > 1600
AND IS_ENTITY_UPRIGHT(sStolenCars[iChosenCar].veh)
AND REQUEST_SCRIPT_AUDIO_BANK("CAR_THEFT_FINALE")
AND HAS_MODEL_LOADED(modelSpikes)
BOOL bAllowSpikes = TRUE
IF DOES_ENTITY_EXIST(objSpikes[0])
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(objSpikes[0])) < 9.0
bAllowSpikes = FALSE
ENDIF
ENDIF
IF bAllowSpikes
INT iSlot = FIND_FREE_OIL_SLICK_SLOT()
//For the moment just go back to the start of the array once all the slots are full. This could be improved to find the furthest away slick and overwrite that one.
IF iSlot = -1
iSlot = 0
ENDIF
sSpikes[iSlot].vPos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sStolenCars[iChosenCar].veh, <<0.0, -2.0, 0.0>>)
sSpikes[iSlot].iForceTimer = 0
sSpikes[iSlot].iCutsceneTimer = 0
sSpikes[iSlot].iCutsceneEvent = 0
sSpikes[iSlot].vehClosest = NULL
REPEAT COUNT_OF(objSpikes) i
IF DOES_ENTITY_EXIST(objSpikes[i])
REMOVE_OBJECT(objSpikes[i], NOT IS_ENTITY_ON_SCREEN(objSpikes[i]))
ENDIF
ENDREPEAT
iSpikeTimer = GET_GAME_TIMER()
iOilSlickTimer = GET_GAME_TIMER()
PLAY_SOUND_FROM_ENTITY(-1, "spikes", sStolenCars[iChosenCar].veh, "CAR_THEFT_DB5_ESCAPE")
//TEMP: Test car
/*IF NOT DOES_ENTITY_EXIST(vehOilSlickTest)
//REQUEST_MODEL(POLICE)
//REQUEST_MODEL(S_M_Y_COP_01)
//IF HAS_MODEL_LOADED(POLICE)
//AND HAS_MODEL_LOADED(S_M_Y_COP_01)
//vehOilSlickTest = CREATE_VEHICLE(POLICE, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sStolenCars[iChosenCar].veh, <<0.0, -20.0, 0.0>>), 0.0)
//pedOilSlickTest = CREATE_PED_INSIDE_VEHICLE(vehOilSlickTest, PEDTYPE_MISSION, S_M_Y_COP_01)
// SET_MODEL_AS_NO_LONGER_NEEDED(POLICE)
// SET_MODEL_AS_NO_LONGER_NEEDED(S_M_Y_COP_01)
//ENDIF
ENDIF
IF IS_VEHICLE_DRIVEABLE(vehOilSlickTest)
AND NOT IS_PED_INJURED(pedOilSlickTest)
SET_ENTITY_COORDS(vehOilSlickTest, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sStolenCars[iChosenCar].veh, <<0.0, -20.0, 0.0>>))
SET_ENTITY_HEADING(vehOilSlickTest, GET_ENTITY_HEADING(sStolenCars[iChosenCar].veh))
SET_VEHICLE_FORWARD_SPEED(vehOilSlickTest, 20.0)
TASK_VEHICLE_MISSION(pedOilSlickTest, vehOilSlickTest, sStolenCars[iChosenCar].veh, MISSION_RAM, 40.0, DRIVINGMODE_PLOUGHTHROUGH,
1.0, 3.0)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(pedOilSlickTest, TRUE)
ELSE
REMOVE_PED(pedOilSlickTest)
REMOVE_VEHICLE(vehOilSlickTest)
ENDIF*/
ENDIF
ENDIF
ENDIF
//Handle the creation of spikes
IF iSpikeTimer != 0
IF GET_GAME_TIMER() - iSpikeTimer < 100
IF NOT DOES_ENTITY_EXIST(objSpikes[0])
objSpikes[0] = CREATE_OBJECT(modelSpikes, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sStolenCars[iChosenCar].veh, <<0.0, -1.2, -0.25>>))
SET_ENTITY_NO_COLLISION_ENTITY(objSpikes[0], sStolenCars[iChosenCar].veh, TRUE)
SET_ENTITY_DYNAMIC(objSpikes[0], TRUE)
ACTIVATE_PHYSICS(objSpikes[0])
bSpikeSparks[0] = FALSE
//PLAY_SOUND_FROM_COORD(-1,"CAR_THEFT_MOVIE_LOT_DROP_SPIKES" , v_spikes[i])
ENDIF
ELIF GET_GAME_TIMER() - iSpikeTimer < 160
IF NOT DOES_ENTITY_EXIST(objSpikes[1])
objSpikes[1] = CREATE_OBJECT(modelSpikes, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sStolenCars[iChosenCar].veh, <<0.15, -1.1, -0.25>>))
SET_ENTITY_NO_COLLISION_ENTITY(objSpikes[1], sStolenCars[iChosenCar].veh, TRUE)
SET_ENTITY_DYNAMIC(objSpikes[1], TRUE)
ACTIVATE_PHYSICS(objSpikes[1])
bSpikeSparks[1] = FALSE
ENDIF
ELIF GET_GAME_TIMER() - iSpikeTimer < 220
IF NOT DOES_ENTITY_EXIST(objSpikes[2])
objSpikes[2] = CREATE_OBJECT(modelSpikes, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sStolenCars[iChosenCar].veh, <<-0.15, -1.0, -0.25>>))
SET_ENTITY_NO_COLLISION_ENTITY(objSpikes[2], sStolenCars[iChosenCar].veh, TRUE)
SET_ENTITY_DYNAMIC(objSpikes[2], TRUE)
ACTIVATE_PHYSICS(objSpikes[2])
iSpikeTimer = 0
bSpikeSparks[2] = FALSE
ENDIF
ENDIF
ENDIF
//play spikes sparks effect
IF HAS_PTFX_ASSET_LOADED()
IF ( bSpikeSparks[0] = FALSE )
IF DOES_ENTITY_EXIST(objSpikes[0])
IF NOT IS_ENTITY_IN_AIR(objSpikes[0])
START_PARTICLE_FX_NON_LOOPED_ON_ENTITY("scr_carsteal4_tyre_spikes", objSpikes[0], << 0.0, 0.0, -0.025 >>, << 0.0, 0.0, 0.0 >>)
bSpikeSparks[0] = TRUE
ENDIF
ENDIF
ENDIF
IF ( bSpikeSparks[1] = FALSE )
IF DOES_ENTITY_EXIST(objSpikes[1])
IF NOT IS_ENTITY_IN_AIR(objSpikes[1])
START_PARTICLE_FX_NON_LOOPED_ON_ENTITY("scr_carsteal4_tyre_spikes", objSpikes[1], << 0.0, 0.0, -0.025 >>, << 0.0, 0.0, 0.0 >>)
bSpikeSparks[1] = TRUE
ENDIF
ENDIF
ENDIF
IF ( bSpikeSparks[2] = FALSE )
IF DOES_ENTITY_EXIST(objSpikes[2])
IF NOT IS_ENTITY_IN_AIR(objSpikes[2])
START_PARTICLE_FX_NON_LOOPED_ON_ENTITY("scr_carsteal4_tyre_spikes", objSpikes[2], << 0.0, 0.0, -0.025 >>, << 0.0, 0.0, 0.0 >>)
bSpikeSparks[2] = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
//Use an invisible ped that's passed into the get closest vehicle array commands.
IF NOT DOES_ENTITY_EXIST(pedSpikeHelper)
REQUEST_MODEL(GET_NPC_PED_MODEL(CHAR_LAMAR))
REQUEST_PTFX_ASSET()
REQUEST_SCRIPT_AUDIO_BANK("CAR_THEFT_FINALE")
IF HAS_MODEL_LOADED(GET_NPC_PED_MODEL(CHAR_LAMAR))
IF sSpikes[0].vPos.x != 0.0
pedSpikeHelper = CREATE_PED(PEDTYPE_MISSION, GET_NPC_PED_MODEL(CHAR_LAMAR), sSpikes[0].vPos - <<0.0, 0.0, 5.0>>)
SET_ENTITY_INVINCIBLE(pedSpikeHelper, TRUE)
SET_ENTITY_VISIBLE(pedSpikeHelper, FALSE)
SET_ENTITY_COLLISION(pedSpikeHelper, FALSE)
FREEZE_ENTITY_POSITION(pedSpikeHelper, TRUE)
SET_MODEL_AS_NO_LONGER_NEEDED(GET_NPC_PED_MODEL(CHAR_LAMAR))
ENDIF
ENDIF
ENDIF
//Burst the tyres of ambient cars.
IF DOES_ENTITY_EXIST(objSpikes[0])
AND DOES_ENTITY_EXIST(objSpikes[1])
AND DOES_ENTITY_EXIST(objSpikes[2])
VEHICLE_INDEX vehClosest
vehClosest = GET_CLOSEST_VEHICLE(sSpikes[0].vPos, 10.0, DUMMY_MODEL_FOR_SCRIPT, GET_TRAFFIC_AND_PLAYER_VEHICLE_SEARCH_FLAGS())
IF NOT IS_ENTITY_DEAD(vehClosest)
AND vehClosest != sStolenCars[iChosenCar].veh
AND vehClosest != sTruck.vehFront
AND vehClosest != sTruck.vehBack
AND GET_ENTITY_MODEL(vehClosest) != POLICE
AND NOT IS_THIS_MODEL_A_BIKE(GET_ENTITY_MODEL(vehClosest))
VECTOR vSpikePos1, vSpikePos2, vSpikePos3, vWheelPos1, vWheelPos2, vWheelPos3, vWheelPos4
vSpikePos1 = GET_ENTITY_COORDS(objSpikes[0])
vSpikePos2 = GET_ENTITY_COORDS(objSpikes[1])
vSpikePos3 = GET_ENTITY_COORDS(objSpikes[2])
vWheelPos1 = GET_WORLD_POSITION_OF_ENTITY_BONE(vehClosest, GET_ENTITY_BONE_INDEX_BY_NAME(vehClosest, "wheel_lf"))
vWheelPos2 = GET_WORLD_POSITION_OF_ENTITY_BONE(vehClosest, GET_ENTITY_BONE_INDEX_BY_NAME(vehClosest, "wheel_rf"))
vWheelPos3 = GET_WORLD_POSITION_OF_ENTITY_BONE(vehClosest, GET_ENTITY_BONE_INDEX_BY_NAME(vehClosest, "wheel_rr"))
vWheelPos4 = GET_WORLD_POSITION_OF_ENTITY_BONE(vehClosest, GET_ENTITY_BONE_INDEX_BY_NAME(vehClosest, "wheel_lr"))
IF VDIST2(vSpikePos1, vWheelPos1) < 4.0
OR VDIST2(vSpikePos2, vWheelPos1) < 4.0
OR VDIST2(vSpikePos3, vWheelPos1) < 4.0
IF NOT IS_VEHICLE_TYRE_BURST(vehClosest, SC_WHEEL_CAR_FRONT_LEFT)
SET_VEHICLE_TYRE_BURST(vehClosest, SC_WHEEL_CAR_FRONT_LEFT, TRUE)
ENDIF
ENDIF
IF VDIST2(vSpikePos1, vWheelPos2) < 4.0
OR VDIST2(vSpikePos2, vWheelPos2) < 4.0
OR VDIST2(vSpikePos3, vWheelPos2) < 4.0
IF NOT IS_VEHICLE_TYRE_BURST(vehClosest, SC_WHEEL_CAR_FRONT_RIGHT)
SET_VEHICLE_TYRE_BURST(vehClosest, SC_WHEEL_CAR_FRONT_RIGHT, TRUE)
ENDIF
ENDIF
IF VDIST2(vSpikePos1, vWheelPos3) < 4.0
OR VDIST2(vSpikePos2, vWheelPos3) < 4.0
OR VDIST2(vSpikePos3, vWheelPos3) < 4.0
IF NOT IS_VEHICLE_TYRE_BURST(vehClosest, SC_WHEEL_CAR_REAR_RIGHT)
SET_VEHICLE_TYRE_BURST(vehClosest, SC_WHEEL_CAR_REAR_RIGHT, TRUE)
ENDIF
ENDIF
IF VDIST2(vSpikePos1, vWheelPos4) < 4.0
OR VDIST2(vSpikePos2, vWheelPos4) < 4.0
OR VDIST2(vSpikePos3, vWheelPos4) < 4.0
IF NOT IS_VEHICLE_TYRE_BURST(vehClosest, SC_WHEEL_CAR_REAR_LEFT)
SET_VEHICLE_TYRE_BURST(vehClosest, SC_WHEEL_CAR_REAR_LEFT, TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
//Cycle through existing oil slicks/spikes, check if police cars approach them and make them spin out.
VECTOR vSpikeOffsets[3]
FLOAT fSpikeGroundZ[3]
INT iShapeResult
VECTOR vShapePos, vShapeNormal
ENTITY_INDEX hitEntity
REPEAT COUNT_OF(sSpikes) i
IF sSpikes[i].vPos.x != 0.0
IF sSpikes[i].iCutsceneEvent = 0 //If a car is approaching then calculate where the camera should be.
IF NOT DOES_CAM_EXIST(camCutscene)
IF VDIST2(sSpikes[i].vPos, vPlayerPos) > 2500.0
sSpikes[i].vPos = <<0.0, 0.0, 0.0>>
ELSE
IF NOT IS_PED_INJURED(pedSpikeHelper)
VECTOR vHelperPos = GET_ENTITY_COORDS(pedSpikeHelper)
IF VDIST2(<<vHelperPos.x, vHelperPos.y, 0.0>>, <<sSpikes[i].vPos.x, sSpikes[i].vPos.y, 0.0>>) > 1.0
SET_ENTITY_COORDS_NO_OFFSET(pedSpikeHelper, sSpikes[i].vPos - <<0.0, 0.0, 5.0>>)
ENDIF
ENDIF
sSpikes[i].vehClosest = GET_CLOSEST_COP_CAR_FROM_PED(pedSpikeHelper)
IF IS_VEHICLE_DRIVEABLE(sSpikes[i].vehClosest)
VECTOR vVehPos = GET_ENTITY_COORDS(sSpikes[i].vehClosest)
IF VDIST2(vVehPos, sSpikes[i].vPos) < 100.0
AND VDIST2(vPlayerPos, sSpikes[i].vPos) > 225.0
AND GET_ENTITY_SPEED(sSpikes[i].vehClosest) > 10.0
AND DOES_ENTITY_EXIST(objSpikes[0])
AND DOES_ENTITY_EXIST(objSpikes[1])
AND DOES_ENTITY_EXIST(objSpikes[2])
VECTOR vVehDir = CONVERT_ROTATION_TO_DIRECTION_VECTOR(<<0.0, 0.0, GET_ENTITY_HEADING(sSpikes[i].vehClosest)>>)
VECTOR vDirToSlick = sSpikes[i].vPos - vVehPos
vDirToSlick = vDirToSlick / VMAG(vDirToSlick)
IF DOT_PRODUCT(vVehDir, vDirToSlick) > 0.0
REQUEST_PTFX_ASSET()
sSpikes[i].vCamPos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sSpikes[i].vehClosest, <<-4.0, 25.0, 2.0>>)
sSpikes[i].vCamLookatPos = GET_ENTITY_COORDS(sSpikes[i].vehClosest)
GET_GROUND_Z_FOR_3D_COORD(sSpikes[i].vCamPos + <<0.0, 0.0, 100.0>>, sSpikes[i].vCamPos.z)
sSpikes[i].vCamPos.z += 2.0
FLOAT fHeightDiff = sSpikes[i].vCamPos.z - sSpikes[i].vCamLookatPos.z
IF fHeightDiff < 7.0
AND fHeightDiff > -1.0
sSpikes[i].iCutsceneEvent++
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELIF sSpikes[i].iCutsceneEvent = 1 //Do a shapetest on the camera position: if there's nothing in the way then start the cutscene.
IF shapetestSpikes = NULL
shapetestSpikes = START_SHAPE_TEST_LOS_PROBE(sSpikes[i].vCamPos, sSpikes[i].vCamLookatPos)
ENDIF
IF shapetestSpikes != NULL
SHAPETEST_STATUS eShapeResult = GET_SHAPE_TEST_RESULT(shapetestSpikes, iShapeResult, vShapePos, vShapeNormal, hitEntity)
//SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
IF eShapeResult = SHAPETEST_STATUS_RESULTS_READY
#IF IS_DEBUG_BUILD
PRINTLN("Shapetest status - READY", iShapeResult)
#ENDIF
ELIF eShapeResult = SHAPETEST_STATUS_NONEXISTENT
#IF IS_DEBUG_BUILD
PRINTLN("Shapetest status - NOT EXISTANT")
#ENDIF
ENDIF
ENDIF
//Reposition the spikes so they always hit if the cutscene triggers
vSpikeOffsets[0] = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sSpikes[i].vehClosest, <<0.8, 6.0, 0.0>>)
vSpikeOffsets[1] = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sSpikes[i].vehClosest, <<0.5, 7.0, 0.0>>)
vSpikeOffsets[2] = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sSpikes[i].vehClosest, <<0.9, 8.0, 0.0>>)
GET_GROUND_Z_FOR_3D_COORD(vSpikeOffsets[0], fSpikeGroundZ[0])
GET_GROUND_Z_FOR_3D_COORD(vSpikeOffsets[1], fSpikeGroundZ[1])
GET_GROUND_Z_FOR_3D_COORD(vSpikeOffsets[2], fSpikeGroundZ[2])
SET_ENTITY_COORDS(objSpikes[0], <<vSpikeOffsets[0].x, vSpikeOffsets[0].y, fSpikeGroundZ[0] + 0.05>>)
SET_ENTITY_COORDS(objSpikes[1], <<vSpikeOffsets[1].x, vSpikeOffsets[1].y, fSpikeGroundZ[1] + 0.05>>)
SET_ENTITY_COORDS(objSpikes[2], <<vSpikeOffsets[2].x, vSpikeOffsets[2].y, fSpikeGroundZ[2] + 0.05>>)
sSpikes[i].vPos = vSpikeOffsets[1]
//Reposition the player in case they're flying into a wall
IF IS_VEHICLE_DRIVEABLE(sStolenCars[iChosenCar].veh)
AND IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[iChosenCar].veh)
/*
VECTOR vNewPos = <<0.0, 0.0, 0.0>>
INT iNumLanes = 0
VECTOR vOffsetFromTruck = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(sTruck.vehBack, GET_ENTITY_COORDS(PLAYER_PED_ID()))
FLOAT fNewHeading = 0.0
fPlayersSpeedAtSpikeStart = GET_ENTITY_SPEED(sStolenCars[iChosenCar].veh)
*/
/*
//If the player is near the truck then place them further away from the truck during the cutscene to prevent issues.
IF ABSF(vOffsetFromTruck.x) < 5.0
AND vOffsetFromTruck.y < 22.5
AND vOffsetFromTruck.y > -14.5
VECTOR vNewTruckOffset = <<0.0, 0.0, -0.5>>
IF vOffsetFromTruck.x > 2.0
vNewTruckOffset.x = 5.0
ELIF vOffsetFromTruck.x < -2.0
vNewTruckOffset.x = -5.0
ENDIF
IF vOffsetFromTruck.y < 0.0
vNewTruckOffset.y = -15.0
ENDIF
vNewPos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehBack, vNewTruckOffset)
fNewHeading = GET_ENTITY_HEADING(sTruck.vehBack)
//If the player is being warped away from the truck then we only need to check for the scripted cops (ambient traffic will be cleared, the truck shouldn't be considered).
IF NOT IS_ENTITY_AT_COORD(sSpikes[i].vehClosest, vNewPos, <<4.0, 4.0, 4.0>>)
AND NOT IS_SCRIPTED_COP_CAR_AT_COORDS(vNewPos, <<4.0, 4.0, 4.0>>)
AND VDIST2(sSpikes[i].vPos, vNewPos) > 16.0
CLEAR_AREA(vNewPos, 3.0, TRUE)
SET_ENTITY_COORDS(sStolenCars[iChosenCar].veh, vNewPos)
SET_VEHICLE_ON_GROUND_PROPERLY(sStolenCars[iChosenCar].veh)
SET_VEHICLE_FORWARD_SPEED(sStolenCars[iChosenCar].veh, fPlayersSpeedAtSpikeStart * 0.75)
#IF IS_DEBUG_BUILD
PRINTLN("Car Steal Finale - repositioned player at truck offset for spike cutscene: ", vNewPos, " ", fNewHeading)
#ENDIF
ELSE
#IF IS_DEBUG_BUILD
PRINTLN("Car Steal Finale - Truck offset is occupied by cop car: ", vNewPos)
#ENDIF
ENDIF
ELSE
IF GET_NTH_CLOSEST_VEHICLE_NODE_WITH_HEADING(GET_ENTITY_COORDS(PLAYER_PED_ID()), 1, vNewPos, fNewHeading, iNumLanes, NF_INCLUDE_SWITCHED_OFF_NODES)
//If the player is being warped to a road node check for any mission entity on that node (ambient cars will be cleared).
IF NOT IS_POINT_OBSCURED_BY_A_MISSION_ENTITY(vNewPos, <<3.0, 3.0, 4.0>>, sStolenCars[iChosenCar].veh)
CLEAR_AREA(vNewPos, 3.0, TRUE)
SET_ENTITY_COORDS(sStolenCars[iChosenCar].veh, vNewPos)
FLOAT fHeadingDiff = ABSF(GET_ENTITY_HEADING(sStolenCars[iChosenCar].veh) - fNewHeading)
IF fHeadingDiff > 180.0
fHeadingDiff = ABSF(fHeadingDiff - 360.0)
ENDIF
IF fHeadingDiff < 90.0
SET_ENTITY_HEADING(sStolenCars[iChosenCar].veh, fNewHeading)
ELSE
SET_ENTITY_HEADING(sStolenCars[iChosenCar].veh, fNewHeading + 180.0)
ENDIF
SET_VEHICLE_ON_GROUND_PROPERLY(sStolenCars[iChosenCar].veh)
SET_VEHICLE_FORWARD_SPEED(sStolenCars[iChosenCar].veh, fPlayersSpeedAtSpikeStart * 0.5)
#IF IS_DEBUG_BUILD
PRINTLN("Car Steal Finale - repositioned player at road node for spike cutscene: ", vNewPos, " ", fNewHeading)
#ENDIF
ELSE
#IF IS_DEBUG_BUILD
PRINTLN("Car Steal Finale - Road node is occupied by mission entity: ", vNewPos)
#ENDIF
ENDIF
ENDIF
ENDIF
*/
camCutscene = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", TRUE)
SET_CAM_COORD(camCutscene, sSpikes[i].vCamPos)
SET_CAM_FOV(camCutscene, 30.0)
SHAKE_CAM(camCutscene, "HAND_SHAKE", 1.0)
POINT_CAM_AT_ENTITY(camCutscene, sSpikes[i].vehClosest, <<0.0, 0.0, 0.0>>)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
TASK_VEHICLE_MISSION_COORS_TARGET(PLAYER_PED_ID(), sStolenCars[iChosenCar].veh, vGasStationCarPos, MISSION_GOTO, 20.0, DRIVINGMODE_AVOIDCARS, 5.0, 10.0)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PLAYER_PED_ID(), TRUE)
KILL_CHASE_HINT_CAM(localChaseHintCamStruct) //kill focus cam on truck, see B*1457536
IF IS_AUDIO_SCENE_ACTIVE("CAR_4_FOCUS_ON_TRUCK") //stop focus on truck audio scene, see B*1457536
STOP_AUDIO_SCENE("CAR_4_FOCUS_ON_TRUCK")
ENDIF
IF NOT IS_AUDIO_SCENE_ACTIVE("CAR_4_SPIKES_CAM_SCENE") //start spikes audio scene
START_AUDIO_SCENE("CAR_4_SPIKES_CAM_SCENE")
ENDIF
INFORM_MISSION_STATS_OF_INCREMENT(CS4_SHREDS)
REPLAY_RECORD_BACK_FOR_TIME(3, 0.0, REPLAY_IMPORTANCE_HIGH)
sSpikes[i].iCutsceneTimer = GET_GAME_TIMER()
sSpikes[i].iCutsceneEvent++
ELSE
sSpikes[i].iCutsceneEvent = 0
ENDIF
ELIF sSpikes[i].iCutsceneEvent = 2 //Run the cutscene.
BOOL bEndCutscene
IF NOT IS_ENTITY_DEAD(sSpikes[i].vehClosest)
VECTOR vVehPos = GET_ENTITY_COORDS(sSpikes[i].vehClosest)
//Once the cop car hits spikes make it spin.
IF sSpikes[i].iForceTimer = 0
IF VDIST2(vVehPos, sSpikes[i].vPos) < 9.0
//Calculate the amount of time the force should be applied based on how fast the police car is going.
FLOAT fMaxSpeed = GET_VEHICLE_ESTIMATED_MAX_SPEED(sSpikes[i].vehClosest)
FLOAT fCurrentSpeed = GET_ENTITY_SPEED(sSpikes[i].vehClosest)
FLOAT fSpeedRatio = fCurrentSpeed / (fMaxSpeed - 20.0)
IF fSpeedRatio > 1.0
fSpeedRatio = 1.0
ELIF fSpeedRatio < 0.3
fSpeedRatio = 0.3
ENDIF
sSpikes[i].iForceTimer = GET_GAME_TIMER() - ROUND((1.0 - fSpeedRatio) * 1000.0)
IF GET_RANDOM_INT_IN_RANGE(0, 2) = 0
sSpikes[i].iForceDirection = 1
ELSE
sSpikes[i].iForceDirection = -1
ENDIF
SET_VEHICLE_TYRE_BURST(sSpikes[i].vehClosest, SC_WHEEL_CAR_FRONT_LEFT)
SET_VEHICLE_TYRE_BURST(sSpikes[i].vehClosest, SC_WHEEL_CAR_FRONT_RIGHT)
IF HAS_PTFX_ASSET_LOADED()
AND REQUEST_SCRIPT_AUDIO_BANK("CAR_THEFT_FINALE")
START_PARTICLE_FX_NON_LOOPED_ON_ENTITY("scr_carsteal5_tyre_spiked", sSpikes[i].vehClosest, <<1.200, 2.000, -0.300>>, <<0.0, 0.0, 0.0>>)
START_PARTICLE_FX_NON_LOOPED_ON_ENTITY("scr_carsteal5_tyre_spiked", sSpikes[i].vehClosest, <<-1.200, 2.000, -0.300>>, <<0.0, 0.0, 0.0>>)
PLAY_SOUND_FROM_ENTITY(-1, "tyre", sSpikes[i].vehClosest, "CAR_THEFT_DB5_ESCAPE")
ENDIF
ENDIF
ELIF GET_GAME_TIMER() - sSpikes[i].iForceTimer < 1000
APPLY_FORCE_TO_ENTITY(sSpikes[i].vehClosest, APPLY_TYPE_FORCE, <<25.0 * sSpikes[i].iForceDirection, 0.0, 0.0>>, <<0.0, -2.0, 0.0>>, 0, TRUE, TRUE, TRUE)
ELIF GET_GAME_TIMER() - sSpikes[i].iForceTimer > 1750
PED_INDEX pedPassenger = GET_PED_IN_VEHICLE_SEAT(sSpikes[i].vehClosest, VS_FRONT_RIGHT)
IF NOT IS_PED_INJURED(pedPassenger)
AND GET_SCRIPT_TASK_STATUS(pedPassenger, SCRIPT_TASK_DRIVE_BY) != PERFORMING_TASK
TASK_DRIVE_BY(pedPassenger, PLAYER_PED_ID(), NULL, <<0.0, 0.0, 0.0>>, 50.0, 100)
ENDIF
ENDIF
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_EXIT)
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)
//End the cutscene after a few seconds
IF GET_GAME_TIMER() - sSpikes[i].iCutsceneTimer > 2000
bEndCutscene = TRUE
ENDIF
ELSE
bEndCutscene = TRUE
ENDIF
IF NOT DOES_CAM_EXIST(camCutscene)
bEndCutscene = TRUE
ENDIF
IF bEndCutscene
//Test for escort truck mission: if a cop car is spiked then kill the driver so it adds to the cops tally.
IF eMissionStage = STAGE_ESCORT_TRUCK
PED_INDEX pedDriver = GET_PED_IN_VEHICLE_SEAT(sSpikes[i].vehClosest, VS_DRIVER)
PED_INDEX pedPassenger = GET_PED_IN_VEHICLE_SEAT(sSpikes[i].vehClosest, VS_FRONT_RIGHT)
IF NOT IS_PED_INJURED(pedDriver)
APPLY_DAMAGE_TO_PED(pedDriver, 200, TRUE)
ENDIF
IF NOT IS_PED_INJURED(pedPassenger)
APPLY_DAMAGE_TO_PED(pedPassenger, 200, TRUE)
ENDIF
ENDIF
CLEAR_PED_TASKS(PLAYER_PED_ID())
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PLAYER_PED_ID(), FALSE)
IF IS_AUDIO_SCENE_ACTIVE("CAR_4_SPIKES_CAM_SCENE")
STOP_AUDIO_SCENE("CAR_4_SPIKES_CAM_SCENE")
ENDIF
DESTROY_ALL_CAMS()
RENDER_SCRIPT_CAMS(FALSE, FALSE)
REMOVE_PTFX_ASSET()
sSpikes[i].iCutsceneEvent = 0
sSpikes[i].vPos = <<0.0, 0.0, 0.0>>
ENDIF
ENDIF
ENDIF
ENDREPEAT
ENDIF
ENDPROC
PROC DISABLE_VEH_CONTROLS()
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_EXIT)
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)
ENDPROC
/// PURPOSE:
/// Reduces wanted level based on the number of scripted cops killed rather than ambient cops.
FUNC BOOL UPDATE_WANTED_LEVEL_DURING_ESCORT_2()
INT i = 0
INT iMaxNumCopCars = COUNT_OF(vehChaseCops)
INT iNumCarsStillAlive = 0
FLOAT fClosestCopDist = 0.0
FLOAT fClosestCopDistToPlayer = 0.0
//Count the number of scripted cops still alive.
REPEAT iMaxNumCopCars i
IF IS_VEHICLE_DRIVEABLE(vehChaseCops[i])
iNumCarsStillAlive++
ELIF i >= iNumChaseCopCarsCreated
iNumCarsStillAlive++
ENDIF
ENDREPEAT
//Get the closest cop car, this is used later to determine when the player is clear of all cop vehicles.
VEHICLE_INDEX vehCops[10]
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
GET_PED_NEARBY_VEHICLES(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], vehCops)
REPEAT COUNT_OF(vehCops) i
IF DOES_ENTITY_EXIST(vehCops[i])
IF IS_MODEL_POLICE_VEHICLE(GET_ENTITY_MODEL(vehCops[i]))
OR GET_ENTITY_MODEL(vehCops[i]) = modelCopCar
IF NOT IS_ENTITY_DEAD(vehCops[i])
FLOAT fCopDist = VDIST2(GET_ENTITY_COORDS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR]), GET_ENTITY_COORDS(vehCops[i]))
FLOAT fCopDistToPlayer = VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(vehCops[i]))
IF fClosestCopDist = 0.0 OR fCopDist < fClosestCopDist
fClosestCopDist = fCopDist
ENDIF
IF fClosestCopDistToPlayer = 0.0 OR fCopDistToPlayer < fClosestCopDistToPlayer
fClosestCopDistToPlayer = fCopDistToPlayer
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
ENDIF
SWITCH iCopsTrashEvent
CASE 0 //3 star wanted level
UPDATE_WANTED_POSITION_THIS_FRAME(PLAYER_ID())
SUPPRESS_LOSING_WANTED_LEVEL_IF_HIDDEN_THIS_FRAME(PLAYER_ID())
REPORT_POLICE_SPOTTED_PLAYER(PLAYER_ID())
IF iNumChaseCopCarsCreated >= 5
SET_MAX_WANTED_LEVEL(2)
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 2)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
iCopsTrashEvent++
ENDIF
BREAK
CASE 1 //2 star wanted level.
UPDATE_WANTED_POSITION_THIS_FRAME(PLAYER_ID())
SUPPRESS_LOSING_WANTED_LEVEL_IF_HIDDEN_THIS_FRAME(PLAYER_ID())
REPORT_POLICE_SPOTTED_PLAYER(PLAYER_ID())
IF iNumChaseCopCarsCreated >= iMaxNumCopCars - 1
//SET_MAX_WANTED_LEVEL(1)
//SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 1)
// SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
iCopsTrashEvent++
ENDIF
BREAK
CASE 2 //1 star wanted level.
UPDATE_WANTED_POSITION_THIS_FRAME(PLAYER_ID())
SUPPRESS_LOSING_WANTED_LEVEL_IF_HIDDEN_THIS_FRAME(PLAYER_ID())
REPORT_POLICE_SPOTTED_PLAYER(PLAYER_ID())
IF NOT IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
OR (iNumCarsStillAlive = 0 AND iNumChaseCopCarsCreated >= iMaxNumCopCars)
#IF IS_DEBUG_BUILD
IF NOT IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
PRINTLN("carsteal4.sc - Player lost wanted level early. iNumCarsStillAlive = ", iNumCarsStillAlive)
ENDIF
#ENDIF
SET_MAX_WANTED_LEVEL(1)
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 1)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
iCopsTrashEvent = 50
iCopsLostTimer = GET_GAME_TIMER()
ENDIF
BREAK
CASE 50 //Wait until the nearest cop ped is further away, then continue.
//Play some dialogue after the player kills the final cop car.
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_CDONE")
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF IS_GAMEPLAY_CAM_RENDERING() //Don't play during the spikes cutscene.
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_CDONE", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_CDONE", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
IF (NOT IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
OR (iNumCarsStillAlive = 0 AND iNumChaseCopCarsCreated >= iMaxNumCopCars))
IF GET_GAME_TIMER() - iCopsLostTimer > 10000
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
CLEAR_PLAYER_WANTED_LEVEL(PLAYER_ID())
SET_WANTED_LEVEL_MULTIPLIER(0.0)
SET_MAX_WANTED_LEVEL(5)
iCopsTrashEvent = 100
ENDIF
ELSE
iCopsLostTimer = GET_GAME_TIMER()
ENDIF
BREAK
CASE 100
RETURN TRUE
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
FUNC BOOL GET_COP_SPAWN_POS_FROM_PLAYER(VECTOR &vSpawnPos, FLOAT &fSpawnHeading, INT iCopIndex, FLOAT fSpawnOffset = -50.0)
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
AND NOT IS_ENTITY_DEAD(sTruck.vehFront)
VECTOR vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID())
VECTOR vTruckPos = GET_ENTITY_COORDS(sTruck.vehBack)
VECTOR vClosestNodeToPlayer, vClosestNodePos, vPlayerOffset
FLOAT fClosestNodeHeading, fHeadingFromNodeToPlayer, fHeadingDiff, fHeadingFromPlayerToTruck
INT iNumLanes
IF GET_CLOSEST_VEHICLE_NODE(vPlayerPos, vClosestNodeToPlayer, NF_INCLUDE_SWITCHED_OFF_NODES)
IF VDIST2(vPlayerPos, vClosestNodeToPlayer) < 100.0
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), sTruck.vehFront)
fHeadingFromPlayerToTruck = GET_ENTITY_HEADING(sTruck.vehFront)
ELSE
fHeadingFromPlayerToTruck = GET_HEADING_FROM_VECTOR_2D(vTruckPos.x - vPlayerPos.x, vTruckPos.y - vPlayerPos.y)
ENDIF
vPlayerOffset = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vPlayerPos, fHeadingFromPlayerToTruck, <<0.0, fSpawnOffset, 0.0>>)
IF GET_NTH_CLOSEST_VEHICLE_NODE_WITH_HEADING(vPlayerOffset, 1, vClosestNodePos, fClosestNodeHeading, iNumLanes, NF_INCLUDE_SWITCHED_OFF_NODES)
vSpawnPos = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vClosestNodePos, fClosestNodeHeading, <<0.0, -10.0 * iCopIndex, 0.0>>)
IF NOT IS_SPHERE_VISIBLE(vSpawnPos, 3.0)
OR IS_SCREEN_FADED_OUT()
//AND NOT IS_AREA_OCCUPIED(vSpawnPos - <<1.5, 1.5, 1.5>>, vSpawnPos + <<1.5, 1.5, 1.5>>, FALSE, TRUE, FALSE, FALSE, FALSE)
fHeadingFromNodeToPlayer = GET_HEADING_FROM_VECTOR_2D(vPlayerPos.x - vSpawnPos.x, vPlayerPos.y - vSpawnPos.y)
fHeadingDiff = ABSF(fHeadingFromNodeToPlayer - fClosestNodeHeading)
IF fHeadingDiff > 180.0
fHeadingDiff = ABSF(fHeadingDiff - 360.0)
ENDIF
IF fHeadingDiff < 90.0
fSpawnHeading = fClosestNodeHeading
ELSE
fSpawnHeading = fClosestNodeHeading + 180.0
ENDIF
#IF IS_DEBUG_BUILD
PRINTLN("Cop spawn: ", vSpawnPos, " ", fSpawnHeading)
#ENDIF
iReplayCameraWarpTimer = GET_GAME_TIMER() + 1000 //Fix for bug 2229446
RETURN TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/*PROC GET_COP_SPAWN_POS_FROM_TRUCK(VECTOR &vSpawnPos, FLOAT &fSpawnHeading, FLOAT fDistanceFromTruck = -100.0)
VECTOR vPlayerOffsetFromTruck, vInitialSpawnPos
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
vPlayerOffsetFromTruck = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(sTruck.vehBack, GET_ENTITY_COORDS(PLAYER_PED_ID()))
IF vPlayerOffsetFromTruck.y > 0.0
vPlayerOffsetFromTruck.y = 0.0
ENDIF
vInitialSpawnPos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehBack, <<0.0, fDistanceFromTruck, 0.0>> + <<0.0, vPlayerOffsetFromTruck.y, 0.0>>)
GET_NTH_CLOSEST_VEHICLE_NODE_FAVOUR_DIRECTION(vInitialSpawnPos, GET_ENTITY_COORDS(sTruck.vehBack), 1, vSpawnPos, fSpawnHeading)
#IF IS_DEBUG_BUILD
PRINTLN("Cop spawn pos: ", vInitialSpawnPos)
#ENDIF
ENDIF
ENDPROC*/
PROC MANAGE_CHASE_COP_IN_VEHICLE(MISSION_PED &ped, VEHICLE_INDEX CopVehicleIndex, PED_INDEX CopDriverPedIndex, VEHICLE_SEAT VehicleSeat, VEHICLE_INDEX TruckVehicleIndex, PED_INDEX TargetPedIndex)
IF DOES_ENTITY_EXIST(ped.ped)
IF NOT IS_ENTITY_DEAD(ped.ped)
FLOAT fDistToTruck = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(TruckVehicleIndex, FALSE), GET_ENTITY_COORDS(CopVehicleIndex, FALSE))
#IF IS_DEBUG_BUILD
DRAW_DEBUG_TEXT_ABOVE_ENTITY(ped.ped, GET_STRING_FROM_FLOAT(fDistToTruck), 1.5)
DRAW_DEBUG_TEXT_ABOVE_ENTITY(ped.ped, GET_COP_STATE_NAME_FOR_DEBUG(ped.iEvent), 1.0)
#ENDIF
SWITCH ped.iEvent
CASE COP_STATE_IDLE
IF ( ped.bHasTask = FALSE )
GIVE_WEAPON_TO_PED(ped.ped, WEAPONTYPE_PISTOL, INFINITE_AMMO)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped.ped, TRUE)
ped.bHasTask = TRUE
ENDIF
IF DOES_ENTITY_EXIST(CopVehicleIndex)
AND NOT IS_ENTITY_DEAD(CopVehicleIndex)
AND IS_VEHICLE_DRIVEABLE(CopVehicleIndex)
IF IS_PED_SITTING_IN_THIS_VEHICLE(ped.ped, CopVehicleIndex)
SWITCH GET_PED_VEHICLE_SEAT(ped.ped, CopVehicleIndex)
CASE VS_DRIVER
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_CHASE_TRUCK_DRIVER
BREAK
CASE VS_FRONT_RIGHT
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_CHASE_TRUCK_PASSENGER
BREAK
ENDSWITCH
ENDIF
ELSE
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_COMBAT_ON_FOOT
ENDIF
BREAK
CASE COP_STATE_ESCORT_TRUCK
IF ( ped.bHasTask = FALSE )
IF IS_VEHICLE_DRIVEABLE(TruckVehicleIndex)
IF IS_VEHICLE_DRIVEABLE(CopVehicleIndex)
TASK_VEHICLE_MISSION(ped.ped, CopVehicleIndex, TruckVehicleIndex, MISSION_ESCORT_LEFT, 50.0, DRIVINGMODE_AVOIDCARS_RECKLESS, 5.0, 10.0)
ENDIF
ENDIF
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped.ped, TRUE)
iEscortTimer = GET_GAME_TIMER()
ped.bHasTask = TRUE
ENDIF
IF ( ped.bHasTask = TRUE )
IF DOES_ENTITY_EXIST(CopVehicleIndex)
IF NOT IS_ENTITY_DEAD(CopVehicleIndex)
IF IS_VEHICLE_TYRE_BURST(CopVehicleIndex, SC_WHEEL_CAR_FRONT_LEFT, TRUE)
OR IS_VEHICLE_TYRE_BURST(CopVehicleIndex, SC_WHEEL_CAR_FRONT_RIGHT, TRUE)
OR IS_VEHICLE_TYRE_BURST(CopVehicleIndex, SC_WHEEL_CAR_REAR_LEFT, TRUE)
OR IS_VEHICLE_TYRE_BURST(CopVehicleIndex, SC_WHEEL_CAR_REAR_RIGHT, TRUE)
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_COMBAT_ON_FOOT
ENDIF
IF NOT IS_PED_IN_VEHICLE(ped.ped, CopVehicleIndex)
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_COMBAT_ON_FOOT
ENDIF
IF IS_PED_JACKING(TargetPedIndex) AND GET_VEHICLE_PED_IS_USING(TargetPedIndex) = CopVehicleIndex
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_COMBAT_ON_FOOT
ENDIF
IF IS_PED_IN_VEHICLE(ped.ped, CopVehicleIndex)
IF IS_VEHICLE_DRIVEABLE(TruckVehicleIndex)
IF ( fDistToTruck < 40.0 )
IF IS_VEHICLE_STOPPED(TruckVehicleIndex)
OR IS_VEHICLE_SEAT_FREE(TruckVehicleIndex, VS_DRIVER)
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_COMBAT_ON_FOOT
ENDIF
ENDIF
ENDIF
IF GET_GAME_TIMER() - iEscortTimer > 45000
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_CHASE_TRUCK_DRIVER
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE COP_STATE_CHASE_TRUCK_DRIVER
IF ( ped.bHasTask = FALSE )
IF IS_VEHICLE_DRIVEABLE(TruckVehicleIndex)
IF DOES_ENTITY_EXIST(GET_PED_IN_VEHICLE_SEAT(TruckVehicleIndex, VS_DRIVER))
TASK_VEHICLE_CHASE(ped.ped, GET_PED_IN_VEHICLE_SEAT(TruckVehicleIndex, VS_DRIVER))
ELSE
IF IS_VEHICLE_DRIVEABLE(CopVehicleIndex)
TASK_VEHICLE_MISSION(ped.ped, CopVehicleIndex, TruckVehicleIndex, MISSION_GOTO, 25.0, DRIVINGMODE_AVOIDCARS_RECKLESS, 20.0, 20.0)
ENDIF
ENDIF
ENDIF
GIVE_WEAPON_TO_PED(ped.ped, WEAPONTYPE_PISTOL, INFINITE_AMMO)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped.ped, TRUE)
ped.bHasTask = TRUE
ENDIF
IF ( ped.bHasTask = TRUE )
IF GET_SCRIPT_TASK_STATUS(ped.ped, SCRIPT_TASK_VEHICLE_CHASE) = PERFORMING_TASK
SET_TASK_VEHICLE_CHASE_BEHAVIOR_FLAG(ped.ped, VEHICLE_CHASE_CANT_RAM, TRUE)
SET_TASK_VEHICLE_CHASE_BEHAVIOR_FLAG(ped.ped, VEHICLE_CHASE_CANT_BLOCK, TRUE)
SET_TASK_VEHICLE_CHASE_BEHAVIOR_FLAG(ped.ped, VEHICLE_CHASE_CANT_BLOCK_FROM_PURSUE, TRUE)
SET_TASK_VEHICLE_CHASE_BEHAVIOR_FLAG(ped.ped, VEHICLE_CHASE_CANT_MAKE_AGGRESSIVE_MOVE, TRUE)
IF eSwitchCamState = SWITCH_CAM_IDLE
SET_TASK_VEHICLE_CHASE_IDEAL_PURSUIT_DISTANCE(ped.ped, 20.0)
ELSE
SET_TASK_VEHICLE_CHASE_IDEAL_PURSUIT_DISTANCE(ped.ped, 60.0)
ENDIF
ENDIF
IF DOES_ENTITY_EXIST(CopVehicleIndex)
IF NOT IS_ENTITY_DEAD(CopVehicleIndex)
IF IS_VEHICLE_TYRE_BURST(CopVehicleIndex, SC_WHEEL_CAR_FRONT_LEFT, TRUE)
OR IS_VEHICLE_TYRE_BURST(CopVehicleIndex, SC_WHEEL_CAR_FRONT_RIGHT, TRUE)
OR IS_VEHICLE_TYRE_BURST(CopVehicleIndex, SC_WHEEL_CAR_REAR_LEFT, TRUE)
OR IS_VEHICLE_TYRE_BURST(CopVehicleIndex, SC_WHEEL_CAR_REAR_RIGHT, TRUE)
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_COMBAT_ON_FOOT
ENDIF
IF NOT IS_PED_IN_VEHICLE(ped.ped, CopVehicleIndex)
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_COMBAT_ON_FOOT
ENDIF
IF IS_PED_JACKING(TargetPedIndex) AND GET_VEHICLE_PED_IS_USING(TargetPedIndex) = CopVehicleIndex
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_COMBAT_ON_FOOT
ENDIF
IF IS_PED_IN_VEHICLE(ped.ped, CopVehicleIndex)
IF IS_VEHICLE_DRIVEABLE(TruckVehicleIndex)
IF ( fDistToTruck < 40.0 )
IF IS_VEHICLE_STOPPED(TruckVehicleIndex)
OR IS_VEHICLE_SEAT_FREE(TruckVehicleIndex, VS_DRIVER)
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_COMBAT_ON_FOOT
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE COP_STATE_CHASE_TRUCK_PASSENGER
IF ( ped.bHasTask = FALSE )
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped.ped, TRUE)
ped.bHasTask = TRUE
ENDIF
IF ( ped.bHasTask = TRUE )
IF DOES_ENTITY_EXIST(CopVehicleIndex)
IF NOT IS_ENTITY_DEAD(CopVehicleIndex)
IF NOT IS_PED_IN_VEHICLE(ped.ped, CopVehicleIndex)
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_COMBAT_ON_FOOT
ENDIF
IF IS_PED_JACKING(TargetPedIndex) AND GET_VEHICLE_PED_IS_USING(TargetPedIndex) = CopVehicleIndex
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_COMBAT_ON_FOOT
ENDIF
IF IS_PED_IN_VEHICLE(ped.ped, CopVehicleIndex)
IF IS_PED_INJURED(CopDriverPedIndex)
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_CHASE_TRUCK_DRIVER
ENDIF
IF IS_VEHICLE_DRIVEABLE(TruckVehicleIndex)
IF ( fDistToTruck < 40.0 )
IF IS_VEHICLE_STOPPED(TruckVehicleIndex)
OR IS_VEHICLE_SEAT_FREE(TruckVehicleIndex, VS_DRIVER)
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_COMBAT_ON_FOOT
ENDIF
ENDIF
ENDIF
IF eMissionStage = STAGE_ESCORT_TRUCK
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(ped.ped, TargetPedIndex)
OR HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(CopVehicleIndex, TargetPedIndex)
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_PASSENGER_DRIVE_BY
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE COP_STATE_PASSENGER_DRIVE_BY
IF ( ped.bHasTask = FALSE )
SET_PED_COMBAT_ATTRIBUTES(ped.ped, CA_CAN_BUST, FALSE)
SET_PED_COMBAT_ATTRIBUTES(ped.ped, CA_USE_VEHICLE, TRUE)
SET_PED_COMBAT_ATTRIBUTES(ped.ped, CA_DO_DRIVEBYS, TRUE)
SET_PED_COMBAT_ATTRIBUTES(ped.ped, CA_LEAVE_VEHICLES, FALSE)
TASK_COMBAT_PED(ped.ped, TargetPedIndex, COMBAT_PED_PREVENT_CHANGING_TARGET)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped.ped, FALSE)
ped.bHasTask = TRUE
ENDIF
IF ( ped.bHasTask = TRUE )
IF DOES_ENTITY_EXIST(CopVehicleIndex)
IF NOT IS_ENTITY_DEAD(CopVehicleIndex)
IF NOT IS_PED_IN_VEHICLE(ped.ped, CopVehicleIndex)
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_COMBAT_ON_FOOT
ENDIF
IF IS_PED_JACKING(TargetPedIndex) AND GET_VEHICLE_PED_IS_USING(TargetPedIndex) = CopVehicleIndex
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_COMBAT_ON_FOOT
ENDIF
IF IS_PED_IN_VEHICLE(ped.ped, CopVehicleIndex)
IF IS_PED_INJURED(CopDriverPedIndex)
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_CHASE_TRUCK_DRIVER
ENDIF
IF IS_VEHICLE_DRIVEABLE(TruckVehicleIndex)
IF ( fDistToTruck < 40.0 )
IF IS_VEHICLE_STOPPED(TruckVehicleIndex)
OR IS_VEHICLE_SEAT_FREE(TruckVehicleIndex, VS_DRIVER)
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_COMBAT_ON_FOOT
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE COP_STATE_COMBAT_ON_FOOT
IF ( ped.bHasTask = FALSE )
SET_PED_COMBAT_RANGE(ped.ped, CR_NEAR)
SET_PED_COMBAT_MOVEMENT(ped.ped, CM_WILLADVANCE)
SET_PED_COMBAT_ABILITY(ped.ped, CAL_PROFESSIONAL)
SET_COMBAT_FLOAT(ped.ped, CCF_STRAFE_WHEN_MOVING_CHANCE, 0.9)
SET_PED_COMBAT_ATTRIBUTES(ped.ped, CA_CAN_BUST, TRUE)
SET_PED_COMBAT_ATTRIBUTES(ped.ped, CA_USE_VEHICLE, FALSE)
SET_PED_COMBAT_ATTRIBUTES(ped.ped, CA_DO_DRIVEBYS, FALSE)
SET_PED_COMBAT_ATTRIBUTES(ped.ped, CA_LEAVE_VEHICLES, TRUE)
SET_COMBAT_FLOAT(ped.ped, CCF_MIN_DISTANCE_TO_TARGET, 15.0)
//TASK_ARREST_PED(ped.ped, TargetPedIndex)
TASK_COMBAT_PED(ped.ped, TargetPedIndex)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped.ped, FALSE)
ped.bHasTask = TRUE
ENDIF
IF ( ped.bHasTask = TRUE )
IF IS_VEHICLE_DRIVEABLE(CopVehicleIndex)
AND IS_VEHICLE_DRIVEABLE(TruckVehicleIndex)
IF DOES_ENTITY_EXIST(GET_PED_IN_VEHICLE_SEAT(TruckVehicleIndex, VS_DRIVER))
IF NOT IS_ENTITY_DEAD(GET_PED_IN_VEHICLE_SEAT(TruckVehicleIndex, VS_DRIVER))
IF IS_PED_SITTING_IN_VEHICLE(GET_PED_IN_VEHICLE_SEAT(TruckVehicleIndex, VS_DRIVER), TruckVehicleIndex)
IF NOT IS_VEHICLE_STOPPED(TruckVehicleIndex)
IF ( fDistToTruck > 50.0 )
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_ENTER_COP_CAR
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE COP_STATE_ENTER_COP_CAR
IF ( ped.bHasTask = FALSE )
IF IS_VEHICLE_DRIVEABLE(CopVehicleIndex)
IF NOT IS_PED_INJURED(CopDriverPedIndex)
IF IS_VEHICLE_SEAT_FREE(CopVehicleIndex, VehicleSeat)
TASK_ENTER_VEHICLE(ped.ped, CopVehicleIndex, DEFAULT_TIME_BEFORE_WARP * 2, VehicleSeat, PEDMOVE_RUN, ECF_DONT_JACK_ANYONE | ECF_RESUME_IF_INTERRUPTED)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped.ped, TRUE)
ENDIF
ELSE
IF IS_VEHICLE_SEAT_FREE(CopVehicleIndex, VS_DRIVER)
TASK_ENTER_VEHICLE(ped.ped, CopVehicleIndex, DEFAULT_TIME_BEFORE_WARP * 2, VS_DRIVER, PEDMOVE_RUN, ECF_RESUME_IF_INTERRUPTED)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped.ped, TRUE)
ENDIF
ENDIF
ENDIF
ped.bHasTask = TRUE
ENDIF
IF IS_VEHICLE_DRIVEABLE(CopVehicleIndex)
IF IS_PED_SITTING_IN_VEHICLE(ped.ped, CopVehicleIndex)
//IF IS_PED_SITTING_IN_VEHICLE_SEAT(ped.ped, CopVehicleIndex, VehicleSeat)
SWITCH GET_PED_VEHICLE_SEAT(ped.ped, CopVehicleIndex)
CASE VS_DRIVER
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_CHASE_TRUCK_DRIVER
BREAK
CASE VS_FRONT_RIGHT
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(ped.ped, TargetPedIndex)
OR HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(CopVehicleIndex, TargetPedIndex)
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_PASSENGER_DRIVE_BY
ELSE
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_CHASE_TRUCK_PASSENGER
ENDIF
BREAK
ENDSWITCH
//ENDIF
ENDIF
ELSE
ped.bHasTask = FALSE
ped.iEvent = COP_STATE_COMBAT_ON_FOOT
ENDIF
BREAK
ENDSWITCH
ENDIF
ENDIF
ENDPROC
PROC UPDATE_CHASE_COPS()
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
AND NOT IS_ENTITY_DEAD(sTruck.vehFront)
VECTOR vCopSpawnPos
VECTOR vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID())
VECTOR vTruckPos = GET_ENTITY_COORDS(sTruck.vehBack)
FLOAT fCopSpawnHeading
REQUEST_MISSION_AUDIO_BANK("JWL_HEIST_CAR_SMASHES_BIG")
IF iNumChaseCopCarsCreated = 0
//The first cop car is created in advance at the same position every time. Once the player gets near it's activated.
IF NOT DOES_ENTITY_EXIST(vehChaseCops[0])
IF VDIST2(vPlayerPos, vCountrysideCopPos) < 40000.0
OR (VDIST2(GET_ENTITY_COORDS(sTruck.vehFront), vDropOffPos) < 16000000.0 AND VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), vCountrysideCopPos) > 4000000.0)
OR eMissionStage = STAGE_ESCORT_TRUCK
REQUEST_MODEL(modelCop)
REQUEST_MODEL(modelCopCar)
IF HAS_MODEL_LOADED(modelCop)
AND HAS_MODEL_LOADED(modelCopCar)
IF eMissionStage = STAGE_ESCORT_TRUCK
OR VDIST2(vPlayerPos, vCountrysideCopPos) > 40000.0
//If we skipped straight to the escort stage just create the car behind the truck.
IF GET_COP_SPAWN_POS_FROM_PLAYER(vCopSpawnPos, fCopSpawnHeading, 0, -40.0)
IF VDIST2(vPlayerPos, vCopSpawnPos) < 40000.0
CLEAR_AREA(vCopSpawnPos, 3.0, TRUE)
vehChaseCops[0] = CREATE_VEHICLE(modelCopCar, vCopSpawnPos, fCopSpawnHeading)
ENDIF
ENDIF
ELSE
vehChaseCops[0] = CREATE_VEHICLE(modelCopCar, vCountrysideCopPos, 54.7075)
ENDIF
IF DOES_ENTITY_EXIST(vehChaseCops[0])
ADD_ENTITY_TO_AUDIO_MIX_GROUP(vehChaseCops[0], "CAR_4_COPS_GROUP")
sChaseCops[0].ped = CREATE_PED_INSIDE_VEHICLE(vehChaseCops[0], PEDTYPE_COP, modelCop)
sChaseCops[1].ped = CREATE_PED_INSIDE_VEHICLE(vehChaseCops[0], PEDTYPE_COP, modelCop, VS_FRONT_RIGHT)
SET_MODEL_AS_NO_LONGER_NEEDED(modelCopCar)
SET_MODEL_AS_NO_LONGER_NEEDED(modelCop)
sChaseCops[0].iEvent = COP_STATE_ESCORT_TRUCK//COP_STATE_IDLE
sChaseCops[1].iEvent = COP_STATE_IDLE
sChaseCops[0].bHasTask = FALSE
sChaseCops[1].bHasTask = FALSE
fCurrentCopSpawnOffset = -60.0
iNumChaseCopCarsCreated++
#IF IS_DEBUG_BUILD
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created ", iNumChaseCopCarsCreated, ". cop car.")
PRINTLN(GET_THIS_SCRIPT_NAME(), ": iNumChaseCopCarsCreated: ", iNumChaseCopCarsCreated, ".")
#ENDIF
iReplayCameraWarpTimer = GET_GAME_TIMER() + 1000 //Fix for bug 2229446
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
AND NOT IS_ENTITY_DEAD(sTruck.vehBack)
AND NOT IS_ENTITY_DEAD(sTruck.vehFront)
REQUEST_MODEL(modelCop)
REQUEST_MODEL(modelCopCar)
INT iNumCopCarsAlive = 0
INT i, iDriverIndex, iPassengerIndex
FLOAT fDistToTruck
FLOAT fDistToPlayer
REPEAT COUNT_OF(vehChaseCops) i
iDriverIndex = i * 2
iPassengerIndex = iDriverIndex + 1
IF DOES_ENTITY_EXIST(vehChaseCops[i])
MANAGE_CHASE_COP_IN_VEHICLE(sChaseCops[iDriverIndex], vehChaseCops[i], sChaseCops[iDriverIndex].ped, VS_DRIVER, sTruck.vehFront, PLAYER_PED_ID())
MANAGE_CHASE_COP_IN_VEHICLE(sChaseCops[iPassengerIndex], vehChaseCops[i], sChaseCops[iDriverIndex].ped, VS_FRONT_RIGHT, sTruck.vehFront, PLAYER_PED_ID())
IF IS_VEHICLE_DRIVEABLE(vehChaseCops[i])
VECTOR vCarPos = GET_ENTITY_COORDS(vehChaseCops[i])
fDistToTruck = VDIST2(vTruckPos, vCarPos)
fDistToPlayer = VDIST2(vPlayerPos, vCarPos)
// SET_VEHICLE_ENGINE_ON(vehChaseCops[i], TRUE, TRUE)
// SET_VEHICLE_SIREN(vehChaseCops[i], TRUE)
// SET_SIREN_WITH_NO_DRIVER(vehChaseCops[i], TRUE)
// SET_VEHICLE_LIGHTS(vehChaseCops[i], FORCE_VEHICLE_LIGHTS_ON)
//Play some random lines from nearby drivers to stop the truck.
IF NOT IS_PED_INJURED(sChaseCops[iDriverIndex].ped)
IF sChaseCops[iDriverIndex].iEvent = COP_STATE_ESCORT_TRUCK
OR sChaseCops[iDriverIndex].iEvent = COP_STATE_CHASE_TRUCK_DRIVER
IF GET_GAME_TIMER() - iFranklinCopsShoutTimer > 0
AND NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF VDIST2(GET_ENTITY_COORDS(sChaseCops[iDriverIndex].ped), GET_ENTITY_COORDS(sTruck.vehBack)) < 1600.0
INT iRandom = GET_RANDOM_INT_IN_RANGE(0, 2)
IF eMissionStage = STAGE_ESCORT_TRUCK
IF VDIST2(GET_ENTITY_COORDS(sChaseCops[iDriverIndex].ped), GET_ENTITY_COORDS(PLAYER_PED_ID())) < 1600.0
//Player has driven off the truck, play more aggressive lines.
IF iRandom = 0
IF iNumTimesPlayedCopsWarn3 < 4
//remove speaker 4 & 6 to clear the conversation struct, fix for B*1581767
REMOVE_PED_FOR_DIALOGUE(sConversationPeds, 4)
REMOVE_PED_FOR_DIALOGUE(sConversationPeds, 6)
ADD_PED_FOR_DIALOGUE(sConversationPeds, 4, sChaseCops[iDriverIndex].ped, "CSTFCop1")
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_COPWAR3", CONV_PRIORITY_MEDIUM)
iFranklinCopsShoutTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(11000, 15000)
iNumTimesPlayedCopsWarn3++
ENDIF
ENDIF
ELSE
IF iNumTimesPlayedCopsWarn4 < 4
//remove speaker 4 & 6 to clear the conversation struct, fix for B*1581767
REMOVE_PED_FOR_DIALOGUE(sConversationPeds, 4)
REMOVE_PED_FOR_DIALOGUE(sConversationPeds, 6)
ADD_PED_FOR_DIALOGUE(sConversationPeds, 6, sChaseCops[iDriverIndex].ped, "CSTFCop2")
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_COPWAR4", CONV_PRIORITY_MEDIUM)
iFranklinCopsShoutTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(11000, 15000)
iNumTimesPlayedCopsWarn4++
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF VDIST2(GET_ENTITY_COORDS(sChaseCops[iDriverIndex].ped), GET_ENTITY_COORDS(PLAYER_PED_ID())) < 2500.0
//Player hasn't driven off yet, play some generic lines.
IF sConversationPeds.PedInfo[4].Index != sChaseCops[iDriverIndex].ped
ADD_PED_FOR_DIALOGUE(sConversationPeds, 4, sChaseCops[iDriverIndex].ped, "CSTFCop1")
ENDIF
IF iNumTimesPlayedCopsWarn1 < 2
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_COPWARN", CONV_PRIORITY_MEDIUM)
iFranklinCopsShoutTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(11000, 15000)
iNumTimesPlayedCopsWarn1++
ENDIF
ELIF iNumTimesPlayedCopsWarn2 < 4
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_COPWAR2", CONV_PRIORITY_MEDIUM)
iFranklinCopsShoutTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(11000, 15000)
iNumTimesPlayedCopsWarn2++
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
//If one of the drive-by cops shoots at the JB700 then play some dialogue.
IF eMissionStage = STAGE_ESCORT_TRUCK
IF GET_GAME_TIMER() - iFranklinShotByCopsTimer > 0
AND NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
AND NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[iChosenCar].veh)
AND NOT IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, sCarGadgets.caGunInput)
AND HAS_BULLET_IMPACTED_IN_AREA(GET_ENTITY_COORDS(PLAYER_PED_ID()), 2.5, FALSE)
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_SHOT", CONV_PRIORITY_MEDIUM)
iFranklinShotByCopsTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(10000, 12500)
ENDIF
ENDIF
ENDIF
ENDIF
//Kill them off if the vehicle was damaged enough, or if they were lost.
IF GET_VEHICLE_ENGINE_HEALTH(vehChaseCops[i]) < 400.0
OR GET_VEHICLE_PETROL_TANK_HEALTH(vehChaseCops[i]) < 400.0
OR (fDistToTruck > 40000.0 AND fDistToPlayer > 40000.0)
IF NOT IS_PED_INJURED(sChaseCops[iDriverIndex].ped)
AND IS_PED_IN_VEHICLE(sChaseCops[iDriverIndex].ped, vehChaseCops[i])
APPLY_DAMAGE_TO_PED(sChaseCops[iDriverIndex].ped, 200, TRUE)
REPLAY_RECORD_BACK_FOR_TIME(3.0, 5.0)
ELSE
REMOVE_PED(sChaseCops[iDriverIndex].ped, FALSE, FALSE)
ENDIF
IF NOT IS_PED_INJURED(sChaseCops[iPassengerIndex].ped)
AND IS_PED_IN_VEHICLE(sChaseCops[iPassengerIndex].ped, vehChaseCops[i])
APPLY_DAMAGE_TO_PED(sChaseCops[iPassengerIndex].ped, 200, TRUE)
ELSE
REMOVE_PED(sChaseCops[iPassengerIndex].ped, FALSE, FALSE)
ENDIF
//Reset the engine/tank health to try and stop instant explosions.
SET_VEHICLE_ENGINE_HEALTH(vehChaseCops[i], 900.0)
SET_VEHICLE_PETROL_TANK_HEALTH(vehChaseCops[i], 900.0)
IF REQUEST_MISSION_AUDIO_BANK("JWL_HEIST_CAR_SMASHES_BIG")
PLAY_SOUND_FROM_ENTITY(-1, "Destroy_Cop_Car", vehChaseCops[i], "JEWEL_HEIST_SOUNDS")
ENDIF
ELSE
//Car: increase damage from JB700 guns.
IF HAS_ENTITY_BEEN_DAMAGED_BY_JB700_GUNS(vehChaseCops[i], sStolenCars[iChosenCar].veh)
SET_VEHICLE_ENGINE_HEALTH(vehChaseCops[i], GET_VEHICLE_ENGINE_HEALTH(vehChaseCops[i]) - 100.0)
CLEAR_ENTITY_LAST_WEAPON_DAMAGE(vehChaseCops[i])
ENDIF
ENDIF
IF NOT IS_PED_INJURED(sChaseCops[iDriverIndex].ped)
AND NOT IS_PED_INJURED(sChaseCops[iPassengerIndex].ped)
iNumCopCarsAlive++
ELSE
IF IS_PED_INJURED(sChaseCops[iDriverIndex].ped)
AND IS_PED_INJURED(sChaseCops[iPassengerIndex].ped)
IF NOT IS_ENTITY_DEAD(vehChaseCops[i])
REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(vehChaseCops[i])
ENDIF
REMOVE_PED(sChaseCops[iDriverIndex].ped, FALSE, FALSE)
REMOVE_PED(sChaseCops[iPassengerIndex].ped, FALSE, FALSE)
REMOVE_VEHICLE(vehChaseCops[i])
ENDIF
ENDIF
ELSE
IF NOT IS_ENTITY_DEAD(vehChaseCops[i])
REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(vehChaseCops[i])
ENDIF
REMOVE_PED(sChaseCops[iDriverIndex].ped, FALSE, TRUE)
REMOVE_PED(sChaseCops[iPassengerIndex].ped, FALSE, TRUE)
REMOVE_VEHICLE(vehChaseCops[i])
ENDIF
ELSE
//Create more cops once other ones are killed.
IF NOT IS_SCREEN_FADED_OUT() //Don't create these cops if we're in the process of skipping.
IF i = iNumChaseCopCarsCreated
IF (iNumCopCarsAlive < 2 AND iNumChaseCopCarsCreated > 1)
OR (iNumCopCarsAlive < 1 AND iNumChaseCopCarsCreated = 1)
IF HAS_MODEL_LOADED(modelCop)
AND HAS_MODEL_LOADED(modelCopCar)
IF IS_PED_SITTING_IN_THIS_VEHICLE(PLAYER_PED_ID(),sTruck.vehFront) //only create cops if player is in mission vehicle
OR IS_PED_SITTING_IN_THIS_VEHICLE(PLAYER_PED_ID(), sStolenCars[iChosenCar].veh)
IF GET_COP_SPAWN_POS_FROM_PLAYER(vCopSpawnPos, fCopSpawnHeading, 0, fCurrentCopSpawnOffset)
IF VDIST2(vPlayerPos, vCopSpawnPos) < 40000.0
CLEAR_AREA(vCopSpawnPos, 3.0, TRUE)
vehChaseCops[i] = CREATE_VEHICLE(modelCopCar, vCopSpawnPos, fCopSpawnHeading)
SET_VEHICLE_ENGINE_ON(vehChaseCops[i], TRUE, TRUE)
SET_VEHICLE_SIREN(vehChaseCops[i], TRUE)
SET_SIREN_WITH_NO_DRIVER(vehChaseCops[i], TRUE)
SET_VEHICLE_LIGHTS(vehChaseCops[i], FORCE_VEHICLE_LIGHTS_ON)
ADD_ENTITY_TO_AUDIO_MIX_GROUP(vehChaseCops[i], "CAR_4_COPS_GROUP")
SET_VEHICLE_STRONG(vehChaseCops[i], TRUE) //Should hopefully prevent issues with the cars blowing up instantly.
SET_VEHICLE_ON_GROUND_PROPERLY(vehChaseCops[i])
sChaseCops[iDriverIndex].ped = CREATE_PED_INSIDE_VEHICLE(vehChaseCops[i], PEDTYPE_COP, modelCop)
sChaseCops[iPassengerIndex].ped = CREATE_PED_INSIDE_VEHICLE(vehChaseCops[i], PEDTYPE_COP, modelCop, VS_FRONT_RIGHT)
sChaseCops[iDriverIndex].iEvent = COP_STATE_IDLE
sChaseCops[iPassengerIndex].iEvent = COP_STATE_IDLE
sChaseCops[iDriverIndex].bHasTask = FALSE
sChaseCops[iPassengerIndex].bHasTask = FALSE
//Adjust the offset for the next cop so they're not created on top of each other.
IF fCurrentCopSpawnOffset = -50.0
fCurrentCopSpawnOffset = -60.0
ELIF fCurrentCopSpawnOffset = -60.0
fCurrentCopSpawnOffset = -50.0
ENDIF
iNumCopCarsAlive++
//increment the counter of cop cars if player is Franklin
//cops will be never ending if player is Trevor before the switch
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
iNumChaseCopCarsCreated++
#IF IS_DEBUG_BUILD
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created ", iNumChaseCopCarsCreated, ". cop car.")
PRINTLN(GET_THIS_SCRIPT_NAME(), ": iNumChaseCopCarsCreated: ", iNumChaseCopCarsCreated, ".")
#ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
ENDIF
ENDIF
ENDIF
ENDPROC
FUNC FLOAT GET_HEADING_OF_WAYPOINT_NODE(STRING strWaypoint, INT iNode, INT iMaxNodes)
VECTOR vNodePos, vNextNodePos
FLOAT fHeading
WAYPOINT_RECORDING_GET_COORD(strWaypoint, iNode, vNodePos)
IF iNode + 1 < iMaxNodes
WAYPOINT_RECORDING_GET_COORD(strWaypoint, iNode + 1, vNextNodePos)
fHeading = GET_HEADING_FROM_VECTOR_2D(vNextNodePos.x - vNodePos.x, vNextNodePos.y - vNodePos.y)
ENDIF
RETURN fHeading
ENDFUNC
FUNC BOOL IS_VEHICLE_ON_SAME_SIDE_AS_TRUCK(VEHICLE_INDEX veh, STRING strTruckWaypoint, INT iMaxWaypointNodes, INT iTruckNode)
IF NOT IS_ENTITY_DEAD(veh)
FLOAT fVehHeading = GET_ENTITY_HEADING(veh)
VECTOR vVehPos = GET_ENTITY_COORDS(veh)
INT iNode
WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(strTruckWaypoint, vVehPos, iNode)
IF iNode > iTruckNode //Car is in front of truck.
FLOAT fClosestNodeHeading = GET_HEADING_OF_WAYPOINT_NODE(strTruckWaypoint, iNode, iMaxWaypointNodes)
IF ABSF(fClosestNodeHeading - fVehHeading) < 45.0
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
PROC MOVE_CARS_OUT_OF_THE_WAY_OF_TREVORS_TRUCK()
SEQUENCE_INDEX seq
REQUEST_WAYPOINT_RECORDING(strWaypointTruckRoute)
IF GET_IS_WAYPOINT_RECORDING_LOADED(strWaypointTruckRoute)
IF NOT IS_ENTITY_DEAD(sTruck.vehFront)
AND NOT IS_ENTITY_DEAD(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
IF GET_GAME_TIMER() - iChaseHelperTimer > 1000
VECTOR vTruckPos = GET_ENTITY_COORDS(sTruck.vehFront)
INT iMaxNodes, iTruckNode
INT i = 0
BOOL bNextCarIsTooFar = FALSE
VEHICLE_INDEX vehTraffic[20]
WAYPOINT_RECORDING_GET_NUM_POINTS(strWaypointTruckRoute, iMaxNodes)
WAYPOINT_RECORDING_GET_CLOSEST_WAYPOINT(strWaypointTruckRoute, GET_ENTITY_COORDS(sTruck.vehFront), iTruckNode)
GET_PED_NEARBY_VEHICLES(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], vehTraffic)
WHILE i < 20
AND NOT bNextCarIsTooFar
IF NOT IS_ENTITY_DEAD(vehTraffic[i])
IF NOT IS_ENTITY_A_MISSION_ENTITY(vehTraffic[i])
AND GET_ENTITY_MODEL(vehTraffic[i]) != POLICE
VECTOR vTrafficPos = GET_ENTITY_COORDS(vehTraffic[i])
IF VDIST2(vTruckPos, vTrafficPos) < 900.0
IF IS_VEHICLE_ON_SAME_SIDE_AS_TRUCK(vehTraffic[i], strWaypointTruckRoute, iMaxNodes, iTruckNode)
#IF IS_DEBUG_BUILD
PRINTLN("Car in front of truck: ", vTrafficPos, " ", i)
#ENDIF
PED_INDEX pedDriver = GET_PED_IN_VEHICLE_SEAT(vehTraffic[i], VS_DRIVER)
IF NOT IS_PED_INJURED(pedDriver)
IF GET_SCRIPT_TASK_STATUS(pedDriver, SCRIPT_TASK_PERFORM_SEQUENCE) = FINISHED_TASK
OPEN_SEQUENCE_TASK(seq)
TASK_VEHICLE_TEMP_ACTION(NULL, vehTraffic[i], TEMPACT_SWERVELEFT, 3000)
TASK_VEHICLE_DRIVE_WANDER(NULL, vehTraffic[i], 15.0, DRIVINGMODE_STOPFORCARS_STRICT)
CLOSE_SEQUENCE_TASK(seq)
TASK_PERFORM_SEQUENCE(pedDriver, seq)
CLEAR_SEQUENCE_TASK(seq)
ENDIF
ENDIF
ENDIF
ELSE
bNextCarIsTooFar = TRUE
ENDIF
ENDIF
ENDIF
i++
ENDWHILE
iChaseHelperTimer = GET_GAME_TIMER()
ENDIF
ENDIF
ENDIF
ENDPROC
PROC UPDATE_TREVOR_AND_LAMAR_IN_TRUCK(BOOL bRefreshDriveTask = FALSE)
REQUEST_VEHICLE_ASSET(modelTruckFront)
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
AND NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
AND NOT IS_PED_INJURED(sLamar.ped)
//SET_VEHICLE_ACT_AS_IF_HAS_SIREN_ON(sTruck.vehFront, TRUE)
SET_VEHICLE_WILL_TELL_OTHERS_TO_HURRY(sTruck.vehFront, TRUE)
//SET_VEHICLE_ACT_AS_IF_HAS_SIREN_ON(sTruck.vehBack, TRUE)
SET_VEHICLE_WILL_TELL_OTHERS_TO_HURRY(sTruck.vehBack, TRUE)
IF IS_PED_GROUP_MEMBER(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], PLAYER_GROUP_ID())
REMOVE_PED_FROM_GROUP(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
ENDIF
IF NOT IS_PED_IN_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], sTruck.vehFront, TRUE)
IF GET_SCRIPT_TASK_STATUS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], SCRIPT_TASK_ENTER_VEHICLE) != PERFORMING_TASK
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], TRUE)
TASK_ENTER_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], sTruck.vehFront, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER)
ENDIF
ELIF IS_PED_SITTING_IN_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], sTruck.vehFront)
IF IS_PED_SITTING_IN_VEHICLE(sLamar.ped, sTruck.vehFront)
SWITCH iTrevorDriveEvent
CASE 0 //Drive to coords.
//If the player is in front of the truck then make Trevor stop.
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, <<0.0, 4.1723, -2.3128>>),
GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, <<0.0, 12.1723, 3.3128>>), 6.0)
OR IS_ENTITY_IN_ANGLED_AREA(sStolenCars[iChosenCar].veh, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, <<0.0, 4.1723, -2.3128>>),
GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, <<0.0, 12.1723, 3.3128>>), 6.0)
IF GET_SCRIPT_TASK_STATUS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], SCRIPT_TASK_VEHICLE_TEMP_ACTION) = FINISHED_TASK
IF GET_ENTITY_SPEED(sTruck.vehFront) > 1.0
TASK_VEHICLE_TEMP_ACTION(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], sTruck.vehFront, TEMPACT_BRAKE, -1)
ENDIF
ENDIF
ELSE
IF VDIST2(GET_ENTITY_COORDS(sTruck.vehFront), vDropOffPos) > 100.0
IF GET_SCRIPT_TASK_STATUS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], SCRIPT_TASK_VEHICLE_DRIVE_TO_COORD) = FINISHED_TASK
OR bRefreshDriveTask
TASK_VEHICLE_DRIVE_TO_COORD(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], sTruck.vehFront, vDropOffPos, 35.0,
DRIVINGSTYLE_NORMAL, modelTruckFront, DF_DontSteerAroundPlayerPed | DF_UseShortCutLinks, 10.0, 20.0)
ENDIF
ENDIF
REQUEST_WAYPOINT_RECORDING(strWaypointRouteEnd)
IF GET_IS_WAYPOINT_RECORDING_LOADED(strWaypointRouteEnd)
IF VDIST2(GET_ENTITY_COORDS(sTruck.vehFront), <<1250.4, 6483.8,19.9>>) < 100.0
iTrevorDriveEvent++
ENDIF
ENDIF
ENDIF
BREAK
CASE 1 //Use the waypoint (only if valid to do so).
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, <<0.0, 4.1723, -2.3128>>),
GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, <<0.0, 12.1723, 3.3128>>), 6.0)
OR IS_ENTITY_IN_ANGLED_AREA(sStolenCars[iChosenCar].veh, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, <<0.0, 4.1723, -2.3128>>),
GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, <<0.0, 12.1723, 3.3128>>), 6.0)
IF GET_SCRIPT_TASK_STATUS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], SCRIPT_TASK_VEHICLE_TEMP_ACTION) = FINISHED_TASK
IF GET_ENTITY_SPEED(sTruck.vehFront) > 1.0
TASK_VEHICLE_TEMP_ACTION(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], sTruck.vehFront, TEMPACT_BRAKE, -1)
ENDIF
ENDIF
ELSE
IF VDIST2(GET_ENTITY_COORDS(sTruck.vehFront), vDropOffPos) > 400.0
IF GET_SCRIPT_TASK_STATUS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], SCRIPT_TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING) = FINISHED_TASK
OR bRefreshDriveTask
TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], sTruck.vehFront, strWaypointRouteEnd, DRIVINGMODE_PLOUGHTHROUGH,
0, EWAYPOINT_START_FROM_CLOSEST_POINT, -1, 35.0, FALSE, 5.0)
ENDIF
ENDIF
ENDIF
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
IF IS_VEHICLE_STOPPED(sTruck.vehFront)
IF NOT HAS_SOUND_FINISHED(iScrapeSound)
STOP_SOUND(iScrapeSound)
RELEASE_NAMED_SCRIPT_AUDIO_BANK("CAR_STEAL_4")
ENDIF
ENDIF
ENDIF
BREAK
ENDSWITCH
//If cars get in the way of Trevor during the lose cops section then play horns randomly.
IF GET_GAME_TIMER() - iTrevorTruckHornTimer > 0
AND IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
/*VECTOR vTruckFront = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, <<0.0, 7.1723, 0.3128>>)
IF IS_AREA_OCCUPIED(vTruckFront - <<2.0, 2.0, 3.0>>, vTruckFront + <<2.0, 2.0, 3.0>>, FALSE, TRUE, FALSE, FALSE, FALSE, sTruck.vehFront, TRUE)
IF NOT IS_ENTITY_IN_AREA(PLAYER_PED_ID(), vTruckFront - <<3.0, 3.0, 3.0>>, vTruckFront + <<3.0, 3.0, 3.0>>)
//START_VEHICLE_HORN(sTruck.vehFront, 2000, HASH("NORMAL"))
iTrevorTruckHornTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(5000, 8000)
ENDIF
ENDIF*/
ENDIF
ENDIF
ENDIF
ENDIF
IF NOT IS_PED_INJURED(sLamar.ped)
If IS_PED_GROUP_MEMBER(sLamar.ped, PLAYER_GROUP_ID())
REMOVE_PED_FROM_GROUP(sLamar.ped)
ENDIF
IF NOT IS_PED_IN_VEHICLE(sLamar.ped, sTruck.vehFront, TRUE)
IF GET_SCRIPT_TASK_STATUS(sLamar.ped, SCRIPT_TASK_ENTER_VEHICLE) != PERFORMING_TASK
TASK_ENTER_VEHICLE(sLamar.ped, sTruck.vehFront, DEFAULT_TIME_BEFORE_WARP, VS_FRONT_RIGHT)
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC UPDATE_MOLLY_WAITING_BY_CAR()
VECTOR vSceneAttachOffset = <<-0.050, 0.000, -0.100>>
IF NOT IS_PED_INJURED(pedMolly)
AND IS_VEHICLE_DRIVEABLE(vehMollyCar)
REQUEST_ANIM_DICT(strMollyAnims)
IF HAS_ANIM_DICT_LOADED(strMollyAnims)
SWITCH eMollyState
CASE MOLLY_STATE_IN_CAR
BREAK
CASE MOLLY_STATE_LEAVING_CAR
BREAK
CASE MOLLY_STATE_IDLE
IF NOT IS_SYNCHRONIZED_SCENE_RUNNING(iMollySyncScene)
IF NOT IS_PED_RAGDOLL(pedMolly)
AND NOT IS_PED_GETTING_UP(pedMolly)
iMollySyncScene = CREATE_SYNCHRONIZED_SCENE(vSceneAttachOffset, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iMollySyncScene, vehMollyCar, 0)
TASK_SYNCHRONIZED_SCENE(pedMolly, iMollySyncScene, strMollyAnims, "ig_1_base", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_USE_PHYSICS,
RBF_MELEE | RBF_IMPACT_OBJECT | RBF_PLAYER_IMPACT)
SET_SYNCHRONIZED_SCENE_LOOPED(iMollySyncScene, TRUE)
SET_SYNCHRONIZED_SCENE_PHASE(iMollySyncScene, 0.0)
SET_ENTITY_NO_COLLISION_ENTITY(pedMolly, vehMollyCar, FALSE)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(pedMolly, TRUE)
SET_PED_CONFIG_FLAG(pedMolly, PCF_CanDiveAwayFromApproachingVehicles, FALSE)
ENDIF
ELSE
TEXT_LABEL strCurrentConvo
strCurrentConvo = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT()
IF ARE_STRINGS_EQUAL(strCurrentConvo, "CST7_MOLLY1")
iMollySyncScene = CREATE_SYNCHRONIZED_SCENE(vSceneAttachOffset, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iMollySyncScene, vehMollyCar, 0)
TASK_SYNCHRONIZED_SCENE(pedMolly, iMollySyncScene, strMollyAnims, "ig_1_idle_b", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_USE_PHYSICS,
RBF_MELEE | RBF_IMPACT_OBJECT | RBF_PLAYER_IMPACT)
SET_SYNCHRONIZED_SCENE_LOOPED(iMollySyncScene, FALSE)
SET_SYNCHRONIZED_SCENE_PHASE(iMollySyncScene, 0.0)
eMollyState = MOLLY_STATE_ANNOYED
ENDIF
ENDIF
BREAK
CASE MOLLY_STATE_ANNOYED
IF IS_SYNCHRONIZED_SCENE_RUNNING(iMollySyncScene)
IF GET_SYNCHRONIZED_SCENE_PHASE(iMollySyncScene) > 0.99
iMollySyncScene = CREATE_SYNCHRONIZED_SCENE(vSceneAttachOffset, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iMollySyncScene, vehMollyCar, 0)
TASK_SYNCHRONIZED_SCENE(pedMolly, iMollySyncScene, strMollyAnims, "ig_1_base", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, SYNCED_SCENE_USE_PHYSICS,
RBF_MELEE | RBF_IMPACT_OBJECT | RBF_PLAYER_IMPACT)
SET_SYNCHRONIZED_SCENE_LOOPED(iMollySyncScene, TRUE)
SET_SYNCHRONIZED_SCENE_PHASE(iMollySyncScene, 0.0)
eMollyState = MOLLY_STATE_IDLE
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDIF
ENDIF
ENDPROC
PROC UPDATE_MOLLY_GAMEPLAY_HINT()
IF DOES_ENTITY_EXIST(pedMolly)
IF NOT IS_ENTITY_DEAD(pedMolly)
IF NOT IS_GAMEPLAY_HINT_ACTIVE()
SET_GAMEPLAY_HINT_FOV(35.0)
SET_GAMEPLAY_ENTITY_HINT(pedMolly, << -1.0, 0.0, 0.5 >>, TRUE, -1, 2500)
SET_GAMEPLAY_HINT_CAMERA_BLEND_TO_FOLLOW_PED_MEDIUM_VIEW_MODE(TRUE)
SET_GAMEPLAY_HINT_CAMERA_RELATIVE_SIDE_OFFSET(-0.750)
SET_GAMEPLAY_HINT_CAMERA_RELATIVE_VERTICAL_OFFSET(0.050)
SET_GAMEPLAY_HINT_FOLLOW_DISTANCE_SCALAR(0.350)
SET_GAMEPLAY_HINT_BASE_ORBIT_PITCH_OFFSET(-4.000)
ENDIF
ENDIF
ENDIF
ENDPROC
PROC REMOVE_ALL_OBJECTS(BOOL bForceDelete = FALSE)
INT i = 0
REPEAT COUNT_OF(objSpikes) i
REMOVE_OBJECT(objSpikes[i], bForceDelete)
ENDREPEAT
ENDPROC
PROC REMOVE_ALL_PEDS(BOOL bForceDelete = FALSE)
REMOVE_PED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], bForceDelete)
REMOVE_PED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], bForceDelete)
REMOVE_PED(sLamar.ped, bForceDelete)
REMOVE_PED(pedSpikeHelper, TRUE)
REMOVE_PED(pedDevin, bForceDelete)
REMOVE_PED(pedOilSlickTest, bForceDelete)
INT i = 0
REPEAT COUNT_OF(sChaseCops) i
REMOVE_PED(sChaseCops[i].ped, bForceDelete, TRUE)
ENDREPEAT
ENDPROC
PROC REMOVE_ALL_VEHICLES(BOOL bForceDelete = FALSE)
INT i = 0
REPEAT COUNT_OF(sStolenCars) i
//If the cars are attached to the trailer, we cannot detach them as it'll be visible on camera (e.g. when dying)
IF bForceDelete
REMOVE_VEHICLE(sStolenCars[i].veh, bForceDelete)
ELSE
SET_VEHICLE_AS_NO_LONGER_NEEDED(sStolenCars[i].veh)
ENDIF
ENDREPEAT
REPEAT COUNT_OF(vehChaseCops) i
REMOVE_VEHICLE(vehChaseCops[i], bForceDelete)
ENDREPEAT
REMOVE_VEHICLE(sTruck.vehFront, bForceDelete, FALSE)
REMOVE_VEHICLE(sTruck.vehBack, bForceDelete, FALSE)
REMOVE_VEHICLE(vehOilSlickTest, bForceDelete)
ENDPROC
PROC REMOVE_ALL_CAMERAS()
BOOL bNeedToTurnOffCams = FALSE
IF DOES_CAM_EXIST(camCutscene)
IF IS_CAM_RENDERING(camCutscene)
bNeedToTurnOffCams = TRUE
ENDIF
DESTROY_CAM(camCutscene)
ENDIF
IF DOES_CAM_EXIST(camAttach)
IF IS_CAM_RENDERING(camAttach)
bNeedToTurnOffCams = TRUE
ENDIF
DESTROY_CAM(camAttach)
ENDIF
IF DOES_CAM_EXIST(camInterp)
IF IS_CAM_RENDERING(camInterp)
bNeedToTurnOffCams = TRUE
ENDIF
DESTROY_CAM(camInterp)
ENDIF
DISPLAY_RADAR(TRUE)
DISPLAY_HUD(TRUE)
IF bNeedToTurnOffCams
RENDER_SCRIPT_CAMS(FALSE, FALSE)
ENDIF
ENDPROC
FUNC BOOL INITIALISE_STOLEN_CAR_DATA()
//The array elements correspond to these positions on the back of the truck:
// --3-- --4-- --5-- |\
// | \
// --0-- --1-- --2-- | \
//-----------------------------|---\
sStolenCars[0].vTruckOffset = <<0.0, -5.0, 0.82>>
sStolenCars[0].vTruckRotation = <<3.8, 0.0, 0.0>>
sStolenCars[0].fPlaybackStartTime = 46164.0000
sStolenCars[0].iCarrec = 5
sStolenCars[0].model = MONROE
sStolenCars[1].vTruckOffset = <<0.0, 0.0, 0.95>>
sStolenCars[1].vTruckRotation = <<-2.6, 0.0, 0.0>>
sStolenCars[1].model = CHEETAH
sStolenCars[2].vTruckOffset = <<0.0, 5.0, 0.85>>
sStolenCars[2].vTruckRotation = <<0.09, 0.0, 0.0>>
sStolenCars[2].model = STINGER
sStolenCars[3].vTruckOffset = <<0.0, -5.0, 3.35>>
sStolenCars[3].vTruckRotation = <<0.09, 0.0, 0.0>>
sStolenCars[3].fPlaybackStartTime = 46045.0000
sStolenCars[3].iCarrec = 7 //6
sStolenCars[3].model = JB700
sStolenCars[4].vTruckOffset = <<0.0, -0.25, 2.95>>
sStolenCars[4].vTruckRotation = <<-4.67, 0.0, 0.0>>
sStolenCars[4].model = ENTITYXF
sStolenCars[5].vTruckOffset = <<0.0, 5.0, 2.91>>
sStolenCars[5].vTruckRotation = <<4.0, 0.0, 0.0>>
sStolenCars[5].model = ZTYPE
//Reset for P-skips
INT i = 0
REPEAT COUNT_OF(sStolenCars) i
sStolenCars[i].bFinishedSliding = FALSE
sStolenCars[i].bPlaybackStarted = FALSE
sStolenCars[i].bInContainer = FALSE
sStolenCars[i].bIsLocked = FALSE
sStolenCars[i].iDeathTimer = 0
ENDREPEAT
RETURN TRUE
ENDFUNC
PROC SET_CUTSCENE_PED_COMPONENT_VARIATIONS(STRING strCutsceneName)
INT iNameHash = GET_HASH_KEY(strCutsceneName)
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
IF iNameHash = HASH("CAR_5_MCS_1")
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Franklin", PLAYER_PED_ID())
IF NOT IS_PED_INJURED(sLamar.ped)
AND NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Lamar", sLamar.ped)
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Trevor", sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
ENDIF
ELIF iNameHash = HASH("CAR_5_MCS_2")
IF NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_FRANKLIN))
AND NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_TREVOR))
AND NOT IS_PED_INJURED(sLamar.ped)
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Franklin", GET_PED_INDEX(CHAR_FRANKLIN))
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Trevor", GET_PED_INDEX(CHAR_TREVOR))
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Lamar", sLamar.ped)
ENDIF
ELIF iNameHash = HASH("CAR_5_MCS_3")
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Franklin", PLAYER_PED_ID())
IF NOT IS_PED_INJURED(pedDevin)
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Devin", pedDevin)
ENDIF
ELIF iNameHash = HASH("CAR_5_EXT")
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Franklin", PLAYER_PED_ID())
IF NOT IS_PED_INJURED(pedMolly)
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("A_F_Y_Vinewood_02", pedMolly)
ENDIF
ENDIF
ENDIF
ENDPROC
//TEMP: suppress any large vehicles as the truck can't plough through them. Need a better way of doing this.
PROC SUPPRESS_LARGE_VEHICLES(BOOL bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(PACKER, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(PHANTOM, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(HAULER, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(POUNDER, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(SCRAP, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(MIXER, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(FLATBED, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(TRAILERSMALL, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(BOATTRAILER, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(TR2, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(TR3, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(TR4, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(TRAILERLOGS, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(TRAILERS, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(TRAILERS2, bSuppress)
SET_VEHICLE_MODEL_IS_SUPPRESSED(TRAILERS3, bSuppress)
//SET_VEHICLE_MODEL_IS_SUPPRESSED(MULE, bSuppress)
//SET_VEHICLE_MODEL_IS_SUPPRESSED(MULE2, bSuppress)
//SET_VEHICLE_MODEL_IS_SUPPRESSED(RUBBLE, bSuppress)
//SET_VEHICLE_MODEL_IS_SUPPRESSED(TOWTRUCK, bSuppress)
//SET_VEHICLE_MODEL_IS_SUPPRESSED(COACH, bSuppress)
//SET_VEHICLE_MODEL_IS_SUPPRESSED(TIPTRUCK, bSuppress)
//SET_VEHICLE_MODEL_IS_SUPPRESSED(TIPTRUCK2, bSuppress)
//SET_VEHICLE_MODEL_IS_SUPPRESSED(TRASH, bSuppress)
//SET_VEHICLE_MODEL_IS_SUPPRESSED(BENSON, bSuppress)
ENDPROC
/// Cancels any music events from this mission that may
PROC CANCEL_ALL_PREPARED_MUSIC_EVENTS()
CANCEL_MUSIC_EVENT("CAR4_RADIO_2_START_TRACK")
CANCEL_MUSIC_EVENT("CAR4_REVERSE")
CANCEL_MUSIC_EVENT("CAR4_RADIO_1")
ENDPROC
///Fail cleanup cannot delete peds in the same group/vehicle as the player, so use this to force delete them.
PROC FORCE_DELETE_PED_FOR_FAIL(PED_INDEX ped)
IF NOT IS_ENTITY_DEAD(ped)
IF IS_PED_GROUP_MEMBER(ped, PLAYER_GROUP_ID())
OR ARE_CHARS_IN_SAME_VEHICLE(PLAYER_PED_ID(), ped)
REMOVE_PED(ped, TRUE)
ENDIF
ENDIF
ENDPROC
PROC MISSION_SETUP()
IF IS_PLAYER_PLAYING(PLAYER_ID())
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
ENDIF
CLEAR_HELP()
CLEAR_PRINTS()
//REGISTER_SCRIPT_WITH_AUDIO()
INIT_PC_SCRIPTED_CONTROLS("Carsteal5_spycar_crane")
REQUEST_ADDITIONAL_TEXT("H4HEIST", MISSION_TEXT_SLOT)
//groupPlayer = GET_PLAYER_GROUP(PLAYER_ID())
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, RELGROUPHASH_PLAYER, RELGROUPHASH_PLAYER)
SET_PED_RELATIONSHIP_GROUP_HASH(PLAYER_PED_ID(), RELGROUPHASH_PLAYER)
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<585.5, -2645.5, 1.6>>, <<600.0, -2610.9, 10.6>>, FALSE)
ADD_PED_FOR_DIALOGUE(sConversationPeds, 1, PLAYER_PED_ID(), "FRANKLIN")
INITIALISE_STOLEN_CAR_DATA()
SUPPRESS_EMERGENCY_CALLS()
//INFORM_MISSION_STATS_OF_MISSION_START_CAR_STEAL_FINAL()
DISABLE_VEHICLE_GEN_ON_MISSION(TRUE)
SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_01_AP, TRUE)
SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_05_ID2, TRUE)
SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_06_BT1, TRUE)
SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_07_CS1, TRUE)
SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_08_CS6, TRUE)
SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_SUPERMOD, TRUE)
RESET_JB700_GADGET_DATA(sCarGadgets)
iScrapeSound = GET_SOUND_ID()
SET_STUNT_JUMPS_CAN_TRIGGER(FALSE)
#IF IS_DEBUG_BUILD
CREATE_WIDGETS()
sSkipMenu[0].sTxtLabel = "START_PHONECALL"
sSkipMenu[1].sTxtLabel = "COLLECT_CAR"
sSkipMenu[2].sTxtLabel = "CAR_5_MCS_1 - GET_IN_TRUCK_CUTSCENE"
sSkipMenu[3].sTxtLabel = "GO_TO_DROP_OFF"
sSkipMenu[4].sTxtLabel = "COPS_ARRIVE"
sSkipMenu[5].sTxtLabel = "ESCORT_TRUCK"
sSkipMenu[6].sTxtLabel = "MEET_MOLLY"
sSkipMenu[7].sTxtLabel = "END_CUTSCENE"
/*sSkipMenu[7].sTxtLabel = "(debug) COPS_ARRIVE_CUTSCENE"
sSkipMenu[8].sTxtLabel = "(debug) CHOOSE_CAR"
sSkipMenu[9].sTxtLabel = "(debug) CAR_DRIVE_OFF_CUTSCENE"
sSkipMenu[10].sTxtLabel = "(debug) GO_TO_DOCKS"
sSkipMenu[11].sTxtLabel = "(debug) LOAD_CARS_INTO_CONTAINERS"
sSkipMenu[12].sTxtLabel = "(debug) CAR_5_MCS_2 - TREVOR_SWITCH_CUTSCENE"
sSkipMenu[13].sTxtLabel = "(debug) USE_CRANE"
sSkipMenu[14].sTxtLabel = "(debug) CAR_5_MCS_3 - FINAL_CUTSCENE" */
#ENDIF
ENDPROC
PROC MISSION_CLEANUP()
CLEAR_HELP()
SET_WANTED_LEVEL_MULTIPLIER(1.0)
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(1.0)
SET_CREATE_RANDOM_COPS(TRUE)
SET_MAX_WANTED_LEVEL(5)
ENABLE_DISPATCH_SERVICE(DT_FIRE_DEPARTMENT, TRUE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_AUTOMOBILE, TRUE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_ROAD_BLOCK, TRUE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_AUTOMOBILE_WAIT_CRUISING, TRUE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_AUTOMOBILE_WAIT_PULLED_OVER, TRUE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_HELICOPTER, TRUE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_RIDERS, TRUE)
ENABLE_DISPATCH_SERVICE(DT_AMBULANCE_DEPARTMENT, TRUE)
BLOCK_DISPATCH_SERVICE_RESOURCE_CREATION(DT_POLICE_HELICOPTER, FALSE)
BLOCK_DISPATCH_SERVICE_RESOURCE_CREATION(DT_POLICE_ROAD_BLOCK, FALSE)
SET_RANDOM_TRAINS(TRUE)
ENABLE_LASER_SIGHT_RENDERING(TRUE)
SET_ALL_SHOPS_TEMPORARILY_UNAVAILABLE(FALSE)
DISABLE_TAXI_HAILING(FALSE)
RESET_DISPATCH_SPAWN_BLOCKING_AREAS()
ALLOW_AMBIENT_VEHICLES_TO_AVOID_ADVERSE_CONDITIONS(TRUE)
SET_PARTICLE_FX_BANG_SCRAPE_LODRANGE_SCALE(1.0)
TRIGGER_MUSIC_EVENT("CAR4_MISSION_FAIL")
IF IS_PLAYER_PLAYING(PLAYER_ID())
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
AND NOT IS_PED_GETTING_INTO_A_VEHICLE(PLAYER_PED_ID())
IF IS_ENTITY_ATTACHED_TO_ANY_VEHICLE(PLAYER_PED_ID())
DETACH_ENTITY(PLAYER_PED_ID())
ENDIF
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), FALSE)
ENDIF
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
CLEAR_PED_TASKS(PLAYER_PED_ID())
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PLAYER_PED_ID(), FALSE)
SET_ENTITY_VISIBLE(PLAYER_PED_ID(), TRUE)
SET_ENTITY_INVINCIBLE(PLAYER_PED_ID(), FALSE)
SET_ENTITY_PROOFS(PLAYER_PED_ID(), FALSE, FALSE, FALSE, FALSE, FALSE)
SET_PED_CURRENT_WEAPON_VISIBLE(PLAYER_PED_ID(), TRUE)
SET_PED_CAN_RAGDOLL(PLAYER_PED_ID(), TRUE)
SET_PLAYER_FORCED_AIM(PLAYER_ID(), FALSE)
SET_DISPATCH_COPS_FOR_PLAYER(PLAYER_ID(), TRUE)
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_ForceDirectEntry, FALSE)
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_AllowedToDetachTrailer, TRUE)
SET_MAX_WANTED_LEVEL(5)
SET_ALL_RANDOM_PEDS_FLEE(PLAYER_ID(), FALSE)
IF bIsJumpingDirectlyToStage
CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID())
ENDIF
ELSE
//If the player died near Molly then make her flee.
IF NOT IS_PED_INJURED(pedMolly)
TASK_SMART_FLEE_COORD(pedMolly, GET_ENTITY_COORDS(pedMolly), 500.0, -1)
SET_PED_KEEP_TASK(pedMolly, TRUE)
ENDIF
ENDIF
IF NOT HAS_CUTSCENE_FINISHED()
STOP_CUTSCENE()
ENDIF
REMOVE_CUTSCENE()
IF bIsJumpingDirectlyToStage
WHILE IS_CUTSCENE_ACTIVE()
WAIT(0)
ENDWHILE
ENDIF
//If mission failed using F debug, the player can be stuck on the trailer.
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
SET_VEHICLE_DOORS_LOCKED(sTruck.vehBack, VEHICLELOCK_UNLOCKED)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sTruck.vehBack, TRUE)
ENDIF
REMOVE_ANIM_DICT("map_objects")
REMOVE_ANIM_DICT(strCarClimbAnims)
REMOVE_ANIM_DICT(strCarClimbAnims2)
REMOVE_ANIM_DICT(strGetInCarAnims)
REMOVE_ANIM_DICT(strTruckIdleAnims)
REMOVE_ANIM_DICT(strTruckCopsIntroAnims)
REMOVE_ANIM_DICT(strTruckSitAnims)
REMOVE_ANIM_DICT(strSleepingAnims)
REMOVE_ANIM_DICT(strSleepingEyeAnims)
REMOVE_ANIM_DICT(strMollyAnims)
REMOVE_VEHICLE_ASSET(modelTruckFront)
STOP_AUDIO_SCENES()
SET_AUDIO_FLAG("ForceSeamlessRadioSwitch", FALSE)
SET_AUDIO_FLAG("AllowScriptedSpeechInSlowMo", FALSE)
RELEASE_NAMED_SCRIPT_AUDIO_BANK("CAR_THEFT_FINALE")
RELEASE_NAMED_SCRIPT_AUDIO_BANK("Crane")
RELEASE_NAMED_SCRIPT_AUDIO_BANK("Crane_Impact_Sweeteners")
RELEASE_NAMED_SCRIPT_AUDIO_BANK("Crane_Stress")
RELEASE_NAMED_SCRIPT_AUDIO_BANK("JWL_HEIST_CAR_SMASHES_BIG")
RELEASE_AMBIENT_AUDIO_BANK()
SET_GPS_MULTI_ROUTE_RENDER(FALSE)
CLEAR_GPS_MULTI_ROUTE()
REMOVE_PTFX_ASSET()
KILL_ANY_CONVERSATION()
CLEANUP_UBER_PLAYBACK(bIsJumpingDirectlyToStage)
REMOVE_PED_FOR_DIALOGUE(sConversationPeds, 2)
INFORM_MISSION_STATS_OF_DAMAGE_WATCH_ENTITY(NULL)
REMOVE_ALL_BLIPS()
REMOVE_ALL_CAMERAS()
REMOVE_ALL_OBJECTS(bIsJumpingDirectlyToStage)
REMOVE_ALL_PEDS(bIsJumpingDirectlyToStage)
REMOVE_ALL_VEHICLES(bIsJumpingDirectlyToStage)
SET_SCRIPTS_SAFE_FOR_CUTSCENE(FALSE)
CLEANUP_JB700_GUNS(sCarGadgets)
CLEAR_SELECTOR_PED_PRIORITY(sSelectorPeds)
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
IF bCreatedAssistedRoute
ASSISTED_MOVEMENT_FLUSH_ROUTE()
ASSISTED_MOVEMENT_CLOSE_ROUTE()
bCreatedAssistedRoute = FALSE
ENDIF
/*SET_VEHICLE_MODEL_IS_SUPPRESSED(sStolenCars[0].model, FALSE)
SET_VEHICLE_MODEL_IS_SUPPRESSED(sStolenCars[1].model, FALSE)
SET_VEHICLE_MODEL_IS_SUPPRESSED(sStolenCars[2].model, FALSE)
SET_VEHICLE_MODEL_IS_SUPPRESSED(sStolenCars[3].model, FALSE)
SET_VEHICLE_MODEL_IS_SUPPRESSED(sStolenCars[4].model, FALSE)
SET_VEHICLE_MODEL_IS_SUPPRESSED(sStolenCars[5].model, FALSE)*/
SET_ROADS_BACK_TO_ORIGINAL(<<491.9493, -1421.7377, 10.2604>>, <<563.2618, -1267.8080, 40.3393>>)
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<468.4835, -1336.4393, 27.2305>>, <<480.8360, -1334.4310, 38.2508>>, TRUE)
BLOCK_SCENARIOS_FOR_CHASE(FALSE)
IF bUseTrailerMode
UNLOAD_ALL_CLOUD_HATS()
CLEAR_WEATHER_TYPE_PERSIST()
ENDIF
CLEAR_WEATHER_TYPE_PERSIST() //clear the extrasunny weather, see TODO B*1493539
STOP_SOUND(iScrapeSound)
RELEASE_NAMED_SCRIPT_AUDIO_BANK("CAR_STEAL_4")
#IF IS_DEBUG_BUILD
//SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(FALSE)
#ENDIF
//Cleanup sparks for skipping etc..
IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxSparksLeft)
STOP_PARTICLE_FX_LOOPED(ptfxSparksLeft)
ENDIF
IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxSparksLeft)
STOP_PARTICLE_FX_LOOPED(ptfxSparksLeft)
ENDIF
IF NOT bIsJumpingDirectlyToStage
//Clean up anything that was created in the initial setup (this stuff must not be cleaned up if p-skipping)
#IF IS_DEBUG_BUILD
DESTROY_WIDGETS()
#ENDIF
//Don't clean up this stuff when p-skipping
SET_BUILDING_STATE(BUILDINGNAME_IPL_DOCK_CRANE, BUILDINGSTATE_NORMAL)
DISABLE_VEHICLE_GEN_ON_MISSION(FALSE)
SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_01_AP, FALSE)
SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_05_ID2, FALSE)
SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_06_BT1, FALSE)
SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_07_CS1, FALSE)
SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_08_CS6, FALSE)
SET_SHOP_IS_TEMPORARILY_UNAVAILABLE(CARMOD_SHOP_SUPERMOD, FALSE)
KILL_FACE_TO_FACE_CONVERSATION()
RELEASE_SUPPRESSED_EMERGENCY_CALLS()
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<585.5, -2645.5, 1.6>>, <<600.0, -2610.9, 10.6>>, TRUE)
SUPPRESS_LARGE_VEHICLES(FALSE)
SHUTDOWN_PC_SCRIPTED_CONTROLS()
SET_STUNT_JUMPS_CAN_TRIGGER(TRUE)
TERMINATE_THIS_THREAD()
ELSE
CLEAR_TRIGGERED_LABELS()
CLEAR_MISSION_LOCATE_STUFF(sLocatesData)
RESET_PUSH_IN(sPushInData)
INITIALISE_STOLEN_CAR_DATA()
CLEAR_PRINTS()
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
SET_MODEL_AS_NO_LONGER_NEEDED(modelCop)
SET_MODEL_AS_NO_LONGER_NEEDED(modelCopCar)
SET_MODEL_AS_NO_LONGER_NEEDED(modelGasStationCar)
SET_MODEL_AS_NO_LONGER_NEEDED(modelMolly)
SET_MODEL_AS_NO_LONGER_NEEDED(modelMollyCar)
SET_MODEL_AS_NO_LONGER_NEEDED(modelMollyDriver)
SET_MODEL_AS_NO_LONGER_NEEDED(modelSpikes)
SET_MODEL_AS_NO_LONGER_NEEDED(modelTruckBack)
SET_MODEL_AS_NO_LONGER_NEEDED(modelTruckFront)
REMOVE_VEHICLE_RECORDING(CARREC_TRUCK_FINAL_CUTSCENE, strCarrec)
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID())
CLEAR_PED_PROP(PLAYER_PED_ID(), ANCHOR_EARS)
CLEAR_AREA(<<0.0, 0.0, 0.0>>, 10000.0, TRUE)
bShitSkippedIntoFinalCar = FALSE
ENDIF
ENDPROC
PROC MISSION_PASSED()
//Ensure all ambient carsteal vehicles are deleted when passing this mission.
//NB: This will be done with IPLs when TODO 692707 is completed.
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_ENTITYXF, BUILDINGSTATE_NORMAL, FALSE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_CHEETAH, BUILDINGSTATE_NORMAL, FALSE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_ZTYPE, BUILDINGSTATE_NORMAL, FALSE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_JB700, BUILDINGSTATE_NORMAL, FALSE)
DO_FADE_IN_WITH_WAIT()
Mission_Flow_Mission_Passed()
MISSION_CLEANUP()
ENDPROC
PROC MISSION_FAILED(FAILED_REASON reason)
IF NOT bMissionFailed
CLEAR_PRINTS()
CLEAR_HELP()
REMOVE_ALL_BLIPS()
CLEAR_MISSION_LOCATE_STUFF(sLocatesData)
RESET_PUSH_IN(sPushInData)
KILL_ANY_CONVERSATION()
//Need to clear the custom GPS if it's visible
IF bCustomGPSActive
SET_GPS_MULTI_ROUTE_RENDER(FALSE)
CLEAR_GPS_MULTI_ROUTE()
bCustomGPSActive = FALSE
ENDIF
IF NOT IS_PED_INJURED(pedMolly)
TASK_SMART_FLEE_COORD(pedMolly, GET_ENTITY_COORDS(pedMolly), 500.0, -1)
SET_PED_KEEP_TASK(pedMolly, TRUE)
ENDIF
SWITCH reason
CASE FAILED_GENERIC
strFailLabel = ""
BREAK
CASE FAILED_DESTROYED_CAR
strFailLabel = "CH_CARDEAD"
BREAK
CASE FAILED_DESTROYED_ALL_CARS
strFailLabel = "CH_CARSDEAD"
BREAK
CASE FAILED_DESTROYED_SOME_CARS
strFailLabel = "CH_CARSDEAD2"
BREAK
CASE FAILED_DESTROYED_TRUCK
strFailLabel = "CH_TRUCKDEAD"
BREAK
CASE FAILED_KILLED_FRANKLIN
strFailLabel = "CMN_FDIED"
BREAK
CASE FAILED_KILLED_TREVOR
strFailLabel = "CMN_TDIED"
BREAK
CASE FAILED_CAR_STUCK
strFailLabel = "CH_STUCK"
BREAK
CASE FAILED_TRUCK_STUCK
strFailLabel = "CH_STUCK2"
BREAK
CASE FAILED_TRAILER_DETACHED
strFailLabel = "CH_TRAILFAIL"
BREAK
CASE FAILED_LEFT_FRANKLIN
strFailLabel = "CMN_FLEFT"
BREAK
CASE FAILED_LAMAR_DIED
strFailLabel = "CH_LAMDEAD"
BREAK
CASE FAILED_LEFT_LAMAR
strFailLabel = "CH_LAMLEFT"
BREAK
CASE FAILED_LEFT_TREVOR
strFailLabel = "CMN_TLEFT"
BREAK
CASE FAILED_LEFT_TREVOR_AND_LAMAR
strFailLabel = "CH_TLLEFT"
BREAK
CASE FAILED_LEFT_FRANKLIN_AND_LAMAR
strFailLabel = "CH_FLLEFT"
BREAK
CASE FAILED_MOLLY_DIED
strFailLabel = "CH_MOLDEAD"
BREAK
CASE FAILED_LEFT_MOLLY
strFailLabel = "CH_MLEFT"
BREAK
CASE FAILED_LED_COPS_TO_CARS
strFailLabel = "CH_COPFAIL3"
BREAK
CASE FAILED_MOLLYS_CAR_DESTROYED
strFailLabel = "CH_MOLCDEAD"
BREAK
CASE FAILED_TRAILER_FELL_OFF
strFailLabel = "CH_TRAILFAIL"
BREAK
CASE FAILED_LED_COPS_TO_TRUCK
strFailLabel = "CH_COPFAIL4"
BREAK
CASE FAILED_LED_COPS_TO_MONROE
strFailLabel = "CH_COPFAIL2"
BREAK
CASE FAILED_FRANKLIN_FELL_OFF
strFailLabel = "CH_FELLFAIL"
BREAK
CASE FAILED_ABANDONED_CAR
strFailLabel = "CH_CARABAN"
BREAK
CASE FAILED_TRAILER_ABANDONED
strFailLabel = "CH_TRABAN"
BREAK
CASE FAILED_SPOOKED_MOLLY
strFailLabel = "CH_MSPOOK"
BREAK
ENDSWITCH
ENDIF
TRIGGER_MUSIC_EVENT("CAR4_MISSION_FAIL")
MISSION_FLOW_MISSION_FAILED_WITH_REASON(strFailLabel)
WHILE NOT GET_MISSION_FLOW_SAFE_TO_CLEANUP()
//Maintain anything that could look weird during fade out (e.g. enemies walking off).
WAIT(0)
ENDWHILE
FORCE_DELETE_PED_FOR_FAIL(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
FORCE_DELETE_PED_FOR_FAIL(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
FORCE_DELETE_PED_FOR_FAIL(sLamar.ped)
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_ENTITYXF, BUILDINGSTATE_DESTROYED, FALSE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_CHEETAH, BUILDINGSTATE_DESTROYED, FALSE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_ZTYPE, BUILDINGSTATE_DESTROYED, FALSE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_JB700, BUILDINGSTATE_DESTROYED, FALSE)
MISSION_CLEANUP()
ENDPROC
PROC JUMP_TO_STAGE(MISSION_STAGE stage, BOOL bIsDebugJump = FALSE)
DO_FADE_OUT_WITH_WAIT()
bIsJumpingDirectlyToStage = TRUE
iCurrentEvent = 0
eMissionStage = stage
eSectionStage = SECTION_STAGE_SETUP
MISSION_CLEANUP()
IF bIsDebugJump
IF eMissionStage >= STAGE_ESCORT_TRUCK
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CHECKPOINT_LOSE_COPS, "LOSE_COPS", TRUE)
ELIF eMissionStage >= STAGE_COPS_ARRIVE
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CHECKPOINT_COPS_ARRIVE, "COPS_ARRIVE")
ELIF eMissionStage >= STAGE_GO_TO_DROP_OFF
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CHECKPOINT_GO_TO_GAS, "GO_TO_GAS_STATION")
ELSE
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(0, "COLLECT_FINAL_CAR")
ENDIF
ENDIF
IF stage >= STAGE_GO_TO_DROP_OFF
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_ENTITYXF, BUILDINGSTATE_NORMAL, FALSE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_CHEETAH, BUILDINGSTATE_NORMAL, FALSE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_ZTYPE, BUILDINGSTATE_NORMAL, FALSE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_JB700, BUILDINGSTATE_NORMAL, FALSE)
ENDIF
ENDPROC
FUNC BOOL SETUP_REQ_SUPPRESS_CHASE_MODELS()
/*SET_VEHICLE_MODEL_IS_SUPPRESSED(sStolenCars[0].model, TRUE)
SET_VEHICLE_MODEL_IS_SUPPRESSED(sStolenCars[1].model, TRUE)
SET_VEHICLE_MODEL_IS_SUPPRESSED(sStolenCars[2].model, TRUE)
SET_VEHICLE_MODEL_IS_SUPPRESSED(sStolenCars[3].model, TRUE)
SET_VEHICLE_MODEL_IS_SUPPRESSED(sStolenCars[4].model, TRUE)
SET_VEHICLE_MODEL_IS_SUPPRESSED(sStolenCars[5].model, TRUE)*/
RETURN TRUE
ENDFUNC
FUNC BOOL SETUP_REQ_LAMAR(VECTOR vPos, FLOAT fHeading = 0.0)
IF NOT DOES_ENTITY_EXIST(sLamar.ped)
IF CREATE_NPC_PED_ON_FOOT(sLamar.ped, CHAR_LAMAR, vPos, fHeading)
SET_PED_CAN_BE_TARGETTED(sLamar.ped, FALSE)
SET_PED_MAX_HEALTH(sLamar.ped, 200)
SET_ENTITY_HEALTH(sLamar.ped, 200)
SET_PED_SUFFERS_CRITICAL_HITS(sLamar.ped, FALSE)
SET_PED_RELATIONSHIP_GROUP_HASH(sLamar.ped, RELGROUPHASH_PLAYER)
SET_PED_CONFIG_FLAG(sLamar.ped, PCF_WillFlyThroughWindscreen, FALSE)
SET_PED_CONFIG_FLAG(sLamar.ped, PCF_RunFromFiresAndExplosions, FALSE)
SET_PED_CAN_USE_AUTO_CONVERSATION_LOOKAT(sLamar.ped, TRUE)
ADD_PED_FOR_DIALOGUE(sConversationPeds, 5, sLamar.ped, "LAMAR")
GIVE_WEAPON_TO_PED(sLamar.ped, WEAPONTYPE_PISTOL, INFINITE_AMMO, FALSE, FALSE)
SET_PED_COMBAT_ATTRIBUTES(sLamar.ped, CA_DO_DRIVEBYS, TRUE)
SET_ENTITY_LOD_DIST(sLamar.ped, 150)
SET_PED_LOD_MULTIPLIER(sLamar.ped, 5.0) //fixes LOD issues with Lamar's hair
RETURN TRUE
ENDIF
ELSE
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL SETUP_REQ_TREVOR(VECTOR vPos, FLOAT fHeading = 0.0)
IF NOT DOES_ENTITY_EXIST(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
IF CREATE_PLAYER_PED_ON_FOOT(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], CHAR_TREVOR, vPos, fHeading)
SET_PED_CAN_USE_AUTO_CONVERSATION_LOOKAT(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], TRUE)
ADD_PED_FOR_DIALOGUE(sConversationPeds, 2, sSelectorPeds.pedID[SELECTOR_PED_TREVOR], "TREVOR")
SET_PED_CAN_BE_TARGETTED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], FALSE)
SET_PED_MAX_HEALTH(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], 200)
SET_ENTITY_HEALTH(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], 200)
SET_PED_SUFFERS_CRITICAL_HITS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], FALSE)
SET_PED_RELATIONSHIP_GROUP_HASH(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], RELGROUPHASH_PLAYER)
RETURN TRUE
ENDIF
ELSE
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL SETUP_REQ_FRANKLIN(VECTOR vPos, FLOAT fHeading = 0.0)
IF NOT DOES_ENTITY_EXIST(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
IF CREATE_PLAYER_PED_ON_FOOT(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], CHAR_FRANKLIN, vPos, fHeading)
SET_PED_CAN_USE_AUTO_CONVERSATION_LOOKAT(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], TRUE)
ADD_PED_FOR_DIALOGUE(sConversationPeds, 1, sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], "FRANKLIN")
SET_PED_CAN_BE_TARGETTED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], FALSE)
SET_PED_MAX_HEALTH(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], 200)
SET_ENTITY_HEALTH(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], 200)
SET_PED_SUFFERS_CRITICAL_HITS(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], FALSE)
SET_PED_RELATIONSHIP_GROUP_HASH(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], RELGROUPHASH_PLAYER)
RETURN TRUE
ENDIF
ELSE
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL SETUP_REQ_PLAYER_IS_FRANKLIN()
IF GET_CURRENT_PLAYER_PED_ENUM() != CHAR_FRANKLIN
SET_CURRENT_SELECTOR_PED(SELECTOR_PED_FRANKLIN)
ELSE
REASSIGN_PLAYER_CHAR_DIALOGUE_SPEAKERS()
SET_PED_RELATIONSHIP_GROUP_HASH(PLAYER_PED_ID(), RELGROUPHASH_PLAYER)
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL SETUP_REQ_PLAYER_IS_TREVOR()
IF GET_CURRENT_PLAYER_PED_ENUM() != CHAR_TREVOR
SET_CURRENT_SELECTOR_PED(SELECTOR_PED_TREVOR)
ELSE
REASSIGN_PLAYER_CHAR_DIALOGUE_SPEAKERS()
SET_PED_RELATIONSHIP_GROUP_HASH(PLAYER_PED_ID(), RELGROUPHASH_PLAYER)
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL SETUP_REQ_CLOSE_ROAD_OUTSIDE_GARAGE()
SET_ROADS_IN_AREA(<<491.9493, -1421.7377, 10.2604>>, <<563.2618, -1267.8080, 40.3393>>, FALSE)
RETURN TRUE
ENDFUNC
FUNC BOOL SETUP_REQ_FIRST_CAR(VECTOR vPos, FLOAT fHeading = 0.0)
IF NOT DOES_ENTITY_EXIST(sStolenCars[0].veh)
REQUEST_MODEL(sStolenCars[0].model)
IF HAS_MODEL_LOADED(sStolenCars[0].model)
CLEAR_AREA(vPos, 22.0, TRUE) // Reduced to fix cars being visibly cleared in compound entrance (url:bugstar:2099568)
sStolenCars[0].veh = CREATE_CAR_STEAL_STRAND_CAR(sStolenCars[0].model, vPos, fHeading)
SET_VEHICLE_AS_RESTRICTED(sStolenCars[0].veh, 0)
SET_MODEL_AS_NO_LONGER_NEEDED(sStolenCars[0].model)
RETURN TRUE
ENDIF
ELSE
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL SETUP_REQ_TRUCK(VECTOR vPos, FLOAT fHeading = 0.0)
IF NOT DOES_ENTITY_EXIST(sTruck.vehBack)
REQUEST_MODEL(modelTruckFront)
REQUEST_MODEL(modelTruckBack)
IF HAS_MODEL_LOADED(modelTruckFront)
AND HAS_MODEL_LOADED(modelTruckBack)
sTruck.vehFront = CREATE_VEHICLE(modelTruckFront, vPos, fHeading)
sTruck.vehBack = CREATE_VEHICLE(modelTruckBack, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, <<-0.3, -9.5, -0.25>>),
GET_ENTITY_HEADING(sTruck.vehFront) - 20.0)
SET_ENTITY_COORDS_NO_OFFSET(sTruck.vehBack, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, << -0.00281182, -9.76194, 0.332852 >>))
SET_ENTITY_HEADING(sTruck.vehBack, fHeading)
SET_VEHICLE_DOORS_LOCKED(sTruck.vehBack, VEHICLELOCK_LOCKOUT_PLAYER_ONLY)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sTruck.vehBack, FALSE)
SET_VEHICLE_TYRES_CAN_BURST(sTruck.vehBack, FALSE)
SET_VEHICLE_EXTRA(sTruck.vehBack, 7, TRUE)
SET_VEHICLE_COLOURS(sTruck.vehFront, 45, 40)
SET_VEHICLE_EXTRA_COLOURS(sTruck.vehFront, 35, 156)
SET_VEHICLE_DOORS_LOCKED(sTruck.vehFront, VEHICLELOCK_LOCKOUT_PLAYER_ONLY)
SET_MODEL_AS_NO_LONGER_NEEDED(modelTruckFront)
SET_MODEL_AS_NO_LONGER_NEEDED(modelTruckBack)
FREEZE_ENTITY_POSITION(sTruck.vehFront, TRUE)
FREEZE_ENTITY_POSITION(sTruck.vehBack, TRUE)
SET_VEHICLE_STRONG(sTruck.vehFront, TRUE)
SET_VEHICLE_HAS_STRONG_AXLES(sTruck.vehFront, TRUE)
SET_VEHICLE_TYRES_CAN_BURST(sTruck.vehFront, FALSE)
SET_VEH_RADIO_STATION(sTruck.vehFront, "RADIO_01_CLASS_ROCK")
SET_VEHICLE_AS_RESTRICTED(sTruck.vehFront, 6)
iTruckSetupStage = 0
iTruckSetupTimer = 0
RETURN TRUE
ENDIF
ELSE
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL SETUP_REQ_TRUCK_AWAITING_LAST_CAR(VECTOR vPos, FLOAT fHeading = 0.0)
INT i = 0
IF SETUP_REQ_TRUCK(vPos, fHeading)
//PRINTLN(iTruckSetupStage)
SWITCH iTruckSetupStage
CASE 0
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
AND IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
FREEZE_ENTITY_POSITION(sTruck.vehBack, FALSE)
SET_ENTITY_COORDS_NO_OFFSET(sTruck.vehBack, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, << -0.00281182, -9.76194, 0.332852 >>))
SET_ENTITY_HEADING(sTruck.vehBack, fHeading)
//SET_ENTITY_COORDS_NO_OFFSET(sTruck.vehBack, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, <<-0.3, -9.5, -0.25>>))
//SET_ENTITY_HEADING(sTruck.vehBack, fHeading)//GET_ENTITY_HEADING(sTruck.vehFront) - 20.0)
iTruckSetupTimer = GET_GAME_TIMER()
iTruckSetupStage++
ENDIF
BREAK
CASE 1
IF GET_GAME_TIMER() - iTruckSetupTimer > 500
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF NOT IS_ENTITY_WAITING_FOR_WORLD_COLLISION(sTruck.vehBack)
AND DOES_ENTITY_HAVE_PHYSICS(sTruck.vehBack)
ATTACH_VEHICLE_TO_TRAILER(sTruck.vehFront, sTruck.vehBack)
SET_VEHICLE_DOOR_OPEN(sTruck.vehBack, SC_DOOR_BOOT)
iTruckSetupTimer = GET_GAME_TIMER()
iTruckSetupStage++
ENDIF
ENDIF
ENDIF
BREAK
CASE 2
IF GET_GAME_TIMER() - iTruckSetupTimer > 1000
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
AND IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sTruck.vehBack)) < 2500.0
AND NOT IS_ENTITY_WAITING_FOR_WORLD_COLLISION(sTruck.vehBack)
AND DOES_ENTITY_HAVE_PHYSICS(sTruck.vehBack)
//DETACH_VEHICLE_FROM_TRAILER(sTruck.vehFront)
//FREEZE_ENTITY_POSITION(sTruck.vehBack, TRUE)
REPEAT COUNT_OF(sStolenCars) i
IF i != 0
IF IS_VEHICLE_DRIVEABLE(sStolenCars[i].veh)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sStolenCars[i].veh, FALSE)
ENDIF
ENDIF
ENDREPEAT
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sTruck.vehFront, FALSE)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sTruck.vehBack, FALSE)
iTruckSetupStage++
ENDIF
ENDIF
ENDIF
BREAK
CASE 3
RETURN TRUE
BREAK
ENDSWITCH
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL SETUP_REQ_TRUCK_UNFROZEN(VECTOR vPos, FLOAT fHeading = 0.0)
IF SETUP_REQ_TRUCK(vPos, fHeading)
IF bIsJumpingDirectlyToStage AND iTruckSetupStage = 0
SET_ENTITY_COORDS(PLAYER_PED_ID(), vPos + <<10.0, 10.0, 0.0>>)
WAIT(500)
ENDIF
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
IF iTruckSetupStage = 0
FREEZE_ENTITY_POSITION(sTruck.vehFront, FALSE)
IF bIsJumpingDirectlyToStage
SET_VEHICLE_ON_GROUND_PROPERLY(sTruck.vehFront)
FREEZE_ENTITY_POSITION(sTruck.vehFront, TRUE)
ENDIF
FREEZE_ENTITY_POSITION(sTruck.vehBack, FALSE)
IF bIsJumpingDirectlyToStage
SET_ENTITY_COORDS_NO_OFFSET(sTruck.vehBack, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, <<-0.00281182, -9.76194, 0.332852>>))
FREEZE_ENTITY_POSITION(sTruck.vehFront, FALSE)
ATTACH_VEHICLE_TO_TRAILER(sTruck.vehFront, sTruck.vehBack)
ENDIF
//SET_VEHICLE_ON_GROUND_PROPERLY(sTruck.vehBack)
SET_VEHICLE_DOOR_SHUT(sTruck.vehBack, SC_DOOR_BOOT)
SET_VEHICLE_DOORS_LOCKED(sTruck.vehFront, VEHICLELOCK_UNLOCKED)
iTruckSetupStage++
RETURN TRUE
ELSE
RETURN TRUE
ENDIF
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL SETUP_REQ_CARS_ON_TRUCK()
IF NOT DOES_ENTITY_EXIST(sStolenCars[5].veh)
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
REQUEST_MODEL(sStolenCars[0].model)
//REQUEST_MODEL(sStolenCars[1].model)
//REQUEST_MODEL(sStolenCars[2].model)
REQUEST_MODEL(sStolenCars[3].model)
//REQUEST_MODEL(sStolenCars[4].model)
//REQUEST_MODEL(sStolenCars[5].model)
IF HAS_MODEL_LOADED(sStolenCars[0].model)
//AND HAS_MODEL_LOADED(sStolenCars[1].model)
//AND HAS_MODEL_LOADED(sStolenCars[2].model)
AND HAS_MODEL_LOADED(sStolenCars[3].model)
//AND HAS_MODEL_LOADED(sStolenCars[4].model)
//AND HAS_MODEL_LOADED(sStolenCars[5].model)
//Cars: attached to the trailer. Only create ones that don't already exist.
INT i = 0
REPEAT COUNT_OF(sStolenCars) i
SWITCH i
CASE 0
CASE 3
IF NOT DOES_ENTITY_EXIST(sStolenCars[i].veh)
sStolenCars[i].veh = CREATE_CAR_STEAL_STRAND_CAR(sStolenCars[i].model, vTruckStartPos + <<0.0, 0.0, i>>, 0.0)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(sStolenCars[i].veh, TRUE)
SET_VEHICLE_AS_RESTRICTED(sStolenCars[i].veh, i)
IF sStolenCars[i].model = MONROE
ATTACH_VEHICLE_ON_TO_TRAILER(sStolenCars[i].veh, sTruck.vehBack, <<0.0, 0.0, 0.0>>, sStolenCars[i].vTruckOffset, sStolenCars[i].vTruckRotation, -1.0)
ELSE
ATTACH_VEHICLE_ON_TO_TRAILER(sStolenCars[i].veh, sTruck.vehBack, <<0.0, 0.0, 0.0>>, sStolenCars[i].vTruckOffset, sStolenCars[i].vTruckRotation, -1.0)
//ATTACH_ENTITY_TO_ENTITY(sStolenCars[i].veh, sTruck.vehBack, -1, sStolenCars[i].vTruckOffset, sStolenCars[i].vTruckRotation, FALSE, FALSE, TRUE)
ENDIF
sStolenCars[i].bInContainer = FALSE
IF sStolenCars[i].model = JB700
SET_VEHICLE_TYRES_CAN_BURST(sStolenCars[i].veh, FALSE)
SET_VEHICLE_STRONG(sStolenCars[i].veh, TRUE)
SET_VEHICLE_HAS_STRONG_AXLES(sStolenCars[i].veh, TRUE)
SET_HORN_ENABLED(sStolenCars[i].veh, FALSE)
ENDIF
ENDIF
SET_MODEL_AS_NO_LONGER_NEEDED(sStolenCars[i].model)
BREAK
ENDSWITCH
ENDREPEAT
RETURN TRUE
ENDIF
ENDIF
ELSE
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL SETUP_REQ_INVISIBLE_TREVOR()
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
SET_ENTITY_VISIBLE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], FALSE)
SET_ENTITY_COLLISION(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], FALSE)
SET_ENTITY_INVINCIBLE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], TRUE)
FREEZE_ENTITY_POSITION(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], TRUE)
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL SETUP_MOLLY_AND_CAR(BOOL bJustRequestAssets = FALSE)
VECTOR vMollyPos = <<1587.4498, 6447.6797, 24.1753>>
VECTOR vMollyCarPos = <<1587.7891, 6445.3828, 24.2117>>
FLOAT fMollyHeading = 88.1625
FLOAT fMollyCarHeading = 156.4450
IF NOT DOES_ENTITY_EXIST(vehMollyCar)
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), vMollyCarPos) < 40000.0
REQUEST_MODEL(modelMolly)
REQUEST_MODEL(modelMollyCar)
REQUEST_MODEL(modelMollyDriver)
IF HAS_MODEL_LOADED(modelMolly)
AND HAS_MODEL_LOADED(modelMollyCar)
AND HAS_MODEL_LOADED(modelMollyDriver)
IF bJustRequestAssets
RETURN TRUE
ELSE
CLEAR_AREA(vMollyCarPos, 10.0, TRUE)
vehMollyCar = CREATE_VEHICLE(modelMollyCar, vMollyCarPos, fMollyCarHeading)
SET_VEHICLE_COLOURS(vehMollyCar, 0, 0)
SET_VEHICLE_EXTRA_COLOURS(vehMollyCar, 0, 0)
SET_VEHICLE_NUMBER_PLATE_TEXT(vehMollyCar, "665LDI37")
SET_VEHICLE_DIRT_LEVEL(vehMollyCar, 0.0)
SET_VEHICLE_ON_GROUND_PROPERLY(vehMollyCar)
SET_VEHICLE_DOOR_OPEN(vehMollyCar, SC_DOOR_REAR_RIGHT, TRUE)
SET_ENTITY_SHOULD_FREEZE_WAITING_ON_COLLISION(vehMollyCar, TRUE)
SET_VEHICLE_RADIO_ENABLED(vehMollyCar, FALSE)
//FREEZE_ENTITY_POSITION(vehMollyCar, TRUE)
pedMolly = CREATE_PED(PEDTYPE_MISSION, modelMolly, vMollyPos, fMollyHeading)
SET_ENTITY_SHOULD_FREEZE_WAITING_ON_COLLISION(pedMolly, TRUE)
SET_PED_RELATIONSHIP_GROUP_HASH(pedMolly, RELGROUPHASH_PLAYER)
SET_PED_PROP_INDEX(pedMolly, ANCHOR_EYES, 0)
SET_PED_LOD_MULTIPLIER(pedMolly, 2.0)
eMollyState = MOLLY_STATE_IDLE
iMollySyncScene = -1
pedMollyDriver = CREATE_PED_INSIDE_VEHICLE(vehMollyCar, PEDTYPE_MISSION, modelMollyDriver)
SET_PED_RELATIONSHIP_GROUP_HASH(pedMollyDriver, RELGROUPHASH_PLAYER)
SET_MODEL_AS_NO_LONGER_NEEDED(modelMolly)
SET_MODEL_AS_NO_LONGER_NEEDED(modelMollyCar)
SET_MODEL_AS_NO_LONGER_NEEDED(modelMollyDriver)
RETURN TRUE
ENDIF
ENDIF
ENDIF
ELSE
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL SETUP_CAR_AT_GAS_STATION(BOOL bJustRequestAssets = FALSE)
IF NOT DOES_ENTITY_EXIST(vehGasStationCar)
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), vGasStationCarPos) < 40000.0
OR IS_SCREEN_FADED_OUT()
REQUEST_MODEL(modelGasStationCar)
IF HAS_MODEL_LOADED(modelGasStationCar)
IF bJustRequestAssets
RETURN TRUE
ELSE
CLEAR_AREA(vGasStationCarPos, 10.0, TRUE)
vehGasStationCar = CREATE_VEHICLE(modelGasStationCar, vGasStationCarPos, fGasStationCarHeading)
SET_VEHICLE_COLOURS(vehGasStationCar, 61, 61)
SET_VEHICLE_EXTRA_COLOURS(vehGasStationCar, 67, 0)
SET_VEHICLE_DIRT_LEVEL(vehGasStationCar, 1.0)
SET_VEHICLE_ON_GROUND_PROPERLY(vehGasStationCar)
SET_ENTITY_SHOULD_FREEZE_WAITING_ON_COLLISION(vehGasStationCar, TRUE)
SET_MODEL_AS_NO_LONGER_NEEDED(modelGasStationCar)
RETURN TRUE
ENDIF
ENDIF
ENDIF
ELSE
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
PROC SET_STOLEN_CARS_AS_LOW_LOD()
INT i
REPEAT COUNT_OF(sStolenCars) i
IF NOT IS_ENTITY_DEAD(sStolenCars[i].veh)
IF sStolenCars[i].model != JB700
//SET_VEHICLE_LOD_MULTIPLIER(sStolenCars[i].veh, 0.4)
ENDIF
ENDIF
ENDREPEAT
ENDPROC
PROC GIVE_MAIN_PEDS_HEADSETS()
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
SET_PED_COMP_ITEM_CURRENT_SP(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], COMP_TYPE_PROPS, PROPS_P1_HEADSET)
ENDIF
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
SET_PED_COMP_ITEM_CURRENT_SP(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], COMP_TYPE_PROPS, PROPS_P2_HEADSET)
ENDIF
IF GET_ENTITY_MODEL(PLAYER_PED_ID()) = GET_PLAYER_PED_MODEL(CHAR_FRANKLIN)
SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_PROPS, PROPS_P1_HEADSET)
ELSE
SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_PROPS, PROPS_P2_HEADSET)
ENDIF
//Lamar needs a headset.
IF NOT IS_PED_INJURED(sLamar.ped)
SET_PED_PROP_INDEX(sLamar.ped, ANCHOR_EARS, 0)
ENDIF
ENDPROC
PROC START_PHONECALL()
IF eSectionStage = SECTION_STAGE_SETUP
IF bIsJumpingDirectlyToStage
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-62.8697, -1457.6414, 31.1163>>)
SET_ENTITY_HEADING(PLAYER_PED_ID(), 111.7820)
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), TRUE)
LOAD_SCENE(GET_ENTITY_COORDS(PLAYER_PED_ID()))
WAIT(0)
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), FALSE)
INITIALISE_STOLEN_CAR_DATA()
bIsJumpingDirectlyToStage = FALSE
ELSE
DO_FADE_IN_WITH_WAIT()
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
SET_WEATHER_TYPE_OVERTIME_PERSIST("EXTRASUNNY", 30.0) //force the weather to be extrasunny, see TODO B*1493539
bFranklinSwitchRecordingStarted = FALSE
iCurrentEvent = 0
eSectionStage = SECTION_STAGE_RUNNING
ENDIF
ENDIF
IF eSectionStage = SECTION_STAGE_RUNNING
SWITCH iCurrentEvent
CASE 0
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_FRANKLIN
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_LAMPH")
REASSIGN_PLAYER_CHAR_DIALOGUE_SPEAKERS()
ADD_PED_FOR_DIALOGUE(sConversationPeds, 5, NULL, "LAMAR")
IF CHAR_CALL_PLAYER_CELLPHONE_FORCE_ANSWER(sConversationPeds, CHAR_LAMAR, "CST7AUD", "CST7_LAMPH", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_LAMPH", TRUE)
ENDIF
ELSE
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF NOT IS_MOBILE_PHONE_CALL_ONGOING()
AND NOT IS_CALLING_CONTACT(CHAR_LAMAR)
AND NOT IS_CONTACT_IN_CONNECTED_CALL(CHAR_LAMAR)
iCurrentEvent = 0
eSectionStage = SECTION_STAGE_CLEANUP
ENDIF
ELIF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), <<-210.6681, -1358.6426, 30.2610>>) <= 65 // url:bugstar:2099568
HANG_UP_AND_PUT_AWAY_PHONE()
ENDIF
ENDIF
BREAK
CASE CHAR_TREVOR
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_LAMPH2")
REASSIGN_PLAYER_CHAR_DIALOGUE_SPEAKERS()
ADD_PED_FOR_DIALOGUE(sConversationPeds, 5, NULL, "LAMAR")
IF CHAR_CALL_PLAYER_CELLPHONE_FORCE_ANSWER(sConversationPeds, CHAR_LAMAR, "CST7AUD", "CST7_LAMPH2", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_LAMPH2", TRUE)
ENDIF
ELSE
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF NOT IS_MOBILE_PHONE_CALL_ONGOING()
AND NOT IS_CALLING_CONTACT(CHAR_LAMAR)
AND NOT IS_CONTACT_IN_CONNECTED_CALL(CHAR_LAMAR)
iCurrentEvent++
ENDIF
ENDIF
ENDIF
BREAK
ENDSWITCH
BREAK
CASE 1
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_FRANKLIN
//player should not be Franklin here
BREAK
CASE CHAR_TREVOR
REQUEST_VEHICLE_RECORDING(900, strCarrec)
IF HAS_VEHICLE_RECORDING_BEEN_LOADED(900, strCarrec)
AND SETUP_REQ_FRANKLIN(<<-951.4235, -1234.1798, 4.2849>>, 299.6498)
AND CREATE_PLAYER_VEHICLE(vehFranklinCar, CHAR_FRANKLIN, <<-952.6679, -1229.8711, 4.3307>>, 298.6130, TRUE, VEHICLE_TYPE_CAR)
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN]) AND IS_VEHICLE_DRIVEABLE(vehFranklinCar)
DESTROY_ALL_CAMS()
camSwitch = CREATE_CAMERA(CAMTYPE_SCRIPTED, FALSE)
SET_CAM_PARAMS(camSwitch, <<-940.171143,-1224.301270,27.479607>>,<<-89.283173,-0.029118,-60.138767>>,44.4)
SET_PED_INTO_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], vehFranklinCar, VS_DRIVER)
START_PLAYBACK_RECORDED_VEHICLE(vehFranklinCar, 900, strCarrec)
SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(vehFranklinCar, 3000)
FORCE_PLAYBACK_RECORDED_VEHICLE_UPDATE(vehFranklinCar)
SET_PLAYBACK_SPEED(vehFranklinCar, 0.0)
MAKE_SELECTOR_PED_SELECTION(sSelectorPeds, SELECTOR_PED_FRANKLIN)
sSelectorCamera.pedTo = sSelectorPeds.pedID[sSelectorPeds.eNewSelectorPed]
iCurrentEvent++
ENDIF
ENDIF
BREAK
ENDSWITCH
BREAK
CASE 2
IF RUN_SWITCH_CAM_FROM_PLAYER_TO_CAM(sSelectorCamera, camSwitch, SWITCH_TYPE_LONG)
IF NOT bFranklinSwitchRecordingStarted
IF IS_VEHICLE_DRIVEABLE(vehFranklinCar)
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vehFranklinCar)
IF GET_PLAYER_SWITCH_STATE() = SWITCH_STATE_JUMPCUT_DESCENT
AND GET_PLAYER_SWITCH_JUMP_CUT_INDEX() = 0
CLEAR_AREA(GET_ENTITY_COORDS(vehFranklinCar), 50.0, TRUE)
SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(vehFranklinCar, 1500 - GET_TIME_POSITION_IN_RECORDING(vehFranklinCar))
SET_PLAYBACK_SPEED(vehFranklinCar, 0.70)
bFranklinSwitchRecordingStarted = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
IF sSelectorCamera.bOKToSwitchPed
IF NOT sSelectorCamera.bPedSwitched
IF TAKE_CONTROL_OF_SELECTOR_PED(sSelectorPeds, TRUE, TRUE)
sSelectorCamera.bPedSwitched = TRUE
ENDIF
ENDIF
ENDIF
IF NOT bFranklinSwitchRecordingTimeSkipped
IF GET_PLAYER_SWITCH_STATE() = SWITCH_STATE_OUTRO_HOLD
SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(vehFranklinCar, 3000 - GET_TIME_POSITION_IN_RECORDING(vehFranklinCar))
bFranklinSwitchRecordingTimeSkipped = TRUE
ENDIF
ENDIF
ELSE
IF NOT IS_SELECTOR_CAM_ACTIVE()
AND NOT IS_PLAYER_SWITCH_IN_PROGRESS()
AND NOT IS_PLAYER_PED_SWITCH_IN_PROGRESS()
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
IF IS_VEHICLE_DRIVEABLE(vehFranklinCar)
REMOVE_VEHICLE_RECORDING(900, strCarrec)
STOP_PLAYBACK_RECORDED_VEHICLE(vehFranklinCar)
SET_VEHICLE_FORWARD_SPEED(vehFranklinCar, GET_ENTITY_SPEED(vehFranklinCar))
SET_VEHICLE_AS_NO_LONGER_NEEDED(vehFranklinCar)
ENDIF
ENDIF
REMOVE_PED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], TRUE)
iCurrentEvent = 0
eSectionStage = SECTION_STAGE_CLEANUP
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDIF
IF eSectionStage = SECTION_STAGE_CLEANUP
CLEAR_PRINTS()
CLEAR_HELP()
CLEAR_MISSION_LOCATE_STUFF(sLocatesData)
REMOVE_ALL_BLIPS()
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
eSectionStage = SECTION_STAGE_SETUP
eMissionStage = STAGE_COLLECT_FINAL_CAR
ENDIF
ENDPROC
PROC COLLECT_FINAL_CAR()
IF eSectionStage = SECTION_STAGE_SETUP
IF bIsJumpingDirectlyToStage
IF bUsedACheckpoint
IF bShitSkippedIntoFinalCar
START_REPLAY_SETUP(<<-212.6681, -1358.6426, 30.2610>>, 326.8683)
ELSE
//CREATE_VEHICLE_FOR_PHONECALL_TRIGGER_REPLAY(vehReplayHelper, FALSE, FALSE, FALSE, FALSE)
START_REPLAY_SETUP(<<-62.8697, -1457.6414, 31.1163>>, 111.7820)
ENDIF
ELSE
IF bShitSkippedIntoFinalCar
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-212.6681, -1358.6426, 30.2610>>)
ELSE
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<493.5279, -1315.5464, 28.2455>>)
ENDIF
SET_ENTITY_HEADING(PLAYER_PED_ID(), 326.8683)
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), TRUE)
LOAD_SCENE(GET_ENTITY_COORDS(PLAYER_PED_ID()))
WAIT(0)
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), FALSE)
ENDIF
INITIALISE_STOLEN_CAR_DATA()
WHILE NOT SETUP_REQ_PLAYER_IS_FRANKLIN()
OR NOT DOES_ENTITY_EXIST(sStolenCars[0].veh)
OR NOT (DOES_ENTITY_EXIST(sLamar.ped) OR NOT bShitSkippedIntoFinalCar)
SETUP_REQ_FIRST_CAR(<<-209.6797, -1360.2938, 30.2959>>, 117.6006)
IF bShitSkippedIntoFinalCar
SETUP_REQ_LAMAR(<<-210.6681, -1358.6426, 30.2610>>, 123.1137)
ENDIF
WAIT(0)
ENDWHILE
END_REPLAY_SETUP(DEFAULT, DEFAULT, FALSE)
bIsJumpingDirectlyToStage = FALSE
ELSE
INITIALISE_STOLEN_CAR_DATA()
IF SETUP_REQ_FIRST_CAR(<<-209.6797, -1360.2938, 30.2959>>, 117.6006)
SETUP_REQ_SUPPRESS_CHASE_MODELS()
//As we start the mission ensure all ambient chopshop cars
//are active as they haven't been loaded onto the packer yet.
//NB: This will be done with IPLs when TODO 692707 is completed.
IF IS_SCREEN_FADED_OUT()
IF bShitSkippedIntoFinalCar
//TODO 402938 - Mid-stage checkpoint: Franklin and Lamar are already in the car.
IF IS_VEHICLE_DRIVEABLE(sStolenCars[0].veh)
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[0].veh)
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), sStolenCars[0].veh)
ENDIF
IF NOT IS_PED_INJURED(sLamar.ped)
AND NOT IS_PED_IN_VEHICLE(sLamar.ped, sStolenCars[0].veh)
SET_PED_INTO_VEHICLE(sLamar.ped, sStolenCars[0].veh, VS_FRONT_RIGHT)
ENDIF
ENDIF
ENDIF
IF IS_VEHICLE_DRIVEABLE(vehReplayHelper)
SET_VEHICLE_ON_GROUND_PROPERLY(vehReplayHelper)
ENDIF
CLEAR_AREA(GET_ENTITY_COORDS(PLAYER_PED_ID()), 2000.0, TRUE, TRUE)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
ENDIF
IF NOT bShitSkippedIntoFinalCar
IF IS_VEHICLE_DRIVEABLE(sStolenCars[0].veh)
FREEZE_ENTITY_POSITION(sStolenCars[0].veh, TRUE)
//SET_ENTITY_NO_COLLISION_ENTITY(sStolenCars[0].veh, sLamar.ped, FALSE)
SET_VEHICLE_ENGINE_ON(sStolenCars[0].veh, TRUE, TRUE)
SET_VEHICLE_RADIO_LOUD(sStolenCars[0].veh, TRUE)
SET_VEH_RADIO_STATION(sStolenCars[0].veh, "RADIO_03_HIPHOP_NEW")
ENDIF
sLamar.iEvent = 0
iCurrentEvent = 0
ELSE
SETUP_REQ_CLOSE_ROAD_OUTSIDE_GARAGE()
IF NOT IS_AUDIO_SCENE_ACTIVE("CAR_4_TAKE_CAR_TO_TRANSPORTER")
START_AUDIO_SCENE("CAR_4_TAKE_CAR_TO_TRANSPORTER")
ENDIF
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CHECKPOINT_MEET_TREVOR, "MEET_TREVOR")
sLamar.iEvent = 1
iCurrentEvent = 50
ENDIF
DO_FADE_IN_WITH_WAIT()
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
IF DOES_ENTITY_EXIST(vehReplayHelper)
SET_VEHICLE_AS_NO_LONGER_NEEDED(vehReplayHelper)
ENDIF
fTimeLamarSpentOnScreen = 0.0
bPlayedTrevorGreetingAnim = FALSE
bLamarKnockedOutOfLeanAnim = FALSE
bIsJumpingDirectlyToStage = FALSE
bTrevorKnockedOver = FALSE
bAlreadyPrintedWantedLevelText = FALSE
iTrevorWaitAnimsTimer = 0
iNumLamarMonroeDamageLines = 0
iLamarMonroeDamageTimer = 0
iNumTrevorReminders = 0
iTrevorReminderTimer = 0
bCurrentConversationInterrupted = FALSE
eSectionStage = SECTION_STAGE_RUNNING
ENDIF
ENDIF
ENDIF
IF eSectionStage = SECTION_STAGE_RUNNING
SET_PARKED_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
IF IS_PLAYER_PLAYING(PLAYER_ID())
SET_ALL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID())
SET_ALL_NEUTRAL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID())
ENDIF
#IF IS_DEBUG_BUILD
DONT_DO_J_SKIP(sLocatesData)
#ENDIF
VEHICLE_INDEX vehClosest[3]
INT i = 0
VECTOR vTruckLocate
VECTOR vTruckBlipPosition = << 507.5, -1316.7, 30.0 >>
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF GET_ENTITY_SPEED(sTruck.vehBack) < 0.5
vTruckLocate = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehBack, <<0.0, -4.8707, 0.5282>>)
ELSE
vTruckLocate = vBackOfTruck
ENDIF
ELSE
vTruckLocate = vBackOfTruck
ENDIF
//Disable the player driving off if Lamar is in the middle of playing his synched scene.
IF IS_SYNCHRONIZED_SCENE_RUNNING(iSyncSceneStartCar)
AND IS_VEHICLE_DRIVEABLE(sStolenCars[0].veh)
AND IS_PED_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[0].veh)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ACCELERATE)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_BRAKE)
ENDIF
//force monroe radio on when Lamar is waiting for the player, see B*1445373 and B*1560430
IF DOES_ENTITY_EXIST(sLamar.ped)
IF NOT IS_ENTITY_DEAD(sLamar.ped)
IF IS_VEHICLE_DRIVEABLE(sStolenCars[0].veh)
IF NOT IS_PED_IN_VEHICLE(sLamar.ped, sStolenCars[0].veh)
SET_VEH_FORCED_RADIO_THIS_FRAME(sStolenCars[0].veh)
SET_VEH_RADIO_STATION(sStolenCars[0].veh, "RADIO_03_HIPHOP_NEW")
ENDIF
ENDIF
ENDIF
ENDIF
IF DOES_ENTITY_EXIST(vehFranklinCar)
SET_VEHICLE_AS_NO_LONGER_NEEDED(vehFranklinCar)
ENDIF
SWITCH iCurrentEvent
CASE 0
//Once Lamar is in view, have him get into the car.
IS_PLAYER_AT_LOCATION_IN_VEHICLE(sLocatesData, vTruckBlipPosition, <<0.001, 0.001, LOCATE_SIZE_HEIGHT>>, FALSE, sStolenCars[0].veh,
"CH_CHOPSHOP", "CH_COLLECT", "CH_GETBACKCAR", TRUE)
IF NOT DOES_ENTITY_EXIST(sLamar.ped)
IF VDIST2(<<-209.6797, -1360.2938, 30.2959>>, GET_ENTITY_COORDS(PLAYER_PED_ID())) < 22500.0
SETUP_REQ_LAMAR(<<-210.6681, -1358.6426, 30.2610>>, 123.1137)
ENDIF
ENDIF
IF NOT IS_PED_INJURED(sLamar.ped)
AND IS_VEHICLE_DRIVEABLE(sStolenCars[0].veh)
IF sLamar.iEvent = 0
REQUEST_ANIM_DICT(strGetInCarAnims)
IF HAS_ANIM_DICT_LOADED(strGetInCarAnims)
iSyncSceneStartCar = CREATE_SYNCHRONIZED_SCENE(<<0.0, -0.6, 0.0>>, <<0.0, 0.0, 0.0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSyncSceneStartCar, sStolenCars[0].veh, GET_ENTITY_BONE_INDEX_BY_NAME(sStolenCars[0].veh, "seat_pside_f"))
TASK_SYNCHRONIZED_SCENE(sLamar.ped, iSyncSceneStartCar, strGetInCarAnims, "waitloop_lamar", INSTANT_BLEND_IN, NORMAL_BLEND_OUT,
SYNCED_SCENE_USE_PHYSICS, RBF_BULLET_IMPACT | RBF_ELECTROCUTION | RBF_PLAYER_IMPACT | RBF_MELEE)
SET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneStartCar, 0.0)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneStartCar, TRUE)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sLamar.ped, TRUE)
sLamar.iEvent++
ENDIF
ELSE
FLOAT fDistToCar
VECTOR vPlayerPos, vCarPos
vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID())
vCarPos = GET_ENTITY_COORDS(sStolenCars[0].veh)
fDistToCar = VDIST2(vPlayerPos, vCarPos)
IF NOT bLamarKnockedOutOfLeanAnim
IF IS_PED_RAGDOLL(sLamar.ped)
OR IS_PED_GETTING_UP(sLamar.ped)
OR NOT IS_SYNCHRONIZED_SCENE_RUNNING(iSyncSceneStartCar)
OR IS_PED_IN_COMBAT(sLamar.ped)
//SET_ENTITY_NO_COLLISION_ENTITY(sStolenCars[0].veh, sLamar.ped, TRUE)
bLamarKnockedOutOfLeanAnim = TRUE
ENDIF
ENDIF
//Do safety checks for another car going near Lamar (e.g. taxi), if this happens he should be broken out of the anim.
GET_PED_NEARBY_VEHICLES(sLamar.ped, vehClosest)
REPEAT COUNT_OF(vehClosest) i
IF vehClosest[i] != sStolenCars[0].veh
IF NOT IS_ENTITY_DEAD(vehClosest[i])
AND NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vehClosest[i])
IF VDIST2(GET_ENTITY_COORDS(sLamar.ped), GET_ENTITY_COORDS(vehClosest[i])) < 100.0
AND GET_ENTITY_SPEED(vehClosest[i]) > 3.0
STOP_SYNCHRONIZED_ENTITY_ANIM(sLamar.ped, NORMAL_BLEND_OUT, TRUE)
CLEAR_PED_TASKS(sLamar.ped)
//SET_ENTITY_NO_COLLISION_ENTITY(sStolenCars[0].veh, sLamar.ped, TRUE)
iSyncSceneStartCar = -1
ENDIF
ENDIF
ENDIF
ENDREPEAT
IF fDistToCar < 225.0
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_ForceDirectEntry, TRUE)
ENDIF
IF fDistToCar < 225.0
IF NOT IS_ENTITY_OCCLUDED(sLamar.ped)
AND IS_ENTITY_ON_SCREEN(sLamar.ped)
fTimeLamarSpentOnScreen += GET_FRAME_TIME()
ENDIF
ENDIF
IF IS_VEHICLE_DRIVEABLE(sStolenCars[0].veh)
IF ( GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()) = sStolenCars[0].veh )
OR ( GET_VEHICLE_PED_IS_ENTERING(PLAYER_PED_ID()) = sStolenCars[0].veh )
FREEZE_ENTITY_POSITION(sStolenCars[0].veh, FALSE)
ENDIF
ENDIF
BOOL bSafeToPlayAnim, bIgnoreAnimChecks
bSafeToPlayAnim = fDistToCar < 225.0
AND ABSF(vPlayerPos.z - vCarPos.z) < 2.0
AND (HAS_ENTITY_CLEAR_LOS_TO_ENTITY_IN_FRONT(sLamar.ped, PLAYER_PED_ID()) OR IS_PED_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[0].veh, TRUE))
AND (fTimeLamarSpentOnScreen > 1.0 OR fDistToCar < 64.0)
bIgnoreAnimChecks = bLamarKnockedOutOfLeanAnim
AND fDistToCar < 400.0
AND ABSF(vPlayerPos.z - vCarPos.z) < 2.0
IF bSafeToPlayAnim
OR bIgnoreAnimChecks
IF NOT IS_PED_RAGDOLL(sLamar.ped)
AND NOT IS_PED_GETTING_UP(sLamar.ped)
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_LAMHI", CONV_PRIORITY_MEDIUM)
IF NOT bLamarKnockedOutOfLeanAnim
iSyncSceneStartCar = CREATE_SYNCHRONIZED_SCENE(<<0.0, -0.6, 0.0>>, <<0.0, 0.0, 0.0>>) //This is at a new offset that works with blending the anim out mid-way (normally at <<0, 0, 0>>)
ATTACH_SYNCHRONIZED_SCENE_TO_ENTITY(iSyncSceneStartCar, sStolenCars[0].veh, GET_ENTITY_BONE_INDEX_BY_NAME(sStolenCars[0].veh, "seat_pside_f"))
TASK_SYNCHRONIZED_SCENE(sLamar.ped, iSyncSceneStartCar, strGetInCarAnims, "entercar_lamar", NORMAL_BLEND_IN, WALK_BLEND_OUT,
SYNCED_SCENE_USE_PHYSICS, RBF_BULLET_IMPACT | RBF_ELECTROCUTION | RBF_PLAYER_IMPACT | RBF_MELEE)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sLamar.ped, TRUE)
SET_ENTITY_COLLISION(sLamar.ped, TRUE)
SET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneStartCar, 0.0)
SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneStartCar, FALSE)
ELSE
STOP_SYNCHRONIZED_ENTITY_ANIM(sLamar.ped, WALK_BLEND_OUT, TRUE)
iSyncSceneStartCar = -1
TASK_ENTER_VEHICLE(sLamar.ped, sStolenCars[0].veh, DEFAULT_TIME_BEFORE_WARP, VS_FRONT_RIGHT)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sLamar.ped, TRUE)
ENDIF
FREEZE_ENTITY_POSITION(sStolenCars[0].veh, FALSE)
CLEAR_MISSION_LOCATE_STUFF(sLocatesData)
CLEAR_PRINTS()
bTaxiDropoffSet = FALSE
iCurrentEvent++
ENDIF
ELSE
STOP_SYNCHRONIZED_ENTITY_ANIM(sLamar.ped, NORMAL_BLEND_OUT, TRUE)
iSyncSceneStartCar = -1
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE 1
BOOL bKnockedCarWhileSyncScenePlaying
IF IS_VEHICLE_DRIVEABLE(sStolenCars[0].veh)
IF NOT IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[0].veh)
IF NOT DOES_BLIP_EXIST(sStolenCars[0].blip)
sStolenCars[0].blip = CREATE_BLIP_FOR_ENTITY(sStolenCars[0].veh)
ENDIF
ELSE
IF DOES_BLIP_EXIST(sStolenCars[0].blip)
REMOVE_BLIP(sStolenCars[0].blip)
ENDIF
ENDIF
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[0].veh)
IF IS_SYNCHRONIZED_SCENE_RUNNING(iSyncSceneStartCar)
IF GET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneStartCar) < 0.55
IF VMAG(GET_ENTITY_VELOCITY(sStolenCars[0].veh)) > 0.5
bKnockedCarWhileSyncScenePlaying = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
IF NOT IS_PED_INJURED(sLamar.ped)
IF IS_SYNCHRONIZED_SCENE_RUNNING(iSyncSceneStartCar)
AND NOT IS_PED_RAGDOLL(sLamar.ped)
AND NOT bKnockedCarWhileSyncScenePlaying
IF IS_VEHICLE_DRIVEABLE(sStolenCars[0].veh)
//Old version: Lamar is warped into the car when the anim ends.
IF GET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneStartCar) >= 1.0
CLEAR_PED_TASKS_IMMEDIATELY(sLamar.ped)
SET_PED_INTO_VEHICLE(sLamar.ped, sStolenCars[0].veh, VS_FRONT_RIGHT)
FORCE_PED_AI_AND_ANIMATION_UPDATE(sLamar.ped)
FREEZE_ENTITY_POSITION(sStolenCars[0].veh, FALSE)
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_ForceDirectEntry, FALSE)
REMOVE_ALL_BLIPS()
iCurrentEvent++
ENDIF
//New version: Lamar is broken out of the anim before he interacts with the car, then gets in. This fixes issues with being able to mess with the anim and cause
//a number of issues.
IF GET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneStartCar) >= 0.24
STOP_SYNCHRONIZED_ENTITY_ANIM(sLamar.ped, WALK_BLEND_OUT, TRUE)
TASK_ENTER_VEHICLE(sLamar.ped, sStolenCars[0].veh, DEFAULT_TIME_BEFORE_WARP, VS_FRONT_RIGHT, PEDMOVE_WALK)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sLamar.ped, TRUE)
FREEZE_ENTITY_POSITION(sStolenCars[0].veh, FALSE)
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_ForceDirectEntry, FALSE)
REMOVE_ALL_BLIPS()
iSyncSceneStartCar = -1
iCurrentEvent++
ENDIF
ENDIF
ELSE
//Something knocked Lamar out of the stage, just clean up the anims and continue
IF IS_SYNCHRONIZED_SCENE_RUNNING(iSyncSceneStartCar)
STOP_SYNCHRONIZED_ENTITY_ANIM(sLamar.ped, NORMAL_BLEND_OUT, TRUE)
ENDIF
IF IS_ENTITY_PLAYING_ANIM(sStolenCars[0].veh, strGetInCarAnims, "entercar_cardoor")
STOP_ENTITY_ANIM(sStolenCars[0].veh, "entercar_cardoor", strGetInCarAnims, NORMAL_BLEND_OUT)
ENDIF
SET_PED_TO_RAGDOLL(sLamar.ped, 1500, 2500, TASK_RELAX, FALSE, FALSE)
FREEZE_ENTITY_POSITION(sStolenCars[0].veh, FALSE)
iSyncSceneStartCar = -1
iCurrentEvent++
ENDIF
ENDIF
IF NOT bTaxiDropoffSet
SET_TAXI_DROPOFF_LOCATION_FOR_BLIP(sStolenCars[0].blip, <<217.3918, -1395.3651, 30.2650>>, 26.1585)
bTaxiDropoffSet = TRUE
ENDIF
BREAK
CASE 2
//Just in case player control was left off in the previous stage when forcing the player to avoid Lamar's synced scene.
IF NOT IS_PLAYER_CONTROL_ON(PLAYER_ID())
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
ENDIF
IF IS_VEHICLE_DRIVEABLE(sStolenCars[0].veh)
AND NOT IS_PED_INJURED(sLamar.ped)
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[0].veh, TRUE)
//Just in case the blip wasn't removed the previous stage (e.g. if Lamar's anim was cancelled somehow).
IF DOES_BLIP_EXIST(sStolenCars[0].blip)
REMOVE_BLIP(sStolenCars[0].blip)
ENDIF
IF VDIST2(GET_ENTITY_COORDS(sLamar.ped), GET_ENTITY_COORDS(sStolenCars[0].veh)) < 16.0
IF (NOT IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0) AND CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_GOTREV", CONV_PRIORITY_MEDIUM))
OR IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
//Ensure all ambient carsteal vehicles are deactivated as the next time
//we go to the chopshop they will be loaded onto the packer.
//NB: This will be done with IPLs when TODO 692707 is completed.
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_ENTITYXF, BUILDINGSTATE_NORMAL, FALSE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_CHEETAH, BUILDINGSTATE_NORMAL, FALSE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_ZTYPE, BUILDINGSTATE_NORMAL, FALSE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_JB700, BUILDINGSTATE_NORMAL, FALSE)
//Once the player reaches the car close the road outside the garage so the truck can be placed safely.
SETUP_REQ_CLOSE_ROAD_OUTSIDE_GARAGE()
//Store the car the player turned up in.
IF IS_REPLAY_START_VEHICLE_UNDER_SIZE_LIMIT(<<0.0, 0.0, 0.0>>, TRUE)
SET_MISSION_START_VEHICLE_AS_VEHICLE_GEN(<<-219.3700, -1355.8894, 30.2681>>, 117.4465)
ENDIF
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CHECKPOINT_MEET_TREVOR, "MEET_TREVOR")
REPLAY_RECORD_BACK_FOR_TIME(10.0, 10.0, REPLAY_IMPORTANCE_HIGHEST)
iInitialDriverConvoTimer = 0
iCurrentEvent = 50
ENDIF
ENDIF
IF NOT IS_AUDIO_SCENE_ACTIVE("CAR_4_TAKE_CAR_TO_TRANSPORTER")
START_AUDIO_SCENE("CAR_4_TAKE_CAR_TO_TRANSPORTER")
ENDIF
ENDIF
ENDIF
IF DOES_BLIP_EXIST(sStolenCars[0].blip)
REMOVE_BLIP(sStolenCars[0].blip)
ENDIF
IS_PLAYER_AT_LOCATION_WITH_BUDDY_IN_VEHICLE(sLocatesData, vTruckBlipPosition, <<0.001, 0.001, LOCATE_SIZE_HEIGHT>>, FALSE, sLamar.ped, sStolenCars[0].veh,
"", "CH_LEAVELAM", "", "CH_GETBACKCAR", FALSE, TRUE, NOT bAlreadyPrintedWantedLevelText)
IF DOES_BLIP_EXIST(sLocatesData.LocationBlip)
SET_BLIP_COLOUR(sLocatesData.LocationBlip, BLIP_COLOUR_BLUE)
SET_BLIP_ROUTE_COLOUR(sLocatesData.LocationBlip, BLIP_COLOUR_BLUE)
IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vTruckLocate, DEFAULT_LOCATES_SIZE_VECTOR(), TRUE) //fudge around the blip issue here (flickering blue route due to truck moving)
//the blip for truck is constant vector
//hide the locates header corona and display custom one
ELSE
IF DOES_BLIP_EXIST(sTruck.blip)
REMOVE_BLIP(sTruck.blip)
ENDIF
ENDIF
BREAK
CASE 50
//FUDGE: Increase vehicle population at this stage as it struggles.
SET_RANDOM_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(1.5)
IF IS_PLAYER_AT_LOCATION_WITH_BUDDY_IN_VEHICLE(sLocatesData, vTruckBlipPosition, <<0.001, 0.001, LOCATE_SIZE_HEIGHT>>, FALSE, sLamar.ped, sStolenCars[0].veh,
"CH_CHOPSHOP", "CH_LEAVELAM", "", "CH_GETBACKCAR", FALSE, TRUE, NOT bAlreadyPrintedWantedLevelText)
iCurrentEvent++
ENDIF
IF DOES_BLIP_EXIST(sLocatesData.LocationBlip)
SET_BLIP_COLOUR(sLocatesData.LocationBlip, BLIP_COLOUR_BLUE)
SET_BLIP_ROUTE_COLOUR(sLocatesData.LocationBlip, BLIP_COLOUR_BLUE)
IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vTruckLocate, DEFAULT_LOCATES_SIZE_VECTOR(), TRUE) //fudge around the blip issue here (flickering blue route due to truck moving)
//the blip for truck is constant vector
//hide the locates header corona and display custom one
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
//Play some "let's do this" dialogue just before the final locate is hit.
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_LINEUP2")
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehBack, <<-0.0340, -9.8469, 0.5873>>),
GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehBack, <<0.1043, -2.2616, 2.2863>>), 1.750000)
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_LINEUP2", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_LINEUP2", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
//IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<509.411072,-1318.539673,30.113941>>, <<507.368958,-1315.807373,31.800457>>, 1.750000)
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehBack, <<-0.0340, -5.8469, 0.5873>>),
GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehBack, <<0.1043, -2.2616, 2.2863>>), 1.750000)
HANG_UP_AND_PUT_AWAY_PHONE()
KILL_FACE_TO_FACE_CONVERSATION()
CLEAR_MISSION_LOCATION_TEXT_AND_BLIPS(sLocatesData)
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
SETTIMERB(0)
iCurrentEvent++
ENDIF
ENDIF
IF IS_FACE_TO_FACE_CONVERSATION_PAUSED()
PAUSE_FACE_TO_FACE_CONVERSATION(FALSE)
ENDIF
//Lamar and Franklin chatter
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_CHAT1")
AND NOT HAS_LABEL_BEEN_TRIGGERED("CST7_CHAT1b")
IF iInitialDriverConvoTimer = 0
iInitialDriverConvoTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(250, 750)
ELIF GET_GAME_TIMER() - iInitialDriverConvoTimer > 0
IF Get_Fails_Count_Total_For_This_Mission_Script() > 0
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_CHAT1", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_CHAT1", TRUE)
ENDIF
ELSE
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_CHAT1b", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_CHAT1b", TRUE)
ENDIF
ENDIF
ENDIF
ELIF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_LINEUP") //Lamar tells franklin to line up the car
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sTruck.vehBack)) < 1600.0
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_LINEUP", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_LINEUP", TRUE)
ENDIF
ENDIF
ENDIF
ELIF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_TREVHI") //Trevor says hi
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
IF IS_ENTITY_VISIBLE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
AND VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])) < 900.0
IF HAS_ENTITY_CLEAR_LOS_TO_ENTITY_IN_FRONT(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], PLAYER_PED_ID())
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_TREVHI", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_TREVHI", TRUE)
iNumTrevorReminders = 0
iTrevorReminderTimer = GET_GAME_TIMER()
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
//If the main chatter conversations were interrupted by player crashing, resume them when crash conversation has played
IF ( bCurrentConversationInterrupted = TRUE )
IF HAS_LABEL_BEEN_TRIGGERED("CST7_DMG")
IF HAS_LABEL_BEEN_TRIGGERED("CST7_CHAT1")
OR HAS_LABEL_BEEN_TRIGGERED("CST7_CHAT1b")
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF NOT IS_STRING_NULL_OR_EMPTY(CurrentConversationRoot)
AND NOT IS_STRING_NULL_OR_EMPTY(CurrentConversationLabel)
#IF IS_DEBUG_BUILD
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Resuming main conversation CurrentConversationRoot is ", CurrentConversationRoot, ".")
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Resuming main conversation CurrentConversationLabel is ", CurrentConversationLabel, ".")
#ENDIF
IF CREATE_CONVERSATION_FROM_SPECIFIC_LINE(sConversationPeds, "CST7AUD", CurrentConversationRoot, CurrentConversationLabel, CONV_PRIORITY_MEDIUM)
bCurrentConversationInterrupted = FALSE
SET_LABEL_AS_TRIGGERED("CST7_DMG", FALSE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
//Trevor says a reminder to load the the monroe onto the trailer
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_BACK")
IF HAS_LABEL_BEEN_TRIGGERED("CST7_TREVHI")
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
IF IS_ENTITY_PLAYING_ANIM(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], strTruckWaitAnims, "packer_idle_base_trevor")
IF ( GET_GAME_TIMER() - iTrevorReminderTimer > 7500 )
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<523.937012,-1325.784912,27.221191>>, <<509.328400,-1302.508789,33.191227>>, 16.0)
IF HAS_ENTITY_CLEAR_LOS_TO_ENTITY_IN_FRONT(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], PLAYER_PED_ID())
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_BACK", CONV_PRIORITY_MEDIUM)
TASK_LOOK_AT_ENTITY(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], PLAYER_PED_ID(), 3000, SLF_WHILE_NOT_IN_FOV)
iNumTrevorReminders++
iTrevorReminderTimer = GET_GAME_TIMER()
IF ( iNumTrevorReminders = 3 )
SET_LABEL_AS_TRIGGERED("CST7_TREVHI", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
//Lamar says a line when player crashes the monroe while driving
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_MONDMG")
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_LINEUP")
IF HAS_ENTITY_COLLIDED_WITH_ANYTHING(sStolenCars[0].veh)
IF ( GET_GAME_TIMER() - iLamarMonroeDamageTimer > 5000 )
//If the main chatter conversations are playing kill them and store root and label for resumption
IF HAS_LABEL_BEEN_TRIGGERED("CST7_CHAT1")
OR HAS_LABEL_BEEN_TRIGGERED("CST7_CHAT1b")
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
CurrentConversationRoot = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT()
IF NOT IS_STRING_NULL_OR_EMPTY(CurrentConversationRoot)
IF ARE_STRINGS_EQUAL(CurrentConversationRoot, "CST7_CHAT1")
OR ARE_STRINGS_EQUAL(CurrentConversationRoot, "CST7_CHAT1b")
CurrentConversationRoot = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT()
CurrentConversationLabel = GET_STANDARD_CONVERSATION_LABEL_FOR_FUTURE_RESUMPTION()
#IF IS_DEBUG_BUILD
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Interrupting main conversation CurrentConversationRoot is ", CurrentConversationRoot, ".")
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Interrupting main conversation CurrentConversationLabel is ", CurrentConversationLabel, ".")
#ENDIF
IF ARE_STRINGS_EQUAL(CurrentConversationLabel, "NULL")
#IF IS_DEBUG_BUILD
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Main conversation CurrentConversationLabel is NULL.")
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Adjusting main conversation CurrentConversationLabel to first conversation line.")
#ENDIF
CurrentConversationLabel = CurrentConversationRoot
CurrentConversationLabel += "_1"
#IF IS_DEBUG_BUILD
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Modified main conversation CurrentConversationRoot is ", CurrentConversationRoot, ".")
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Modified main conversation CurrentConversationLabel is ", CurrentConversationLabel, ".")
#ENDIF
ENDIF
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
bCurrentConversationInterrupted = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
//Play Lamar's random conversation for crashing monroe
IF ( bCurrentConversationInterrupted = TRUE )
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_DMG")
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_DMG", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_DMG", TRUE)
iNumLamarMonroeDamageLines++
iLamarMonroeDamageTimer = GET_GAME_TIMER()
IF ( iNumLamarMonroeDamageLines = 4 )
SET_LABEL_AS_TRIGGERED("CST7_MONDMG", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF HAS_LABEL_BEEN_TRIGGERED("CST7_CHAT1")
OR HAS_LABEL_BEEN_TRIGGERED("CST7_CHAT1b")
IF NOT IS_FACE_TO_FACE_CONVERSATION_PAUSED()
PAUSE_FACE_TO_FACE_CONVERSATION(TRUE)
ENDIF
ENDIF
IF DOES_BLIP_EXIST(sTruck.blip)
REMOVE_BLIP(sTruck.blip)
ENDIF
ENDIF
//Request mocap in advance
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sTruck.vehBack)) < DEFAULT_CUTSCENE_LOAD_DIST*DEFAULT_CUTSCENE_LOAD_DIST
REQUEST_CUTSCENE("CAR_5_MCS_1")
SET_CUTSCENE_PED_COMPONENT_VARIATIONS("CAR_5_MCS_1")
ENDIF
ENDIF
BREAK
CASE 51
IF NOT IS_ENTITY_DEAD(sStolenCars[0].veh)
IF GET_ENTITY_SPEED(sStolenCars[0].veh) < 0.5
//FREEZE_ENTITY_POSITION(sStolenCars[0].veh, TRUE) //don't freeze the car, see bug B*1930394
BRING_VEHICLE_TO_HALT(sStolenCars[0].veh, 1.0, 5) //bring it to halt instead and let it settle
ENDIF
ENDIF
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_LINEUP2")
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_LINEUP2", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_LINEUP2", TRUE)
ENDIF
ELIF TIMERB() > 1000
eSectionStage = SECTION_STAGE_CLEANUP
ENDIF
ENDIF
BREAK
ENDSWITCH
//Keep track of if wanted level text was printed. This solves issues where one locates header call doesn't remember if the last one printed wanted text.
IF NOT bAlreadyPrintedWantedLevelText
IF IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
bAlreadyPrintedWantedLevelText = TRUE
ENDIF
ELSE
IF NOT IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
bAlreadyPrintedWantedLevelText = FALSE
ENDIF
ENDIF
//Fail if the player leaves Lamar behind.
IF iCurrentEvent > 0
IF NOT IS_PED_INJURED(sLamar.ped)
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sLamar.ped)) > 90000.0
MISSION_FAILED(FAILED_LEFT_LAMAR)
ENDIF
ENDIF
ENDIF
IF IS_VEHICLE_DRIVEABLE(sStolenCars[0].veh)
IF iCurrentEvent > 0 //Start requesting the truck once the player reaches Lamar.
IF NOT SETUP_REQ_TRUCK_AWAITING_LAST_CAR(vTruckStartPos, fTruckStartHeading)
//Make sure there's no cars in the way
SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<468.4835, -1336.4393, 27.2305>>, <<480.8360, -1334.4310, 38.2508>>, FALSE)
CLEAR_AREA_OF_VEHICLES(vTruckStartPos, 30.0)
ENDIF
//Create the cars as soon as the truck is ready
SETUP_REQ_CARS_ON_TRUCK()
IF NOT DOES_ENTITY_EXIST(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
SETUP_REQ_TREVOR(<<503.2, -1345.4, 29.9>>, fTrevorStartHeading)
SETUP_REQ_INVISIBLE_TREVOR()
ENDIF
ENDIF
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[0].veh)
//Disable jumping out the car if the player is right next to the truck (fixes bug 333453)
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehBack, <<-0.0617, -15.5324, -0.8495>>),
GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehBack, <<0.0877, 1.9641, 4.6127>>), 3.750000)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_EXIT)
ENDIF
ENDIF
ENDIF
ENDIF
//Handle Trevor's anims: he hangs around by the truck
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
IF IS_ENTITY_VISIBLE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
REQUEST_ANIM_DICT(strTruckWaitAnims)
IF HAS_ANIM_DICT_LOADED(strTruckWaitAnims)
AND NOT IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
IF iTrevorWaitAnimsTimer = 0
TASK_PLAY_ANIM(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], strTruckWaitAnims, "packer_idle_base_trevor",
NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING)
iTrevorWaitAnimsTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(-2000, 2000)
ELIF NOT bTrevorKnockedOver
//If Trevor is knocked out of the anims for some reason then don't play them again.
IF GET_SCRIPT_TASK_STATUS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], SCRIPT_TASK_PLAY_ANIM) != PERFORMING_TASK
AND GET_SCRIPT_TASK_STATUS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], SCRIPT_TASK_PERFORM_SEQUENCE) != PERFORMING_TASK
CLEAR_PED_TASKS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
bTrevorKnockedOver = TRUE
ELSE
IF GET_GAME_TIMER() - iTrevorWaitAnimsTimer > 10000
AND IS_ENTITY_PLAYING_ANIM(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], strTruckWaitAnims, "packer_idle_base_trevor")
SEQUENCE_INDEX seq
INT iRandom = GET_RANDOM_INT_IN_RANGE(0, 3)
OPEN_SEQUENCE_TASK(seq)
IF iRandom = 0
TASK_PLAY_ANIM(NULL, strTruckWaitAnims, "packer_idle_1_trevor", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_USE_KINEMATIC_PHYSICS)
ELIF iRandom = 1
IF NOT bPlayedTrevorGreetingAnim
TASK_PLAY_ANIM(NULL, strTruckWaitAnims, "packer_idle_2_trevor", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_USE_KINEMATIC_PHYSICS)
ENDIF
ELIF iRandom = 2
TASK_PLAY_ANIM(NULL, strTruckWaitAnims, "packer_idle_3_trevor", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_USE_KINEMATIC_PHYSICS)
ENDIF
TASK_PLAY_ANIM(NULL, strTruckWaitAnims, "packer_idle_base_trevor", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING | AF_USE_KINEMATIC_PHYSICS)
CLOSE_SEQUENCE_TASK(seq)
TASK_PERFORM_SEQUENCE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], seq)
CLEAR_SEQUENCE_TASK(seq)
iTrevorWaitAnimsTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(-2000, 2000)
ENDIF
IF NOT bPlayedTrevorGreetingAnim
IF HAS_LABEL_BEEN_TRIGGERED("CST7_TREVHI")
SEQUENCE_INDEX seq
OPEN_SEQUENCE_TASK(seq)
TASK_PLAY_ANIM(NULL, strTruckWaitAnims, "packer_idle_4_trevor", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_USE_KINEMATIC_PHYSICS)
TASK_PLAY_ANIM(NULL, strTruckWaitAnims, "packer_idle_base_trevor", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING | AF_USE_KINEMATIC_PHYSICS)
CLOSE_SEQUENCE_TASK(seq)
TASK_PERFORM_SEQUENCE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], seq)
CLEAR_SEQUENCE_TASK(seq)
bPlayedTrevorGreetingAnim = TRUE
ENDIF
ENDIF
ENDIF
ELSE
IF VDIST2(vTrevorStartPos, GET_ENTITY_COORDS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])) > 2.0
IF GET_SCRIPT_TASK_STATUS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], SCRIPT_TASK_PERFORM_SEQUENCE) != PERFORMING_TASK
SEQUENCE_INDEX seq
OPEN_SEQUENCE_TASK(seq)
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, vTrevorStartPos, PEDMOVE_WALK, DEFAULT_TIME_BEFORE_WARP, 0.25)
TASK_TURN_PED_TO_FACE_COORD(NULL, <<512.32, -1316.91, 30.32>>)
CLOSE_SEQUENCE_TASK(seq)
TASK_PERFORM_SEQUENCE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], seq)
CLEAR_SEQUENCE_TASK(seq)
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
//Once the truck is created it's safe for Trevor to appear.
IF NOT IS_ENTITY_DEAD(sTruck.vehFront)
SET_ENTITY_VISIBLE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], TRUE)
SET_ENTITY_COLLISION(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], TRUE)
SET_ENTITY_INVINCIBLE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], FALSE)
FREEZE_ENTITY_POSITION(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], FALSE)
SET_ENTITY_COORDS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], <<519.930, -1327.700, 28.310>>)
SET_ENTITY_HEADING(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], 51.000)
ENDIF
ENDIF
ENDIF
//Fail if the player brings cops to the truc/cars.
IF IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
IF NOT IS_ENTITY_DEAD(sTruck.vehFront)
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sTruck.vehFront)) < 2500.0
MISSION_FAILED(FAILED_LED_COPS_TO_TRUCK)
ENDIF
ENDIF
IF NOT IS_ENTITY_DEAD(sStolenCars[0].veh)
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sStolenCars[0].veh)) < 2500.0
MISSION_FAILED(FAILED_LED_COPS_TO_MONROE)
ENDIF
ENDIF
ENDIF
ENDIF
IF eSectionStage = SECTION_STAGE_CLEANUP
CLEAR_PRINTS()
CLEAR_HELP()
CLEAR_MISSION_LOCATE_STUFF(sLocatesData)
REMOVE_ALL_BLIPS()
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
REMOVE_ANIM_DICT(strGetInCarAnims)
eSectionStage = SECTION_STAGE_SETUP
eMissionStage = STAGE_GET_IN_TRUCK_CUTSCENE
ENDIF
IF eSectionStage = SECTION_STAGE_SKIP
IF IS_VEHICLE_DRIVEABLE(sStolenCars[0].veh)
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[0].veh)
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), sStolenCars[0].veh)
ENDIF
IF NOT IS_PED_INJURED(sLamar.ped)
AND NOT IS_PED_IN_VEHICLE(sLamar.ped, sStolenCars[0].veh)
SET_PED_INTO_VEHICLE(sLamar.ped, sStolenCars[0].veh, VS_FRONT_RIGHT)
//SET_ENTITY_NO_COLLISION_ENTITY(sStolenCars[0].veh, sLamar.ped, TRUE)
ENDIF
FREEZE_ENTITY_POSITION(sStolenCars[0].veh, FALSE)
IF iCurrentEvent >= 2
SET_ENTITY_COORDS_NO_OFFSET(sStolenCars[0].veh, vBackOfTruck)
SET_ENTITY_HEADING(sStolenCars[0].veh, fTruckStartHeading)
ENDIF
ENDIF
eSectionStage = SECTION_STAGE_RUNNING
ENDIF
ENDPROC
PROC GET_IN_TRUCK_CUTSCENE()
IF eSectionStage = SECTION_STAGE_SETUP
IF bIsJumpingDirectlyToStage
IF iCurrentEvent != 99
IF bUsedACheckpoint
START_REPLAY_SETUP(vTruckStartPos + <<5.0, 5.0, 0.0>>, 0.0)
iCurrentEvent = 99
ELSE
SET_ENTITY_COORDS(PLAYER_PED_ID(), vTruckStartPos + <<5.0, 5.0, 0.0>>)
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), TRUE)
LOAD_SCENE(GET_ENTITY_COORDS(PLAYER_PED_ID()))
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), FALSE)
iCurrentEvent = 99
ENDIF
ELSE
IF SETUP_REQ_PLAYER_IS_FRANKLIN()
AND INITIALISE_STOLEN_CAR_DATA()
CLEAR_AREA_OF_VEHICLES(vTruckStartPos, 30.0)
IF SETUP_REQ_CLOSE_ROAD_OUTSIDE_GARAGE()
AND SETUP_REQ_SUPPRESS_CHASE_MODELS()
AND SETUP_REQ_TRUCK_UNFROZEN(vTruckStartPos, fTruckStartHeading)
AND SETUP_REQ_CARS_ON_TRUCK()
AND SETUP_REQ_LAMAR(<<504.1672, -1304.7441, 28.3103>>, 200.8915)
AND SETUP_REQ_TREVOR(<<496.6033, -1308.3790, 28.3020>>, 204.3612)
END_REPLAY_SETUP(DEFAULT, DEFAULT, FALSE)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
bIsJumpingDirectlyToStage = FALSE
ENDIF
ENDIF
ENDIF
ELSE
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON)
REQUEST_CUTSCENE("CAR_5_MCS_1")
SET_CUTSCENE_PED_COMPONENT_VARIATIONS("CAR_5_MCS_1")
IF HAS_CUTSCENE_LOADED_WITH_FAILSAFE()
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
REGISTER_ENTITY_FOR_CUTSCENE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], "Trevor", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
IF NOT IS_PED_INJURED(sLamar.ped)
REGISTER_ENTITY_FOR_CUTSCENE(sLamar.ped, "Lamar", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
FREEZE_ENTITY_POSITION(sTruck.vehFront, FALSE)
REGISTER_ENTITY_FOR_CUTSCENE(sTruck.vehFront, "CAR_5_Truck", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
//SET_VEHICLE_EXTRA(sTruck.vehBack, 7, FALSE)
FREEZE_ENTITY_POSITION(sTruck.vehBack, FALSE)
REGISTER_ENTITY_FOR_CUTSCENE(sTruck.vehBack, "CAR_5_Trailer", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
SET_CUTSCENE_FADE_VALUES(FALSE, FALSE, FALSE, FALSE)
SET_VEHICLE_MODEL_PLAYER_WILL_EXIT_SCENE(modelTruckFront)
START_CUTSCENE(CUTSCENE_PLAYER_FP_FLASH_TREVOR)
REPLAY_START_EVENT(REPLAY_IMPORTANCE_HIGHEST)
REPLAY_RECORD_BACK_FOR_TIME(8.0, 0.0, REPLAY_IMPORTANCE_HIGHEST)
DO_FADE_IN_WITH_WAIT()
SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE)
bSkippedMocap = FALSE
iCurrentEvent = 0
eSectionStage = SECTION_STAGE_RUNNING
ENDIF
ENDIF
ENDIF
IF eSectionStage = SECTION_STAGE_RUNNING
IF NOT bSkippedMocap
IF IS_CUTSCENE_SKIP_BUTTON_PRESSED()
bSkippedMocap = TRUE
ENDIF
ENDIF
IF NOT IS_CUTSCENE_ACTIVE()
eSectionStage = SECTION_STAGE_CLEANUP
ENDIF
REQUEST_ANIM_DICT(strTruckSitAnims)
SWITCH iCurrentEvent
CASE 0
IF IS_CUTSCENE_PLAYING()
IF IS_VEHICLE_DRIVEABLE(sStolenCars[0].veh)
AND NOT IS_ENTITY_DEAD(sTruck.vehBack)
SET_ENTITY_COLLISION(sStolenCars[0].veh, TRUE)
FREEZE_ENTITY_POSITION(sStolenCars[0].veh, FALSE)
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(sStolenCars[0].veh, TRUE)
//ATTACH_ENTITY_TO_ENTITY(sStolenCars[0].veh, sTruck.vehBack, -1, sStolenCars[0].vTruckOffset, sStolenCars[0].vTruckRotation, FALSE, FALSE, TRUE)
ATTACH_VEHICLE_ON_TO_TRAILER(sStolenCars[0].veh, sTruck.vehBack, <<0.0, 0.0, 0.0>>, sStolenCars[0].vTruckOffset, sStolenCars[0].vTruckRotation, -1.0)
SET_VEHICLE_ENGINE_ON(sStolenCars[0].veh, FALSE, FALSE)
SET_VEHICLE_RADIO_LOUD(sStolenCars[0].veh, FALSE)
SET_VEHICLE_DOOR_SHUT(sTruck.vehBack, SC_DOOR_BOOT)
ENDIF
SETUP_REQ_CLOSE_ROAD_OUTSIDE_GARAGE()
CLEAR_AREA_OF_VEHICLES(vTruckStartPos, 200.0)
CLEAR_AREA_OF_PROJECTILES(vTruckStartPos, 100.0)
STOP_AUDIO_SCENES()
iCurrentEvent++
ENDIF
BREAK
ENDSWITCH
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
AND NOT IS_ENTITY_DEAD(sTruck.vehFront)
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("CAR_5_Truck")
SET_VEHICLE_DOORS_SHUT(sTruck.vehFront, TRUE)
SET_VEHICLE_DOORS_LOCKED(sTruck.vehFront, VEHICLELOCK_UNLOCKED)
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("CAR_5_Trailer")
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Franklin")
IF GET_CURRENT_PLAYER_PED_ENUM() != CHAR_TREVOR
MAKE_SELECTOR_PED_SELECTION(sSelectorPeds, SELECTOR_PED_TREVOR)
TAKE_CONTROL_OF_SELECTOR_PED(sSelectorPeds)
REASSIGN_PLAYER_CHAR_DIALOGUE_SPEAKERS()
IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_IN_VEHICLE) != CAM_VIEW_MODE_FIRST_PERSON
ANIMPOSTFX_PLAY("SwitchSceneTrevor", 0, FALSE)
PLAY_SOUND_FRONTEND(-1, "Hit_1", "LONG_PLAYER_SWITCH_SOUNDS")
ENDIF
ENDIF
SET_PED_RELATIONSHIP_GROUP_HASH(PLAYER_PED_ID(), RELGROUPHASH_PLAYER)
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
SET_PED_RELATIONSHIP_GROUP_HASH(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], RELGROUPHASH_PLAYER)
ENDIF
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), sTruck.vehFront, VS_DRIVER)
FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID())
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
SET_PED_INTO_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], sTruck.vehFront, VS_FRONT_RIGHT)
FORCE_PED_AI_AND_ANIMATION_UPDATE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
ENDIF
ENDIF
IF CAN_SET_EXIT_STATE_FOR_CAMERA()
REPLAY_STOP_EVENT()
REPLAY_RECORD_BACK_FOR_TIME(0.0, 10.0, REPLAY_IMPORTANCE_HIGHEST)
//fix for B*1809850 - jb700 pops up due to attachment/physics when cutscene ends
IF NOT WAS_CUTSCENE_SKIPPED()
IF DOES_ENTITY_EXIST(sStolenCars[3].veh) AND NOT IS_ENTITY_DEAD(sStolenCars[3].veh)
DETACH_ENTITY(sStolenCars[3].veh, FALSE, TRUE)
ATTACH_VEHICLE_ON_TO_TRAILER(sStolenCars[3].veh, sTruck.vehBack, <<0.0, 0.0, 0.0>>, sStolenCars[3].vTruckOffset, sStolenCars[3].vTruckRotation, -1.0)
ENDIF
ENDIF
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
SET_STOLEN_CARS_AS_LOW_LOD()
ENDIF
IF NOT IS_PED_INJURED(sLamar.ped)
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Lamar")
SET_PED_MAX_HEALTH(sLamar.ped, 500)
SET_ENTITY_HEALTH(sLamar.ped, 500)
UPDATE_LAMAR_TRUCK_ANIMS()
ENDIF
ENDIF
ENDIF
REQUEST_ANIM_DICT(strTruckIdleAnims)
ENDIF
IF eSectionStage = SECTION_STAGE_CLEANUP
REQUEST_ANIM_DICT(strTruckIdleAnims)
IF HAS_ANIM_DICT_LOADED(strTruckIdleAnims)
If bSkippedMocap
//If the player skipped the mocap the peds need to be warped.
WHILE IS_CUTSCENE_ACTIVE()
WAIT(0)
ENDWHILE
ENDIF
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
AND NOT IS_ENTITY_DEAD(sTruck.vehFront)
IF NOT IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), sTruck.vehFront)
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), sTruck.vehFront)
ENDIF
ENDIF
SET_ROADS_BACK_TO_ORIGINAL(<<491.9493, -1421.7377, 10.2604>>, <<563.2618, -1267.8080, 40.3393>>)
SET_SCRIPTS_SAFE_FOR_CUTSCENE(FALSE)
REMOVE_ANIM_DICT(strTruckWaitAnims)
iCurrentEvent = 0
eSectionStage = SECTION_STAGE_SETUP
eMissionStage = STAGE_GO_TO_DROP_OFF
ENDIF
ENDIF
IF eSectionStage = SECTION_STAGE_SKIP
DO_FADE_OUT_WITH_WAIT()
REPLAY_CANCEL_EVENT()
STOP_CUTSCENE()
bSkippedMocap = TRUE
eSectionStage = SECTION_STAGE_RUNNING
ENDIF
ENDPROC
//Drive to the new drop-off point, cops arrive and Franklin has to get in the JB700.
PROC GO_TO_DROP_OFF_LOCATION()
SET_ALL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID())
SET_PED_RESET_FLAG(PLAYER_PED_ID(), PRF_DisableAgitationTriggers, TRUE)
IF NOT IS_PED_INJURED(sLamar.ped)
SET_PED_RESET_FLAG(sLamar.ped, PRF_DisableFriendlyGunReactAudio, TRUE)
ENDIF
VECTOR vTruckStart = vTruckStartPos
FLOAT fTruckStart = fTruckStartHeading
IF eMissionStage = STAGE_COPS_ARRIVE
vTruckStart = <<-2205.1599, 4326.3677, 48.4147>>
fTruckStart = 339.0508
ENDIF
IF eSectionStage = SECTION_STAGE_SETUP
IF bIsJumpingDirectlyToStage
IF bUsedACheckpoint
START_REPLAY_SETUP(vTruckStart + <<5.0, 5.0, 0.0>>, 0.0)
ELSE
SET_ENTITY_COORDS(PLAYER_PED_ID(), vTruckStart + <<5.0, 5.0, 0.0>>)
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), TRUE)
LOAD_SCENE(GET_ENTITY_COORDS(PLAYER_PED_ID()))
WAIT(0)
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), FALSE)
ENDIF
INITIALISE_STOLEN_CAR_DATA()
SETUP_REQ_SUPPRESS_CHASE_MODELS()
REQUEST_ANIM_DICT(strTruckIdleAnims)
REQUEST_ANIM_DICT(strDriveOffTrailerAnims)
REQUEST_ANIM_DICT(strCamShakeAnims)
WHILE NOT SETUP_REQ_PLAYER_IS_TREVOR()
OR NOT SETUP_REQ_TRUCK_UNFROZEN(vTruckStart, fTruckStart)
OR NOT SETUP_REQ_CARS_ON_TRUCK()
OR NOT SETUP_REQ_LAMAR(vTruckStart + <<10.0, 10.0, 0.0>>, 200.8915)
OR NOT SETUP_REQ_FRANKLIN(vTruckStart + <<15.0, 15.0, 0.0>>, 204.3612)
OR NOT HAS_ANIM_DICT_LOADED(strTruckIdleAnims)
OR NOT HAS_ANIM_DICT_LOADED(strDriveOffTrailerAnims)
OR NOT HAS_ANIM_DICT_LOADED(strCamShakeAnims)
REQUEST_ANIM_DICT(strTruckIdleAnims)
CLEAR_AREA_OF_VEHICLES(vTruckStartPos, 30.0)
WAIT(0)
ENDWHILE
END_REPLAY_SETUP(sTruck.vehFront, VS_DRIVER, FALSE)
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
AND NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), sTruck.vehFront)
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), sTruck.vehFront, VS_DRIVER)
ENDIF
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
SET_PED_INTO_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], sTruck.vehFront, VS_FRONT_RIGHT)
ENDIF
IF NOT IS_PED_INJURED(sLamar.ped)
SET_PED_MAX_HEALTH(sLamar.ped, 500)
SET_ENTITY_HEALTH(sLamar.ped, 500)
UPDATE_LAMAR_TRUCK_ANIMS()
ENDIF
ENDIF
SET_STOLEN_CARS_AS_LOW_LOD()
iCurrentEvent = 99
bIsJumpingDirectlyToStage = FALSE
ELSE
iNumChaseCopCarsCreated = 0
iNumTimesPlayedUnhookDialogue = 0
iNumTimesPlayedRehookDialogue = 0
iNumTimesPlayedUnhookReminder = 0
iNumTimesPlayedCopsWarn1 = 0
iNumTimesPlayedCopsWarn2 = 0
iNumTimesPlayedCopsWarn3 = 0
iNumTimesPlayedCopsWarn4 = 0
SUPPRESS_LARGE_VEHICLES(TRUE)
BLOCK_SCENARIOS_FOR_CHASE(TRUE)
IF IS_SCREEN_FADED_OUT()
//If skipping to halfway through this stage warp the truck where the cops arrive.
IF eMissionStage = STAGE_COPS_ARRIVE
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
AND NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), sTruck.vehFront)
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), sTruck.vehFront)
ENDIF
CLEAR_AREA_OF_VEHICLES(vTruckStart, 100.0)
SET_ENTITY_COORDS(sTruck.vehFront, vTruckStart)
SET_ENTITY_HEADING(sTruck.vehFront, fTruckStart)
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
AND NOT IS_ENTITY_DEAD(sTruck.vehBack)
SET_VEHICLE_ON_GROUND_PROPERLY(struck.vehFront)
SET_ENTITY_COORDS_NO_OFFSET(sTruck.vehBack, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, <<0.191836, -9.89637, 0.27933>>))
SET_ENTITY_HEADING(sTruck.vehBack, GET_ENTITY_HEADING(sTruck.vehFront))
ATTACH_VEHICLE_TO_TRAILER(sTruck.vehFront, sTruck.vehBack)
ACTIVATE_PHYSICS(sTruck.vehBack)
ENDIF
ENDIF
SETTIMERB(0)
WHILE TIMERB() < 2000
UPDATE_CHASE_COPS()
WAIT(0)
ENDWHILE
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 2)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
ELSE
IF iCurrentEvent != 99
LOAD_SCENE(GET_ENTITY_COORDS(PLAYER_PED_ID()))
WAIT(500)
ENDIF
ENDIF
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
ENDIF
INT i = 0
REPEAT COUNT_OF(sStolenCars) i
IF IS_VEHICLE_DRIVEABLE(sStolenCars[i].veh)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sStolenCars[i].veh, FALSE)
ENDIF
ENDREPEAT
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sTruck.vehFront, TRUE)
SET_VEHICLE_DOORS_LOCKED(sTruck.vehFront, VEHICLELOCK_UNLOCKED)
ENDIF
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sTruck.vehBack, FALSE)
ENDIF
SET_MAX_WANTED_LEVEL(0)
SET_CREATE_RANDOM_COPS(FALSE)
SET_WANTED_LEVEL_MULTIPLIER(0.0)
BLOCK_DISPATCH_SERVICE_RESOURCE_CREATION(DT_POLICE_HELICOPTER, TRUE)
BLOCK_DISPATCH_SERVICE_RESOURCE_CREATION(DT_POLICE_ROAD_BLOCK, TRUE)
BLOCK_DISPATCH_SERVICE_RESOURCE_CREATION(DT_POLICE_AUTOMOBILE_WAIT_CRUISING, TRUE)
BLOCK_DISPATCH_SERVICE_RESOURCE_CREATION(DT_POLICE_AUTOMOBILE_WAIT_PULLED_OVER, TRUE)
CLEAR_AREA_OF_COPS(GET_ENTITY_COORDS(PLAYER_PED_ID()), 500.0)
bDontUseCustomGPS = FALSE
bCustomGPSActive = FALSE
bClimbCamActive = FALSE
bFranklinTruckClimbActive = FALSE
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_AllowedToDetachTrailer, FALSE)
IF eMissionStage = STAGE_COPS_ARRIVE
IF NOT IS_AUDIO_SCENE_ACTIVE("CAR_4_COPS_ARRIVE")
START_AUDIO_SCENE("CAR_4_COPS_ARRIVE")
ENDIF
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CHECKPOINT_COPS_ARRIVE, "COPS_ARRIVE")
bCopsTriggered = TRUE
ELSE
IF NOT IS_AUDIO_SCENE_ACTIVE("CAR_4_GET_TO_PALETO")
START_AUDIO_SCENE("CAR_4_GET_TO_PALETO")
ENDIF
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CHECKPOINT_GO_TO_GAS, "GO_TO_GAS_STATION")
ENDIF
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
IF NOT IS_SCREEN_FADED_IN()
CLEAR_AREA_OF_COPS(GET_ENTITY_COORDS(PLAYER_PED_ID()), 500.0)
CLEAR_AREA_OF_VEHICLES(GET_ENTITY_COORDS(PLAYER_PED_ID()), 100.0)
IF eMissionStage = STAGE_GO_TO_DROP_OFF
WAIT(2000) //wait for the truck and trailer to settle their physics
ENDIF
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
WHILE NOT IS_SCREEN_FADED_IN()
IF eMissionStage = STAGE_COPS_ARRIVE
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
SET_VEHICLE_FORWARD_SPEED(sTruck.vehFront, 15.0)
ENDIF
ENDIF
WAIT(0)
ENDWHILE
ENDIF
IF NOT IS_PED_INJURED(sLamar.ped)
SET_PED_CAN_USE_AUTO_CONVERSATION_LOOKAT(sLamar.ped, TRUE)
ENDIF
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
SET_PED_CAN_USE_AUTO_CONVERSATION_LOOKAT(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], TRUE)
ENDIF
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
SET_PED_CAN_USE_AUTO_CONVERSATION_LOOKAT(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], TRUE)
ENDIF
ADD_PED_FOR_DIALOGUE(sConversationPeds, 2, PLAYER_PED_ID(), "TREVOR")
ADD_PED_FOR_DIALOGUE(sConversationPeds, 1, sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], "FRANKLIN")
CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_GODROP", CONV_PRIORITY_MEDIUM)
vPathNodesMinPos = <<0.0, 0.0, 0.0>>
vPathNodesMaxPos = <<0.0, 0.0, 0.0>>
iCopsDialoguePauseTimer = 0
fPrevTruckSpeed = 0.0
bTruckAnimIsUpToDate = TRUE
bCopsTriggered = FALSE
iCurrentMusicEvent = 0
iPrevClosestNode = -1
iLeftLightOnTimer = 0
iLeftLightOffTimer = 0
iRightLightOnTimer = 0
iRightLightOffTimer = 0
iCurrentEvent = 0
eSectionStage = SECTION_STAGE_RUNNING
ENDIF
ENDIF
IF eSectionStage = SECTION_STAGE_RUNNING
#IF IS_DEBUG_BUILD
DONT_DO_J_SKIP(sLocatesData)
#ENDIF
//Track the chase cops throughout this section: this will create the first cop in advance, then make them aggressive once wanted level is active.
UPDATE_CHASE_COPS()
UPDATE_LAMAR_TRUCK_ANIMS()
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxSparksLeft)
DRAW_FLICKERING_LIGHT(GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehBack, vSparksOffsetLeft + vSparksLightOffset),
vSparksLightColour, vSparksLightRange.x, vSparksLightRange.y, iLeftLightOnTimer, iLeftLightOffTimer,
50, 300, 30, 100)
ENDIF
IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxSparksRight)
DRAW_FLICKERING_LIGHT(GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehBack, vSparksOffsetRight + vSparksLightOffset),
vSparksLightColour, vSparksLightRange.x, vSparksLightRange.y, iRightLightOnTimer, iRightLightOffTimer,
50, 300, 30, 100)
ENDIF
ENDIF
//If the trailer becomes detached while the player is driving, the mission needs to fail.
IF NOT IS_ENTITY_DEAD(sTruck.vehFront)
IF NOT IS_VEHICLE_ATTACHED_TO_TRAILER(sTruck.vehFront)
IF DOES_BLIP_EXIST(sLocatesData.LocationBlip)
AND iCurrentEvent < 100
IF NOT DOES_BLIP_EXIST(sTruck.blip)
CLEAR_PRINTS()
sTruck.blip = CREATE_BLIP_FOR_ENTITY(sTruck.vehBack)
ENDIF
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_UNHOOK")
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF iNumTimesPlayedUnhookDialogue < 3
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_UNHOOK", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_UNHOOK", TRUE)
SET_LABEL_AS_TRIGGERED("CST7_HOOKED", FALSE)
iNumTimesPlayedUnhookDialogue++
ELSE
KILL_FACE_TO_FACE_CONVERSATION()
ENDIF
ELSE
SET_LABEL_AS_TRIGGERED("CST7_UNHOOK", TRUE)
ENDIF
ELSE
TEXT_LABEL strRoot = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT()
IF ARE_STRINGS_EQUAL(strRoot, "CST7_DRIVE2B")
OR ARE_STRINGS_EQUAL(strRoot, "CST7_DRIVE2B")
OR ARE_STRINGS_EQUAL(strRoot, "CST7_DRIVE2C")
OR ARE_STRINGS_EQUAL(strRoot, "CST7_DRIVcon")
OR ARE_STRINGS_EQUAL(strRoot, "CST7_DRIVE2D")
OR ARE_STRINGS_EQUAL(strRoot, "CST7_DRIVE2R")
OR ARE_STRINGS_EQUAL(strRoot, "CST7_DRIVE2F")
OR ARE_STRINGS_EQUAL(strRoot, "CST7_DRIV2Fb")
OR ARE_STRINGS_EQUAL(strRoot, "CST7_DRIVE2G")
KILL_FACE_TO_FACE_CONVERSATION()
ENDIF
ENDIF
ELIF NOT HAS_LABEL_BEEN_TRIGGERED("CH_REATTACH")
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_DIALOGUE_IF_SUBTITLES_OFF)
PRINT_NOW("CH_REATTACH", DEFAULT_GOD_TEXT_TIME, 0)
SET_LABEL_AS_TRIGGERED("CH_REATTACH", TRUE)
ENDIF
ELIF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_UNHOOK2")
IF iNumTimesPlayedUnhookReminder < 5
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF GET_GAME_TIMER() - iUnhookReminderTimer > 7700
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_UNHOOK2", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_UNHOOK2", TRUE)
iNumTimesPlayedUnhookReminder++
ENDIF
ENDIF
ELSE
iUnhookReminderTimer = GET_GAME_TIMER()
ENDIF
ENDIF
ENDIF
ELSE
IF DOES_BLIP_EXIST(sTruck.blip)
REMOVE_BLIP(sTruck.blip)
ENDIF
ENDIF
IF GET_GAME_TIMER() - iTrailerFailTimer > 90000
MISSION_FAILED(FAILED_TRAILER_DETACHED)
ENDIF
IF GET_GAME_TIMER() - iTrailerFailTimer > 30000
IF NOT IS_VEHICLE_ATTACHED_TO_TRAILER(sTruck.vehFront)
IF NOT IS_ENTITY_UPRIGHT(sTruck.vehBack)
OR IS_ENTITY_UPSIDEDOWN(sTruck.vehBack)
MISSION_FAILED(FAILED_TRAILER_DETACHED)
ENDIF
ENDIF
ENDIF
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sTruck.vehBack)) > 40000.0
MISSION_FAILED(FAILED_TRAILER_ABANDONED)
ENDIF
ENDIF
ELSE
IF DOES_BLIP_EXIST(sTruck.blip)
REMOVE_BLIP(sTruck.blip)
ENDIF
IF IS_THIS_PRINT_BEING_DISPLAYED("CH_REATTACH")
CLEAR_PRINTS()
ENDIF
IF HAS_LABEL_BEEN_TRIGGERED("CST7_UNHOOK")
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_HOOKED")
IF iNumTimesPlayedRehookDialogue < 2
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_HOOKED", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_HOOKED", TRUE)
iNumTimesPlayedRehookDialogue++
ENDIF
ENDIF
ENDIF
SET_LABEL_AS_TRIGGERED("CST7_UNHOOK", FALSE)
ENDIF
iTrailerFailTimer = GET_GAME_TIMER()
ENDIF
ENDIF
VECTOR vTrailerRot
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
vTrailerRot = GET_ENTITY_ROTATION(sTruck.vehBack)
ENDIF
//TODO 971662 - Reduce the density for the cops section.
IF eMissionStage = STAGE_COPS_ARRIVE
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.5)
CALCULATE_PATH_NODES_AREA_FOR_POS(GET_ENTITY_COORDS(sTruck.vehFront)) //calculate and request path nodes each frame when cops arrive
REQUEST_PATH_NODES_IN_AREA_THIS_FRAME(vPathNodesMinPos.x, vPathNodesMinPos.y, vPathNodesMaxPos.x, vPathNodesMaxPos.y)
#IF IS_DEBUG_BUILD
PRINTLN(GET_THIS_SCRIPT_NAME(), ": STAGE_COPS_ARRIVE - Calling REQUEST_PATH_NODES_IN_AREA_THIS_FRAME(", vPathNodesMinPos.x, ", ",
vPathNodesMinPos.y, ", ", vPathNodesMaxPos.x, ", ", vPathNodesMaxPos.y, ").")
#ENDIF
ELSE
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.7)
ENDIF
//2009548 - New audio scene to mute Franklin's climbing anim sounds when driving truck in first person
IF eMissionStage = STAGE_COPS_ARRIVE
IF IS_PED_IN_THIS_VEHICLE(PLAYER_PED_ID(), sTruck.vehFront) //check player in truck
AND GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_IN_VEHICLE) = CAM_VIEW_MODE_FIRST_PERSON //check if first person
AND ( NOT DOES_CAM_EXIST(camCutscene) OR ( DOES_CAM_EXIST(camCutscene) AND NOT IS_CAM_RENDERING(camCutscene) ) )//check if rendering scripted camera
IF NOT IS_AUDIO_SCENE_ACTIVE("CAR_4_FIRST_PERSON_MUTES_SCENE")
START_AUDIO_SCENE("CAR_4_FIRST_PERSON_MUTES_SCENE")
ENDIF
ELSE
IF IS_AUDIO_SCENE_ACTIVE("CAR_4_FIRST_PERSON_MUTES_SCENE")
STOP_AUDIO_SCENE("CAR_4_FIRST_PERSON_MUTES_SCENE")
ENDIF
ENDIF
ELSE
IF IS_AUDIO_SCENE_ACTIVE("CAR_4_FIRST_PERSON_MUTES_SCENE")
STOP_AUDIO_SCENE("CAR_4_FIRST_PERSON_MUTES_SCENE")
ENDIF
ENDIF
SWITCH iCurrentEvent
CASE 0
IF eMissionStage != STAGE_COPS_ARRIVE
SET_BIT(sLocatesData.iLocatesBitSet, BS_DONT_CLEAR_LOCATE_AREA_OF_VEHICLES)
IF IS_VEHICLE_ATTACHED_TO_TRAILER(sTruck.vehFront)
IS_PLAYER_AT_LOCATION_WITH_BUDDY_IN_VEHICLE(sLocatesData, vDropOffPos, <<0.001, 0.001, LOCATE_SIZE_HEIGHT>>, TRUE, sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN],
sTruck.vehFront, "CH_GOTODROP", "CH_LEAVEFRAN", "CH_GETIN_TRUCK", "CH_GETBACK", FALSE, FALSE)
ELSE
IS_PLAYER_AT_LOCATION_WITH_BUDDY_IN_VEHICLE(sLocatesData, vDropOffPos, <<0.001, 0.001, LOCATE_SIZE_HEIGHT>>, TRUE, sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN],
sTruck.vehFront, "", "CH_LEAVEFRAN", "CH_GETIN_TRUCK", "CH_GETBACK", FALSE, FALSE)
ENDIF
ENDIF
VECTOR vCopPos
BOOL bPlayerAntagonisedCop
IF NOT IS_ENTITY_DEAD(vehChaseCops[0])
vCopPos = GET_ENTITY_COORDS(vehChaseCops[0])
bPlayerAntagonisedCop = IS_PROJECTILE_IN_AREA(vCopPos - <<15.0, 15.0, 15.0>>, vCopPos + <<15.0, 15.0, 15.0>>, TRUE)
OR IS_EXPLOSION_IN_SPHERE(EXP_TAG_DONTCARE, vCopPos, 30.0)
OR IS_BULLET_IN_AREA(vCopPos, 30.0, TRUE)
OR VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), vCopPos) < 225.0
ENDIF
IF NOT bCopsTriggered
BOOL bPlayerHitStandardTrigger
bPlayerHitStandardTrigger = IS_ENTITY_IN_ANGLED_AREA(sTruck.vehFront, <<-2149.357910,4304.076660,70.419449>>, <<-2375.683838,4450.167969,-5.207527>>, 53.500000)
IF VDIST2(GET_ENTITY_COORDS(sTruck.vehFront), vDropOffPos) < 16000000.0 //4000m away from drop-off point
OR bPlayerHitStandardTrigger
OR bPlayerAntagonisedCop
IF bPlayerHitStandardTrigger
OR bPlayerAntagonisedCop
OR VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), vCountrysideCopPos) > 4000000.0 //Player drove an alternate route.
OR (DOES_ENTITY_EXIST(vehChaseCops[0]) AND IS_ENTITY_DEAD(vehChaseCops[0]))
//Once the cop has been created trigger the wanted level a few seconds later.
SET_MAX_WANTED_LEVEL(5)
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 2)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
SET_WANTED_LEVEL_MULTIPLIER(0.0)
SET_POLICE_RADAR_BLIPS(TRUE)
SET_DISPATCH_COPS_FOR_PLAYER(PLAYER_ID(), FALSE)
SET_CREATE_RANDOM_COPS(FALSE)
ENABLE_DISPATCH_SERVICE(DT_FIRE_DEPARTMENT, FALSE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_AUTOMOBILE, FALSE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_ROAD_BLOCK, FALSE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_HELICOPTER, FALSE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_RIDERS, FALSE)
ENABLE_DISPATCH_SERVICE(DT_AMBULANCE_DEPARTMENT, FALSE)
IF IS_AUDIO_SCENE_ACTIVE("CAR_4_GET_TO_PALETO")
STOP_AUDIO_SCENE("CAR_4_GET_TO_PALETO")
ENDIF
IF NOT IS_AUDIO_SCENE_ACTIVE("CAR_4_COPS_ARRIVE")
START_AUDIO_SCENE("CAR_4_COPS_ARRIVE")
ENDIF
PLAY_POLICE_REPORT("SCRIPTED_SCANNER_REPORT_CAR_STEAL_4_01", 0.0)
bCopsTriggered = TRUE
ENDIF
ENDIF
ENDIF
//Custom GPS and conversation control.
IF (DOES_BLIP_EXIST(sLocatesData.LocationBlip) OR eMissionStage = STAGE_COPS_ARRIVE)
AND IS_VEHICLE_ATTACHED_TO_TRAILER(sTruck.vehFront)
IF eMissionStage != STAGE_COPS_ARRIVE
UPDATE_GAS_STATION_CUSTOM_GPS_ROUTE(TRUE)
ENDIF
IF IS_FACE_TO_FACE_CONVERSATION_PAUSED()
PAUSE_FACE_TO_FACE_CONVERSATION(FALSE)
ENDIF
IF bCopsTriggered
//Progress once the cops conversation has played.
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_WAKE", CONV_PRIORITY_MEDIUM)
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
IF IS_ENTITY_PLAYING_ANIM(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], strSleepingAnims, "franklin_asleep")
STOP_ANIM_TASK(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], strSleepingAnims, "franklin_asleep", -1)
ENDIF
CLEAR_PED_SECONDARY_TASK(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
CLEAR_FACIAL_IDLE_ANIM_OVERRIDE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
STOP_PED_SPEAKING(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], FALSE)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], TRUE)
ENDIF
IF bCustomGPSActive
SET_GPS_MULTI_ROUTE_RENDER(FALSE)
CLEAR_GPS_MULTI_ROUTE()
bCustomGPSActive = FALSE
ENDIF
CLEAR_MISSION_LOCATE_STUFF(sLocatesData)
INFORM_MISSION_STATS_SYSTEM_OF_TIME_WINDOW_OPEN(CS4_COP_LOSS_TIME)
REPLAY_RECORD_BACK_FOR_TIME(5.0, 5.0, REPLAY_IMPORTANCE_HIGHEST)
fAnimTime = 0.0
iChosenCar = 3 //JB700
iTruckClimbEvent = 0
iCurrentEvent++
eMissionStage = STAGE_COPS_ARRIVE
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CHECKPOINT_COPS_ARRIVE, "COPS_ARRIVE")
ELSE
KILL_FACE_TO_FACE_CONVERSATION()
ENDIF
ENDIF
IF eMissionStage != STAGE_COPS_ARRIVE
//Lamar and Trevor chatter on the way (don't trigger once the player gets close to the cops trigger).
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), vCountrysideCopPos) > 10000.0
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_DRIVE2B")
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_DRIVE2B", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_DRIVE2B", TRUE)
iTruckAwkwardSilenceTimer = 0
ENDIF
ELIF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_DRIVE2C")
REQUEST_ANIM_DICT(strSleepingAnims)
REQUEST_ANIM_DICT(strSleepingEyeAnims)
IF iTruckAwkwardSilenceTimer = 0
IF HAS_ANIM_DICT_LOADED(strSleepingAnims)
AND HAS_ANIM_DICT_LOADED(strSleepingEyeAnims)
TASK_PLAY_ANIM(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], strSleepingAnims, "franklin_asleep", 1, -1, -1, AF_LOOPING | AF_NOT_INTERRUPTABLE)
SET_FACIAL_IDLE_ANIM_OVERRIDE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], "mood_sleeping_1")
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], TRUE) //block non-temp events, see B*1460213
STOP_PED_SPEAKING(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], TRUE) //stop franklin from reacting to car crashes, see B*1508193
iTruckAwkwardSilenceTimer = GET_GAME_TIMER()
ENDIF
ELIF GET_GAME_TIMER() - iTruckAwkwardSilenceTimer > 5000
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_DRIVE2C", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_DRIVE2C", TRUE)
iTruckAwkwardSilenceTimer = 0
ENDIF
ENDIF
ELIF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_DRIVCon")
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_DRIVCon", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_DRIVCon", TRUE)
iTruckAwkwardSilenceTimer = 0
ENDIF
ELIF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_DRIVE2D")
IF iTruckAwkwardSilenceTimer = 0
iTruckAwkwardSilenceTimer = GET_GAME_TIMER()
ELIF GET_GAME_TIMER() - iTruckAwkwardSilenceTimer > 5000
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_DRIVE2D", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_DRIVE2D", TRUE)
iTruckAwkwardSilenceTimer = 0
ENDIF
ENDIF
ELIF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_DRIVE2E")
IF iTruckAwkwardSilenceTimer = 0
iTruckAwkwardSilenceTimer = GET_GAME_TIMER()
ELIF GET_GAME_TIMER() - iTruckAwkwardSilenceTimer > 3000
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_DRIVE2E", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_DRIVE2E", TRUE)
ENDIF
ENDIF
ELIF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_DRIVE2F")
IF iTruckAwkwardSilenceTimer = 0
iTruckAwkwardSilenceTimer = GET_GAME_TIMER()
ELIF GET_GAME_TIMER() - iTruckAwkwardSilenceTimer > 3000
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_DRIVE2F", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_DRIVE2F", TRUE)
ENDIF
ENDIF
ELIF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_DRIV2Fb")
IF iTruckAwkwardSilenceTimer = 0
iTruckAwkwardSilenceTimer = GET_GAME_TIMER()
ELIF GET_GAME_TIMER() - iTruckAwkwardSilenceTimer > 2000
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_DRIV2Fb", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_DRIV2Fb", TRUE)
ENDIF
ENDIF
ELIF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_DRIVE2G")
IF iTruckAwkwardSilenceTimer = 0
iTruckAwkwardSilenceTimer = GET_GAME_TIMER()
ELIF GET_GAME_TIMER() - iTruckAwkwardSilenceTimer > 3000
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_DRIVE2G", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_DRIVE2G", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
UPDATE_GAS_STATION_CUSTOM_GPS_ROUTE(FALSE)
IF IS_VEHICLE_ATTACHED_TO_TRAILER(sTruck.vehFront)
IF HAS_LABEL_BEEN_TRIGGERED("CST7_FHANG")
OR HAS_LABEL_BEEN_TRIGGERED("CST7_DRIVE2B")
IF NOT IS_FACE_TO_FACE_CONVERSATION_PAUSED()
IF IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
IF iCopsDialoguePauseTimer = 0
OR GET_GAME_TIMER() - iCopsDialoguePauseTimer > 7000
PAUSE_FACE_TO_FACE_CONVERSATION(TRUE)
ENDIF
ELSE
PAUSE_FACE_TO_FACE_CONVERSATION(TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
//Franklin truck behaviour: he'll lean into corners etc.
//UPDATE_FRANKLINS_TRUCK_ANIMS()
//TEMP: trailer offset from truck
//<< -0.00420758, -9.89839, 0.259329 >>
//<< 0.191836, -9.89637, 0.27933 >>
//PRINTVECTOR(GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(sTruck.vehFront, GET_ENTITY_COORDS(sTruck.vehBack)))
//PRINTNL()
BREAK
CASE 1 //Wait for Franklin to get in the back.
UPDATE_WANTED_POSITION_THIS_FRAME(PLAYER_ID())
REQUEST_PTFX_ASSET()
REQUEST_ANIM_DICT(strDriveOffTrailerAnims)
REQUEST_ANIM_DICT(strCamShakeAnims)
SET_BIT(sLocatesData.iLocatesBitSet, BS_DONT_CLEAR_LOCATE_AREA_OF_VEHICLES)
IF IS_VEHICLE_ATTACHED_TO_TRAILER(sTruck.vehFront)
IS_PLAYER_AT_LOCATION_IN_VEHICLE(sLocatesData, vDropOffPos, <<0.001, 0.001, LOCATE_SIZE_HEIGHT>>, FALSE,
sTruck.vehFront, "", "", "CH_GETBACK", FALSE)
ELSE
IS_PLAYER_AT_LOCATION_IN_VEHICLE(sLocatesData, vDropOffPos, <<0.001, 0.001, LOCATE_SIZE_HEIGHT>>, FALSE,
sTruck.vehFront, "", "", "CH_GETBACK", FALSE)
ENDIF
IF DOES_BLIP_EXIST(sLocatesData.LocationBlip)
AND IS_VEHICLE_ATTACHED_TO_TRAILER(sTruck.vehFront)
SET_BLIP_ALPHA(sLocatesData.LocationBlip, 0)
SET_BLIP_ROUTE(sLocatesData.LocationBlip, FALSE)
IF NOT DOES_BLIP_EXIST(blipCurrentDestination)
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
blipCurrentDestination = CREATE_BLIP_FOR_ENTITY(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
ENDIF
ENDIF
ELSE
IF DOES_BLIP_EXIST(blipCurrentDestination)
REMOVE_BLIP(blipCurrentDestination)
ENDIF
IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) AND NOT IS_VEHICLE_ATTACHED_TO_TRAILER(sTruck.vehFront)
SET_BLIP_ALPHA(sLocatesData.LocationBlip, 0)
SET_BLIP_ROUTE(sLocatesData.LocationBlip, FALSE)
ENDIF
ENDIF
IF HAS_LABEL_BEEN_TRIGGERED("CST7_SIDE")
UPDATE_FRANKLIN_CLIMBING_FROM_TRUCK_TO_CAR()
ENDIF
BOOL bSafeToShowClimbCam
//VECTOR vCamPos
bSafeToShowClimbCam = TRUE
IF ABSF(vTrailerRot.y) > 30.0
bSafeToShowClimbCam = FALSE
ENDIF
//This currently is returning true all the time.
/*IF DOES_CAM_EXIST(camCutscene)
vCamPos = GET_CAM_COORD(camCutscene)
IF IS_AREA_OCCUPIED(vCamPos - <<0.25, 0.25, 0.25>>, vCamPos + <<0.25, 0.25, 0.25>>, TRUE, FALSE, FALSE, FALSE, FALSE, sTruck.vehBack)
bSafeToShowClimbCam = FALSE
ENDIF
ENDIF*/
//Allow player to switch to cinematic of Franklin climbing.
IF NOT IS_PHONE_ONSCREEN()
AND IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
AND DOES_CAM_EXIST(camCutscene)
AND SAFE_TO_PRINT_CHASE_HINT_CAM_HELP(DEFAULT, DEFAULT, TRUE)
AND SHOULD_CONTROL_CHASE_HINT_CAM(localChaseHintCamStruct, DEFAULT, DEFAULT, TRUE)
AND bSafeToShowClimbCam
AND IS_VEHICLE_ATTACHED_TO_TRAILER(sTruck.vehFront)
IF DOES_CAM_EXIST(camCutscene)
IF NOT bClimbCamActive
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("CH_FRANHELP")
CLEAR_HELP()
ENDIF
IF NOT IS_AUDIO_SCENE_ACTIVE("CAR_4_FOCUS_ON_FRANKLIN")
START_AUDIO_SCENE("CAR_4_FOCUS_ON_FRANKLIN")
ENDIF
RENDER_SCRIPT_CAMS(TRUE, FALSE)
bClimbCamActive = TRUE
ENDIF
ENDIF
ELSE
IF bClimbCamActive
IF IS_AUDIO_SCENE_ACTIVE("CAR_4_FOCUS_ON_FRANKLIN")
STOP_AUDIO_SCENE("CAR_4_FOCUS_ON_FRANKLIN")
ENDIF
RENDER_SCRIPT_CAMS(FALSE, FALSE)
bClimbCamActive = FALSE
ENDIF
ENDIF
//Play cops dialogue
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_TODO")
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_TODO", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_TODO", TRUE)
ENDIF
ENDIF
ELIF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_OUTSIDE")
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_OUTSIDE", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_OUTSIDE", TRUE)
ENDIF
ENDIF
ELIF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_SIDE")
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_SIDE", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_SIDE", TRUE)
ENDIF
ENDIF
ELIF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_HEADS")
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_HEADS", CONV_PRIORITY_MEDIUM)
GIVE_MAIN_PEDS_HEADSETS()
SET_LABEL_AS_TRIGGERED("CST7_HEADS", TRUE)
ENDIF
ENDIF
ELIF NOT HAS_LABEL_BEEN_TRIGGERED("CH_STEADY")
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_DIALOGUE_IF_SUBTITLES_OFF)
IF DOES_BLIP_EXIST(blipCurrentDestination)
PRINT_NOW("CH_STEADY", DEFAULT_GOD_TEXT_TIME, 0)
REPLAY_RECORD_BACK_FOR_TIME(4.0, 10.0, REPLAY_IMPORTANCE_HIGHEST)
SET_LABEL_AS_TRIGGERED("CH_STEADY", TRUE)
ENDIF
ENDIF
ELIF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_WAIT") //Lamar says the cops must have waited.
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_WAIT", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_WAIT", TRUE)
iFranklinClimbDialogueTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(10000, 12000)
ENDIF
ENDIF
ELIF GET_GAME_TIMER() - iFranklinClimbDialogueTimer > 0 //Franklin shouts while climbing.
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF bFranklinTruckClimbActive
VECTOR vTrailerRotation
vTrailerRotation = GET_ENTITY_ROTATION(sTruck.vehBack)
IF HAS_ENTITY_COLLIDED_WITH_ANYTHING(sTruck.vehBack)
OR HAS_ENTITY_COLLIDED_WITH_ANYTHING(sTruck.vehFront)
OR vTrailerRotation.Y < - 5.0 OR vTrailerRotation.Y > 5.0
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_MESS", CONV_PRIORITY_MEDIUM)
iFranklinClimbDialogueTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(9000, 11000)
ENDIF
ELSE
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_CLIMB", CONV_PRIORITY_MEDIUM)
iFranklinClimbDialogueTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(9000, 11000)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
#IF IS_DEBUG_BUILD
DRAW_DEBUG_TEXT_ABOVE_ENTITY(sTruck.vehBack, GET_STRING_FROM_VECTOR(GET_ENTITY_ROTATION(sTruck.vehBack)), 2.0)
#ENDIF
IF IS_VEHICLE_DRIVEABLE(sStolenCars[iChosenCar].veh)
AND NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
IF IS_PED_SITTING_IN_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], sStolenCars[iChosenCar].veh)
REMOVE_ANIM_DICT(strCarClimbAnims)
REMOVE_ANIM_DICT(strCarClimbAnims2)
REMOVE_ANIM_DICT(strTruckCopsIntroAnims)
REMOVE_ANIM_DICT(strSleepingAnims)
REMOVE_ANIM_DICT(strSleepingEyeAnims)
IF IS_AUDIO_SCENE_ACTIVE("CAR_4_FOCUS_ON_FRANKLIN")
STOP_AUDIO_SCENE("CAR_4_FOCUS_ON_FRANKLIN")
ENDIF
REPLAY_RECORD_BACK_FOR_TIME(7.0, 5.0, REPLAY_IMPORTANCE_HIGHEST)
SET_SELECTOR_PED_PRIORITY(sSelectorPeds, SELECTOR_PED_FRANKLIN, SELECTOR_PED_MICHAEL, SELECTOR_PED_TREVOR)
SET_SELECTOR_PED_HINT(sSelectorPeds, SELECTOR_PED_FRANKLIN, TRUE)
CLEAR_MISSION_LOCATE_STUFF(sLocatesData)
REMOVE_ALL_BLIPS()
iCurrentEvent++
ENDIF
ENDIF
BREAK
CASE 2 //Switch if it's safe to do so.
SET_BIT(sLocatesData.iLocatesBitSet, BS_DONT_CLEAR_LOCATE_AREA_OF_VEHICLES)
IS_PLAYER_AT_LOCATION_IN_VEHICLE(sLocatesData, vDropOffPos, <<0.001, 0.001, LOCATE_SIZE_HEIGHT>>, FALSE,
sTruck.vehFront, "", "", "CH_GETBACK", FALSE)
UPDATE_WANTED_POSITION_THIS_FRAME(PLAYER_ID())
SUPPRESS_LOSING_WANTED_LEVEL_IF_HIDDEN_THIS_FRAME(PLAYER_ID())
REPORT_POLICE_SPOTTED_PLAYER(PLAYER_ID())
REQUEST_SCRIPT_AUDIO_BANK("CAR_STEAL_4")
IF DOES_BLIP_EXIST(sLocatesData.LocationBlip)
AND IS_VEHICLE_ATTACHED_TO_TRAILER(sTruck.vehFront)
SET_BLIP_ALPHA(sLocatesData.LocationBlip, 0)
SET_BLIP_ROUTE(sLocatesData.LocationBlip, FALSE)
IF ABSF(vTrailerRot.y) < 30.0
IF NOT HAS_LABEL_BEEN_TRIGGERED("CH_SWFRAN")
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_DIALOGUE_IF_SUBTITLES_OFF)
PRINT_NOW("CH_SWFRAN", DEFAULT_GOD_TEXT_TIME * 2, 0)
SET_LABEL_AS_TRIGGERED("CH_SWFRAN", TRUE)
ENDIF
ENDIF
IF UPDATE_SELECTOR_HUD(sSelectorPeds, TRUE)
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
SET_VEHICLE_DOORS_LOCKED(sTruck.vehBack, VEHICLELOCK_UNLOCKED)
SET_VEHICLE_DOOR_OPEN(sTruck.vehBack, SC_DOOR_BOOT, FALSE)
SET_VEHICLE_WILL_TELL_OTHERS_TO_HURRY(sTruck.vehBack, TRUE)
ENDIF
IF NOT IS_ENTITY_DEAD(sTruck.vehFront)
SET_VEHICLE_WILL_TELL_OTHERS_TO_HURRY(sTruck.vehFront, TRUE)
ENDIF
IF IS_AUDIO_SCENE_ACTIVE("CAR_4_COPS_ARRIVE")
STOP_AUDIO_SCENE("CAR_4_COPS_ARRIVE")
ENDIF
IF IS_AUDIO_SCENE_ACTIVE("CAR_4_FIRST_PERSON_MUTES_SCENE")
STOP_AUDIO_SCENE("CAR_4_FIRST_PERSON_MUTES_SCENE")
ENDIF
IF NOT IS_AUDIO_SCENE_ACTIVE("CAR_4_REVERSE_OFF_TRUCK")
START_AUDIO_SCENE("CAR_4_REVERSE_OFF_TRUCK")
ENDIF
//Set the player to drive the truck during the switch (while Trevor AI ped doesn't exist).
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
TASK_VEHICLE_DRIVE_TO_COORD(PLAYER_PED_ID(), sTruck.vehFront, vDropOffPos, 35.0, DRIVINGSTYLE_NORMAL, modelTruckFront,
DF_DontSteerAroundPlayerPed | DF_UseShortCutLinks, 10.0, 20.0)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PLAYER_PED_ID(), TRUE)
SET_SELECTOR_PED_HINT(sSelectorPeds, SELECTOR_PED_FRANKLIN, FALSE)
CLEAR_MISSION_LOCATE_STUFF(sLocatesData)
CLEAR_PRINTS()
SETTIMERB(0)
iCurrentEvent = 100
bSwitchFX0Started = FALSE
IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_IN_VEHICLE) = CAM_VIEW_MODE_FIRST_PERSON
eSwitchCamState = SWITCH_CAM_WAIT_BEFORE_SPLINE1
ELSE
eSwitchCamState = SWITCH_CAM_START_SPLINE1
ENDIF
ENDIF
ENDIF
ENDIF
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_CLIMB2")
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
IF NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
IF IS_PED_IN_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], sStolenCars[iChosenCar].veh)
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_CLIMB2", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_CLIMB2", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE 100 //Wait for the switch cam to finish.
IF NOT IS_ENTITY_DEAD(sTruck.vehFront)
SET_VEHICLE_LIGHTS(sTruck.vehFront, FORCE_VEHICLE_LIGHTS_ON)
ENDIF
UPDATE_WANTED_POSITION_THIS_FRAME(PLAYER_ID())
SUPPRESS_LOSING_WANTED_LEVEL_IF_HIDDEN_THIS_FRAME(PLAYER_ID())
REPORT_POLICE_SPOTTED_PLAYER(PLAYER_ID())
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_NEXT_CAMERA) //block camera view mode changing during the switch camera
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_SWITCH")
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
IF NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
IF IS_PED_IN_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], sStolenCars[iChosenCar].veh)
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_SWITCH", CONV_PRIORITY_MEDIUM)
REPLAY_RECORD_BACK_FOR_TIME(2.0, 10.0, REPLAY_IMPORTANCE_HIGHEST)
SET_LABEL_AS_TRIGGERED("CST7_SWITCH", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
//Get rid of Lamar's fudged seat, and stick him in the correct passenger seat.
IF NOT IS_PED_INJURED(sLamar.ped)
AND NOT IS_ENTITY_DEAD(sTruck.vehFront)
IF NOT IS_PED_SITTING_IN_VEHICLE(sLamar.ped, sTruck.vehFront)
CLEAR_PED_TASKS_IMMEDIATELY(sLamar.ped)
IF IS_ENTITY_ATTACHED(sLamar.ped)
DETACH_ENTITY(sLamar.ped)
ENDIF
SET_PED_INTO_VEHICLE(sLamar.ped, sTruck.vehFront, VS_FRONT_RIGHT)
ENDIF
ENDIF
IF HANDLE_TRUCK_TO_CAR_SWITCH_CAM(scsTruckToCar)
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
REASSIGN_PLAYER_CHAR_DIALOGUE_SPEAKERS()
ALLOW_AMBIENT_VEHICLES_TO_AVOID_ADVERSE_CONDITIONS(FALSE)
sStolenCars[iChosenCar].iEvent = 0
iCurrentEvent++
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
eSectionStage = SECTION_STAGE_CLEANUP
ELSE
DISABLE_VEH_CONTROLS()
UPDATE_TREVOR_AND_LAMAR_IN_TRUCK()
ENDIF
BREAK
ENDSWITCH
SWITCH iCurrentMusicEvent
CASE 0 //Cops arrive.
IF IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
TRIGGER_MUSIC_EVENT("CAR4_RADIO_2")
iMusicEventTimer = GET_GAME_TIMER()
iCurrentMusicEvent++
ENDIF
BREAK
CASE 1 //Trigger next scene a few seconds after.
PREPARE_MUSIC_EVENT("CAR4_RADIO_2_START_TRACK")
IF GET_GAME_TIMER() - iMusicEventTimer > 6000
TRIGGER_MUSIC_EVENT("CAR4_RADIO_2_START_TRACK")
iCurrentMusicEvent++
ENDIF
BREAK
CASE 2 //Franklin reaches the top of the truck.
IF bFranklinTruckClimbActive
AND NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
IF IS_SYNCHRONIZED_SCENE_RUNNING(iSyncSceneOnTruck)
IF GET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneOnTruck) > 0.6
TRIGGER_MUSIC_EVENT("CAR4_CLIMB")
iCurrentMusicEvent++
ENDIF
ENDIF
ENDIF
BREAK
ENDSWITCH
//If the player leaves the truck fail for leaving buddies behind.
IF NOT IS_PED_INJURED(sLamar.ped)
AND NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sLamar.ped)) > 90000.0
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])) > 40000.0
MISSION_FAILED(FAILED_LEFT_FRANKLIN_AND_LAMAR)
ELSE
MISSION_FAILED(FAILED_LEFT_LAMAR)
ENDIF
ENDIF
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])) > 90000.0
IF GET_GAME_TIMER() - iFranklinFailTimer > 500
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sLamar.ped)) > 40000.0
MISSION_FAILED(FAILED_LEFT_FRANKLIN_AND_LAMAR)
ELSE
MISSION_FAILED(FAILED_LEFT_FRANKLIN)
ENDIF
ENDIF
ELSE
//Franklin repositioning after a warp lags a frame behind due to the synced scene, so use a timer to make sure we wait a bit before checking the fail.
iFranklinFailTimer = GET_GAME_TIMER()
ENDIF
ENDIF
//if the player drives the truck to the military base, fail for bringing cops to the cars
IF DOES_ENTITY_EXIST(sTruck.vehFront)
AND DOES_ENTITY_EXIST(sTruck.vehBack)
AND NOT IS_ENTITY_DEAD(sTruck.vehBack)
AND NOT IS_ENTITY_DEAD(sTruck.vehFront)
IF ( IS_COORD_IN_SPECIFIED_AREA(GET_ENTITY_COORDS(sTruck.vehFront), AC_MILITARY_BASE) AND IS_COORD_IN_SPECIFIED_AREA(GET_ENTITY_COORDS(sTruck.vehBack), AC_MILITARY_BASE) )
OR ( IS_COORD_IN_SPECIFIED_AREA(GET_ENTITY_COORDS(sTruck.vehFront), AC_PRISON) AND IS_COORD_IN_SPECIFIED_AREA(GET_ENTITY_COORDS(sTruck.vehBack), AC_PRISON) )
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 3)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
MISSION_FAILED(FAILED_LED_COPS_TO_TRUCK)
ENDIF
ENDIF
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
AND NOT IS_ENTITY_DEAD(sTruck.vehFront)
AND NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
AND NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
IF NOT IS_PED_IN_ANY_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
AND iCurrentEvent > 0
//If the trailer is tilted then have Franklin fall off.
IF NOT IS_PED_IN_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], sStolenCars[iChosenCar].veh)
IF ABSF(vTrailerRot.y) > 45.0
STOP_SYNCHRONIZED_ENTITY_ANIM(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], NORMAL_BLEND_OUT, TRUE)
iSyncSceneOnTruck = -1
DETACH_ENTITY(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], TRUE, FALSE)
SET_PED_CAN_RAGDOLL(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], TRUE)
SET_PED_TO_RAGDOLL(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], 3000, 10000, TASK_NM_BALANCE)
ENDIF
ENDIF
//If Franklin is somehow detached from the truck then have the mission fail.
IF NOT IS_SYNCHRONIZED_SCENE_RUNNING(iSyncSceneOnTruck)
AND NOT IS_ENTITY_ATTACHED_TO_ENTITY(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], sTruck.vehBack)
AND NOT IS_ENTITY_ATTACHED_TO_ENTITY(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], sTruck.vehFront)
IF GET_GAME_TIMER() - iFranklinDetachFailTimer > 500
MISSION_FAILED(FAILED_FRANKLIN_FELL_OFF)
ENDIF
ELSE
iFranklinDetachFailTimer = GET_GAME_TIMER()
ENDIF
ENDIF
ENDIF
ENDIF
IF eSectionStage = SECTION_STAGE_CLEANUP
REMOVE_ALL_BLIPS()
CLEAR_MISSION_LOCATE_STUFF(sLocatesData)
KILL_FACE_TO_FACE_CONVERSATION()
CLEAR_SELECTOR_PED_PRIORITY(sSelectorPeds)
STOP_AUDIO_SCENES()
REMOVE_ANIM_DICT(strTruckSitAnims)
REMOVE_ANIM_DICT(strSleepingAnims)
REMOVE_ANIM_DICT(strSleepingEyeAnims)
REMOVE_ANIM_DICT(strDriveOffTrailerAnims)
REMOVE_ANIM_DICT(strCamShakeAnims)
//REMOVE_PTFX_ASSET()
eSectionStage = SECTION_STAGE_SETUP
eMissionStage = STAGE_ESCORT_TRUCK
ENDIF
IF eSectionStage = SECTION_STAGE_SKIP
IF iCurrentEvent = 0
IF bCustomGPSActive
SET_GPS_MULTI_ROUTE_RENDER(FALSE)
CLEAR_GPS_MULTI_ROUTE()
bCustomGPSActive = FALSE
ENDIF
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
AND IS_VEHICLE_DRIVEABLE(sTruck.vehBack)
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), sTruck.vehFront)
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), sTruck.vehFront)
ENDIF
SET_ENTITY_COORDS(sTruck.vehFront, <<-2205.1599, 4326.3677, 48.4147>>)
SET_ENTITY_HEADING(sTruck.vehFront, 339.0508)
SET_VEHICLE_ON_GROUND_PROPERLY(struck.vehFront)
SET_ENTITY_COORDS_NO_OFFSET(sTruck.vehBack, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, <<0.191836, -9.89637, 0.27933>>))
SET_ENTITY_HEADING(sTruck.vehBack, GET_ENTITY_HEADING(sTruck.vehFront))
ATTACH_VEHICLE_TO_TRAILER(sTruck.vehFront, sTruck.vehBack)
ACTIVATE_PHYSICS(sTruck.vehBack)
ENDIF
WHILE NOT DOES_ENTITY_EXIST(vehChaseCops[0])
UPDATE_CHASE_COPS()
WAIT(0)
ENDWHILE
SETTIMERB(0)
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
CLEAR_PRINTS()
eSectionStage = SECTION_STAGE_RUNNING
ELSE
JUMP_TO_STAGE(STAGE_ESCORT_TRUCK)
ENDIF
ENDIF
ENDPROC
//Alternate version of mission: after driving off the back of the truck the player has to use the JB700 to keep the cops away from the truck.
PROC ESCORT_TRUCK()
SET_ALL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID())
IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxSparksLeft)
SET_PARTICLE_FX_LOOPED_OFFSETS(ptfxSparksLeft, vSparksOffsetLeft, vSparksRotation)
ENDIF
IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxSparksRight)
SET_PARTICLE_FX_LOOPED_OFFSETS(ptfxSparksRight, vSparksOffsetRight, vSparksRotation)
ENDIF
//PRINTLN(vSparksOffsetLeft, " ", vSparksRotation)
IF eSectionStage = SECTION_STAGE_SETUP
IF bIsJumpingDirectlyToStage
IF iCurrentEvent != 99
IF bUsedACheckpoint
START_REPLAY_SETUP(<<-1815.5596, 4701.3066, 56.0453>>, 314.9911)
iCurrentEvent = 99
ELSE
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-1815.5596, 4701.3066, 56.0453>>)
SET_ENTITY_HEADING(PLAYER_PED_ID(), 314.9911)
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), TRUE)
LOAD_SCENE(GET_ENTITY_COORDS(PLAYER_PED_ID()))
WAIT(0)
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), FALSE)
iCurrentEvent = 99
ENDIF
//Create the first chase cop behind the player.
iNumChaseCopCarsCreated = 0
iNumTimesPlayedCopsWarn1 = 0
iNumTimesPlayedCopsWarn2 = 0
iNumTimesPlayedCopsWarn3 = 0
iNumTimesPlayedCopsWarn4 = 0
SETUP_REQ_SUPPRESS_CHASE_MODELS()
SUPPRESS_LARGE_VEHICLES(TRUE)
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
CLEAR_AREA_OF_PEDS(<<-1779.3804, 4732.6870, 56.0433>>, 15.0) //clear area of peds around truck and trailer, see B*1490689
CLEAR_AREA_OF_VEHICLES(<<-1810.5596, 4701.3066, 56.0453>>, 100.0)
CALCULATE_PATH_NODES_AREA_FOR_POS(<<-1815.5596, 4701.3066, 56.0453>>)
REQUEST_PTFX_ASSET()
WHILE NOT SETUP_REQ_PLAYER_IS_FRANKLIN()
OR NOT SETUP_REQ_TRUCK_UNFROZEN(<<-1779.3804, 4732.6870, 56.0433>>, 314.9911)
OR NOT SETUP_REQ_CARS_ON_TRUCK()
OR NOT SETUP_REQ_LAMAR(<<504.1672, -1304.7441, 28.3103>>, 200.8915)
OR NOT SETUP_REQ_TREVOR(<<496.6033, -1308.3790, 28.3020>>, 204.3612)
OR NOT HAS_PTFX_ASSET_LOADED()
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
WAIT(0)
ENDWHILE
END_REPLAY_SETUP(DEFAULT, DEFAULT, FALSE)
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF NOT DOES_PARTICLE_FX_LOOPED_EXIST(ptfxSparksLeft)
ptfxSparksLeft = START_PARTICLE_FX_LOOPED_ON_ENTITY("scr_carsteal4_trailer_scrape", sTruck.vehBack, vSparksOffsetLeft, vSparksRotation)
ENDIF
IF NOT DOES_PARTICLE_FX_LOOPED_EXIST(ptfxSparksRight)
ptfxSparksRight = START_PARTICLE_FX_LOOPED_ON_ENTITY("scr_carsteal4_trailer_scrape", sTruck.vehBack, vSparksOffsetRight , vSparksRotation)
ENDIF
ENDIF
SETTIMERB(0)
WHILE NOT DOES_ENTITY_EXIST(vehChaseCops[0])
OR TIMERB() < 2000
IF NOT IS_PED_INJURED(sLamar.ped)
UPDATE_CHASE_COPS()
ENDIF
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
CALCULATE_PATH_NODES_AREA_FOR_POS(GET_ENTITY_COORDS(sTruck.vehFront))
REQUEST_PATH_NODES_IN_AREA_THIS_FRAME(vPathNodesMinPos.x, vPathNodesMinPos.y, vPathNodesMaxPos.x, vPathNodesMaxPos.y)
#IF IS_DEBUG_BUILD
PRINTLN(GET_THIS_SCRIPT_NAME(), ": STAGE_ESCORT_TRUCK - Calling REQUEST_PATH_NODES_IN_AREA_THIS_FRAME(", vPathNodesMinPos.x, ", ",
vPathNodesMinPos.y, ", ", vPathNodesMaxPos.x, ", ", vPathNodesMaxPos.y, ").")
#ENDIF
WAIT(0)
ENDWHILE
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
SET_PED_INTO_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], sTruck.vehFront)
ENDIF
IF NOT IS_PED_INJURED(sLamar.ped)
SET_PED_INTO_VEHICLE(sLamar.ped, sTruck.vehFront, VS_FRONT_RIGHT)
ENDIF
ENDIF
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
SET_VEHICLE_DOOR_OPEN(sTruck.vehBack, SC_DOOR_BOOT)
ENDIF
GIVE_MAIN_PEDS_HEADSETS()
IF IS_VEHICLE_DRIVEABLE(sStolenCars[iChosenCar].veh)
IF IS_ENTITY_ATTACHED(sStolenCars[iChosenCar].veh)
DETACH_ENTITY(sStolenCars[iChosenCar].veh)
ENDIF
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), sStolenCars[iChosenCar].veh)
SET_VEHICLE_TYRES_CAN_BURST(sStolenCars[iChosenCar].veh, FALSE)
SET_VEHICLE_STRONG(sStolenCars[iChosenCar].veh, TRUE)
SET_VEHICLE_HAS_STRONG_AXLES(sStolenCars[iChosenCar].veh, TRUE)
SET_ENTITY_COLLISION(sStolenCars[iChosenCar].veh, TRUE)
SET_VEHICLE_ENGINE_ON(sStolenCars[iChosenCar].veh, TRUE, TRUE)
SET_ENTITY_COORDS(sStolenCars[iChosenCar].veh, <<-1810.5596, 4701.3066, 56.0453>>)
SET_ENTITY_HEADING(sStolenCars[iChosenCar].veh, 309.9444)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sStolenCars[iChosenCar].veh, TRUE)
SET_VEHICLE_ON_GROUND_PROPERLY(sStolenCars[iChosenCar].veh)
ENDIF
SET_STOLEN_CARS_AS_LOW_LOD()
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_AllowedToDetachTrailer, FALSE)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
bCleanedUpSwitchCams = TRUE
bIsJumpingDirectlyToStage = FALSE
ENDIF
ELSE
//Keep Lamar and Trevor inside the truck
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
IF IS_PED_GROUP_MEMBER(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], PLAYER_GROUP_ID())
REMOVE_PED_FROM_GROUP(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
ENDIF
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], TRUE)
SET_PED_MAX_HEALTH(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], 1800)
SET_ENTITY_HEALTH(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], 1800)
SET_PED_COMBAT_ATTRIBUTES(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], CA_LEAVE_VEHICLES, FALSE)
SET_PED_SUFFERS_CRITICAL_HITS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], FALSE)
ENDIF
IF NOT IS_PED_INJURED(sLamar.ped)
IF IS_PED_GROUP_MEMBER(sLamar.ped, PLAYER_GROUP_ID())
REMOVE_PED_FROM_GROUP(sLamar.ped)
ENDIF
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sLamar.ped, TRUE)
SET_PED_MAX_HEALTH(sLamar.ped, 1800)
SET_ENTITY_HEALTH(sLamar.ped, 1800)
SET_PED_COMBAT_ATTRIBUTES(sLamar.ped, CA_LEAVE_VEHICLES, FALSE)
SET_PED_SUFFERS_CRITICAL_HITS(sLamar.ped, FALSE)
ENDIF
//Lock all the cars to prevent the player from getting in
INT i = 0
REPEAT COUNT_OF(sStolenCars) i
IF i != iChosenCar
IF IS_VEHICLE_DRIVEABLE(sStolenCars[i].veh)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sStolenCars[i].veh, FALSE)
ENDIF
ENDIF
ENDREPEAT
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sTruck.vehFront, FALSE)
SET_ENTITY_CAN_BE_DAMAGED_BY_RELATIONSHIP_GROUP(sTruck.vehFront, FALSE, RELGROUPHASH_PLAYER)
SET_ENTITY_LOAD_COLLISION_FLAG(sTruck.vehFront, TRUE)
ADD_ENTITY_TO_AUDIO_MIX_GROUP(sTruck.vehFront, "CAR_4_TRANSPORTER_GROUP")
ENDIF
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sTruck.vehBack, FALSE)
SET_ENTITY_LOAD_COLLISION_FLAG(sTruck.vehBack, TRUE)
ADD_ENTITY_TO_AUDIO_MIX_GROUP(sTruck.vehBack, "CAR_4_TRANSPORTER_GROUP")
ENDIF
//Force wanted level at this stage
SET_POLICE_RADAR_BLIPS(TRUE)
SET_DISPATCH_COPS_FOR_PLAYER(PLAYER_ID(), FALSE)
SET_CREATE_RANDOM_COPS(FALSE)
ENABLE_DISPATCH_SERVICE(DT_FIRE_DEPARTMENT, FALSE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_AUTOMOBILE, FALSE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_ROAD_BLOCK, FALSE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_HELICOPTER, FALSE)
ENABLE_DISPATCH_SERVICE(DT_POLICE_RIDERS, FALSE)
ENABLE_DISPATCH_SERVICE(DT_AMBULANCE_DEPARTMENT, FALSE)
BLOCK_DISPATCH_SERVICE_RESOURCE_CREATION(DT_POLICE_HELICOPTER, TRUE)
BLOCK_DISPATCH_SERVICE_RESOURCE_CREATION(DT_POLICE_ROAD_BLOCK, TRUE)
ALLOW_AMBIENT_VEHICLES_TO_AVOID_ADVERSE_CONDITIONS(FALSE)
SET_PARTICLE_FX_BANG_SCRAPE_LODRANGE_SCALE(5.0)
BLOCK_SCENARIOS_FOR_CHASE(TRUE)
SET_ALL_SHOPS_TEMPORARILY_UNAVAILABLE(TRUE)
IF IS_SCREEN_FADED_OUT()
TRIGGER_MUSIC_EVENT("CAR4_TRUCK_RESTART")
ENDIF
IF NOT IS_AUDIO_SCENE_ACTIVE("CAR_4_DEFEND_THE_TRUCK")
START_AUDIO_SCENE("CAR_4_DEFEND_THE_TRUCK")
ENDIF
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 3)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
SET_WANTED_LEVEL_MULTIPLIER(0.0)
SET_MAX_WANTED_LEVEL(3)
iCopsTrashEvent = 0
iTrevorDriveEvent = 0
RESET_JB700_GADGET_DATA(sCarGadgets)
REASSIGN_PLAYER_CHAR_DIALOGUE_SPEAKERS()
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CHECKPOINT_LOSE_COPS, "LOSE_COPS")
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
IF NOT IS_SCREEN_FADED_IN()
CLEAR_AREA_OF_COPS(GET_ENTITY_COORDS(PLAYER_PED_ID()), 500.0)
CLEAR_AREA_OF_VEHICLES(GET_ENTITY_COORDS(PLAYER_PED_ID()), 300.0)
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
WHILE NOT IS_SCREEN_FADED_IN()
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
UPDATE_WANTED_POSITION_THIS_FRAME(PLAYER_ID())
SUPPRESS_LOSING_WANTED_LEVEL_IF_HIDDEN_THIS_FRAME(PLAYER_ID())
REPORT_POLICE_SPOTTED_PLAYER(PLAYER_ID())
REQUEST_PATH_NODES_IN_AREA_THIS_FRAME(vPathNodesMinPos.x, vPathNodesMinPos.y, vPathNodesMaxPos.x, vPathNodesMaxPos.y)
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
SET_VEHICLE_FORWARD_SPEED(sTruck.vehFront, 15.0)
ENDIF
IF IS_VEHICLE_DRIVEABLE(sStolenCars[iChosenCar].veh)
SET_VEHICLE_FORWARD_SPEED(sStolenCars[iChosenCar].veh, 15.0)
ENDIF
WAIT(0)
ENDWHILE
ENDIF
IF IS_VEHICLE_DRIVEABLE(sStolenCars[iChosenCar].veh) //allow JB700 to be damaged by player
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(sStolenCars[iChosenCar].veh, FALSE) //so that damage stat can be tracked for it
ENDIF
SETTIMERB(0)
iFranklinShotByCopsTimer = 0
iFranklinAttackTruckTimer = 0
iNumFranklinBashTruckLines = 0
iNumFranklinStingTruckLines = 0
iNumFranklinShootTruckLines = 0
iLeftLightOnTimer = 0
iLeftLightOffTimer = 0
iRightLightOnTimer = 0
iRightLightOffTimer = 0
iCurrentMusicEvent = 0
iMusicEventTimer = GET_GAME_TIMER()
iCurrentEvent = 0
eSectionStage = SECTION_STAGE_RUNNING
ENDIF
ENDIF
IF eSectionStage = SECTION_STAGE_RUNNING
#IF IS_DEBUG_BUILD
DONT_DO_J_SKIP(sLocatesData)
#ENDIF
IF DOES_ENTITY_EXIST(sTruck.vehFront)
IF NOT IS_ENTITY_DEAD(sTruck.vehFront)
SET_FORCE_HD_VEHICLE(sTruck.vehFront, TRUE)
ENDIF
ENDIF
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxSparksLeft)
DRAW_FLICKERING_LIGHT(GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehBack, vSparksOffsetLeft + vSparksLightOffset),
vSparksLightColour, vSparksLightRange.x, vSparksLightRange.y, iLeftLightOnTimer, iLeftLightOffTimer,
50, 300, 30, 100)
ENDIF
IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxSparksRight)
DRAW_FLICKERING_LIGHT(GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehBack, vSparksOffsetRight + vSparksLightOffset),
vSparksLightColour, vSparksLightRange.x, vSparksLightRange.y, iRightLightOnTimer, iRightLightOffTimer,
50, 300, 30, 100)
ENDIF
ENDIF
//Clean up the switch spline if it's still interping to gameplay at this stage.
IF NOT bCleanedUpSwitchCams
IF NOT IS_INTERPOLATING_FROM_SCRIPT_CAMS()
DESTROY_ALL_CAMS()
bCleanedUpSwitchCams = TRUE
ENDIF
ENDIF
CALCULATE_PATH_NODES_AREA_FOR_POS(GET_ENTITY_COORDS(sTruck.vehFront))
REQUEST_PATH_NODES_IN_AREA_THIS_FRAME(vPathNodesMinPos.x, vPathNodesMinPos.y, vPathNodesMaxPos.x, vPathNodesMaxPos.y)
#IF IS_DEBUG_BUILD
PRINTLN(GET_THIS_SCRIPT_NAME(), ": STAGE_ESCORT_TRUCK - Calling REQUEST_PATH_NODES_IN_AREA_THIS_FRAME(", vPathNodesMinPos.x, ", ",
vPathNodesMinPos.y, ", ", vPathNodesMaxPos.x, ", ", vPathNodesMaxPos.y, ").")
#ENDIF
IF DOES_BLIP_EXIST(sLocatesData.LocationBlip)
IF NOT DOES_BLIP_EXIST(sTruck.blip)
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
sTruck.blip = CREATE_BLIP_FOR_ENTITY(sTruck.vehFront)
ENDIF
ENDIF
ELSE
IF DOES_BLIP_EXIST(sTruck.blip)
REMOVE_BLIP(sTruck.blip)
ENDIF
ENDIF
//952818 - Lower traffic density a little bit.
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.5)
UPDATE_CHASE_COPS()
SETUP_MOLLY_AND_CAR() //Do this in advance in case the player drives ahead to where Molly will be.
UPDATE_MOLLY_WAITING_BY_CAR()
SETUP_CAR_AT_GAS_STATION()
//MOVE_CARS_OUT_OF_THE_WAY_OF_TREVORS_TRUCK()
UPDATE_OIL_SLICKS()
UPDATE_JB700_GUNS(sStolenCars[iChosenCar].veh, sCarGadgets)
UPDATE_TREVOR_AND_LAMAR_IN_TRUCK()
//BOOL bKilledEnoughCops = UPDATE_WANTED_LEVEL_DURING_ESCORT()
BOOL bKilledEnoughCops = UPDATE_WANTED_LEVEL_DURING_ESCORT_2()
SWITCH iCurrentEvent
CASE 0
IS_PLAYER_AT_LOCATION_IN_VEHICLE(sLocatesData, vDropOffPos, <<0.001, 0.001, LOCATE_SIZE_HEIGHT>>, FALSE, sStolenCars[iChosenCar].veh,
"CH_DEFTRUCK", "CH_GETINCAR", "CH_GETBACKCAR", FALSE)
IF bKilledEnoughCops
OR NOT IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
CLEAR_MISSION_LOCATE_STUFF(sLocatesData)
CLEAR_PRINTS()
SET_CREATE_RANDOM_COPS(FALSE)
SET_MODEL_AS_NO_LONGER_NEEDED(modelCop)
SET_MODEL_AS_NO_LONGER_NEEDED(modelCopCar)
IF IS_AUDIO_SCENE_ACTIVE("CAR_4_DEFEND_THE_TRUCK")
STOP_AUDIO_SCENE("CAR_4_DEFEND_THE_TRUCK")
ENDIF
IF NOT IS_AUDIO_SCENE_ACTIVE("CAR_4_FOLLOW_TRUCK")
START_AUDIO_SCENE("CAR_4_FOLLOW_TRUCK")
ENDIF
INFORM_MISSION_STATS_SYSTEM_OF_TIME_WINDOW_CLOSED()
iCurrentEvent++
ELSE
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_NEAREND")
AND iCopsTrashEvent < 50
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF VDIST2(GET_ENTITY_COORDS(sTruck.vehFront), vDropOffPos) < 640000.0
AND VDIST2(GET_ENTITY_COORDS(sTruck.vehFront), GET_ENTITY_COORDS(PLAYER_PED_ID())) < 40000.0
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_NEAREND", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_NEAREND", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
//Lamar shouts lines if the player is nearby.
IF GET_GAME_TIMER() - iChaseDialogueTimer > 0
AND iNumChaseLamarLinesPlayed < 7
AND NOT HAS_LABEL_BEEN_TRIGGERED("CST7_CDONE")
AND NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF VDIST2(GET_ENTITY_COORDS(sTruck.vehFront), GET_ENTITY_COORDS(PLAYER_PED_ID())) < 40000.0
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", PICK_STRING(GET_RANDOM_BOOL(), "CST7_LAMSH", "CST7_LOFF"), CONV_PRIORITY_MEDIUM)
iNumChaseLamarLinesPlayed++
iChaseDialogueTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(10000, 13000 + (iNumChaseLamarLinesPlayed * 500))
ENDIF
ENDIF
ENDIF
//Custom convo between Franklin and Lamar.
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_HSET")
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF TIMERB() > GET_RANDOM_INT_IN_RANGE(10000, 13000)
IF GET_RANDOM_INT_IN_RANGE(0, 2) = 0
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_HSET1", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_HSET", TRUE)
ENDIF
ELSE
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_HSET2", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_HSET", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
//Conversations for player attacking, damaging, crashing into the truck or dropping spikes in front of the truck
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF GET_GAME_TIMER() - iFranklinAttackTruckTimer > 0
//Play conversation when bullets from JB700 hit the truck or the stolen cars
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_SHOOT")
IF IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[iChosenCar].veh)
IF IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, sCarGadgets.caGunInput)
IF IS_BULLET_IN_AREA(GET_ENTITY_COORDS(sTruck.vehFront), 2.5, TRUE)
OR IS_BULLET_IN_AREA(GET_ENTITY_COORDS(sTruck.vehFront), 2.5, TRUE)
OR IS_BULLET_IN_AREA(GET_ENTITY_COORDS(sStolenCars[0].veh), 2.5, TRUE)
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_SHOOT", CONV_PRIORITY_MEDIUM)
iNumFranklinShootTruckLines++
iFranklinAttackTruckTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(8000, 15000)
IF ( iNumFranklinShootTruckLines = 5 )
SET_LABEL_AS_TRIGGERED("CST7_SHOOT", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
//Play conversation when player crashes JB700 into the truck
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_BASH")
IF IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[iChosenCar].veh)
IF NOT IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, sCarGadgets.caGunInput)
IF IS_ENTITY_TOUCHING_ENTITY(sTruck.vehBack, sStolenCars[iChosenCar].veh)
OR IS_ENTITY_TOUCHING_ENTITY(sTruck.vehFront, sStolenCars[iChosenCar].veh)
OR IS_ENTITY_TOUCHING_ENTITY(sStolenCars[0].veh, sStolenCars[iChosenCar].veh)
OR HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(sTruck.vehBack, sStolenCars[iChosenCar].veh)
OR HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(sTruck.vehFront, sStolenCars[iChosenCar].veh)
OR HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(sStolenCars[0].veh, sStolenCars[iChosenCar].veh)
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_BASH", CONV_PRIORITY_MEDIUM)
iNumFranklinBashTruckLines++
iFranklinAttackTruckTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(8000, 15000)
CLEAR_ENTITY_LAST_DAMAGE_ENTITY(sTruck.vehBack)
CLEAR_ENTITY_LAST_DAMAGE_ENTITY(sTruck.vehFront)
CLEAR_ENTITY_LAST_DAMAGE_ENTITY(sStolenCars[0].veh)
IF ( iNumFranklinBashTruckLines = 6 )
SET_LABEL_AS_TRIGGERED("CST7_BASH", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
//Play conversation when player drops spikes in front of the truck
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_STING")
IF IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[iChosenCar].veh)
INT i
REPEAT 3 i
IF DOES_ENTITY_EXIST(objSpikes[i])
IF NOT IS_ENTITY_DEAD(objSpikes[i])
IF IS_ENTITY_IN_ANGLED_AREA(objSpikes[i], GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, <<0.0, 4.1723, -2.3128>>),
GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, <<0.0, 12.1723, 3.3128>>), 6.0)
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_STING", CONV_PRIORITY_MEDIUM)
iNumFranklinStingTruckLines++
iFranklinAttackTruckTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(8000, 15000)
IF ( iNumFranklinStingTruckLines = 3 )
SET_LABEL_AS_TRIGGERED("CST7_STING", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE 1
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_FIN02")
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_FIN01")
AND NOT HAS_LABEL_BEEN_TRIGGERED("CST7_FIN01B")
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), vDropOffPos) > 40000.0
ADD_PED_FOR_DIALOGUE(sConversationPeds, 8, NULL, "MOLLY")
IF PLAYER_CALL_CHAR_CELLPHONE(sConversationPeds, CHAR_MOLLY, "CST7AUD", PICK_STRING(IS_REPLAY_IN_PROGRESS(), "CST7_FIN01B", "CST7_FIN01"), CONV_PRIORITY_CELLPHONE)
SET_LABEL_AS_TRIGGERED(PICK_STRING(IS_REPLAY_IN_PROGRESS(), "CST7_FIN01B", "CST7_FIN01"), TRUE)
REPLAY_RECORD_BACK_FOR_TIME(4.0, 10.0, REPLAY_IMPORTANCE_HIGHEST)
ENDIF
ELSE
SET_LABEL_AS_TRIGGERED("CST7_FIN01", TRUE)
SET_LABEL_AS_TRIGGERED("CST7_FIN01B", TRUE)
ENDIF
ENDIF
ELSE
IF NOT IS_MOBILE_PHONE_CALL_ONGOING()
SET_LABEL_AS_TRIGGERED("CST7_FIN02", TRUE)
ENDIF
ENDIF
ELSE
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_STOP")
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_STOP", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_STOP", TRUE)
ENDIF
ELIF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_DRIVE")
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_DRIVE", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_DRIVE", TRUE)
ENDIF
ENDIF
IS_PLAYER_AT_LOCATION_IN_VEHICLE(sLocatesData, vDropOffPos, <<0.001, 0.001, LOCATE_SIZE_HEIGHT>>, FALSE, sStolenCars[iChosenCar].veh,
"CH_FOLTRUCK2", "CH_GETINCAR", "CH_GETBACKCAR", FALSE)
ENDIF
//If the player gets another wanted level then go back to the previous stage.
IF IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
CLEAR_MISSION_LOCATE_STUFF(sLocatesData)
iCopsTrashEvent = 0
iCurrentEvent--
ENDIF
//If the player gets to the drop off positon while inside the JB700 and the truck around
IF DOES_BLIP_EXIST(sLocatesData.LocationBlip)
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
//Progress once the truck stops.
IF VDIST2(GET_ENTITY_COORDS(sTruck.vehFront), vDropOffPos) < 400.0
AND VDIST2(GET_ENTITY_COORDS(sTruck.vehFront), GET_ENTITY_COORDS(PLAYER_PED_ID())) < 900.0
eSectionStage = SECTION_STAGE_CLEANUP
ENDIF
ENDIF
ENDIF
//If the player gets to the drop off positon before the truck and gets out of the truck
IF DOES_BLIP_EXIST(sLocatesData.vehicleBlip)
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
//Progress once the truck stops.
IF VDIST2(GET_ENTITY_COORDS(sTruck.vehFront), vDropOffPos) < 400.0
AND VDIST2(GET_ENTITY_COORDS(sTruck.vehFront), GET_ENTITY_COORDS(PLAYER_PED_ID())) < 900.0
eSectionStage = SECTION_STAGE_CLEANUP
ENDIF
ENDIF
ENDIF
BREAK
ENDSWITCH
//Play dialogue if the player approaches Molly before the truck arrives at drop off position.
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_WALK2")
IF VDIST2(GET_ENTITY_COORDS(sTruck.vehFront), vDropOffPos) > 900.0
IF DOES_BLIP_EXIST(sLocatesData.vehicleBlip)
IF NOT IS_PED_INJURED(pedMolly)
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_ENTITY_COORDS(pedMolly), << 18.0, 18.0, 18.0 >>)
IF HAS_ENTITY_CLEAR_LOS_TO_ENTITY_IN_FRONT(pedMolly, PLAYER_PED_ID())
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
ADD_PED_FOR_DIALOGUE(sConversationPeds, 8, pedMolly, "MOLLY")
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_WALK2", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_WALK2", TRUE)
ENDIF
ELSE
IF NOT IS_AMBIENT_SPEECH_PLAYING(pedMolly)
PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(pedMolly, "CST7_AIAA", "MOLLY", SPEECH_PARAMS_FORCE_NORMAL)
SET_LABEL_AS_TRIGGERED("CST7_WALK2", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
//Play dialogue if the player gets close to Molly before the truck arrives at drop off position.
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_WALK1")
IF HAS_LABEL_BEEN_TRIGGERED("CST7_WALK2") //Play conversation only after the inital approach converasation was triggered
IF VDIST2(GET_ENTITY_COORDS(sTruck.vehFront), vDropOffPos) > 900.0
IF DOES_BLIP_EXIST(sLocatesData.vehicleBlip)
IF NOT IS_PED_INJURED(pedMolly)
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_ENTITY_COORDS(pedMolly), << 10.0, 10.0, 10.0 >>)
IF HAS_ENTITY_CLEAR_LOS_TO_ENTITY_IN_FRONT(pedMolly, PLAYER_PED_ID())
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
ADD_PED_FOR_DIALOGUE(sConversationPeds, 8, pedMolly, "MOLLY")
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_WALK1", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_WALK1", TRUE)
ENDIF
ELSE
IF NOT IS_AMBIENT_SPEECH_PLAYING(pedMolly)
PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(pedMolly, "CST7_AIAA", "MOLLY", SPEECH_PARAMS_FORCE_NORMAL)
SET_LABEL_AS_TRIGGERED("CST7_WALK1", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
//Music events.
SWITCH iCurrentMusicEvent
CASE 0
//IF NOT IS_MUSIC_ONESHOT_PLAYING()
// iMusicEventTimer = GET_GAME_TIMER()
iCurrentMusicEvent++
//ELSE
// //Something went wrong, cancel all previous music events.
// IF GET_GAME_TIMER() - iMusicEventTimer > 20000
// CANCEL_ALL_PREPARED_MUSIC_EVENTS()
// ENDIF
//ENDIF
BREAK
CASE 1 //When the player loses the cops.
IF NOT IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
//AND GET_GAME_TIMER() - iMusicEventTimer > 500
IF PREPARE_MUSIC_EVENT("CAR4_RADIO_1") //don't prepare score too early, see B*1532941
TRIGGER_MUSIC_EVENT("CAR4_RADIO_1")
#IF IS_DEBUG_BUILD
PRINTLN("Triggering CAR4_RADIO_1.")
#ENDIF
iMusicEventTimer = GET_GAME_TIMER()
iCurrentMusicEvent++
ENDIF
ENDIF
BREAK
CASE 2 //Disable score with radio.
IF GET_GAME_TIMER() - iMusicEventTimer > 5000
iCurrentMusicEvent++
ENDIF
BREAK
ENDSWITCH
//Play dialogue when a new cop car approaches the truck.
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_MORE")
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData)
IF iCurrentCopBeingTrackedForDialogue > 1
INT iCopIndex = iCurrentCopBeingTrackedForDialogue - 1
IF NOT IS_ENTITY_DEAD(vehChaseCops[iCopIndex])
AND NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF VDIST2(GET_ENTITY_COORDS(sTruck.vehBack), GET_ENTITY_COORDS(vehChaseCops[iCopIndex])) < 1600.0
IF GET_RANDOM_INT_IN_RANGE(0, 2) = 0
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_LMORE", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_MORE", TRUE)
ENDIF
ELSE
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_TMORE", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_MORE", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
IF iCurrentCopBeingTrackedForDialogue != iNumChaseCopCarsCreated
SET_LABEL_AS_TRIGGERED("CST7_MORE", FALSE)
ENDIF
ENDIF
iCurrentCopBeingTrackedForDialogue = iNumChaseCopCarsCreated
//Hide the locates header blip (we're using a custom blip for Trevor's truck).
IF DOES_BLIP_EXIST(sLocatesData.LocationBlip)
SET_BLIP_ALPHA(sLocatesData.LocationBlip, 0)
SET_BLIP_ROUTE(sLocatesData.LocationBlip, FALSE)
ENDIF
IF NOT HAS_LABEL_BEEN_TRIGGERED("CH_SHOTHELP")
IF TIMERB() > 3000
AND NOT IS_HELP_MESSAGE_BEING_DISPLAYED()
CLEAR_HELP(TRUE)
// Different help on PC if using keyboard and mouse.
IF IS_USING_KEYBOARD_AND_MOUSE(PLAYER_CONTROL)
PRINT_HELP("CH_SHOTHELP_KM", 15000)
ELSE
PRINT_HELP("CH_SHOTHELP", 15000)
ENDIF
SET_LABEL_AS_TRIGGERED("CH_SHOTHELP", TRUE)
ENDIF
ENDIF
IF IS_VEHICLE_DRIVEABLE(sStolenCars[iChosenCar].veh)
IF IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), sStolenCars[iChosenCar].veh)
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_BUTTON")
//Clear the god text early if it's the "lose the cops" text (TODO 341429)
IF IS_THIS_PRINT_BEING_DISPLAYED("LOSE_WANTED")
IF TIMERB() > 4000
CLEAR_PRINTS()
ENDIF
ENDIF
IF ( sCarGadgets.bGunsFired = FALSE )
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_BUTTON", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_BUTTON", TRUE)
ENDIF
ENDIF
ELSE
SET_LABEL_AS_TRIGGERED("CST7_BUTTON", TRUE)
ENDIF
ENDIF
ELSE
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("CH_SHOTHELP")
CLEAR_HELP(TRUE)
ENDIF
IF VDIST2(GET_ENTITY_COORDS(sStolenCars[iChosenCar].veh), GET_ENTITY_COORDS(PLAYER_PED_ID())) > 10000.0
MISSION_FAILED(FAILED_ABANDONED_CAR)
ENDIF
ENDIF
IF NOT IS_ENTITY_DEAD(sTruck.vehFront)
CONTROL_VEHICLE_CHASE_HINT_CAM_IN_VEHICLE(localChaseHintCamStruct, sTruck.vehFront)
ENDIF
ENDIF
IF IS_GAMEPLAY_HINT_ACTIVE()
IF NOT IS_AUDIO_SCENE_ACTIVE("CAR_4_FOCUS_ON_TRUCK")
START_AUDIO_SCENE("CAR_4_FOCUS_ON_TRUCK")
ENDIF
ELSE
IF IS_AUDIO_SCENE_ACTIVE("CAR_4_FOCUS_ON_TRUCK")
STOP_AUDIO_SCENE("CAR_4_FOCUS_ON_TRUCK")
ENDIF
ENDIF
//Fail for the truck being destroyed.
IF NOT IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
MISSION_FAILED(FAILED_DESTROYED_TRUCK)
ENDIF
//If the trailer becomes detached the mission needs to fail.
IF NOT IS_ENTITY_DEAD(sTruck.vehFront)
IF NOT IS_VEHICLE_ATTACHED_TO_TRAILER(sTruck.vehFront)
MISSION_FAILED(FAILED_TRAILER_DETACHED)
ENDIF
ENDIF
//If the player leaves the truck fail for leaving buddies behind.
IF NOT IS_PED_INJURED(sLamar.ped)
AND NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sLamar.ped)) > 90000.0
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])) > 40000.0
MISSION_FAILED(FAILED_LEFT_TREVOR_AND_LAMAR)
ELSE
MISSION_FAILED(FAILED_LEFT_LAMAR)
ENDIF
ENDIF
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])) > 90000.0
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sLamar.ped)) > 40000.0
MISSION_FAILED(FAILED_LEFT_TREVOR_AND_LAMAR)
ELSE
MISSION_FAILED(FAILED_LEFT_TREVOR)
ENDIF
ENDIF
ENDIF
//Fail if the cops are led to the drop-off point.
IF IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
IF VDIST2(GET_ENTITY_COORDS(sTruck.vehFront), vDropOffPos) < 22500.0
AND VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sTruck.vehFront)) < 3600.0
MISSION_FAILED(FAILED_LED_COPS_TO_CARS)
ENDIF
ENDIF
IF DOES_ENTITY_EXIST(pedMolly)
IF NOT IS_ENTITY_DEAD(pedMolly)
//Kill Molly if there's an explosion near her.
IF IS_EXPLOSION_IN_SPHERE(EXP_TAG_GRENADE, GET_ENTITY_COORDS(pedMolly), 5.0)
OR IS_EXPLOSION_IN_SPHERE(EXP_TAG_ROCKET, GET_ENTITY_COORDS(pedMolly), 5.0)
OR IS_EXPLOSION_IN_SPHERE(EXP_TAG_STICKYBOMB, GET_ENTITY_COORDS(pedMolly), 5.0)
OR IS_EXPLOSION_IN_SPHERE(EXP_TAG_TANKSHELL, GET_ENTITY_COORDS(pedMolly), 5.0)
OR IS_EXPLOSION_IN_SPHERE(EXP_TAG_MOLOTOV, GET_ENTITY_COORDS(pedMolly), 5.0)
OR IS_EXPLOSION_IN_SPHERE(EXP_TAG_GRENADELAUNCHER, GET_ENTITY_COORDS(pedMolly), 5.0)
APPLY_DAMAGE_TO_PED(pedMolly, 400, TRUE)
ENDIF
//Kill Molly if player car touches her
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(pedMolly, PLAYER_PED_ID(), TRUE)
OR HAS_ENTITY_BEEN_DAMAGED_BY_ANY_VEHICLE(pedMolly)
OR IS_ENTITY_TOUCHING_ENTITY(pedMolly, PLAYER_PED_ID())
PLAY_PAIN(pedMolly, AUD_DAMAGE_REASON_SCREAM_SCARED)
STOP_SYNCHRONIZED_ENTITY_ANIM(pedMolly, NORMAL_BLEND_OUT, TRUE)
TASK_SMART_FLEE_PED(pedMolly, PLAYER_PED_ID(), 200.0, -1)
MISSION_FAILED(FAILED_SPOOKED_MOLLY)
ENDIF
IF DOES_ENTITY_EXIST(vehMollyCar)
IF NOT IS_ENTITY_DEAD(vehMollyCar)
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(vehMollyCar, PLAYER_PED_ID(), TRUE)
OR (IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) AND IS_ENTITY_TOUCHING_ENTITY(vehMollyCar, GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())))
PLAY_PAIN(pedMolly, AUD_DAMAGE_REASON_SCREAM_SCARED)
STOP_SYNCHRONIZED_ENTITY_ANIM(pedMolly, NORMAL_BLEND_OUT, TRUE)
TASK_SMART_FLEE_PED(pedMolly, PLAYER_PED_ID(), 200.0, -1)
MISSION_FAILED(FAILED_SPOOKED_MOLLY)
ENDIF
ENDIF
ENDIF
//Have Molly run off if any bullets are near her.
IF IS_BULLET_IN_AREA(GET_ENTITY_COORDS(pedMolly), 8.0, TRUE)
PLAY_PAIN(pedMolly, AUD_DAMAGE_REASON_SCREAM_SCARED)
STOP_SYNCHRONIZED_ENTITY_ANIM(pedMolly, NORMAL_BLEND_OUT, TRUE)
TASK_SMART_FLEE_PED(pedMolly, PLAYER_PED_ID(), 200.0, -1)
MISSION_FAILED(FAILED_SPOOKED_MOLLY)
ENDIF
ENDIF
ENDIF
ENDIF
//Stop the spark particle effects when the truck comes to a halt
IF DOES_ENTITY_EXIST(sTruck.vehFront) AND NOT IS_ENTITY_DEAD(sTruck.vehFront)
AND DOES_ENTITY_EXIST(sTruck.vehBack) AND NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF GET_ENTITY_SPEED(sTruck.vehFront) < 1.0
OR IS_VEHICLE_STOPPED(sTruck.vehFront)
IF NOT HAS_SOUND_FINISHED(iScrapeSound)
STOP_SOUND(iScrapeSound)
ENDIF
IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxSparksLeft)
//IF VDIST2(GET_ENTITY_COORDS(sTruck.vehFront), vDropOffPos) < 50.0
STOP_PARTICLE_FX_LOOPED(ptfxSparksLeft)
//ENDIF
ENDIF
IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxSparksRight)
//IF VDIST2(GET_ENTITY_COORDS(sTruck.vehFront), vDropOffPos) < 50.0
STOP_PARTICLE_FX_LOOPED(ptfxSparksRight)
//ENDIF
ENDIF
ELSE
IF HAS_SOUND_FINISHED(iScrapeSound)
IF REQUEST_SCRIPT_AUDIO_BANK("CAR_STEAL_4")
IF DOES_ENTITY_EXIST(sStolenCars[0].veh) AND NOT IS_ENTITY_DEAD(sStolenCars[0].veh)
PLAY_SOUND_FROM_ENTITY(iScrapeSound, "CAR_STEAL_4_RAMP_SCRAPE", sStolenCars[0].veh, "CAR_STEAL_4_SOUNDSET")
ENDIF
ENDIF
ENDIF
IF NOT DOES_PARTICLE_FX_LOOPED_EXIST(ptfxSparksLeft)
ptfxSparksLeft = START_PARTICLE_FX_LOOPED_ON_ENTITY("scr_carsteal4_trailer_scrape", sTruck.vehBack, vSparksOffsetLeft, vSparksRotation)
ENDIF
IF NOT DOES_PARTICLE_FX_LOOPED_EXIST(ptfxSparksRight)
ptfxSparksRight = START_PARTICLE_FX_LOOPED_ON_ENTITY("scr_carsteal4_trailer_scrape", sTruck.vehBack, vSparksOffsetRight , vSparksRotation)
ENDIF
ENDIF
ENDIF
IF eSectionStage = SECTION_STAGE_CLEANUP
CLEAR_PRINTS()
REMOVE_ALL_BLIPS()
CLEAR_MISSION_LOCATE_STUFF(sLocatesData)
STOP_AUDIO_SCENES()
SET_PARTICLE_FX_BANG_SCRAPE_LODRANGE_SCALE(1.0)
KILL_CHASE_HINT_CAM(localChaseHintCamStruct)
IF NOT HAS_SOUND_FINISHED(iScrapeSound)
STOP_SOUND(iScrapeSound)
ENDIF
IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxSparksLeft)
STOP_PARTICLE_FX_LOOPED(ptfxSparksLeft)
ENDIF
IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxSparksRight)
STOP_PARTICLE_FX_LOOPED(ptfxSparksRight)
ENDIF
eSectionStage = SECTION_STAGE_SETUP
eMissionStage = STAGE_MEET_MOLLY
ENDIF
IF eSectionStage = SECTION_STAGE_SKIP
JUMP_TO_STAGE(STAGE_MEET_MOLLY)
ENDIF
ENDPROC
PROC MEET_MOLLY()
SET_ALL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID())
IF eSectionStage = SECTION_STAGE_SETUP
IF bIsJumpingDirectlyToStage
IF iCurrentEvent != 99
IF SETUP_REQ_PLAYER_IS_FRANKLIN()
IF bUsedACheckpoint
START_REPLAY_SETUP(<<1542.9697, 6481.6245, 21.5820>>, 314.9911)
iCurrentEvent = 99
ELSE
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<1542.9697, 6481.6245, 21.5820>>)
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), TRUE)
LOAD_SCENE(GET_ENTITY_COORDS(PLAYER_PED_ID()))
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), FALSE)
iCurrentEvent = 99
ENDIF
ENDIF
ELSE
CLEAR_AREA_OF_VEHICLES(vDropOffPos, 50.0)
IF SETUP_REQ_SUPPRESS_CHASE_MODELS()
AND SETUP_REQ_TRUCK_UNFROZEN(<<1563.57, 6465.22, 23.96>>, 231.4902)
AND SETUP_REQ_CARS_ON_TRUCK()
AND SETUP_REQ_LAMAR(<<504.1672, -1304.7441, 28.3103>>, 200.8915)
AND SETUP_REQ_TREVOR(<<496.6033, -1308.3790, 28.3020>>, 204.3612)
AND SETUP_MOLLY_AND_CAR()
AND SETUP_CAR_AT_GAS_STATION()
END_REPLAY_SETUP(DEFAULT, DEFAULT, FALSE)
SUPPRESS_LARGE_VEHICLES(TRUE)
SET_ALL_SHOPS_TEMPORARILY_UNAVAILABLE(TRUE)
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
SET_PED_INTO_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], sTruck.vehFront)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], TRUE)
SET_PED_MAX_HEALTH(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], 1800)
SET_ENTITY_HEALTH(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], 1800)
SET_PED_COMBAT_ATTRIBUTES(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], CA_LEAVE_VEHICLES, FALSE)
SET_PED_SUFFERS_CRITICAL_HITS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], FALSE)
ENDIF
IF NOT IS_PED_INJURED(sLamar.ped)
SET_PED_INTO_VEHICLE(sLamar.ped, sTruck.vehFront, VS_FRONT_RIGHT)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sLamar.ped, TRUE)
SET_PED_MAX_HEALTH(sLamar.ped, 1800)
SET_ENTITY_HEALTH(sLamar.ped, 1800)
SET_PED_COMBAT_ATTRIBUTES(sLamar.ped, CA_LEAVE_VEHICLES, FALSE)
SET_PED_SUFFERS_CRITICAL_HITS(sLamar.ped, FALSE)
ENDIF
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sTruck.vehFront, FALSE)
SET_ENTITY_CAN_BE_DAMAGED_BY_RELATIONSHIP_GROUP(sTruck.vehFront, FALSE, RELGROUPHASH_PLAYER)
ENDIF
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
SET_VEHICLE_DOOR_OPEN(sTruck.vehBack, SC_DOOR_BOOT)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sTruck.vehBack, FALSE)
ENDIF
IF IS_VEHICLE_DRIVEABLE(sStolenCars[iChosenCar].veh)
DETACH_ENTITY(sStolenCars[iChosenCar].veh)
SET_VEHICLE_TYRES_CAN_BURST(sStolenCars[iChosenCar].veh, FALSE)
SET_VEHICLE_STRONG(sStolenCars[iChosenCar].veh, TRUE)
SET_VEHICLE_HAS_STRONG_AXLES(sStolenCars[iChosenCar].veh, TRUE)
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), sStolenCars[iChosenCar].veh)
SET_ENTITY_COLLISION(sStolenCars[iChosenCar].veh, TRUE)
SET_VEHICLE_ENGINE_ON(sStolenCars[iChosenCar].veh, TRUE, TRUE)
SET_ENTITY_COORDS(sStolenCars[iChosenCar].veh, <<1542.9697, 6481.6245, 21.5820>>)
SET_ENTITY_HEADING(sStolenCars[iChosenCar].veh, 231.4902)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sStolenCars[iChosenCar].veh, TRUE)
SET_VEHICLE_ON_GROUND_PROPERLY(sStolenCars[iChosenCar].veh)
ENDIF
RESET_JB700_GADGET_DATA(sCarGadgets)
SET_STOLEN_CARS_AS_LOW_LOD()
BLOCK_SCENARIOS_FOR_CHASE(TRUE)
//Lock all the cars to prevent the player from getting in
INT i = 0
REPEAT COUNT_OF(sStolenCars) i
IF i != iChosenCar
IF IS_VEHICLE_DRIVEABLE(sStolenCars[i].veh)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sStolenCars[i].veh, FALSE)
ENDIF
ENDIF
ENDREPEAT
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
bIsJumpingDirectlyToStage = FALSE
ENDIF
ENDIF
ELSE
//Reset car density and cops.
SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
SET_WANTED_LEVEL_MULTIPLIER(0.0)
SET_MAX_WANTED_LEVEL(5)
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(1.0)
ALLOW_AMBIENT_VEHICLES_TO_AVOID_ADVERSE_CONDITIONS(TRUE)
iTrevorDriveEvent = 0
iNumMollyWarnings = 0
iMollyWarningTimer = 0
iTruckWaitDialogueTimer = 0
iMollyGameplayHintTimer = 0
bPlayerIsCloseToMolly = FALSE
bMollyGameplayHintActive = FALSE
IF NOT IS_PED_INJURED(pedMolly)
TASK_LOOK_AT_ENTITY(pedMolly, PLAYER_PED_ID(), -1, SLF_WHILE_NOT_IN_FOV)
ENDIF
DO_FADE_IN_WITH_WAIT()
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
SETTIMERB(0)
iCurrentEvent = 0
eSectionStage = SECTION_STAGE_RUNNING
ENDIF
ENDIF
IF eSectionStage = SECTION_STAGE_RUNNING
#IF IS_DEBUG_BUILD
DONT_DO_J_SKIP(sLocatesData)
#ENDIF
UPDATE_TREVOR_AND_LAMAR_IN_TRUCK()
UPDATE_OIL_SLICKS()
UPDATE_JB700_GUNS(sStolenCars[iChosenCar].veh, sCarGadgets)
UPDATE_MOLLY_WAITING_BY_CAR()
IF NOT IS_PED_INJURED(pedMolly)
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_MEET")
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
//fix for B*1531732
IF PRELOAD_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_MEET", CONV_PRIORITY_MEDIUM)
BEGIN_PRELOADED_CONVERSATION()
SET_LABEL_AS_TRIGGERED("CST7_MEET", TRUE)
REPLAY_RECORD_BACK_FOR_TIME(4.0, 10.0, REPLAY_IMPORTANCE_HIGHEST)
ENDIF
//IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_MEET", CONV_PRIORITY_MEDIUM)
// SET_LABEL_AS_TRIGGERED("CST7_MEET", TRUE)
//ENDIF
ENDIF
ENDIF
IS_PLAYER_AT_LOCATION_ANY_MEANS(sLocatesData, vDropOffPos, <<0.001, 0.001, LOCATE_SIZE_HEIGHT>>, FALSE, "CH_MEETMOL", TRUE)
IF DOES_BLIP_EXIST(sLocatesData.LocationBlip)
VEHICLE_INDEX vehPlayerVehicle
SWITCH iCurrentEvent
CASE 0
IF NOT DOES_BLIP_EXIST(blipCurrentDestination)
SET_BLIP_ALPHA(sLocatesData.LocationBlip, 0)
SET_BLIP_ROUTE(sLocatesData.LocationBlip, FALSE)
blipCurrentDestination = CREATE_BLIP_FOR_ENTITY(pedMolly)
ENDIF
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<1575.005005,6446.952637,23.162960>>, <<1595.827515,6440.487305,29.378531>>, 16.0)
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
iMollyGameplayHintTimer = GET_GAME_TIMER()
bMollyGameplayHintActive = TRUE
ENDIF
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
TEXT_LABEL_23 LocalConversationRoot
LocalConversationRoot = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT()
IF NOT IS_STRING_NULL_OR_EMPTY(LocalConversationRoot)
IF ARE_STRINGS_EQUAL(LocalConversationRoot, "CST7_MEET")
KILL_FACE_TO_FACE_CONVERSATION()
ENDIF
ENDIF
ENDIF
iCurrentEvent++
ENDIF
BREAK
CASE 1
IF bMollyGameplayHintActive = TRUE
UPDATE_BLOCKED_PLAYER_FOR_LEAD_IN(TRUE)
UPDATE_MOLLY_GAMEPLAY_HINT()
ENDIF
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID(), TRUE)
IF bMollyGameplayHintActive = TRUE
IF GET_GAME_TIMER() - iMollyGameplayHintTimer > 3000
eSectionStage = SECTION_STAGE_CLEANUP
ENDIf
ENDIF
ELSE
vehPlayerVehicle = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), TRUE)
IF NOT IS_ENTITY_DEAD(vehPlayerVehicle)
IF BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(vehPlayerVehicle, 5.0, 1)
TASK_LEAVE_ANY_VEHICLE(PLAYER_PED_ID())
iCurrentEvent++
ENDIF
ENDIF
ENDIF
BREAK
CASE 2
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
iMollyGameplayHintTimer = GET_GAME_TIMER()
bMollyGameplayHintActive = TRUE
iCurrentEvent++
ENDIF
BREAK
CASE 3
IF bMollyGameplayHintActive = TRUE
UPDATE_BLOCKED_PLAYER_FOR_LEAD_IN(TRUE)
UPDATE_MOLLY_GAMEPLAY_HINT()
ENDIF
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID(), TRUE)
IF bMollyGameplayHintActive = TRUE
IF GET_GAME_TIMER() - iMollyGameplayHintTimer > 3000
eSectionStage = SECTION_STAGE_CLEANUP
ENDIf
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDIF
//Play dialogue if the player just sits by the truck.
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_NOGO")
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF iTruckWaitDialogueTimer = 0
iTruckWaitDialogueTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(6000, 9000)
ELIF GET_GAME_TIMER() - iTruckWaitDialogueTimer > 0
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_NOGO", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_NOGO", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
//Play dialogue if the player aims a gun at Molly.
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_MOLLY")
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_ENTITY_COORDS(pedMolly), << 18.0, 18.0, 18.0 >>)
IF IS_PLAYER_PLAYING(PLAYER_ID())
IF IS_PLAYER_TARGETTING_ENTITY(PLAYER_ID(), pedMolly)
OR IS_PLAYER_FREE_AIMING_AT_ENTITY(PLAYER_ID(), pedMolly)
IF HAS_ENTITY_CLEAR_LOS_TO_ENTITY_IN_FRONT(pedMolly, PLAYER_PED_ID())
IF ( GET_GAME_TIMER() - iMollyWarningTimer > 6000 )
WEAPON_TYPE eCurrentWeapon
IF GET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), eCurrentWeapon)
IF GET_WEAPONTYPE_GROUP(eCurrentWeapon) != WEAPONGROUP_MELEE
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
ADD_PED_FOR_DIALOGUE(sConversationPeds, 8, pedMolly, "MOLLY")
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_MOLLY", CONV_PRIORITY_MEDIUM)
iNumMollyWarnings++
iMollyWarningTimer = GET_GAME_TIMER()
IF ( iNumMollyWarnings = 4 )
SET_LABEL_AS_TRIGGERED("CST7_MOLLY", TRUE)
ENDIF
ENDIF
ELSE
IF NOT IS_AMBIENT_SPEECH_PLAYING(pedMolly)
PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(pedMolly, "CST7_AJAA", "MOLLY", SPEECH_PARAMS_FORCE_NORMAL)
iNumMollyWarnings++
iMollyWarningTimer = GET_GAME_TIMER()
IF ( iNumMollyWarnings = 4 )
SET_LABEL_AS_TRIGGERED("CST7_MOLLY", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
//Play dialogue if the player goes near Molly and then leaves.
IF NOT HAS_LABEL_BEEN_TRIGGERED("CST7_MOLLY1")
IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF)
IF NOT bPlayerIsCloseToMolly
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_ENTITY_COORDS(pedMolly), <<11.0, 11.0, 6.0>>)
IF HAS_LABEL_BEEN_TRIGGERED("CST7_MEET")
bPlayerIsCloseToMolly = TRUE
ENDIF
ENDIF
ELSE
IF NOT IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_ENTITY_COORDS(pedMolly), <<13.0, 13.0, 6.0>>)
ADD_PED_FOR_DIALOGUE(sConversationPeds, 8, pedMolly, "MOLLY")
IF CREATE_CONVERSATION(sConversationPeds, "CST7AUD", "CST7_MOLLY1", CONV_PRIORITY_MEDIUM)
SET_LABEL_AS_TRIGGERED("CST7_MOLLY1", TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
//Kill Molly if there's an explosion near her.
IF IS_EXPLOSION_IN_SPHERE(EXP_TAG_GRENADE, GET_ENTITY_COORDS(pedMolly), 5.0)
OR IS_EXPLOSION_IN_SPHERE(EXP_TAG_ROCKET, GET_ENTITY_COORDS(pedMolly), 5.0)
OR IS_EXPLOSION_IN_SPHERE(EXP_TAG_STICKYBOMB, GET_ENTITY_COORDS(pedMolly), 5.0)
OR IS_EXPLOSION_IN_SPHERE(EXP_TAG_TANKSHELL, GET_ENTITY_COORDS(pedMolly), 5.0)
OR IS_EXPLOSION_IN_SPHERE(EXP_TAG_MOLOTOV, GET_ENTITY_COORDS(pedMolly), 5.0)
OR IS_EXPLOSION_IN_SPHERE(EXP_TAG_GRENADELAUNCHER, GET_ENTITY_COORDS(pedMolly), 5.0)
APPLY_DAMAGE_TO_PED(pedMolly, 400, TRUE)
ENDIF
//Have Molly run off if any bullets are near her.
IF IS_BULLET_IN_AREA(GET_ENTITY_COORDS(pedMolly), 8.0, TRUE)
PLAY_PAIN(pedMolly, AUD_DAMAGE_REASON_SCREAM_SCARED)
STOP_SYNCHRONIZED_ENTITY_ANIM(pedMolly, NORMAL_BLEND_OUT, TRUE)
TASK_SMART_FLEE_PED(pedMolly, PLAYER_PED_ID(), 200.0, -1)
MISSION_FAILED(FAILED_SPOOKED_MOLLY)
ENDIF
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(pedMolly, PLAYER_PED_ID(), TRUE)
OR HAS_ENTITY_BEEN_DAMAGED_BY_ANY_VEHICLE(pedMolly)
PLAY_PAIN(pedMolly, AUD_DAMAGE_REASON_SCREAM_SCARED)
STOP_SYNCHRONIZED_ENTITY_ANIM(pedMolly, NORMAL_BLEND_OUT, TRUE)
TASK_SMART_FLEE_PED(pedMolly, PLAYER_PED_ID(), 200.0, -1)
MISSION_FAILED(FAILED_SPOOKED_MOLLY)
ENDIF
ENDIF
//Fail for the truck being destroyed.
IF NOT IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
MISSION_FAILED(FAILED_DESTROYED_TRUCK)
ENDIF
//If the trailer becomes detached the mission needs to fail.
IF NOT IS_ENTITY_DEAD(sTruck.vehFront)
IF NOT IS_VEHICLE_ATTACHED_TO_TRAILER(sTruck.vehFront)
MISSION_FAILED(FAILED_TRAILER_DETACHED)
ENDIF
ENDIF
//If the player leaves the area fail for leaving Molly.
IF NOT IS_PED_INJURED(pedMolly)
FLOAT fDistFromMolly = VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(pedMolly))
IF fDistFromMolly < DEFAULT_CUTSCENE_LOAD_DIST*DEFAULT_CUTSCENE_LOAD_DIST
REQUEST_CUTSCENE("CAR_5_EXT")
SET_CUTSCENE_PED_COMPONENT_VARIATIONS("CAR_5_EXT")
ELIF fDistFromMolly > 40000.0
MISSION_FAILED(FAILED_LEFT_MOLLY)
ENDIF
ENDIF
//If the player gets a wanted level fail for leading the cops.
IF IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
MISSION_FAILED(FAILED_LED_COPS_TO_CARS)
ENDIF
ENDIF
IF eSectionStage = SECTION_STAGE_CLEANUP
CLEAR_PRINTS()
REMOVE_ALL_BLIPS()
CLEAR_MISSION_LOCATE_STUFF(sLocatesData)
KILL_FACE_TO_FACE_CONVERSATION()
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_ALLOW_PLAYER_DAMAGE | SPC_LEAVE_CAMERA_CONTROL_ON)
SETTIMERA(0)
eSectionStage = SECTION_STAGE_SETUP
eMissionStage = STAGE_END_CUTSCENE
ENDIF
IF eSectionStage = SECTION_STAGE_SKIP
JUMP_TO_STAGE(STAGE_END_CUTSCENE, TRUE)
ENDIF
ENDPROC
PROC END_CUTSCENE()
IF eSectionStage = SECTION_STAGE_SETUP
IF bIsJumpingDirectlyToStage
IF iCurrentEvent != 99
IF SETUP_REQ_PLAYER_IS_FRANKLIN()
IF bUsedACheckpoint
START_REPLAY_SETUP(<<1542.9697, 6481.6245, 21.5820>>, 314.9911)
iCurrentEvent = 99
ELSE
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<1542.9697, 6481.6245, 21.5820>>)
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), TRUE)
LOAD_SCENE(GET_ENTITY_COORDS(PLAYER_PED_ID()))
FREEZE_ENTITY_POSITION(PLAYER_PED_ID(), FALSE)
iCurrentEvent = 99
ENDIF
ENDIF
ELSE
CLEAR_AREA_OF_VEHICLES(vDropOffPos, 50.0)
IF SETUP_REQ_SUPPRESS_CHASE_MODELS()
AND SETUP_REQ_TRUCK_UNFROZEN(<<1563.57, 6465.22, 23.96>>, 231.4902)
AND SETUP_REQ_CARS_ON_TRUCK()
AND SETUP_REQ_LAMAR(<<1522.9697, 6481.6245, 21.5820>>, 200.8915)
AND SETUP_REQ_TREVOR(<<1512.9697, 6481.6245, 21.5820>>, 204.3612)
AND SETUP_MOLLY_AND_CAR()
AND SETUP_CAR_AT_GAS_STATION()
END_REPLAY_SETUP(DEFAULT, DEFAULT, FALSE)
SUPPRESS_LARGE_VEHICLES(TRUE)
SET_ALL_SHOPS_TEMPORARILY_UNAVAILABLE(TRUE)
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
SET_PED_INTO_VEHICLE(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], sTruck.vehFront)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], TRUE)
SET_PED_MAX_HEALTH(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], 1800)
SET_ENTITY_HEALTH(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], 1800)
SET_PED_COMBAT_ATTRIBUTES(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], CA_LEAVE_VEHICLES, FALSE)
SET_PED_SUFFERS_CRITICAL_HITS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], FALSE)
ENDIF
IF NOT IS_PED_INJURED(sLamar.ped)
SET_PED_INTO_VEHICLE(sLamar.ped, sTruck.vehFront, VS_FRONT_RIGHT)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sLamar.ped, TRUE)
SET_PED_MAX_HEALTH(sLamar.ped, 1800)
SET_ENTITY_HEALTH(sLamar.ped, 1800)
SET_PED_COMBAT_ATTRIBUTES(sLamar.ped, CA_LEAVE_VEHICLES, FALSE)
SET_PED_SUFFERS_CRITICAL_HITS(sLamar.ped, FALSE)
ENDIF
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sTruck.vehFront, FALSE)
SET_ENTITY_CAN_BE_DAMAGED_BY_RELATIONSHIP_GROUP(sTruck.vehFront, FALSE, RELGROUPHASH_PLAYER)
ENDIF
IF NOT IS_ENTITY_DEAD(sTruck.vehBack)
SET_VEHICLE_DOOR_OPEN(sTruck.vehBack, SC_DOOR_BOOT)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sTruck.vehBack, FALSE)
ENDIF
IF IS_VEHICLE_DRIVEABLE(sStolenCars[iChosenCar].veh)
DETACH_ENTITY(sStolenCars[iChosenCar].veh)
SET_VEHICLE_TYRES_CAN_BURST(sStolenCars[iChosenCar].veh, FALSE)
SET_VEHICLE_STRONG(sStolenCars[iChosenCar].veh, TRUE)
SET_VEHICLE_HAS_STRONG_AXLES(sStolenCars[iChosenCar].veh, TRUE)
SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), sStolenCars[iChosenCar].veh)
SET_ENTITY_COLLISION(sStolenCars[iChosenCar].veh, TRUE)
SET_VEHICLE_ENGINE_ON(sStolenCars[iChosenCar].veh, TRUE, TRUE)
SET_ENTITY_COORDS(sStolenCars[iChosenCar].veh, <<1542.9697, 6481.6245, 21.5820>>)
SET_ENTITY_HEADING(sStolenCars[iChosenCar].veh, 231.4902)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sStolenCars[iChosenCar].veh, TRUE)
SET_VEHICLE_ON_GROUND_PROPERLY(sStolenCars[iChosenCar].veh)
ENDIF
//Lock all the cars to prevent the player from getting in
INT i = 0
REPEAT COUNT_OF(sStolenCars) i
IF i != iChosenCar
IF IS_VEHICLE_DRIVEABLE(sStolenCars[i].veh)
SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(sStolenCars[i].veh, FALSE)
ENDIF
ENDIF
ENDREPEAT
BLOCK_SCENARIOS_FOR_CHASE(TRUE)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
bIsJumpingDirectlyToStage = FALSE
ENDIF
ENDIF
ELSE
REQUEST_CUTSCENE("CAR_5_EXT")
UPDATE_BLOCKED_PLAYER_FOR_LEAD_IN(TRUE)
SET_CUTSCENE_PED_COMPONENT_VARIATIONS("CAR_5_EXT")
IF HAS_CUTSCENE_LOADED_WITH_FAILSAFE()
AND NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData)
CLEAR_PRINTS()
CLEAR_HELP()
SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED)
IF NOT IS_PED_INJURED(pedMolly)
//REGISTER_ENTITY_FOR_CUTSCENE(pedMolly, "A_F_Y_Vinewood_02", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
REGISTER_ENTITY_FOR_CUTSCENE(pedMolly, "Molly", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
TASK_CLEAR_LOOK_AT(pedMolly)
ENDIF
IF NOT IS_PED_INJURED(pedMollyDriver)
REGISTER_ENTITY_FOR_CUTSCENE(pedMollyDriver, "CAR_5_Driver", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
IF IS_VEHICLE_DRIVEABLE(vehMollyCar)
REGISTER_ENTITY_FOR_CUTSCENE(vehMollyCar, "Felon", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
ENDIF
SET_ROADS_IN_AREA(<<1547.4613, 6427.1416, 0.6085>>, <<1577.7007, 6472.8677, 58.6085>>, TRUE)
SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE)
SET_CUTSCENE_FADE_VALUES(FALSE, FALSE, FALSE, FALSE)
START_CUTSCENE()
REPLAY_RECORD_BACK_FOR_TIME(5.0, 0.0, REPLAY_IMPORTANCE_HIGHEST)
REPLAY_START_EVENT(REPLAY_IMPORTANCE_HIGHEST)
SETTIMERB(0)
sLamar.iEvent = 0
iCurrentEvent = 0
bSkippedMocap = FALSE
bClearedCarsDuringCutscene = FALSE
eSectionStage = SECTION_STAGE_RUNNING
ENDIF
ENDIF
ENDIF
IF eSectionStage = SECTION_STAGE_RUNNING
IF NOT bClearedCarsDuringCutscene
IF IS_CUTSCENE_PLAYING()
AND GET_CUTSCENE_TIME() > 55000
CLEAR_ANGLED_AREA_OF_VEHICLES(<<1570.440674,6426.117676,23.428368>>, <<1644.326172,6396.519043,35.548843>>, 17.250000)
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
bClearedCarsDuringCutscene = TRUE
ENDIF
ELSE
SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0)
ENDIF
SWITCH iCurrentEvent
CASE 0
IF IS_CUTSCENE_PLAYING()
//Remove the player's headset.
CLEAR_PED_PROP(PLAYER_PED_ID(), ANCHOR_EARS)
STOP_GAMEPLAY_HINT(TRUE)
IF NOT IS_ENTITY_DEAD(vehGasStationCar)
SET_ENTITY_HEADING(vehGasStationCar, fGasStationCarHeading)
SET_ENTITY_COORDS(vehGasStationCar, vGasStationCarPos)
ENDIF
IF NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
SET_VEHICLE_ENGINE_ON(sStolenCars[iChosenCar].veh, FALSE, FALSE)
//check if player's car is in the cutscene area and then move it away, see B*2018081
IF IS_ENTITY_AT_COORD(sStolenCars[iChosenCar].veh, <<1587.146973,6446.022949,25.640854>>, <<3.0, 6.0, 2.0>>)
SET_ENTITY_HEADING(sStolenCars[iChosenCar].veh, 231.4902)
SET_ENTITY_COORDS(sStolenCars[iChosenCar].veh, <<1542.9697, 6481.6245, 21.5820>>)
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Moving JB700 away from the cutscene area.")
ENDIF
ENDIF
IF NOT IS_ENTITY_DEAD(sTruck.vehFront)
REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(sTruck.vehFront)
ENDIF
CLEANUP_JB700_GUNS(sCarGadgets)
REMOVE_ANIM_DICT(strMollyAnims)
CLEAR_AREA(GET_ENTITY_COORDS(PLAYER_PED_ID()), 200.0, TRUE)
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
STOP_SOUND(iScrapeSound)
RELEASE_NAMED_SCRIPT_AUDIO_BANK("CAR_STEAL_4")
DO_FADE_IN_WITH_WAIT()
iCurrentEvent++
ENDIF
BREAK
CASE 1
IF WAS_CUTSCENE_SKIPPED()
SET_CUTSCENE_FADE_VALUES(FALSE, FALSE, FALSE, FALSE) //if cutscene was skipped, fade out and don't fade in
bSkippedMocap = TRUE
ENDIF
IF IS_CUTSCENE_ACTIVE()
IF IS_CUTSCENE_PLAYING()
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Franklin")
//FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_IDLE, FALSE, FAUS_CUTSCENE_EXIT)
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Molly")
IF IS_VEHICLE_DRIVEABLE(vehMollyCar)
AND NOT IS_PED_INJURED(pedMolly)
SET_PED_INTO_VEHICLE(pedMolly, vehMollyCar, VS_BACK_RIGHT)
ENDIF
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("CAR_5_Driver")
IF IS_VEHICLE_DRIVEABLE(vehMollyCar)
AND NOT IS_PED_INJURED(pedMollyDriver)
SET_PED_INTO_VEHICLE(pedMollyDriver, vehMollyCar, VS_DRIVER)
TASK_VEHICLE_DRIVE_TO_COORD_LONGRANGE(pedMollyDriver, vehMollyCar, <<133.1, 6550.4, 31.4>>, 70.0, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS, 5.0)
SET_PED_KEEP_TASK(pedMollyDriver, TRUE)
ENDIF
ENDIF
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Felon")
IF IS_VEHICLE_DRIVEABLE(vehMollyCar)
SET_VEHICLE_DOORS_SHUT(vehMollyCar, TRUE)
SET_VEHICLE_ENGINE_ON(vehMollyCar, TRUE, TRUE)
SET_ENTITY_HEADING(vehMollyCar, 152.2173)
SET_ENTITY_COORDS(vehMollyCar, <<1589.9984, 6438.8867, 24.1705>>)
SET_VEHICLE_FORWARD_SPEED(vehMollyCar, 7.5) //slow down the car a bit to help with erratic driving on the nodes, see B*2018120
ENDIF
ENDIF
ELSE
IF HAS_CUTSCENE_FINISHED()
REMOVE_PED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], TRUE)
REMOVE_PED(sLamar.ped, TRUE)
INT i
REPEAT COUNT_OF(sStolenCars) i
REMOVE_VEHICLE(sStolenCars[i].veh, TRUE)
ENDREPEAT
REMOVE_VEHICLE(sTruck.vehBack, TRUE)
REMOVE_VEHICLE(sTruck.vehFront, TRUE)
IF ( bSkippedMocap = TRUE )
REMOVE_PED(pedMolly, TRUE)
REMOVE_PED(pedMollyDriver, TRUE)
REMOVE_VEHICLE(vehMollyCar, TRUE)
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<1586.3639, 6446.7622, 24.1461>>)
SET_ENTITY_HEADING(PLAYER_PED_ID(), 160.0188)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
ENDIF
SET_SCRIPTS_SAFE_FOR_CUTSCENE(FALSE)
REPLAY_STOP_EVENT()
SETTIMERB(0)
iCurrentEvent++
ENDIF
ENDIF
BREAK
CASE 2
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ENTER)
IF TIMERB() > 3000
OR bSkippedMocap
eSectionStage = SECTION_STAGE_CLEANUP
ENDIF
BREAK
ENDSWITCH
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
AND IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
SWITCH sLamar.iEvent
CASE 0
REQUEST_VEHICLE_RECORDING(CARREC_TRUCK_FINAL_CUTSCENE, strCarrec)
IF IS_CUTSCENE_PLAYING()
AND HAS_VEHICLE_RECORDING_BEEN_LOADED(CARREC_TRUCK_FINAL_CUTSCENE, strCarrec)
AND GET_CUTSCENE_TIME() > 29000
//detach trailer from truck when cutscene starts
DETACH_VEHICLE_FROM_TRAILER(sTruck.vehFront)
//attach jb700 to trailer if not attached
IF DOES_ENTITY_EXIST(sStolenCars[iChosenCar].veh)
IF NOT IS_ENTITY_DEAD(sStolenCars[iChosenCar].veh)
IF NOT IS_VEHICLE_ATTACHED_TO_TRAILER(sStolenCars[iChosenCar].veh)
ATTACH_VEHICLE_ON_TO_TRAILER(sStolenCars[iChosenCar].veh, sTruck.vehBack, <<0.0, 0.0, 0.0>>, sStolenCars[iChosenCar].vTruckOffset, sStolenCars[iChosenCar].vTruckRotation, -1.0)
ENDIF
SET_VEHICLE_TYRES_CAN_BURST(sStolenCars[iChosenCar].veh, FALSE)
SET_VEHICLE_STRONG(sStolenCars[iChosenCar].veh, TRUE)
SET_VEHICLE_HAS_STRONG_AXLES(sStolenCars[iChosenCar].veh, TRUE)
SET_HORN_ENABLED(sStolenCars[iChosenCar].veh, FALSE)
ENDIF
ENDIF
//start recording on the truck with playback speed of 0
SET_VEHICLE_ENGINE_ON(sTruck.vehFront, TRUE, TRUE)
START_PLAYBACK_RECORDED_VEHICLE(sTruck.vehFront, CARREC_TRUCK_FINAL_CUTSCENE, strCarrec)
FORCE_PLAYBACK_RECORDED_VEHICLE_UPDATE(sTruck.vehFront, FALSE)
SET_PLAYBACK_SPEED(sTruck.vehFront, 0.0)
SET_VEHICLE_DOOR_SHUT(sTruck.vehBack, SC_DOOR_BOOT)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sSelectorPeds.pedID[SELECTOR_PED_TREVOR], TRUE)
sLamar.iEvent++
ENDIF
BREAK
CASE 1
//attach trailer to truck if not attached during cutscene
IF NOT IS_VEHICLE_ATTACHED_TO_TRAILER(sTruck.vehFront)
SET_ENTITY_COORDS_NO_OFFSET(sTruck.vehBack, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sTruck.vehFront, <<0.191836, -9.89637, 0.27933>>))
SET_ENTITY_HEADING(sTruck.vehBack, GET_ENTITY_HEADING(sTruck.vehFront))
ATTACH_VEHICLE_TO_TRAILER(sTruck.vehFront, sTruck.vehBack)
SET_VEHICLE_DOOR_SHUT(sTruck.vehBack, SC_DOOR_BOOT)
ACTIVATE_PHYSICS(sTruck.vehBack)
ENDIF
IF GET_CUTSCENE_TIME() > 49000
SET_VEHICLE_DOOR_SHUT(sTruck.vehBack, SC_DOOR_BOOT)
SET_PLAYBACK_SPEED(sTruck.vehFront, 1.0)
sLamar.iEvent++
ENDIF
BREAK
CASE 2
BREAK
ENDSWITCH
ENDIF
ENDIF
IF eSectionStage = SECTION_STAGE_CLEANUP
CLEAR_PRINTS()
CLEAR_HELP()
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
SET_ROADS_BACK_TO_ORIGINAL(<<1547.4613, 6427.1416, 0.6085>>, <<1577.7007, 6472.8677, 58.6085>>)
IF IS_SCREEN_FADED_OUT()
DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME)
ENDIF
MISSION_PASSED()
ENDIF
IF eSectionStage = SECTION_STAGE_SKIP
STOP_CUTSCENE()
WHILE IS_CUTSCENE_ACTIVE()
WAIT(0)
ENDWHILE
bSkippedMocap = TRUE
eSectionStage = SECTION_STAGE_RUNNING
ENDIF
ENDPROC
#IF IS_DEBUG_BUILD
PROC UPDATE_WIDGETS()
IF bDebugRecordTruckAndTrailerForMocap
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
AND NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF NOT IS_RECORDING_GOING_ON_FOR_VEHICLE(sTruck.vehFront)
START_RECORDING_VEHICLE(sTruck.vehFront, 2, "Truck_trailer", TRUE)
PRINT_STRING_WITH_LITERAL_STRING_NOW("STRING", "RECORDING STARTED", DEFAULT_GOD_TEXT_TIME, 0)
ENDIF
IF NOT IS_RECORDING_GOING_ON_FOR_VEHICLE(sTruck.vehBack)
START_RECORDING_VEHICLE(sTruck.vehBack, 3, "Truck_trailer", TRUE)
ENDIF
ENDIF
ELSE
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
AND NOT IS_ENTITY_DEAD(sTruck.vehBack)
IF IS_RECORDING_GOING_ON_FOR_VEHICLE(sTruck.vehFront)
STOP_RECORDING_VEHICLE(sTruck.vehFront)
PRINT_STRING_WITH_LITERAL_STRING_NOW("STRING", "RECORDING STOPPED", DEFAULT_GOD_TEXT_TIME, 0)
ENDIF
IF IS_RECORDING_GOING_ON_FOR_VEHICLE(sTruck.vehBack)
STOP_RECORDING_VEHICLE(sTruck.vehBack)
ENDIF
ENDIF
ENDIF
IF bDebugPlaybackTruckTrailerForMocap
REQUEST_VEHICLE_RECORDING(2, "Truck_trailer")
REQUEST_VEHICLE_RECORDING(3, "Truck_trailer")
IF HAS_VEHICLE_RECORDING_BEEN_LOADED(2, "Truck_trailer")
AND HAS_VEHICLE_RECORDING_BEEN_LOADED(3, "Truck_trailer")
IF IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
AND NOT IS_ENTITY_DEAD(sTruck.vehBack)
SET_ENTITY_COLLISION(sTruck.vehFront, FALSE)
SET_ENTITY_COLLISION(sTruck.vehBack, FALSE)
START_PLAYBACK_RECORDED_VEHICLE(sTruck.vehFront, 2, "Truck_trailer")
START_PLAYBACK_RECORDED_VEHICLE(sTruck.vehBack, 3, "Truck_trailer")
FORCE_PLAYBACK_RECORDED_VEHICLE_UPDATE(sTruck.vehFront)
FORCE_PLAYBACK_RECORDED_VEHICLE_UPDATE(sTruck.vehBack)
SET_PLAYBACK_SPEED(sTruck.vehFront, 0.0)
SET_PLAYBACK_SPEED(sTruck.vehBack, 0.0)
bDebugPlaybackTruckTrailerForMocap = FALSE
ENDIF
ENDIF
ENDIF
IF bDebugUpdateVehLODs
INT i = 0
REPEAT COUNT_OF(sStolenCars) i
IF NOT IS_ENTITY_DEAD(sStolenCars[i].veh)
IF sStolenCars[i].model != JB700
AND sStolenCars[i].model != MONROE
SET_VEHICLE_LOD_MULTIPLIER(sStolenCars[i].veh, fDebugLODMultiplier)
SET_ENTITY_LOD_DIST(sStolenCars[i].veh, iDebugLODDist)
ENDIF
ENDIF
ENDREPEAT
bDebugUpdateVehLODs = FALSE
ENDIF
ENDPROC
PROC DO_DEBUG()
UPDATE_WIDGETS()
//Reset any skipping from the previous frame
IF eSectionStage = SECTION_STAGE_SKIP
eSectionStage = SECTION_STAGE_RUNNING
ENDIF
IF eSectionStage = SECTION_STAGE_RUNNING
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S)
MISSION_PASSED()
ELIF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F)
MISSION_FAILED(FAILED_GENERIC)
ELIF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J)
eSectionStage = SECTION_STAGE_SKIP
ELIF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P)
//Work out which stage we want to reach based on the current stage
INT iCurrentStage = ENUM_TO_INT(eMissionStage)
IF iCurrentStage > 0
MISSION_STAGE eStage = INT_TO_ENUM(MISSION_STAGE, iCurrentStage - 1)
JUMP_TO_STAGE(eStage, TRUE)
ENDIF
ELIF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_NUMPAD1)
OUTPUT_DEBUG_CAM_RELATIVE_TO_ENTITY(GET_FOCUS_ENTITY_INDEX())
ENDIF
IF LAUNCH_MISSION_STAGE_MENU(sSkipMenu, iDebugJumpStage)
PRINTLN("carsteal4.sc - player used a Z-skip: ", iDebugJumpStage)
MISSION_STAGE eStage = INT_TO_ENUM(MISSION_STAGE, iDebugJumpStage)
JUMP_TO_STAGE(eStage, TRUE)
ENDIF
ENDIF
ENDPROC
#ENDIF
SCRIPT
SET_MISSION_FLAG(TRUE)
IF HAS_FORCE_CLEANUP_OCCURRED()
Mission_Flow_Mission_Force_Cleanup()
MISSION_CLEANUP()
ENDIF
MISSION_SETUP()
IF Is_Replay_In_Progress()
INT iStage = Get_Replay_Mid_Mission_Stage()
IF g_bShitskipAccepted
iStage++
ENDIF
IF iStage = 0
JUMP_TO_STAGE(STAGE_START_PHONECALL)
ELIF iStage = CHECKPOINT_MEET_TREVOR
JUMP_TO_STAGE(STAGE_COLLECT_FINAL_CAR)
bShitSkippedIntoFinalCar = TRUE
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_ENTITYXF, BUILDINGSTATE_NORMAL, FALSE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_CHEETAH, BUILDINGSTATE_NORMAL, FALSE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_ZTYPE, BUILDINGSTATE_NORMAL, FALSE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_CARSTEAL_JB700, BUILDINGSTATE_NORMAL, FALSE)
ELIF iStage = CHECKPOINT_GO_TO_GAS
JUMP_TO_STAGE(STAGE_GO_TO_DROP_OFF)
ELIF iStage = CHECKPOINT_COPS_ARRIVE
JUMP_TO_STAGE(STAGE_COPS_ARRIVE)
ELIF iStage = CHECKPOINT_LOSE_COPS
JUMP_TO_STAGE(STAGE_ESCORT_TRUCK)
ELIF iStage > CHECKPOINT_LOSE_COPS
JUMP_TO_STAGE(STAGE_END_CUTSCENE)
ENDIF
bUsedACheckpoint = TRUE
ELSE
SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(0, "START_PHONE_CALL")
ENDIF
IF IS_REPLAY_IN_PROGRESS()
OR IS_REPEAT_PLAY_ACTIVE()
IF IS_SCREEN_FADED_OUT()
SET_WEATHER_TYPE_NOW_PERSIST("EXTRASUNNY") //set weather type to extrasunny for this mission, see TODO B*1493539
ENDIF
ENDIF
WHILE (TRUE)
WAIT(0)
//Reset the checkpoint flag once the mission is running again. This flag is used to determine if we jumped using a checkpoint or via Z-skip,
//as some bits of setup are only done when debug skipping (e.g. giving the player weapons).
IF bUsedACheckpoint
IF eSectionStage = SECTION_STAGE_RUNNING
bUsedACheckpoint = FALSE
ENDIF
ENDIF
//Global fail conditions
IF DOES_ENTITY_EXIST(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
IF IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
MISSION_FAILED(FAILED_KILLED_FRANKLIN)
ENDIF
ENDIF
IF DOES_ENTITY_EXIST(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
IF IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
MISSION_FAILED(FAILED_KILLED_TREVOR)
ENDIF
ENDIF
IF DOES_ENTITY_EXIST(sLamar.ped)
IF IS_PED_INJURED(sLamar.ped)
MISSION_FAILED(FAILED_LAMAR_DIED)
ENDIF
ENDIF
IF DOES_ENTITY_EXIST(sTruck.vehBack)
IF IS_ENTITY_DEAD(sTruck.vehBack) //Trailer can never be driveable so check for dead instead
MISSION_FAILED(FAILED_DESTROYED_TRUCK)
ELSE
SET_VEHICLE_WILL_FORCE_OTHER_VEHICLES_TO_STOP(sTruck.vehBack, TRUE)
ENDIF
ENDIF
IF DOES_ENTITY_EXIST(sTruck.vehFront)
IF NOT IS_VEHICLE_DRIVEABLE(sTruck.vehFront)
MISSION_FAILED(FAILED_DESTROYED_TRUCK)
ELSE
IF IS_VEHICLE_PERMANENTLY_STUCK(sTruck.vehFront)
OR IS_VEHICLE_STUCK_TIMER_UP(sTruck.vehBack, VEH_STUCK_ON_ROOF, ROOF_TIME)
OR IS_VEHICLE_STUCK_TIMER_UP(sTruck.vehBack, VEH_STUCK_HUNG_UP, HUNG_UP_TIME)
OR IS_VEHICLE_STUCK_TIMER_UP(sTruck.vehBack, VEH_STUCK_ON_SIDE, SIDE_TIME)
MISSION_FAILED(FAILED_TRUCK_STUCK)
ENDIF
SET_VEHICLE_WILL_FORCE_OTHER_VEHICLES_TO_STOP(sTruck.vehFront, TRUE)
ENDIF
ENDIF
IF DOES_ENTITY_EXIST(pedMolly)
IF IS_PED_INJURED(pedMolly)
MISSION_FAILED(FAILED_MOLLY_DIED)
ENDIF
ENDIF
IF DOES_ENTITY_EXIST(vehMollyCar)
IF NOT IS_VEHICLE_DRIVEABLE(vehMollyCar)
MISSION_FAILED(FAILED_MOLLYS_CAR_DESTROYED)
ENDIF
ENDIF
INT i = 0
INT iNumCarsDead = 0
REPEAT COUNT_OF(sStolenCars) i
IF DOES_ENTITY_EXIST(sStolenCars[i].veh)
IF NOT IS_VEHICLE_DRIVEABLE(sStolenCars[i].veh)
iNumCarsDead++
ELSE
IF eMissionStage = STAGE_COLLECT_FINAL_CAR OR eMissionStage = STAGE_ESCORT_TRUCK
IF NOT IS_ENTITY_ATTACHED(sStolenCars[i].veh)
BOOL bSafeToCheck = TRUE
//For the escort truck stage only check on the JB700
IF eMissionStage = STAGE_ESCORT_TRUCK
AND i = iChosenCar
bSafeToCheck = TRUE
ENDIF
IF IS_VEHICLE_PERMANENTLY_STUCK(sStolenCars[i].veh)
AND bSafeToCheck
MISSION_FAILED(FAILED_CAR_STUCK)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
IF iNumCarsDead > 0
IF iNumCarsDead = 1
MISSION_FAILED(FAILED_DESTROYED_CAR)
ELIF iNumCarsDead = COUNT_OF(sStolenCars)
MISSION_FAILED(FAILED_DESTROYED_ALL_CARS)
ELSE
MISSION_FAILED(FAILED_DESTROYED_SOME_CARS)
ENDIF
ENDIF
//Disable cargens after the first stage to help streaming.
IF eMissionStage > STAGE_COLLECT_FINAL_CAR
IF NOT IS_VEHCILE_GEN_DISABLED_ON_MISSION()
DISABLE_VEHICLE_GEN_ON_MISSION(TRUE)
ENDIF
ENDIF
IF IS_PED_SITTING_IN_ANY_VEHICLE(PLAYER_PED_ID())
//Track the vehicle speed/damage stat.
VEHICLE_INDEX veh = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
IF NOT IS_ENTITY_DEAD(veh)
IF NOT DOES_ENTITY_EXIST(g_MissionStatSingleSpeedWatchEntity)
OR (IS_ENTITY_A_VEHICLE(g_MissionStatSingleSpeedWatchEntity) AND GET_VEHICLE_INDEX_FROM_ENTITY_INDEX(g_MissionStatSingleSpeedWatchEntity) != veh)
INFORM_MISSION_STATS_OF_SPEED_WATCH_ENTITY(veh)
ENDIF
IF veh != sTruck.vehFront
IF eMissionStage > STAGE_GO_TO_DROP_OFF
IF NOT DOES_ENTITY_EXIST(g_MissionStatSingleDamageWatchEntity)
OR (IS_ENTITY_A_VEHICLE(g_MissionStatSingleDamageWatchEntity) AND GET_VEHICLE_INDEX_FROM_ENTITY_INDEX(g_MissionStatSingleDamageWatchEntity) != veh)
IF IS_VEHICLE_DRIVEABLE(veh)
AND IS_VEHICLE_MODEL(veh, JB700)
INFORM_MISSION_STATS_OF_DAMAGE_WATCH_ENTITY(veh)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
#IF IS_DEBUG_BUILD
IF bDebugPrintTruckAndTrailerPos
IF NOT IS_ENTITY_DEAD(sTruck.vehFront)
AND NOT IS_ENTITY_DEAD(sTruck.vehBack)
PRINTVECTOR(GET_ENTITY_COORDS(sTruck.vehFront))
PRINTSTRING(" ")
PRINTVECTOR(GET_ENTITY_COORDS(sTruck.vehBack))
PRINTSTRING(" ")
PRINTVECTOR(GET_ENTITY_ROTATION(sTruck.vehFront))
PRINTSTRING(" ")
PRINTVECTOR(GET_ENTITY_ROTATION(sTruck.vehBack))
PRINTNL()
ENDIF
ENDIF
#ENDIF
//REPEAT COUNT_OF(sStolenCars) i
// VECTOR vPos = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(sTruck.vehBack, GET_ENTITY_COORDS(sStolenCars[i].veh))
// PRINTLN(i, " ", vPos)
//ENDREPEAT
REPLAY_CHECK_FOR_EVENT_THIS_FRAME("M_PackMan")
IF iReplayCameraWarpTimer > GET_GAME_TIMER()
REPLAY_DISABLE_CAMERA_MOVEMENT_THIS_FRAME() //Fix for bug 2229446
ENDIF
SWITCH eMissionStage
CASE STAGE_START_PHONECALL
START_PHONECALL()
BREAK
CASE STAGE_COLLECT_FINAL_CAR
COLLECT_FINAL_CAR()
BREAK
CASE STAGE_GET_IN_TRUCK_CUTSCENE
GET_IN_TRUCK_CUTSCENE()
BREAK
CASE STAGE_GO_TO_DROP_OFF
CASE STAGE_COPS_ARRIVE
GO_TO_DROP_OFF_LOCATION()
BREAK
CASE STAGE_ESCORT_TRUCK
ESCORT_TRUCK()
BREAK
CASE STAGE_MEET_MOLLY
MEET_MOLLY()
BREAK
CASE STAGE_END_CUTSCENE
END_CUTSCENE()
BREAK
ENDSWITCH
#IF IS_DEBUG_BUILD
DO_DEBUG()
UPDATE_SPLINE_CAM_WIDGETS(scsTruckToCar)
#ENDIF
ENDWHILE
ENDSCRIPT