//|=======================================================================================| //| Author: Lukasz Bogaj / Jim McMahon Date: 28/11/2011 | //|=======================================================================================| //| FAMILY3.sc | //| MARRIAGE COUNSELLING | //| | //|=======================================================================================| //Compile out Title Update changes to header functions. //Must be before includes. //CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R. //|==================================== INCLUDE FILES ====================================| USING "rage_builtins.sch" USING "globals.sch" //Commands headers USING "commands_fire.sch" USING "commands_script.sch" USING "commands_pad.sch" USING "commands_object.sch" USING "commands_misc.sch" USING "commands_player.sch" USING "commands_streaming.sch" USING "commands_camera.sch" USING "Commands_clock.sch" USING "Commands_interiors.sch" USING "commands_cutscene.sch" USING "commands_physics.sch" USING "commands_entity.sch" USING "commands_recording.sch" //Script headers USING "script_player.sch" USING "script_blips.sch" USING "script_ped.sch" //Public headers USING "dialogue_public.sch" USING "cellphone_public.sch" USING "locates_public.sch" USING "chase_hint_cam.sch" USING "flow_public_game.sch" USING "flow_public_core_override.sch" USING "stats_public.sch" USING "replay_public.sch" USING "cutscene_public.sch" USING "mission_stat_public.sch" USING "selector_public.sch" USING "building_control_public.sch" USING "clearMissionArea.sch" USING "taxi_functions.sch" USING "vehicle_gen_public.sch" USING "carsteal_public.sch" USING "flow_help_public.sch" USING "respawn_location_private.sch" USING "emergency_call.sch" USING "buddy_head_track_public.sch" USING "cellphone_public.sch" //================================ UBER PLAYBACK CONSTANTS ===============================| //Replace the default uber playback values stored in "traffic_default_values.sch" //total should not exceed 225 CONST_INT TOTAL_NUMBER_OF_TRAFFIC_CARS 150 CONST_INT TOTAL_NUMBER_OF_PARKED_CARS 50 CONST_INT TOTAL_NUMBER_OF_SET_PIECE_CARS 25 //total should not exceed 12 CONST_INT MAX_NUMBER_OF_TRAFFIC_CARS_PLAYING_BACK 14 CONST_INT MAX_NUMBER_OF_SET_PIECE_CARS_PLAYING_BACK 21 //this should be fine CONST_INT MAX_NUMBER_OF_PARKED_CARS_PLAYING_BACK 6 //============================== END UBER PLAYBACK CONSTANTS =============================| USING "traffic.sch" //Debug headers #IF IS_DEBUG_BUILD USING "script_debug.sch" USING "select_mission_stage.sch" #ENDIF //===================================== ENUMS & STRUCTS ==================================| /// PURPOSE: Specifies stages of the mission. ENUM MISSION_STAGES MISSION_STAGE_CUTSCENE_INTRO = 0, //Intro cutscene MISSION_STAGE_CAR_CHASE = 1, //Michael and Franklin chase after tennis coach MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE = 2, //Cutscene taking place at the back of the house MISSION_STAGE_PULL_HOUSE_DOWN = 3, //Michael and Franklin pull the house down MISSION_STAGE_ESCAPE_GOONS = 4, //Michael and Franklin escape goons chasing them after pulling the house down MISSION_STAGE_CUTSCENE_END = 5, //End cutscene MISSION_STAGE_LEADOUT = 6, //Mission lead out, Michael is seen making a phone call to Lester after mission pass #IF IS_DEBUG_BUILD MISSION_STAGE_DEBUG_RECORD_CHASE = 7, //Debug stage to record the car chase MISSION_STAGE_DEBUG_PLAYBACK_CHASE = 8, //Debug stage to playback car chase #ENDIF MISSION_STAGE_PASSED, //Mission passed MISSION_STAGE_FAILED //Mission failed ENDENUM /// PURPOSE: Specifies mission fail reasons. ENUM MISSION_FAILS MISSION_FAIL_EMPTY = 0, //Generic fail MISSION_FAIL_CAR_DESTROYED, //Mission car destroyed MISSION_FAIL_CAR_STUCK, //Mission car stuck MISSION_FAIL_MICHAEL_DEAD, //Michael killed MISSION_FAIL_MICHAEL_LEFT_BEHIND, //Michael left behind MISSION_FAIL_FRANKLIN_DEAD, //Franklin killed MISSION_FAIL_FRANKLIN_LEFT_BEHIND, //Franklin left behind MISSION_FAIL_COACH_DEAD, //Tennis coach killed MISSION_FAIL_COACH_ATTACKED, //Tennis coach attacked MISSION_FAIL_COACH_SPOOKED, //Tennis coach spooked MISSION_FAIL_FORCE_FAIL, //Debug forced fail MAX_MISSION_FAILS ENDENUM /// PURPOSE: Specifies mid-mission checkpoints for mission retry. ENUM MID_MISSION_STAGES MID_MISSION_STAGE_CAR_CHASE = 0, //Checkpoint at MISSION_STAGE_CAR_CHASE MID_MISSION_STAGE_PULL_HOUSE_DOWN = 1, //Checkpoint at MISSION_STAGE_PULL_HOUSE_DOWN MID_MISSION_STAGE_ESCAPE_GOONS = 2, //Checkpoint at MISSION_STAGE_ESCAPE_GOONS MID_MISSION_STAGE_DRIVE_HOME = 3 //Checkpoint at MISSION_STAGE_DRIVE_HOME ENDENUM ENUM PED_STATES PED_STATE_IDLE = 0, PED_STATE_ON_FOOT, PED_STATE_ENTERING_VEHICLE, PED_STATE_SITTING_IN_VEHICLE_PASSENGER, PED_STATE_SITTING_IN_VEHICLE_DRIVER, PED_STATE_SHUFFLING_VEHICLE_SEATS, PED_STATE_LOOKING_BEHIND_IN_VEHICLE, PED_STATE_COMBAT_ON_FOOT, PED_STATE_COMBAT_FROM_CAR_NO_SHOOTING, PED_STATE_COMBAT_FROM_CAR_SHOOTING, PED_STATE_DRIVE_FLEE_TARGETS, PED_STATE_DRIVE_FLEE_COPS, PED_STATE_DRIVE_TO_DESTINATION, PED_STATE_FOLLOWING_PLAYER, PED_STATE_WAITING_FOR_PLAYER, PED_STATE_WAITING_FOR_TASK_AFTER_SWITCH ENDENUM ENUM FRANKLIN_CAR_ANIMATIONS FCA_BRACE_START = 1, FCA_BRACE_LOOP = 2, FCA_BRACE_EXIT = 3, FCA_BUMPS_LOOP = 4 ENDENUM ENUM CHASE_FINISHED_REASONS CHASE_FINISHED_TARGET_LOST = 0, CHASE_FINISHED_END_REACHED = 1 ENDENUM ENUM PED_CLEANUP_REASONS PED_CLEANUP_NO_CLEANUP = 0, PED_CLEANUP_LOST = 1, PED_CLEANUP_KILLED_BY_MICHAEL = 2, PED_CLEANUP_KILLED_BY_FRANKLIN = 3, PED_CLEANUP_KILLED_BY_VEHICLE = 4, PED_CLEANUP_KILLED_BY_PLAYER_AS_MICHAEL = 5, PED_CLEANUP_KILLED_BY_PLAYER_AS_FRANKLIN = 6 ENDENUM /// PURPOSE: Specifies details of mission peds. STRUCT PED_STRUCT PED_INDEX PedIndex //Ped Index BLIP_INDEX BlipIndex //Ped's Blip Index VECTOR vPosition //Ped's start location FLOAT fHeading //Ped's start heading MODEL_NAMES ModelName //Ped's model INT iTimer //Ped's timer INT iAgressiveTimer //Ped's timer to become aggressive INT iConversationTimer //Ped's conversation timer INT iConversationCounter //Ped's conversation counter INT iProgress //Ped's progress INT iCleanupAttempts BOOL bHasTask BOOL bCleanupConversationTriggered FLOAT fDistanceToTarget PED_STATES eState PED_CLEANUP_REASONS eCleanupReason #IF IS_DEBUG_BUILD TEXT_LABEL_31 sDebugName #ENDIF ENDSTRUCT /// PURPOSE: Specifies details of mission vehicles. STRUCT VEH_STRUCT VEHICLE_INDEX VehicleIndex //Vehicle index BLIP_INDEX BlipIndex //Vehicle blip VECTOR vPosition //Vehicle postion FLOAT fHeading //Vehicle heading MODEL_NAMES ModelName //Vehicle model INT iProgress //Vehicle progress counter INT iTimer //Vehicle timer INT iRecordingNumber //Vehicle recording number FLOAT fPlaybackSpeed //Vehicle recording playback speed BOOL bAutoDrive //Vehicle using auto driving BOOL bLOSFlag //Vehicle line of sight flag INT iWarpTimer VECTOR vWarpOffset VECTOR vTargetPosition FLOAT fTargetHeading FLOAT fDistanceToTarget #IF IS_DEBUG_BUILD TEXT_LABEL_63 sDebugName #ENDIF ENDSTRUCT STRUCT OBJECT_STRUCT OBJECT_INDEX ObjectIndex //ObjectIndex VECTOR vPosition //Object position VECTOR vRotation //Object rotation MODEL_NAMES ModelName //Object model name ENDSTRUCT /// PURPOSE: Contains player postion, heading and destination. STRUCT LOCATION_STRUCT BLIP_INDEX DestinationBlip VECTOR vPosition FLOAT fHeading ENDSTRUCT //|======================================= CONSTANTS =====================================| //asset requirements CONST_INT MAX_MODELS 8 CONST_INT MAX_CAR_RECORDINGS 6 CONST_INT MAX_ANIMATIONS 1 CONST_INT MAX_BUDDY_PED_HEALTH 400 TWEAK_FLOAT BLIP_SLIDE_AMOUNT 1.1 //1.0 TWEAK_FLOAT fForceConverge 0.5 TWEAK_FLOAT fSideForceValue 130.0 TWEAK_FLOAT fDownForceValue 450.0 TWEAK_FLOAT fFirstPersonFlashPhase1 0.900 TWEAK_FLOAT fFirstPersonFlashPhase2 0.500 TWEAK_FLOAT fFirstPersonFlashPhase3 0.900 TWEAK_INT iTennisCoachHintDuration 9500 TWEAK_INT iFirstPersonFlashTime 300 CONST_FLOAT CHASE_TARGET_LOST_DISTANCE 250.0 CONST_FLOAT ROPE_MAX_LEN 28.0 STRING ROPE_DATA_FILE = "ropeFamily3" VECTOR vInteriorPosition = << -813.80, 179.23, 71.16 >> //room: V_Michael_G_Front VECTOR vVanLocateSize = << 40.0, 40.0, 40.0 >> //<< 37.5, 37.5, 37.5 >> VECTOR vUnderBalconyPosition = << -991.65, 645.38, 138.64 >> VECTOR vMichaelsHousePosition = << -822.26, 182.90, 70.90 >> VECTOR vTennisCoachHintPosition = << -977.222, 634.37, 156.00 >> //<< -1035.22, 653.37, 154.92 >> VECTOR vBalconyHintPosition = << -1015.8, 656.4, 149.2 >> STRING sVehicleRecordingsFile = "famthree" #IF IS_DEBUG_BUILD STRING sUberRecordingFile = "ft" //"fam3" //"famthree" #ENDIF VECTOR vRearLeftWheelOffset = << -0.875, -1.75, -0.475 >> VECTOR vRearRightWheelOffset = << 0.875, -1.75, -0.475 >> VECTOR vPTFXRotation = << 0.0, 0.0, 0.0 >> VECTOR vForceBackOffset = << 0.0, -2.6, 0.20 >> TEXT_LABEL sLabelGIT = "FAM3_GIT" TEXT_LABEL sLabelDCAN = "FAM3_DCAN" TEXT_LABEL sLabelDHOUSE = "FAM3_DHOUSE" TEXT_LABEL sLabelGETBCK = "FAM3_GBIT" TEXT_LABEL sLabelFLEAVE = "CMN_FLEAVE" TEXT_LABEL sLabelMLEAVE = "CMN_MLEAVE" TEXT_LABEL sLabelLWANTED = "LOSE_WANTED" //|======================================= VARIABLES =====================================| MISSION_STAGES eMissionStage = MISSION_STAGE_CUTSCENE_INTRO MISSION_FAILS eMissionFail = MISSION_FAIL_EMPTY CHASE_FINISHED_REASONS eChaseFinishReason = CHASE_FINISHED_TARGET_LOST REL_GROUP_HASH rgEnemies REL_GROUP_HASH rgTennisCoach //mission peds PED_STRUCT psFranklin PED_STRUCT psMichael PED_STRUCT psCoach PED_STRUCT psVanDriver //mission vehicles VEH_STRUCT vsMichaelsEndCar VEH_STRUCT vsPlayersCar VEH_STRUCT vsCoachsCar VEH_STRUCT vsVan VEH_STRUCT vsCutsceneCar OBJECT_STRUCT osRacket01 OBJECT_STRUCT osRacket02 OBJECT_STRUCT osCellphone OBJECT_STRUCT osRopeDummy OBJECT_STRUCT osRopeAnchor OBJECT_STRUCT osRopeProp OBJECT_STRUCT osBootCollision OBJECT_STRUCT osBrokenPlantPot //switch data BOOL bAllowHotSwap BOOL bHotSwapHinted BOOL bHotSwapTriggered INT iHotSwapHintTimer SELECTOR_PED_STRUCT sSelectorPeds SELECTOR_CAM_STRUCT sCamDetails //locates header data LOCATES_HEADER_DATA sLocatesData CHASE_HINT_CAM_STRUCT localChaseHintCamStruct //conversation struct structPedsForConversation sFamily3Conversation INT iRandomLinesTriggered //progress counters and flags for loading, skipping and replays INT iStageSetupProgress INT iMissionStageProgress BOOL bSkipFlag BOOL bReplayFlag BOOL bLoadingFlag //asset request counters INT iModelsRequested INT iRecordingsRequested INT iAnimationsRequested //text printing INT iTriggeredTextHashes[30] INT iNumTextHashesStored //scripted cutscene & rayfire INT iSyncedSceneCoachID INT iScriptedCameraProgress CAMERA_INDEX ScriptedCamera RAYFIRE_INDEX riHouseFallRayfire RAYFIRE_INDEX riFrenchDoorRayfire ROPE_INDEX Rope BOOL bRopeAttached BOOL bHousePullStarted BOOL bHousePullCompleted INT iRayfireMapObjectProgress INT iRayfireSequenceProgress FLOAT fRayfirePhase BOOL bRayfirePrimed BOOL bRayfireStarted BOOL bRayfirePaused BOOL bRayfireFinished FLOAT fCameraShakeAmplitude FLOAT fWheelspinValue BOOL bPTFXStarted PTFX_ID ptfxRearLeftWheel PTFX_ID ptfxRearRightWheel PTFX_ID ptfxDustCloud INT iConversationProgress INT iConversationIdleTimer INT iGoonsChaseDelayTimer INT iVehicleSwitchTimer INT iVehicleImpactSoundTimer BOOL bPhoneCallInterruptedByPlayer BOOL bCustomRouteActive BOOL bShouldUseDefaultRoute BOOL bRunLocatesHeaderCheck BOOL bDisplayDestinationBlip BOOL bStartGoonTimerDelay TEXT_LABEL_23 lConversationLabel = "" TEXT_LABEL_23 lConversationRoot = "" BOOL bConversationPaused BOOL bCoachLostConversationStarted BOOL bPlayerCrashedIntoVan BOOL bChaseInProgress BOOL bChaseFinished BOOL bCoachVisible BOOL bCoachSpotted BOOL bMichaelStartedShouting BOOL bSpotConversationFinished BOOL bRecordingPlaybackStarted BOOL bCutsceneSkipped BOOL bCutsceneAssetsRequested BOOL bTruckRepositionedForCutscene BOOL bAllowConvsersationOutsideOfCar BOOL bStopScriptedConversations BOOL bStatConversationFinished BOOL bVanDriverCrashSpeechTriggered FLOAT fChaseDistanceFromPlayerToCoach FLOAT fChaseSpeed = 0.65 //initialise to uber chase start speed value FLOAT fChaseTime BOOL bRandomConversationAllowed FLOAT fClosestRoadNodeHeading VECTOR vClosestRoadNode VECTOR vPullStartVehiclePosition //goons stage INT iGoonsProgress BOOL bGoonsAllowed BOOL bGoonsAttacked BOOL bGoonsChaseInProgress BOOL bGoonsChaseFinished BOOL bGoonsAggressive BOOL bCombatAllowed BOOL bPlayerFiredAsPassenger BOOL bLoseWantedDisplayed INT iGoonsChaseInitialTimer BOOL bGoonsChaseInitialTimePassed //kill counters INT iPlayerMichaelKills INT iPlayerFranklinKills INT iBuddyMichaelKills INT iBuddyFranklinKills INT iPlayerShootingTimer INT iDriveTaskDelayTimer BOOL bDriveTaskDelayed BOOL bShutVehicleBoot BOOL bMusicEventMissionStartTriggered BOOL bMusicEventHookedUpTriggered BOOL bVehicleReversed BOOL bChaseHintCamAllowed BOOL bPlayerVehicleEntered BOOL bBuddyPedCoverTaskCleared BOOL bWantedLevelBlockedOnBuddyDrive INT iApplyForceSide INT iApplyForceTimer FLOAT fMinX, fMinY, fMaxX, fMaxY INT bGameplayHintTimer INT iPhoneCallSceneID = -1 INT iNMBlockingObject01 = -1 //blocks the house debris with larger part of the deck INT iNMBlockingObject02 = -1 //blocks the house debris with smaller part of the deck INT iNMBlockingObject03 = -1 //blocks the house debris with the smallest part of the deck INT iLeadOutTimer INT iCutsceneCarLightsProgress INT iCustomSwitchSoundID INT iMichaelsVehicleExitDelay = 0 INT iFranklinsVehicleExitDelay = 250 INT iCameraTimer INT iCameraProgress INT iLeadOutLoadSceneTimer BOOL bLeadoutConversationEnded BOOL bFirstSwitchCompleted BOOL bRunDirectSwitch BOOL bPedsTaskedToLeaveAnyVehicle BOOL bStopRandomChaseConversations BOOL bStartPreloadingVanConversation INT iMichaelEnemyKillConversations INT iFranklinEnemyKillConversations BOOL bResetFirstPersonCamera BOOL bStopForcingThirdPersonCamera BOOL bFirstPersonFlashPlayed BOOL bTriggerSwitchFlash INT iFirstPersonFlashTimer INT iReplayCameraWarpTimer //|========================================= ARRAYS ======================================| BOOL FailFlags[MAX_MISSION_FAILS] //asset arrays MODEL_NAMES MissionModels[MAX_MODELS] INT MissionRecordings[MAX_CAR_RECORDINGS] STRING MissionAnimations[MAX_ANIMATIONS] FLOAT fPlayerHeadings[8] VECTOR vPlayerPositions[8] VECTOR vEnemyCarsOffset[2] VEH_STRUCT vsEnemyCars[2] PED_STRUCT psEnemyGoonsCar0[2] PED_STRUCT psEnemyGoonsCar1[2] //|========================= MISCELLANEOUS PROCEDURES & FUNCTIONS ========================| /// PURPOSE: /// Resets all mission flags and progress counters to their default values. PROC RESET_MISSION_FLAGS() //reset setup progress to 1, so that iSetupProgress = 0 only runs once, on initial mission load. iStageSetupProgress = 1 iMissionStageProgress = 0 psFranklin.iTimer = 0 psFranklin.iConversationTimer = 0 psFranklin.iConversationCounter = 0 psMichael.iConversationTimer = 0 psMichael.iConversationCounter = 0 iRandomLinesTriggered = 0 psFranklin.iProgress = 0 psFranklin.bHasTask = FALSE psFranklin.eState = PED_STATE_IDLE psCoach.iProgress = 0 vsVan.iProgress = 0 vsPlayersCar.iProgress = 0 vsPlayersCar.bAutoDrive = FALSE bRandomConversationAllowed = FALSE bPhoneCallInterruptedByPlayer = FALSE bCustomRouteActive = FALSE bShouldUseDefaultRoute = FALSE bRunLocatesHeaderCheck = FALSE bDisplayDestinationBlip = FALSE fChaseSpeed = 0.65 fChaseTime = 0.0 bChaseInProgress = FALSE bChaseFinished = FALSE bCoachVisible = FALSE bCoachSpotted = FALSE bMichaelStartedShouting = FALSE bSpotConversationFinished = FALSE bRecordingPlaybackStarted = FALSE iSyncedSceneCoachID = 0 iScriptedCameraProgress = 0 iRayfireMapObjectProgress = 0 iRayfireSequenceProgress = 0 fRayfirePhase = 0.0 bRayfireStarted = FALSE bRayfirePaused = FALSE bPTFXStarted = FALSE fWheelspinValue = 0.0 fCameraShakeAmplitude = 0.0 bConversationPaused = FALSE bPlayerCrashedIntoVan = FALSE bCoachLostConversationStarted = FALSE bCutsceneSkipped = FALSE bCutsceneAssetsRequested = FALSE bAllowConvsersationOutsideOfCar = FALSE bStopScriptedConversations = FALSE bStatConversationFinished = FALSE bVanDriverCrashSpeechTriggered = FALSE bHousePullStarted = FALSE bHousePullCompleted = FALSE iVehicleSwitchTimer = 0 iGoonsChaseDelayTimer = 0 iConversationProgress = 0 iConversationIdleTimer = 0 iVehicleImpactSoundTimer = 0 iGoonsProgress = 0 bGoonsAllowed = FALSE bGoonsAttacked = FALSE bGoonsChaseInProgress = FALSE bGoonsChaseFinished = FALSE bGoonsAggressive = FALSE bCombatAllowed = FALSE bPlayerFiredAsPassenger = FALSE bLoseWantedDisplayed = FALSE bTruckRepositionedForCutscene = FALSE bStartGoonTimerDelay = FALSE iPlayerShootingTimer = 0 sLabelDCAN = "FAM3_DCAN" sLabelDHOUSE = "FAM3_DHOUSE" sLabelGETBCK = "FAM3_GBIT" sLabelFLEAVE = "CMN_FLEAVE" sLabelMLEAVE = "CMN_MLEAVE" sLabelLWANTED = "LOSE_WANTED" eChaseFinishReason = CHASE_FINISHED_TARGET_LOST bMusicEventHookedUpTriggered = FALSE bMusicEventMissionStartTriggered= FALSE bChaseHintCamAllowed = FALSE bPlayerVehicleEntered = FALSE iApplyForceSide = 1 iApplyForceTimer = 0 bAllowHotSwap = FALSE bHotSwapHinted = FALSE bHotSwapTriggered = FALSE iHotSwapHintTimer = 0 bGameplayHintTimer = 0 iDriveTaskDelayTimer = 0 bDriveTaskDelayed = FALSE bBuddyPedCoverTaskCleared = FALSE bWantedLevelBlockedOnBuddyDrive = FALSE iGoonsChaseInitialTimer = 0 bGoonsChaseInitialTimePassed = FALSE bShutVehicleBoot = FALSE iLeadOutTimer = 0 iCutsceneCarLightsProgress = 0 iCameraTimer = 0 iCameraProgress = 0 iLeadOutLoadSceneTimer = 0 bLeadoutConversationEnded = FALSE bFirstSwitchCompleted = FALSE bPedsTaskedToLeaveAnyVehicle = FALSE bStopRandomChaseConversations = FALSE bStartPreloadingVanConversation = FALSE iMichaelEnemyKillConversations = 0 iFranklinEnemyKillConversations = 0 bResetFirstPersonCamera = FALSE bStopForcingThirdPersonCamera = FALSE bRunDirectSwitch = FALSE bFirstPersonFlashPlayed = FALSE iFirstPersonFlashTimer = 0 #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Mission flags and progress counters are reset.") #ENDIF ENDPROC /// PURPOSE: /// Sets all fail flags to specified boolean value. /// PARAMS: /// bNewBool - Boolean value to set all flags to TRUE or FALSE. PROC SET_FAIL_FLAGS(BOOL bNewBool) INT i = 0 FOR i = 0 TO ( COUNT_OF(FailFlags) - 1 ) FailFlags[i] = bNewBool ENDFOR ENDPROC PROC INITIALISE_UBER_ARRAY() TrafficCarPos[0] = <<-867.2245, 209.0847, 73.3253>> TrafficCarQuatX[0] = 0.0774 TrafficCarQuatY[0] = 0.0159 TrafficCarQuatZ[0] = 0.8993 TrafficCarQuatW[0] = -0.4302 TrafficCarRecording[0] = 4 TrafficCarStartime[0] = 2600.0 TrafficCarModel[0] = dilettante TrafficCarPos[1] = <<-785.0840, 220.7164, 75.9672>> TrafficCarQuatX[1] = 0.0123 TrafficCarQuatY[1] = 0.0143 TrafficCarQuatZ[1] = 0.7330 TrafficCarQuatW[1] = 0.6799 TrafficCarRecording[1] = 76 TrafficCarStartime[1] = 6170.0 TrafficCarModel[1] = Baller TrafficCarPos[2] = <<-992.3110, 217.7745, 67.0249>> TrafficCarQuatX[2] = 0.0234 TrafficCarQuatY[2] = 0.0272 TrafficCarQuatZ[2] = -0.1712 TrafficCarQuatW[2] = 0.9846 TrafficCarRecording[2] = 10 TrafficCarStartime[2] = 10475.0 TrafficCarModel[2] = jackal TrafficCarPos[3] = <<-967.0320, 362.0272, 71.8551>> TrafficCarQuatX[3] = -0.0168 TrafficCarQuatY[3] = -0.0225 TrafficCarQuatZ[3] = 0.7457 TrafficCarQuatW[3] = -0.6657 TrafficCarRecording[3] = 1 TrafficCarStartime[3] = 11425.0 TrafficCarModel[3] = voltic TrafficCarPos[4] = <<-991.3395, 258.1681, 67.7794>> TrafficCarQuatX[4] = -0.0273 TrafficCarQuatY[4] = 0.0303 TrafficCarQuatZ[4] = 0.7281 TrafficCarQuatW[4] = -0.6843 TrafficCarRecording[4] = 71 TrafficCarStartime[4] = 12480.0 TrafficCarModel[4] = Baller TrafficCarPos[5] = <<-1069.2350, 209.9156, 61.2541>> TrafficCarQuatX[5] = 0.0255 TrafficCarQuatY[5] = 0.0146 TrafficCarQuatZ[5] = 0.1780 TrafficCarQuatW[5] = 0.9836 TrafficCarRecording[5] = 7 TrafficCarStartime[5] = 13475.0 TrafficCarModel[5] = RapidGT TrafficCarPos[6] = <<-1007.4832, 269.8612, 66.4751>> TrafficCarQuatX[6] = -0.0376 TrafficCarQuatY[6] = -0.0134 TrafficCarQuatZ[6] = 0.7170 TrafficCarQuatW[6] = 0.6959 TrafficCarRecording[6] = 15 TrafficCarStartime[6] = 15000.0 TrafficCarModel[6] = rocoto TrafficCarPos[7] = <<-1078.1970, 278.4990, 63.8791>> TrafficCarQuatX[7] = 0.0064 TrafficCarQuatY[7] = -0.0266 TrafficCarQuatZ[7] = 0.3714 TrafficCarQuatW[7] = 0.9281 TrafficCarRecording[7] = 16 TrafficCarStartime[7] = 16225.0 TrafficCarModel[7] = Baller TrafficCarPos[8] = <<-1064.9928, 270.3903, 63.4535>> TrafficCarQuatX[8] = -0.0069 TrafficCarQuatY[8] = -0.0066 TrafficCarQuatZ[8] = 0.6859 TrafficCarQuatW[8] = 0.7276 TrafficCarRecording[8] = 18 TrafficCarStartime[8] = 17396.0 TrafficCarModel[8] = blista TrafficCarPos[9] = <<-1084.0250, 290.5645, 63.6725>> TrafficCarQuatX[9] = -0.0006 TrafficCarQuatY[9] = -0.0104 TrafficCarQuatZ[9] = 0.9994 TrafficCarQuatW[9] = 0.0340 TrafficCarRecording[9] = 19 TrafficCarStartime[9] = 18189.0 TrafficCarModel[9] = felon2 TrafficCarPos[10] = <<-1104.4526, 262.3094, 64.0965>> TrafficCarQuatX[10] = -0.0328 TrafficCarQuatY[10] = 0.0305 TrafficCarQuatZ[10] = -0.7028 TrafficCarQuatW[10] = 0.7099 TrafficCarRecording[10] = 20 TrafficCarStartime[10] = 18960.0 TrafficCarModel[10] = rocoto TrafficCarPos[11] = <<-1105.7966, 267.6655, 63.9132>> TrafficCarQuatX[11] = -0.0315 TrafficCarQuatY[11] = 0.0297 TrafficCarQuatZ[11] = -0.6890 TrafficCarQuatW[11] = 0.7234 TrafficCarRecording[11] = 21 TrafficCarStartime[11] = 18990.0 TrafficCarModel[11] = prairie TrafficCarPos[12] = <<-1118.2029, 260.7814, 64.8678>> TrafficCarQuatX[12] = -0.0372 TrafficCarQuatY[12] = 0.0464 TrafficCarQuatZ[12] = -0.6148 TrafficCarQuatW[12] = 0.7865 TrafficCarRecording[12] = 22 TrafficCarStartime[12] = 19500.0 TrafficCarModel[12] = serrano TrafficCarPos[13] = <<-1074.3485, 351.9871, 67.1602>> TrafficCarQuatX[13] = 0.0396 TrafficCarQuatY[13] = -0.0133 TrafficCarQuatZ[13] = 0.0033 TrafficCarQuatW[13] = 0.9991 TrafficCarRecording[13] = 23 TrafficCarStartime[13] = 20950.0 TrafficCarModel[13] = dilettante TrafficCarPos[14] = <<-1064.6390, 341.6877, 67.0819>> TrafficCarQuatX[14] = 0.0006 TrafficCarQuatY[14] = -0.0231 TrafficCarQuatZ[14] = 0.6850 TrafficCarQuatW[14] = 0.7282 TrafficCarRecording[14] = 24 TrafficCarStartime[14] = 22890.0 TrafficCarModel[14] = rocoto TrafficCarPos[15] = <<-1114.7520, 483.8648, 82.1372>> TrafficCarQuatX[15] = -0.0001 TrafficCarQuatY[15] = -0.0011 TrafficCarQuatZ[15] = 0.9945 TrafficCarQuatW[15] = 0.1048 TrafficCarRecording[15] = 73 TrafficCarStartime[15] = 33000.0//32000.0 //32400.0 TrafficCarModel[15] = Baller TrafficCarPos[16] = <<-1300.9729, 457.5321, 97.5162>> TrafficCarQuatX[16] = -0.0343 TrafficCarQuatY[16] = 0.0347 TrafficCarQuatZ[16] = -0.6816 TrafficCarQuatW[16] = 0.7301 TrafficCarRecording[16] = 28 TrafficCarStartime[16] = 39850.0 TrafficCarModel[16] = felon TrafficCarPos[17] = <<-1360.6454, 458.8226, 102.7037>> TrafficCarQuatX[17] = 0.0295 TrafficCarQuatY[17] = -0.0343 TrafficCarQuatZ[17] = 0.7530 TrafficCarQuatW[17] = -0.6565 TrafficCarRecording[17] = 29 TrafficCarStartime[17] = 40850.0 TrafficCarModel[17] = cogcabrio SetPieceCarPos[0] = <<-947.3407, 422.2456, 78.9748>> SetPieceCarQuatX[0] = -0.0513 SetPieceCarQuatY[0] = -0.0036 SetPieceCarQuatZ[0] = 0.8378 SetPieceCarQuatW[0] = 0.5436 SetPieceCarRecording[0] = 2 SetPieceCarStartime[0] = 15000.0 SetPieceCarRecordingSpeed[0] = 0.8000 SetPieceCarModel[0] = Benson SetPieceCarPos[1] = <<-1062.9193, 452.6988, 74.4478>> SetPieceCarQuatX[1] = 0.0294 SetPieceCarQuatY[1] = -0.0410 SetPieceCarQuatZ[1] = 0.8439 SetPieceCarQuatW[1] = 0.5341 SetPieceCarRecording[1] = 70 SetPieceCarStartime[1] = 28912.0 SetPieceCarRecordingSpeed[1] = 1.0000 SetPieceCarModel[1] = cogcabrio ENDPROC PROC ADD_NAVMESH_BLOCKING_OBJECTS() IF ( iNMBlockingObject01 = -1) iNMBlockingObject01 = ADD_NAVMESH_BLOCKING_OBJECT(<< -1018.043, 642.159, 140.444 >>, << 18.0, 10.0, 4.0 >>, (-6.120 / 360.0) * 6.28) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Adding nav mesh blocking object iNMBlockingObject01.") #ENDIF ENDIF IF ( iNMBlockingObject02 = -1) iNMBlockingObject02 = ADD_NAVMESH_BLOCKING_OBJECT(<< -1032.143, 646.559, 140.444 >>, << 15.0, 9.0, 4.0 >>, (-27.0 / 360.0) * 6.28) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Adding nav mesh blocking object iNMBlockingObject02.") #ENDIF ENDIF IF ( iNMBlockingObject03 = -1) iNMBlockingObject03 = ADD_NAVMESH_BLOCKING_OBJECT(<< -1008.675, 641.048, 140.000 >>, << 5.0, 5.0, 4.0 >>, (-26.280 / 360.0) * 6.28) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Adding nav mesh blocking object iNMBlockingObject03.") #ENDIF ENDIF ENDPROC PROC REMOVE_NAVMESH_BLOCKING_OBJECTS() IF ( iNMBlockingObject01 != -1) REMOVE_NAVMESH_BLOCKING_OBJECT(iNMBlockingObject01) iNMBlockingObject01 = -1 #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Removing nav mesh blocking object iNMBlockingObject01.") #ENDIF ENDIF IF ( iNMBlockingObject02 != -1) REMOVE_NAVMESH_BLOCKING_OBJECT(iNMBlockingObject02) iNMBlockingObject02 = -1 #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Removing nav mesh blocking object iNMBlockingObject02.") #ENDIF ENDIF IF ( iNMBlockingObject03 != -1) REMOVE_NAVMESH_BLOCKING_OBJECT(iNMBlockingObject03) iNMBlockingObject03 = -1 #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Removing nav mesh blocking object iNMBlockingObject03.") #ENDIF ENDIF ENDPROC /// PURPOSE: /// Warps specified ped to new coordinates and sets specified ped's new heading. /// PARAMS: /// ped - PED_INDEX to warp. /// vNewPosition - VECTOR coordinates specifying new ped's position. /// fNewHeading - FLOAT specifying new ped's heading. /// bKeepVehicle - Specifies if ped should keep vehicle they are currently in. /// bResetGameplayCamera - Specifies if gameplay camera should be positioned behind player's back. Works only for PLAYER_PED_ID(). /// bLoadScene - Specifies if scene at new provided coordinates should be loaded. Works only for PLAYER_PED_ID(). PROC WARP_PED(PED_INDEX ped, VECTOR vNewPosition, FLOAT fNewHeading, BOOL bKeepVehicle, BOOL bResetGameplayCamera, BOOL bLoadScene) IF NOT IS_PED_INJURED(ped) IF ( bKeepVehicle = TRUE ) SET_PED_COORDS_KEEP_VEHICLE(ped, vNewPosition) ELIF ( bKeepVehicle = FALSE ) SET_ENTITY_COORDS(ped, vNewPosition) ENDIF SET_ENTITY_HEADING(ped, fNewHeading) IF ( ped = PLAYER_PED_ID()) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Warping player ped to coordinates ", vNewPosition, " and heading ", fNewHeading, ".") #ENDIF IF ( bResetGameplayCamera = TRUE) SET_GAMEPLAY_CAM_RELATIVE_HEADING(0) SET_GAMEPLAY_CAM_RELATIVE_PITCH(0) ENDIF IF ( bLoadScene = TRUE ) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Calling LOAD_SCENE() at coordinates ", vNewPosition, ". This might take a while to load.") #ENDIF LOAD_SCENE(vNewPosition) ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Returns PED_INDEX for specified player ped character from enumCharacterList. /// PARAMS: /// CHAR_TYPE - Character to get ped index for. For example CHAR_FRANKLIN, CHAR_TREVOR or CHAR_MICHAEL. /// RETURNS: /// PED_INDEX for the specified player ped character. FUNC PED_INDEX GET_PED_INDEX(enumCharacterList CHAR_TYPE) IF ( GET_CURRENT_PLAYER_PED_ENUM() = CHAR_TYPE ) RETURN PLAYER_PED_ID() ELSE RETURN sSelectorPeds.pedID[GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(CHAR_TYPE)] ENDIF ENDFUNC PROC CALCULATE_VEHICLE_EXIT_DELAYS() //return default values by default iMichaelsVehicleExitDelay = 0 iFranklinsVehicleExitDelay = 250 IF NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_MICHAEL)) AND NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_FRANKLIN)) AND ARE_PEDS_IN_THE_SAME_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL), GET_PED_INDEX(CHAR_FRANKLIN)) VEHICLE_INDEX VehicleIndex VehicleIndex = GET_VEHICLE_PED_IS_USING(GET_PED_INDEX(CHAR_MICHAEL)) IF IS_PED_SITTING_IN_THIS_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL), VehicleIndex) AND IS_PED_SITTING_IN_THIS_VEHICLE(GET_PED_INDEX(CHAR_FRANKLIN), VehicleIndex) SWITCH GET_PED_VEHICLE_SEAT(GET_PED_INDEX(CHAR_MICHAEL), VehicleIndex) CASE VS_DRIVER SWITCH GET_PED_VEHICLE_SEAT(GET_PED_INDEX(CHAR_FRANKLIN), VehicleIndex) CASE VS_BACK_LEFT iMichaelsVehicleExitDelay = 1250 iFranklinsVehicleExitDelay = 0 BREAK DEFAULT iMichaelsVehicleExitDelay = 0 iFranklinsVehicleExitDelay = 250 BREAK ENDSWITCH BREAK CASE VS_BACK_LEFT SWITCH GET_PED_VEHICLE_SEAT(GET_PED_INDEX(CHAR_FRANKLIN), VehicleIndex) CASE VS_DRIVER iMichaelsVehicleExitDelay = 0 iFranklinsVehicleExitDelay = 1250 BREAK DEFAULT iMichaelsVehicleExitDelay = 0 iFranklinsVehicleExitDelay = 250 BREAK ENDSWITCH BREAK DEFAULT iMichaelsVehicleExitDelay = 0 iFranklinsVehicleExitDelay = 250 BREAK ENDSWITCH ENDIF ENDIF #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": iMichaelsVehicleExitDelay: ", iMichaelsVehicleExitDelay, ", iFranklinsVehicleExitDelay: ", iFranklinsVehicleExitDelay, ".") #ENDIF ENDPROC PROC CALCULATE_PATH_NODES_AREA_FOR_POS(VECTOR vPosition) IF ( vPosition.x < vMichaelsHousePosition.x ) fMinX = vPosition.x - 25.0 fMaxX = vMichaelsHousePosition.x + 25.0 ELIF ( vPosition.x > vMichaelsHousePosition.x ) fMinX = vMichaelsHousePosition.x - 25.0 fMaxX = vPosition.x + 25.0 ENDIF IF ( vPosition.y < vMichaelsHousePosition.y ) fMinY = vPosition.y - 25.0 fMaxY = vMichaelsHousePosition.y + 25.0 ELIF ( vPosition.y > vMichaelsHousePosition.y ) fMinY = vMichaelsHousePosition.y - 25.0 fMaxY = vPosition.y + 25.0 ENDIF ENDPROC FUNC PED_INDEX GET_CLOSEST_PED_FROM_GROUP(PED_STRUCT &array[], INT &iOutIndex) INT i = 0 INT iClosestIndex = -1 FLOAT fCurrentDistance = 0.0 FLOAT fShortestDistance = 500.0 FOR i = 0 TO (COUNT_OF(array) - 1) IF DOES_ENTITY_EXIST(array[i].PedIndex) IF NOT IS_ENTITY_DEAD(array[i].PedIndex) fCurrentDistance = array[i].fDistanceToTarget IF ( fCurrentDistance < fShortestDistance ) fShortestDistance = fCurrentDistance iClosestIndex = i ENDIF ENDIF ENDIF ENDFOR IF ( iClosestIndex = -1 ) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Could not find closest ped from specified ped group.") #ENDIF iOutIndex = iClosestIndex RETURN NULL ELSE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Found closest ped ", array[iClosestIndex].sDebugName, " from ped group at distance ", array[iClosestIndex].fDistanceToTarget, " with index ", iClosestIndex, ".") #ENDIF iOutIndex = iClosestIndex RETURN array[iClosestIndex].PedIndex ENDIF ENDFUNC FUNC FLOAT GET_DISTANCE_TO_CLOSEST_PED_FROM_GROUPS(PED_STRUCT &array1[], PED_STRUCT &array2[]) INT i, k GET_CLOSEST_PED_FROM_GROUP(array1, i) GET_CLOSEST_PED_FROM_GROUP(array2, k) IF ( i <> -1 AND k <> -1) IF ( array1[i].fDistanceToTarget <= array2[k].fDistanceToTarget ) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Distance to closest ped ", array1[i].sDebugName, " is ", array1[i].fDistanceToTarget, ".") #ENDIF RETURN array1[i].fDistanceToTarget ELSE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Distance to closest ped ", array2[k].sDebugName, " is ", array2[k].fDistanceToTarget, ".") #ENDIF RETURN array2[k].fDistanceToTarget ENDIF ELSE IF ( i <> -1 ) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Distance to closest ped ", array1[i].sDebugName, " is ", array1[i].fDistanceToTarget, ".") #ENDIF RETURN array1[i].fDistanceToTarget ELIF ( k <> -1 ) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Distance to closest ped ", array2[k].sDebugName, " is ", array2[k].fDistanceToTarget, ".") #ENDIF RETURN array2[k].fDistanceToTarget ENDIF ENDIF #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Unable to return distance to closest ped from specified ped groups.") #ENDIF RETURN -1.0 ENDFUNC FUNC VEHICLE_INDEX GET_CLOSEST_MISSION_VEHICLE_TO_ENTITY(ENTITY_INDEX EntityIndex, FLOAT fRadius, MODEL_NAMES ModelName) VEHICLE_INDEX VehicleIndex IF DOES_ENTITY_EXIST(EntityIndex) VECTOR vPosition vPosition = GET_ENTITY_COORDS(EntityIndex, FALSE) VehicleIndex = GET_CLOSEST_VEHICLE(vPosition, fRadius, ModelName, VEHICLE_SEARCH_FLAG_RETURN_MISSION_VEHICLES | VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_CONTAINING_A_DEAD_OR_DYING_PED | VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_WITH_PEDS_ENTERING_OR_EXITING | VEHICLE_SEARCH_FLAG_ALLOW_VEHICLE_OCCUPANTS_TO_BE_PERFORMING_A_SCRIPTED_TASK) #IF IS_DEBUG_BUILD IF DOES_ENTITY_EXIST(VehicleIndex) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Found closest mission vehicle with model ", GET_MODEL_NAME_FOR_DEBUG(ModelName), " in radius ", fRadius, ".") DRAW_DEBUG_LINE(GET_ENTITY_COORDS(EntityIndex, FALSE), GET_ENTITY_COORDS(VehicleIndex, FALSE), 255) ELSE PRINTLN(GET_THIS_SCRIPT_NAME(), ": Not found any mission vehicles with model ", GET_MODEL_NAME_FOR_DEBUG(ModelName), " in radius ", fRadius, ".") ENDIF #ENDIF ENDIF RETURN VehicleIndex ENDFUNC FUNC BOOL IS_PED_SHOOTING_AT_ENTITY(PED_INDEX PedIndex, ENTITY_INDEX EntityIndex, BOOL bPlayerPed = FALSE, FLOAT fRadius = 7.5) IF DOES_ENTITY_EXIST(PedIndex) AND DOES_ENTITY_EXIST(EntityIndex) IF NOT IS_ENTITY_DEAD(PedIndex) AND NOT IS_ENTITY_DEAD(EntityIndex) IF ( bPlayerPed = TRUE ) IF IS_BULLET_IN_AREA(GET_ENTITY_COORDS(EntityIndex), fRadius, bPlayerPed) RETURN TRUE ENDIF ENDIF IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(EntityIndex, PedIndex, FALSE) IF HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON(EntityIndex, WEAPONTYPE_INVALID, GENERALWEAPON_TYPE_ANYWEAPON) RETURN TRUE ENDIF ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC FUNC BOOL DOES_VEHICLE_HAVE_A_DRIVER(VEHICLE_INDEX VehicleIndex) IF DOES_ENTITY_EXIST(VehicleIndex) IF NOT IS_ENTITY_DEAD(VehicleIndex) IF NOT IS_VEHICLE_SEAT_FREE(VehicleIndex, VS_DRIVER) PED_INDEX DriverPedIndex DriverPedIndex = GET_PED_IN_VEHICLE_SEAT(VehicleIndex, VS_DRIVER) IF DOES_ENTITY_EXIST(DriverPedIndex) IF NOT IS_ENTITY_DEAD(DriverPedIndex) RETURN TRUE ENDIF ENDIF ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC FUNC PED_CLEANUP_REASONS GET_PED_CLEANUP_REASON(PED_STRUCT &ped) IF DOES_ENTITY_EXIST(ped.PedIndex) IF IS_ENTITY_DEAD(ped.PedIndex) ENTITY_INDEX SourceOfDeathEntity SourceOfDeathEntity = GET_PED_SOURCE_OF_DEATH(ped.PedIndex) IF DOES_ENTITY_EXIST(SourceOfDeathEntity) IF IS_ENTITY_A_PED(SourceOfDeathEntity) PED_INDEX SourceOfDeathPed SourceOfDeathPed = GET_PED_INDEX_FROM_ENTITY_INDEX(SourceOfDeathEntity) IF ( SourceOfDeathPed = GET_PED_INDEX(CHAR_FRANKLIN) ) SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Ped ", ped.sDebugName, " cleaned up with reason PED_CLEANUP_KILLED_BY_FRANKLIN.") #ENDIF RETURN PED_CLEANUP_KILLED_BY_FRANKLIN BREAK CASE CHAR_FRANKLIN #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Ped ", ped.sDebugName, " cleaned up with reason PED_CLEANUP_KILLED_BY_PLAYER_AS_FRANKLIN.") #ENDIF RETURN PED_CLEANUP_KILLED_BY_PLAYER_AS_FRANKLIN BREAK ENDSWITCH ELIF ( SourceOfDeathPed = GET_PED_INDEX(CHAR_MICHAEL) ) SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Ped ", ped.sDebugName, " cleaned up with reason PED_CLEANUP_KILLED_BY_PLAYER_AS_MICHAEL.") #ENDIF RETURN PED_CLEANUP_KILLED_BY_PLAYER_AS_MICHAEL BREAK CASE CHAR_FRANKLIN #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Ped ", ped.sDebugName, " cleaned up with reason PED_CLEANUP_KILLED_BY_MICHAEL.") #ENDIF RETURN PED_CLEANUP_KILLED_BY_MICHAEL BREAK ENDSWITCH ELSE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Ped ", ped.sDebugName, " cleaned up with reason PED_CLEANUP_LOST.") PRINTLN(GET_THIS_SCRIPT_NAME(), ": Ped ", ped.sDebugName, " source of death was a ped but not Franklin or Michael.") #ENDIF RETURN PED_CLEANUP_LOST ENDIF ELIF IS_ENTITY_A_VEHICLE(SourceOfDeathEntity) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Ped ", ped.sDebugName, " cleaned up with reason PED_CLEANUP_KILLED_BY_VEHICLE.") #ENDIF RETURN PED_CLEANUP_KILLED_BY_VEHICLE ELSE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Ped ", ped.sDebugName, " cleaned up with reason PED_CLEANUP_LOST.") PRINTLN(GET_THIS_SCRIPT_NAME(), ": Ped ", ped.sDebugName, " source of death was not a ped or vehicle.") #ENDIF RETURN PED_CLEANUP_LOST ENDIF ELSE ped.iCleanupAttempts++ #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Ped ", ped.sDebugName, " source of death does not exist.") PRINTLN(GET_THIS_SCRIPT_NAME(), ": Ped ", ped.sDebugName, " had ", ped.iCleanupAttempts, " cleanup attempts .") #ENDIF IF ( ped.iCleanupAttempts = 10 ) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Ped ", ped.sDebugName, " cleaned up with reason PED_CLEANUP_LOST due to cleanup attempts running out.") #ENDIF RETURN PED_CLEANUP_LOST ENDIF ENDIF ENDIF ENDIF #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Ped ", ped.sDebugName, " cleaned up with reason PED_CLEANUP_NO_CLEANUP.") #ENDIF RETURN PED_CLEANUP_NO_CLEANUP ENDFUNC PROC UPDATE_PLAYER_AND_BUDDY_KILL_COUNTERS(PED_CLEANUP_REASONS eCleanupReason, INT &iPlayerKillsAsMichael, INT &iPlayerKillsAsFranklin, INT &iBuddyKillsAsMichael, INT &iBuddyKillsAsFranklin) SWITCH eCleanupReason CASE PED_CLEANUP_KILLED_BY_PLAYER_AS_MICHAEL iPlayerKillsAsMichael++ INFORM_MISSION_STATS_OF_INCREMENT(FAM3_KILLS) //increment mission stat for kills IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) INFORM_MISSION_STATS_OF_INCREMENT(FAM3_VEHICLE_KILLS) //increment mission stat for from vehicle kills ENDIF BREAK CASE PED_CLEANUP_KILLED_BY_PLAYER_AS_FRANKLIN iPlayerKillsAsFranklin++ INFORM_MISSION_STATS_OF_INCREMENT(FAM3_KILLS) //increment mission stat IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) INFORM_MISSION_STATS_OF_INCREMENT(FAM3_VEHICLE_KILLS) //increment mission stat for from vehicle kills ENDIF BREAK CASE PED_CLEANUP_KILLED_BY_MICHAEL iBuddyKillsAsMichael++ BREAK CASE PED_CLEANUP_KILLED_BY_FRANKLIN iBuddyKillsAsFranklin++ BREAK ENDSWITCH #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": *********************** UPDATE_PLAYER_AND_BUDDY_KILL_COUNTERS *************************") PRINTLN(GET_THIS_SCRIPT_NAME(), ": Player kills as Michael: ", iPlayerKillsAsMichael, ". Player kills as Franklin: ", iPlayerKillsAsFranklin, ".") PRINTLN(GET_THIS_SCRIPT_NAME(), ": Buddy kills as Michael: ", iBuddyKillsAsMichael, ". Buddy kills as Franklin: ", iBuddyKillsAsFranklin, ".") PRINTLN(GET_THIS_SCRIPT_NAME(), ": ***************************************************************************************") #ENDIF ENDPROC PROC SET_MISSION_PED_PROPERTIES(PED_INDEX PedIndex, REL_GROUP_HASH relGroupHash, BOOL bCanFlyThroughWindscreen, BOOL bKeepRelGroupOnCleanup, BOOL bCanBeTargetted, BOOL bIsEnemy) IF DOES_ENTITY_EXIST(PedIndex) IF NOT IS_PED_INJURED(PedIndex) SET_PED_INFINITE_AMMO(PedIndex, FALSE) SET_PED_AS_ENEMY(PedIndex, bIsEnemy) SET_PED_CAN_BE_TARGETTED(PedIndex, bCanBeTargetted) SET_PED_RELATIONSHIP_GROUP_HASH(PedIndex, relGroupHash) SET_PED_CONFIG_FLAG(PedIndex, PCF_WillFlyThroughWindscreen, bCanFlyThroughWindscreen) SET_PED_CONFIG_FLAG(PedIndex, PCF_KeepRelationshipGroupAfterCleanUp, bKeepRelGroupOnCleanup) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PedIndex, TRUE) ENDIF ENDIF ENDPROC FUNC BOOL IS_ENTITY_PLAYING_LOOK_BEHIND_ANIM(ENTITY_INDEX EntityIndex) IF DOES_ENTITY_EXIST(EntityIndex) IF NOT IS_ENTITY_DEAD(EntityIndex) IF IS_ENTITY_PLAYING_ANIM(EntityIndex, "missfam3", "incar_lookbehind_enter_driver") OR IS_ENTITY_PLAYING_ANIM(EntityIndex, "missfam3", "incar_lookbehind_idle_driver") OR IS_ENTITY_PLAYING_ANIM(EntityIndex, "missfam3", "incar_lookbehind_exit_driver") OR IS_ENTITY_PLAYING_ANIM(EntityIndex, "missfam3", "incar_lookbehind_enter_passenger") OR IS_ENTITY_PLAYING_ANIM(EntityIndex, "missfam3", "incar_lookbehind_idle_passenger") OR IS_ENTITY_PLAYING_ANIM(EntityIndex, "missfam3", "incar_lookbehind_exit_passenger") RETURN TRUE ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC PROC TASK_PLAY_LOOK_BEHIND_ANIM(PED_INDEX PedIndex, VEHICLE_SEAT eSeat, INT iTime = -1, ANIMATION_FLAGS Animflags = AF_DEFAULT) IF DOES_ENTITY_EXIST(PedIndex) IF NOT IS_ENTITY_DEAD(PedIndex) STRING sEnterAnim STRING sLoopAnim STRING sExitAnim SEQUENCE_INDEX SequenceIndex SWITCH eSeat CASE VS_DRIVER CASE VS_BACK_LEFT sEnterAnim = "incar_lookbehind_enter_driver" sLoopAnim = "incar_lookbehind_idle_driver" sExitAnim = "incar_lookbehind_exit_driver" BREAK CASE VS_FRONT_RIGHT CASE VS_BACK_RIGHT sEnterAnim = "incar_lookbehind_enter_passenger" sLoopAnim = "incar_lookbehind_idle_passenger" sExitAnim = "incar_lookbehind_exit_passenger" BREAK ENDSWITCH CLEAR_SEQUENCE_TASK(SequenceIndex) OPEN_SEQUENCE_TASK(SequenceIndex) TASK_PLAY_ANIM(NULL, "missfam3", sEnterAnim, SLOW_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_UPPERBODY | Animflags) TASK_PLAY_ANIM(NULL, "missfam3", sLoopAnim, NORMAL_BLEND_IN, NORMAL_BLEND_OUT, iTime, AF_UPPERBODY | Animflags | AF_LOOPING) TASK_PLAY_ANIM(NULL, "missfam3", sExitAnim, NORMAL_BLEND_IN, SLOW_BLEND_OUT, -1, AF_UPPERBODY | Animflags) CLOSE_SEQUENCE_TASK(SequenceIndex) TASK_PERFORM_SEQUENCE(PedIndex, SequenceIndex) CLEAR_SEQUENCE_TASK(SequenceIndex) ENDIF ENDIF ENDPROC /// PURPOSE: /// Creates a ped or player ped to be used by player and returns TRUE if such pad was created successfully. /// PARAMS: /// psPed - PED_STRUCT containg ped details, like PED_INDEX, blip, coordinates, heading, model etc. /// bPlayerPed - Boolean indicating if a player ped or NPC ped should be created. /// relGroupHash - Relationship group hash for the created ped. /// bCreateBlip - Boolean indicating if a blip for this ped should be created. /// eCharacter - Enum specifying character from story characters list. Use NO_CHARACTER for characters not stored in that list and provide a MODEL_NAMES in PED_STRUCT. /// bCanFlyThroughWindscreen - Sets if ped can fly through windscreen when car crashes. /// bCanBeTargetted - Sets if ped can be targetted by player. /// bIsEnemy - Sets if ped is considered an enemy. /// VehicleIndex - Specify a vehicle index if ped should be created inside a vehicle. IF not use NULL. /// eVehicleSeat - Vehicle seat enum for peds created in vehicles. /// RETURNS: /// TRUE if ped was created successfully, FALSE if otherwise. FUNC BOOL HAS_MISSION_PED_BEEN_CREATED(PED_STRUCT &psPed, BOOL bPlayerPed, REL_GROUP_HASH relGroupHash, BOOL bCreateBlip, enumCharacterList eCharacter, BOOL bCanFlyThroughWindscreen = FALSE, BOOL bCanBeTargetted = FALSE, BOOL bIsEnemy = FALSE, VEHICLE_INDEX VehicleIndex = NULL, VEHICLE_SEAT eVehicleSeat = VS_DRIVER, BOOL bKeepRelGroupOnCleanup = TRUE #IF IS_DEBUG_BUILD, STRING sDebugName = NULL #ENDIF) IF ( bPlayerPed = FALSE ) //create non player ped IF NOT DOES_ENTITY_EXIST(psPed.PedIndex) REQUEST_MODEL(psPed.ModelName) IF HAS_MODEL_LOADED(psPed.ModelName) IF ( VehicleIndex = NULL ) //create ped outside of vehicle IF ( eCharacter = NO_CHARACTER ) //use MODEL_NAMES stored in the PED_STRUCT if no character was specified psPed.PedIndex = CREATE_PED(PEDTYPE_MISSION, psPed.ModelName, psPed.vPosition, psPed.fHeading) SET_MODEL_AS_NO_LONGER_NEEDED(psPed.ModelName) ELSE //use character name to define the ped MODEL_NAMES IF CREATE_NPC_PED_ON_FOOT(psPed.PedIndex, eCharacter, psPed.vPosition, psPed.fHeading) SET_MODEL_AS_NO_LONGER_NEEDED(psPed.ModelName) ENDIF ENDIF IF NOT IS_PED_INJURED(psPed.PedIndex) SET_MISSION_PED_PROPERTIES(psPed.PedIndex, relGroupHash, bCanFlyThroughWindscreen, bKeepRelGroupOnCleanup, bCanBeTargetted, bIsEnemy) IF ( bCreateBlip = TRUE ) psPed.BlipIndex = CREATE_BLIP_FOR_ENTITY(psPed.PedIndex, FALSE) ENDIF ENDIF #IF IS_DEBUG_BUILD IF NOT Is_String_Null_Or_Empty(sDebugName) SET_PED_NAME_DEBUG(psPed.PedIndex, sDebugName) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created mission ped ", sDebugName, " with model ", GET_MODEL_NAME_FOR_DEBUG(psPed.ModelName), " at coordinates ", psPed.vPosition, ".") ELSE PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created mission ped with model ", GET_MODEL_NAME_FOR_DEBUG(psPed.ModelName), " at coordinates ", psPed.vPosition, ".") ENDIF #ENDIF RETURN TRUE ELIF ( VehicleIndex != NULL ) //create ped in a vehicle IF IS_VEHICLE_DRIVEABLE(VehicleIndex) IF ( eCharacter = NO_CHARACTER ) //use MODEL_NAMES stored in the PED_STRUCT psPed.PedIndex = CREATE_PED_INSIDE_VEHICLE(VehicleIndex, PEDTYPE_MISSION, psPed.ModelName, eVehicleSeat) SET_MODEL_AS_NO_LONGER_NEEDED(psPed.ModelName) ELSE //use character name to define the ped MODEL_NAMES IF CREATE_NPC_PED_INSIDE_VEHICLE(psPed.PedIndex, eCharacter, VehicleIndex, eVehicleSeat) SET_MODEL_AS_NO_LONGER_NEEDED(psPed.ModelName) ENDIF ENDIF IF NOT IS_PED_INJURED(psPed.PedIndex) SET_MISSION_PED_PROPERTIES(psPed.PedIndex, relGroupHash, bCanFlyThroughWindscreen, bKeepRelGroupOnCleanup, bCanBeTargetted, bIsEnemy) IF ( bCreateBlip = TRUE ) psPed.BlipIndex = CREATE_BLIP_FOR_ENTITY(psPed.PedIndex, FALSE) ENDIF ENDIF #IF IS_DEBUG_BUILD IF NOT Is_String_Null_Or_Empty(sDebugName) SET_PED_NAME_DEBUG(psPed.PedIndex, sDebugName) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created mission ped ", sDebugName, " with model ", GET_MODEL_NAME_FOR_DEBUG(psPed.ModelName), " in vehicle.") ELSE PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created mission ped with model ", GET_MODEL_NAME_FOR_DEBUG(psPed.ModelName), " in vehicle.") ENDIF #ENDIF RETURN TRUE ENDIF ENDIF ENDIF ELSE //if the ped already exists return true RETURN TRUE ENDIF ELIF ( bPlayerPed = TRUE ) //create player ped, for example a ped that player can hotswap to and take control of IF NOT DOES_ENTITY_EXIST(psPed.PedIndex) IF ( VehicleIndex = NULL ) //create player ped outside of vehicle IF CREATE_PLAYER_PED_ON_FOOT(psPed.PedIndex, eCharacter, psPed.vPosition, psPed.fHeading, TRUE) SET_MISSION_PED_PROPERTIES(psPed.PedIndex, relGroupHash, bCanFlyThroughWindscreen, bKeepRelGroupOnCleanup, bCanBeTargetted, bIsEnemy) IF ( bCreateBlip = TRUE ) psPed.BlipIndex = CREATE_BLIP_FOR_ENTITY(psPed.PedIndex, FALSE) ENDIF #IF IS_DEBUG_BUILD IF NOT Is_String_Null_Or_Empty(sDebugName) SET_PED_NAME_DEBUG(psPed.PedIndex, sDebugName) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created player ped ", sDebugName, " with model ", GET_MODEL_NAME_FOR_DEBUG(psPed.ModelName), " at coordinates ", psPed.vPosition, ".") ELSE PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created player ped with model ", GET_MODEL_NAME_FOR_DEBUG(psPed.ModelName), " at coordinates ", psPed.vPosition, ".") ENDIF #ENDIF RETURN TRUE ENDIF ELIF ( VehicleIndex != NULL ) //create player ped in a vehicle IF IS_VEHICLE_DRIVEABLE(VehicleIndex) IF CREATE_PLAYER_PED_INSIDE_VEHICLE(psPed.PedIndex, eCharacter, VehicleIndex, eVehicleSeat, TRUE) SET_MISSION_PED_PROPERTIES(psPed.PedIndex, relGroupHash, bCanFlyThroughWindscreen, bKeepRelGroupOnCleanup, bCanBeTargetted, bIsEnemy) IF ( bCreateBlip = TRUE ) psPed.BlipIndex = CREATE_BLIP_FOR_ENTITY(psPed.PedIndex, FALSE) ENDIF #IF IS_DEBUG_BUILD IF NOT Is_String_Null_Or_Empty(sDebugName) SET_PED_NAME_DEBUG(psPed.PedIndex, sDebugName) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created player ped ", sDebugName, " in vehicle with model ", GET_MODEL_NAME_FOR_DEBUG(psPed.ModelName), ".") ELSE PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created player ped in vehicle with model ", GET_MODEL_NAME_FOR_DEBUG(psPed.ModelName), ".") ENDIF #ENDIF RETURN TRUE ENDIF ENDIF ENDIF ELSE //if the ped already exists, return true RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC PROC SET_MISSION_VEHICLE_PROPERTIES(VEH_STRUCT &vsVehicle, BOOL bMissionCritical = TRUE, INT iColourCombination = -1, INT iColour1 = -1, INT iColour2 = -1, INT iColour3 = 0, INT iColour4 = 0 #IF IS_DEBUG_BUILD, STRING sDebugName = NULL #ENDIF) IF DOES_ENTITY_EXIST(vsVehicle.VehicleIndex) IF NOT IS_ENTITY_DEAD(vsVehicle.VehicleIndex) //make sure doors are unlocked SET_VEHICLE_DOORS_LOCKED(vsVehicle.VehicleIndex, VEHICLELOCK_UNLOCKED) SET_VEHICLE_HAS_STRONG_AXLES(vsVehicle.VehicleIndex, bMissionCritical) //limit damage that can be done to the vehicle SET_VEHICLE_CAN_LEAK_OIL(vsVehicle.VehicleIndex, NOT bMissionCritical) SET_VEHICLE_CAN_LEAK_PETROL(vsVehicle.VehicleIndex, NOT bMissionCritical) //make the vehicle not attach to tow truck if mission critical SET_VEHICLE_AUTOMATICALLY_ATTACHES(vsVehicle.VehicleIndex, NOT bMissionCritical) IF IS_THIS_MODEL_A_CAR(vsVehicle.ModelName) SET_DOOR_ALLOWED_TO_BE_BROKEN_OFF(vsVehicle.VehicleIndex, SC_DOOR_FRONT_LEFT, NOT bMissionCritical) SET_DOOR_ALLOWED_TO_BE_BROKEN_OFF(vsVehicle.VehicleIndex, SC_DOOR_FRONT_RIGHT, NOT bMissionCritical) SET_VEHICLE_TYRES_CAN_BURST(vsVehicle.VehicleIndex, NOT bMissionCritical) ENDIF //set vehicle colours, if they are provided IF ( iColour1 != -1) AND ( iColour2 != -1 ) SET_VEHICLE_COLOURS(vsVehicle.VehicleIndex, iColour1, iColour2) ENDIF //set vehicle colour combination, if it is provided IF ( iColourCombination != -1 ) SET_VEHICLE_COLOUR_COMBINATION(vsVehicle.VehicleIndex, iColourCombination) ENDIF SET_VEHICLE_EXTRA_COLOURS(vsVehicle.VehicleIndex, iColour3, iColour4) #IF IS_DEBUG_BUILD IF NOT Is_String_Null_Or_Empty(sDebugName) SET_VEHICLE_NAME_DEBUG(vsVehicle.VehicleIndex, sDebugName) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Set mission vehicle properties for vehicle ", sDebugName, " with model ", GET_MODEL_NAME_FOR_DEBUG(vsVehicle.ModelName), ".") ELSE PRINTLN(GET_THIS_SCRIPT_NAME(), ": Set mission vehicle properties for vehicle with model ", GET_MODEL_NAME_FOR_DEBUG(vsVehicle.ModelName), ".") ENDIF #ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Creates vehicle to be used on a mission by player and returns TRUE if such vehicle was created successfully. /// PARAMS: /// vsVehicle - VEH_STRUCT containing model, position and heading of the vehicle. /// bPlayerVehicle - If set to TRUE will create player specific vehicles using CREATE_PLAYER_VEHICLE() /// bCarStealVehicle - If set to TRUE will create car steal strand vehicle with a specific command. Works when bPlayerVehicle is FALSE. /// eCharacter - Character enum indicating which character specific vehicle to create. /// bMissionCritical - Sets the vehicle to be unable to leak oil/petrol and break off doors. Set to TRUE to stop these damage types to vehicle. /// iColourCombination - Colour combination of the vehicle. /// iColour1 - Colour 1 of the vehicle. /// iColour2 - Colour 2 of the vehicle. /// RETURNS: /// TRUE if vehicle was created, FALSE if otherwise. FUNC BOOL HAS_MISSION_VEHICLE_BEEN_CREATED(VEH_STRUCT &vsVehicle, BOOL bPlayerVehicle = FALSE, BOOL bCarStealVehicle = FALSE, enumCharacterList eCharacter = CHAR_MICHAEL, BOOL bMissionCritical = TRUE, INT iColourCombination = -1, INT iColour1 = -1, INT iColour2 = -1, INT iColour3 = 0, INT iColour4 = 0 #IF IS_DEBUG_BUILD, STRING sDebugName = NULL #ENDIF) //create any vehicle that can be used on a mission by player IF ( bPlayerVehicle = FALSE ) IF NOT DOES_ENTITY_EXIST(vsVehicle.VehicleIndex) REQUEST_MODEL(vsVehicle.ModelName) IF HAS_MODEL_LOADED(vsVehicle.ModelName) IF( bCarStealVehicle = TRUE ) vsVehicle.VehicleIndex = CREATE_CAR_STEAL_STRAND_CAR(vsVehicle.ModelName, vsVehicle.vPosition, vsVehicle.fHeading) SET_MODEL_AS_NO_LONGER_NEEDED(vsVehicle.ModelName) ELSE IF ( eCharacter = NO_CHARACTER ) vsVehicle.VehicleIndex = CREATE_VEHICLE(vsVehicle.ModelName, vsVehicle.vPosition, vsVehicle.fHeading) SET_MODEL_AS_NO_LONGER_NEEDED(vsVehicle.ModelName) ELSE //create npc vehicle based on the character enum specified IF CREATE_NPC_VEHICLE(vsVehicle.VehicleIndex, eCharacter, vsVehicle.vPosition, vsVehicle.fHeading) SET_MODEL_AS_NO_LONGER_NEEDED(vsVehicle.ModelName) ENDIF ENDIF ENDIF IF IS_VEHICLE_DRIVEABLE(vsVehicle.VehicleIndex) //set vehicle colours, if they are provided IF ( iColour1 != -1) AND ( iColour2 != -1 ) SET_VEHICLE_COLOURS(vsVehicle.VehicleIndex, iColour1, iColour2) ENDIF //set vehicle colour combination, if it is provided IF ( iColourCombination != -1 ) SET_VEHICLE_COLOUR_COMBINATION(vsVehicle.VehicleIndex, iColourCombination) ENDIF SET_VEHICLE_EXTRA_COLOURS(vsVehicle.VehicleIndex, iColour3, iColour4) SET_VEHICLE_HAS_STRONG_AXLES(vsVehicle.VehicleIndex, bMissionCritical) //limit damage that can be done to the vehicle SET_VEHICLE_CAN_LEAK_OIL(vsVehicle.VehicleIndex, NOT bMissionCritical) SET_VEHICLE_CAN_LEAK_PETROL(vsVehicle.VehicleIndex, NOT bMissionCritical) //make the vehicle not attach to tow truck if mission critical SET_VEHICLE_AUTOMATICALLY_ATTACHES(vsVehicle.VehicleIndex, NOT bMissionCritical) IF IS_THIS_MODEL_A_CAR(vsVehicle.ModelName) SET_DOOR_ALLOWED_TO_BE_BROKEN_OFF(vsVehicle.VehicleIndex, SC_DOOR_FRONT_LEFT, NOT bMissionCritical) SET_DOOR_ALLOWED_TO_BE_BROKEN_OFF(vsVehicle.VehicleIndex, SC_DOOR_FRONT_RIGHT, NOT bMissionCritical) SET_VEHICLE_TYRES_CAN_BURST(vsVehicle.VehicleIndex, NOT bMissionCritical) ENDIF SET_VEHICLE_ON_GROUND_PROPERLY(vsVehicle.VehicleIndex) ENDIF #IF IS_DEBUG_BUILD IF NOT Is_String_Null_Or_Empty(sDebugName) SET_VEHICLE_NAME_DEBUG(vsVehicle.VehicleIndex, sDebugName) IF ( bCarStealVehicle = TRUE ) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created car steal strand vehicle ", sDebugName, " with model ", GET_MODEL_NAME_FOR_DEBUG(vsVehicle.ModelName), " at coordinates ", vsVehicle.vPosition, " and heading ", vsVehicle.fHeading, ".") ELSE PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created vehicle ", sDebugName, " with model ", GET_MODEL_NAME_FOR_DEBUG(vsVehicle.ModelName), " at coordinates ", vsVehicle.vPosition, " and heading ", vsVehicle.fHeading, ".") ENDIF ELSE IF ( bCarStealVehicle = TRUE ) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created car steal strand vehicle with model ", GET_MODEL_NAME_FOR_DEBUG(vsVehicle.ModelName), " at coordinates ", vsVehicle.vPosition, " and heading ", vsVehicle.fHeading, ".") ELSE PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created vehicle with model ", GET_MODEL_NAME_FOR_DEBUG(vsVehicle.ModelName), " at coordinates ", vsVehicle.vPosition, " and heading ", vsVehicle.fHeading, ".") ENDIF ENDIF #ENDIF RETURN TRUE ENDIF ELSE //if the vehicle exists, return true RETURN TRUE ENDIF //create player specific vehicle ELIF ( bPlayerVehicle = TRUE ) IF NOT DOES_ENTITY_EXIST(vsVehicle.VehicleIndex) //call the player vehicle creation until it returns true IF CREATE_PLAYER_VEHICLE(vsVehicle.VehicleIndex, eCharacter, vsVehicle.vPosition, vsVehicle.fHeading, TRUE) SET_VEHICLE_HAS_STRONG_AXLES(vsVehicle.VehicleIndex, bMissionCritical) //limit damage that can be done to the vehicle SET_VEHICLE_CAN_LEAK_OIL(vsVehicle.VehicleIndex, NOT bMissionCritical) SET_VEHICLE_CAN_LEAK_PETROL(vsVehicle.VehicleIndex, NOT bMissionCritical) //make the vehicle not attach to tow truck if mission critical SET_VEHICLE_AUTOMATICALLY_ATTACHES(vsVehicle.VehicleIndex, NOT bMissionCritical) IF IS_THIS_MODEL_A_CAR(vsVehicle.ModelName) SET_DOOR_ALLOWED_TO_BE_BROKEN_OFF(vsVehicle.VehicleIndex, SC_DOOR_FRONT_LEFT, NOT bMissionCritical) SET_DOOR_ALLOWED_TO_BE_BROKEN_OFF(vsVehicle.VehicleIndex, SC_DOOR_FRONT_RIGHT, NOT bMissionCritical) SET_VEHICLE_TYRES_CAN_BURST(vsVehicle.VehicleIndex, NOT bMissionCritical) ENDIF #IF IS_DEBUG_BUILD IF NOT Is_String_Null_Or_Empty(sDebugName) SET_VEHICLE_NAME_DEBUG(vsVehicle.VehicleIndex, sDebugName) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created player vehicle ", sDebugName, " with model ", GET_MODEL_NAME_FOR_DEBUG(vsVehicle.ModelName), " at coordinates ", vsVehicle.vPosition, " and heading ", vsVehicle.fHeading, ".") ELSE PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created player vehicle with model ", GET_MODEL_NAME_FOR_DEBUG(vsVehicle.ModelName), " at coordinates ", vsVehicle.vPosition, " and heading ", vsVehicle.fHeading, ".") ENDIF #ENDIF RETURN TRUE ENDIF ELSE //if the vehicle exists, return true RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC FUNC BOOL IS_PLAYER_IN_CONTROL_OF_VEHICLE(VEHICLE_INDEX VehicleIndex) INT iLeftStickX, iLeftStickY, iRightStickX, iRightStickY IF IS_VEHICLE_DRIVEABLE(VehicleIndex) IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), VehicleIndex) GET_CONTROL_VALUE_OF_ANALOGUE_STICKS(iLeftStickX, iLeftStickY, iRightStickX, iRightStickY) IF (iLeftStickX < -20 OR iLeftStickX > 20) OR (iLeftStickY < -20 OR iLeftStickY > 20) OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_ACCELERATE) OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_BRAKE) OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_HANDBRAKE) OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_EXIT) OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_HEADLIGHT) OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_HORN) CLEAR_PED_TASKS(PLAYER_PED_ID()) RETURN TRUE ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Creates an object and returns TRUE if such object was created successfully. /// PARAMS: /// osObject - OBJECT_STRUCT containing model, position and rotation of the object. /// bFreezeObject - Specify if this object's position should be frozen. /// RETURNS: /// TRUE if object was created, FALSE if otherwise. FUNC BOOL HAS_MISSION_OBJECT_BEEN_CREATED(OBJECT_STRUCT &osObject, BOOL bFreezeObject = FALSE) IF NOT DOES_ENTITY_EXIST(osObject.ObjectIndex) REQUEST_MODEL(osObject.ModelName) IF HAS_MODEL_LOADED(osObject.ModelName) osObject.ObjectIndex = CREATE_OBJECT(osObject.ModelName, osObject.vPosition) SET_ENTITY_COORDS_NO_OFFSET(osObject.ObjectIndex, osObject.vPosition) SET_ENTITY_ROTATION(osObject.ObjectIndex, osObject.vRotation) FREEZE_ENTITY_POSITION(osObject.ObjectIndex, bFreezeObject) SET_ENTITY_INVINCIBLE(osObject.ObjectIndex, TRUE) SET_MODEL_AS_NO_LONGER_NEEDED(osObject.ModelName) ENDIF ENDIF IF DOES_ENTITY_EXIST(osObject.ObjectIndex) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created object with model ", GET_MODEL_NAME_FOR_DEBUG(osObject.ModelName), " at coordinates ", osObject.vPosition, ".") #ENDIF RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Performs a screen fade in with a wait for a specified time. /// PARAMS: /// iTime - Duration of the fade in miliseconds. PROC DO_SAFE_SCREEN_FADE_IN(INT iTime) IF NOT IS_SCREEN_FADED_IN() DO_SCREEN_FADE_IN(iTime) WHILE NOT IS_SCREEN_FADED_IN() WAIT(0) ENDWHILE ENDIF ENDPROC /// PURPOSE: /// Performs a screen fade out with a wait for a specified time. /// PARAMS: /// iTime - Duration of the fade in miliseconds. PROC DO_SAFE_SCREEN_FADE_OUT(INT iTime) IF NOT IS_SCREEN_FADED_OUT() DO_SCREEN_FADE_OUT(iTime) WHILE NOT IS_SCREEN_FADED_OUT() WAIT(0) ENDWHILE ENDIF ENDPROC /// PURPOSE: /// Stops an active mocap cutscene and waits until it has finished. PROC DO_SAFE_STOP_CUTSCENE() IF IS_CUTSCENE_PLAYING() SET_CUTSCENE_FADE_VALUES(FALSE, FALSE, FALSE, FALSE) STOP_CUTSCENE(TRUE) SET_SCRIPTS_SAFE_FOR_CUTSCENE(FALSE) //needs to be called to make sure all scripted systems work correctly when cutscene is skipped ENDIF WHILE NOT HAS_CUTSCENE_FINISHED() WAIT(0) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Waiting for the cutscene to finish.") #ENDIF ENDWHILE ENDPROC /// PURPOSE: /// Checks if the specified mocap cutscene has loaded. /// Removes any other loaded mocap cutscene and requests the specified cutscene until it is loaded. /// PARAMS: /// sSceneName - Mocap cutscene name to check for being loaded. /// CutsceneSection - Cutscene section specifying at what section to start the cutscene. Use CS_SECTION_1 to play from start. /// RETURNS: /// TRUE if the specified cutscene has loaded, FALSE if otherwise. FUNC BOOL HAS_REQUESTED_CUTSCENE_LOADED(STRING sSceneName, CUTSCENE_SECTION CutsceneSection = CS_SECTION_1) //check if the specified cutscene has loaded first IF HAS_THIS_CUTSCENE_LOADED_WITH_FAILSAFE(sSceneName) RETURN TRUE ELSE //if the expected reuqested cutscene has not loaded, but there already is a loaded cutscene //then remove it and keep requesting specified mocap cutscene IF HAS_CUTSCENE_LOADED_WITH_FAILSAFE() REMOVE_CUTSCENE() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": HAS_REQUESTED_CUTSCENE_LOADED() Removing cutscene from memory, because cutscene ", sSceneName, " was expected to be loaded.") #ENDIF ENDIF IF ( CutsceneSection = CS_SECTION_1) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Cutscene ", sSceneName, " is loading.") #ENDIF //if the cutscene is not loaded, keep requesting it REQUEST_CUTSCENE(sSceneName) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Requesting ", sSceneName, ".") #ENDIF ELSE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Cutscene ", sSceneName, " is loading with playback list.") #ENDIF //if the cutscene is not loaded, keep requesting it REQUEST_CUTSCENE_WITH_PLAYBACK_LIST(sSceneName, CutsceneSection) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Requesting ", sSceneName, " cutscene with playback list.") #ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC FUNC BOOL IS_VEHICLE_REVERSING(VEHICLE_INDEX VehicleIndex) IF DOES_ENTITY_EXIST(VehicleIndex) IF IS_VEHICLE_DRIVEABLE(VehicleIndex) VECTOR vVelocity = GET_ENTITY_SPEED_VECTOR(VehicleIndex, TRUE) IF ( vVelocity.y < -1.0 ) RETURN TRUE ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC FUNC BOOL IS_THIS_CONVERSATION_PLAYING(STRING sRoot) IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() TEXT_LABEL txtRoot = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT() IF ARE_STRINGS_EQUAL(sRoot, txtRoot) RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC PROC REMOVE_LABEL_ARRAY_SPACES() INT iArrayLength = COUNT_OF(iTriggeredTextHashes) INT i = 0 REPEAT (iArrayLength - 1) i IF iTriggeredTextHashes[i] = 0 IF iTriggeredTextHashes[i+1] != 0 iTriggeredTextHashes[i] = iTriggeredTextHashes[i+1] iTriggeredTextHashes[i+1] = 0 ENDIF ENDIF ENDREPEAT ENDPROC FUNC INT GET_LABEL_INDEX(INT iLabelHash) INT i = 0 REPEAT iNumTextHashesStored i IF iTriggeredTextHashes[i] = iLabelHash RETURN i ENDIF ENDREPEAT RETURN -1 ENDFUNC FUNC BOOL HAS_LABEL_BEEN_TRIGGERED(STRING strLabel) INT iHash = GET_HASH_KEY(strLabel) IF GET_LABEL_INDEX(iHash) != -1 RETURN TRUE ENDIF RETURN FALSE ENDFUNC PROC SET_LABEL_AS_TRIGGERED(STRING strLabel, BOOL bTrigger) INT iHash = GET_HASH_KEY(strLabel) IF bTrigger IF NOT HAS_LABEL_BEEN_TRIGGERED(strLabel) INT iArraySize = COUNT_OF(iTriggeredTextHashes) IF iNumTextHashesStored < iArraySize iTriggeredTextHashes[iNumTextHashesStored] = iHash iNumTextHashesStored++ #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": SET_LABEL_AS_TRIGGERED(): ", strLabel, " TRUE.") PRINTLN(GET_THIS_SCRIPT_NAME(), ": SET_LABEL_AS_TRIGGERED(): ", iNumTextHashesStored, "/", COUNT_OF(iTriggeredTextHashes), ".") #ENDIF ELSE #IF IS_DEBUG_BUILD SCRIPT_ASSERT("SET_LABEL_AS_TRIGGERED: Label array is full.") #ENDIF ENDIF ENDIF ELSE INT iIndex = GET_LABEL_INDEX(iHash) IF iIndex != -1 iTriggeredTextHashes[iIndex] = 0 REMOVE_LABEL_ARRAY_SPACES() iNumTextHashesStored-- #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": SET_LABEL_AS_TRIGGERED(): ", strLabel, " FALSE.") PRINTLN(GET_THIS_SCRIPT_NAME(), ": SET_LABEL_AS_TRIGGERED(): ", iNumTextHashesStored, "/", COUNT_OF(iTriggeredTextHashes), ".") #ENDIF ENDIF ENDIF ENDPROC PROC CLEAR_TRIGGERED_LABELS() INT iArraySize = COUNT_OF(iTriggeredTextHashes) INT i = 0 REPEAT iArraySize i iTriggeredTextHashes[i] = 0 ENDREPEAT iNumTextHashesStored = 0 ENDPROC PROC UPDATE_TRIGGERED_LABEL(TEXT_LABEL &sLabel) IF NOT IS_STRING_NULL_OR_EMPTY(sLabel) //if the label is not empty, which means not yet printed by locates header IF NOT HAS_LABEL_BEEN_TRIGGERED(sLabel) //if it was not set as triggered by script IF IS_THIS_PRINT_BEING_DISPLAYED(sLabel) //if the label was displayed on screen SET_LABEL_AS_TRIGGERED(sLabel, TRUE) //mark it as triggered ENDIF ELSE //if the label was set as triggered by script, //which means it was printed by locates header IF NOT IS_THIS_PRINT_BEING_DISPLAYED(sLabel) //but is not currently being printed, cleared off screen or timed out sLabel = "" //mark is as empty ENDIF ENDIF ENDIF ENDPROC PROC PRINT_GOD_TEXT_ADVANCED(STRING sLabel, INT iDuration = DEFAULT_GOD_TEXT_TIME, BOOL bOnce = TRUE) IF NOT HAS_LABEL_BEEN_TRIGGERED(sLabel) PRINT(sLabel, iDuration, 1) SET_LABEL_AS_TRIGGERED(sLabel, bOnce) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Printing god text ", sLabel, ".") #ENDIF ENDIF ENDPROC /// PURPOSE: /// Returns the next mission stage after the specified mission stage. /// PARAMS: /// eStage - Mission stage to get the next mission stage. /// RETURNS: /// Mission stage that is next after the specified mission stage. FUNC MISSION_STAGES GET_NEXT_MISSION_STAGE(MISSION_STAGES eStage) IF eStage = MISSION_STAGE_CUTSCENE_END RETURN MISSION_STAGE_CUTSCENE_END ENDIF MISSION_STAGES eNextStage INT iNextStage = ENUM_TO_INT(eStage) + 1 eNextStage = INT_TO_ENUM(MISSION_STAGES, iNextStage) RETURN eNextStage ENDFUNC /// PURPOSE: /// Check is the specified time has passed using specified timer. /// PARAMS: /// iTimeAmount - Time to check. /// iTimer - Timer to use. /// RETURNS: /// True is the specified amount of time has passed for the specified timer. FUNC BOOL HAS_TIME_PASSED(INT iTimeAmount, INT iTimer) INT iCurrentTime INT iTimeDifference iCurrentTime = GET_GAME_TIMER() iTimeDifference = iCurrentTime - iTimeAmount IF iTimeDifference > iTimer RETURN TRUE ENDIF RETURN FALSE ENDFUNC PROC CLEANUP_RAYFIRE_MAP_OBJECT(BOOL bSendToStart = TRUE, BOOL bWaitForPlayerToLeaveArea = FALSE) IF ( bSendToStart = TRUE ) //send to start_state by setting state to starting state SET_BUILDING_STATE(BUILDINGNAME_RF_STILT_HOUSE, BUILDINGSTATE_NORMAL, bWaitForPlayerToLeaveArea) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting BUILDINGNAME_RF_STILT_HOUSE to BUILDINGSTATE_NORMAL.") #ENDIF ELSE SET_BUILDING_STATE(BUILDINGNAME_RF_STILT_HOUSE, BUILDINGSTATE_DESTROYED, bWaitForPlayerToLeaveArea) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting BUILDINGNAME_RF_STILT_HOUSE to BUILDINGSTATE_DESTROYED.") #ENDIF ENDIF ENDPROC PROC CLEANUP_PED(PED_STRUCT &ped, BOOL bDelete = FALSE, BOOL bDeathOnly = TRUE, BOOL bKeepTask = TRUE) IF ( bDelete = FALSE ) IF DOES_ENTITY_EXIST(ped.PedIndex) IF ( bDeathOnly = TRUE ) IF IS_PED_INJURED(ped.PedIndex) IF IS_ENTITY_DEAD(ped.PedIndex) REMOVE_PED_DEFENSIVE_AREA(ped.PedIndex) ENDIF SET_PED_AS_NO_LONGER_NEEDED(ped.PedIndex) IF DOES_BLIP_EXIST(ped.BlipIndex) REMOVE_BLIP(ped.BlipIndex) ENDIF ENDIF ELIF ( bDeathOnly = FALSE ) IF NOT IS_PED_INJURED(ped.PedIndex) IF NOT IS_PED_INJURED(ped.PedIndex) IF IS_PED_GROUP_MEMBER(ped.PedIndex, PLAYER_GROUP_ID()) REMOVE_PED_FROM_GROUP(ped.PedIndex) ENDIF ENDIF SET_PED_KEEP_TASK(ped.PedIndex, bKeepTask) SET_PED_AS_NO_LONGER_NEEDED(ped.PedIndex) IF DOES_BLIP_EXIST(ped.BlipIndex) REMOVE_BLIP(ped.BlipIndex) ENDIF ENDIF ENDIF ENDIF ELIF ( bDelete = TRUE ) IF DOES_ENTITY_EXIST(ped.PedIndex) IF NOT IS_PED_INJURED(ped.PedIndex) IF IS_PED_GROUP_MEMBER(ped.PedIndex, PLAYER_GROUP_ID()) REMOVE_PED_FROM_GROUP(ped.PedIndex) ENDIF ENDIF IF NOT IS_PED_INJURED(ped.PedIndex) REMOVE_PED_DEFENSIVE_AREA(ped.PedIndex) ENDIF DELETE_PED(ped.PedIndex) ENDIF IF DOES_BLIP_EXIST(ped.BlipIndex) REMOVE_BLIP(ped.BlipIndex) ENDIF ped.iTimer = 0 ped.iConversationTimer = 0 ped.iConversationCounter = 0 ped.iAgressiveTimer = 0 ped.iProgress = 0 ped.iCleanupAttempts = 0 ped.fDistanceToTarget = 0.0 ped.bHasTask = FALSE ped.bCleanupConversationTriggered = FALSE ped.eCleanupReason = PED_CLEANUP_NO_CLEANUP ENDIF ENDPROC PROC CLEANUP_PED_GROUP(PED_STRUCT &array[], BOOL bDelete = FALSE, BOOL bDeathOnly = TRUE, BOOL bKeepTask = TRUE) INT i = 0 FOR i = 0 TO ( COUNT_OF(array) - 1 ) CLEANUP_PED(array[i], bDelete, bDeathOnly, bKeepTask) ENDFOR ENDPROC PROC CLEANUP_VEHICLE(VEH_STRUCT &vehicle, BOOL bDelete = FALSE, BOOL bDeathOnly = TRUE) IF ( bDelete = FALSE ) IF DOES_ENTITY_EXIST(vehicle.VehicleIndex) IF ( bDeathOnly = TRUE ) IF NOT IS_VEHICLE_DRIVEABLE(vehicle.VehicleIndex) OR IS_ENTITY_DEAD(vehicle.VehicleIndex) REMOVE_VEHICLE_STUCK_CHECK(vehicle.VehicleIndex) REMOVE_VEHICLE_UPSIDEDOWN_CHECK(vehicle.VehicleIndex) REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(vehicle.VehicleIndex) SET_VEHICLE_AS_NO_LONGER_NEEDED(vehicle.VehicleIndex) ENDIF IF DOES_BLIP_EXIST(vehicle.BlipIndex) REMOVE_BLIP(vehicle.BlipIndex) ENDIF ELIF ( bDeathOnly = FALSE ) IF NOT IS_ENTITY_DEAD(vehicle.VehicleIndex) REMOVE_VEHICLE_STUCK_CHECK(vehicle.VehicleIndex) REMOVE_VEHICLE_UPSIDEDOWN_CHECK(vehicle.VehicleIndex) REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(vehicle.VehicleIndex) SET_VEHICLE_AS_NO_LONGER_NEEDED(vehicle.VehicleIndex) ENDIF IF DOES_BLIP_EXIST(vehicle.BlipIndex) REMOVE_BLIP(vehicle.BlipIndex) ENDIF ENDIF ENDIF ELIF ( bDelete = TRUE ) IF DOES_ENTITY_EXIST(vehicle.VehicleIndex) IF IS_ENTITY_A_MISSION_ENTITY(vehicle.VehicleIndex) IF IS_ENTITY_DEAD(vehicle.VehicleIndex) OR NOT IS_ENTITY_DEAD(vehicle.VehicleIndex) REMOVE_VEHICLE_STUCK_CHECK(vehicle.VehicleIndex) REMOVE_VEHICLE_UPSIDEDOWN_CHECK(vehicle.VehicleIndex) REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(vehicle.VehicleIndex) DELETE_VEHICLE(vehicle.VehicleIndex) ENDIF ENDIF ENDIF IF DOES_BLIP_EXIST(vehicle.BlipIndex) REMOVE_BLIP(vehicle.BlipIndex) ENDIF vehicle.iProgress = 0 vehicle.bAutoDrive = FALSE vehicle.bLOSFlag = FALSE vehicle.iWarpTimer = 0 vehicle.vTargetPosition = << 0.0, 0.0, 0.0 >> vehicle.fTargetHeading = 0.0 vehicle.fDistanceToTarget = 0.0 ENDIF ENDPROC PROC CLEANUP_VEHICLE_GROUP(VEH_STRUCT &vsArray[], BOOL bDelete = FALSE, BOOL bDeathOnly = TRUE) INT i = 0 FOR i = 0 TO ( COUNT_OF(vsArray) - 1 ) CLEANUP_VEHICLE(vsArray[i], bDelete, bDeathOnly) ENDFOR ENDPROC FUNC PED_INDEX CREATE_ENEMY_PED_IN_VEHICLE(VEHICLE_INDEX VehicleIndex, MODEL_NAMES ModelName, VEHICLE_SEAT eVehicleSeat, INT iHealth = 200, WEAPON_TYPE eWeaponType = WEAPONTYPE_UNARMED #IF IS_DEBUG_BUILD, STRING sDebugName = NULL #ENDIF) IF IS_VEHICLE_DRIVEABLE(VehicleIndex) PED_INDEX PedIndex = CREATE_PED_INSIDE_VEHICLE(VehicleIndex, PEDTYPE_MISSION, ModelName, eVehicleSeat) SET_PED_MAX_HEALTH(PedIndex, iHealth) SET_ENTITY_HEALTH(PedIndex, iHealth) SET_PED_DIES_WHEN_INJURED(PedIndex, TRUE) GIVE_WEAPON_TO_PED(PedIndex, eWeaponType, INFINITE_AMMO, FALSE) SET_PED_INFINITE_AMMO(PedIndex, TRUE, eWeaponType) SET_PED_RELATIONSHIP_GROUP_HASH(PedIndex, rgEnemies) SET_PED_AS_ENEMY(PedIndex, TRUE) SET_PED_TARGET_LOSS_RESPONSE(PedIndex, TLR_NEVER_LOSE_TARGET) SET_PED_FLEE_ATTRIBUTES(PedIndex, FA_NEVER_FLEE, TRUE) SET_PED_COMBAT_ATTRIBUTES(PedIndex, CA_ALWAYS_FLEE, FALSE) SET_PED_COMBAT_ATTRIBUTES(PedIndex, CA_ALWAYS_FIGHT, TRUE) SET_PED_CONFIG_FLAG(PedIndex, PCF_DisableHurt, TRUE) SET_PED_CONFIG_FLAG(PedIndex, PCF_RunFromFiresAndExplosions, FALSE) SET_PED_CONFIG_FLAG(PedIndex, PCF_KeepRelationshipGroupAfterCleanUp, TRUE) SET_PED_CONFIG_FLAG(PedIndex, PCF_AllowToBeTargetedInAVehicle, TRUE) SET_ENTITY_IS_TARGET_PRIORITY(PedIndex, TRUE) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PedIndex, TRUE) #IF IS_DEBUG_BUILD IF NOT Is_String_Null_Or_Empty(sDebugName) SET_PED_NAME_DEBUG(PedIndex, sDebugName) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created enemy ped in vehicle with debug name ", sDebugName, ".") ELSE PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created enemy ped in vehicle.") ENDIF #ENDIF RETURN PedIndex ENDIF RETURN NULL ENDFUNC /// PURPOSE: /// Checks if specified ped is using petrol can weapon to pour petrol at or around the specified entity. /// PARAMS: /// PedIndex - Ped to check for petrol can usage. /// EntityIndex - Entity to check for petrol being used against. /// fRadius - Radius to check around the specified entity. /// RETURNS: /// TRUE if specified ped is using petrol can to pour petrol around specified entity in the specified radius. FALSE if otherwise. FUNC BOOL IS_PED_USING_PETROL_CAN_AT_ENTITY(PED_INDEX PedIndex, ENTITY_INDEX EntityIndex, FLOAT fRadius = 2.5 #IF IS_DEBUG_BUILD, BOOL bDrawDebugSphere = TRUE, INT iRed = 0, INT iGreen = 255, INT iBlue = 0, INT iAlpha = 128 #ENDIF) IF NOT IS_PED_INJURED(PedIndex) IF DOES_ENTITY_EXIST(EntityIndex) IF NOT IS_ENTITY_DEAD(EntityIndex) WEAPON_TYPE PedCurrentWeaponType IF GET_CURRENT_PED_WEAPON(PedIndex, PedCurrentWeaponType) //check if ped has petrol can equipped first IF ( PedCurrentWeaponType = WEAPONTYPE_PETROLCAN ) VECTOR vEntityPosition = GET_ENTITY_COORDS(EntityIndex) FLOAT fGroundZ IF GET_GROUND_Z_FOR_3D_COORD(vEntityPosition, fGroundZ) vEntityPosition.Z = fGroundZ ENDIF //draw debug sphere to visualise the check area, this will only draw when petrol can is equipped by ped #IF IS_DEBUG_BUILD IF ( bDrawDebugSphere = TRUE ) DRAW_DEBUG_SPHERE(vEntityPosition, fRadius, iRed, iGreen, iBlue, iAlpha) ENDIF #ENDIF //check if ped is using petrol can and if any petrol decals are the entity IF IS_PED_SHOOTING(PedIndex) AND GET_IS_PETROL_DECAL_IN_RANGE(vEntityPosition, fRadius) RETURN TRUE ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC FUNC BOOL IS_PED_DRIVING_VEHICLE(PED_INDEX PedIndex, VEHICLE_INDEX VehicleIndex) IF DOES_ENTITY_EXIST(PedIndex) AND NOT IS_ENTITY_DEAD(PedIndex) IF DOES_ENTITY_EXIST(VehicleIndex) AND NOT IS_ENTITY_DEAD(VehicleIndex) IF IS_PED_SITTING_IN_VEHICLE(PedIndex, VehicleIndex) IF NOT IS_VEHICLE_STOPPED(VehicleIndex) RETURN TRUE ENDIF ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC PROC MAKE_PED_FLEE_PED(PED_INDEX PedIndex, PED_INDEX PedIndexToFleeFrom, FLOAT fSafeDistance, INT iTime) IF NOT IS_PED_INJURED(PedIndexToFleeFrom) IF DOES_ENTITY_EXIST(PedIndex) IF NOT IS_PED_INJURED(PedIndex) CLEAR_PED_TASKS(PedIndex) SET_PED_FLEE_ATTRIBUTES(PedIndex, FA_CAN_SCREAM, TRUE) TASK_SMART_FLEE_PED(PedIndex, PedIndexToFleeFrom, fSafeDistance, iTime) SET_PED_KEEP_TASK(PedIndex, TRUE) ENDIF ENDIF ENDIF ENDPROC PROC START_VEHICLE_RECORDING_PLAYBACK_FOR_VEHICLE(VEH_STRUCT vsCar, STRING sFileName, FLOAT fPlaybackSpeed, BOOL bPaused = FALSE, FLOAT fTime = 0.0, BOOL bSkipToVehiclePosition = FALSE, BOOL bUseFlags = FALSE, INT iFlags = SWITCH_ON_PLAYER_VEHICLE_IMPACT) IF IS_VEHICLE_DRIVEABLE(vsCar.VehicleIndex) IF NOT IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vsCar.VehicleIndex) IF HAS_VEHICLE_RECORDING_BEEN_LOADED(vsCar.iRecordingNumber, sFileName) IF ( bUseFlags = FALSE ) START_PLAYBACK_RECORDED_VEHICLE(vsCar.VehicleIndex, vsCar.iRecordingNumber, sFileName) ELIF ( bUseFlags = TRUE ) START_PLAYBACK_RECORDED_VEHICLE_WITH_FLAGS(vsCar.VehicleIndex, vsCar.iRecordingNumber, sFileName, iFlags) ENDIF IF ( fTime > 0.0 ) SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(vsCar.VehicleIndex, fTime) ELIF ( bSkipToVehiclePosition = TRUE ) SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(vsCar.VehicleIndex, GET_CLOSEST_TIME_POSITION_IN_RECORDING_TO_POINT(GET_ENTITY_COORDS(vsCar.VehicleIndex), vsCar.iRecordingNumber, sFileName, 16)) ENDIF SET_PLAYBACK_SPEED(vsCar.VehicleIndex, fPlaybackSpeed) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Vehicle recording ", sFileName, " number ", vsCar.iRecordingNumber, " for vehicle ", GET_MODEL_NAME_FOR_DEBUG(vsCar.ModelName), " started with playback speed ", fPlaybackSpeed, "and time ", fTime, ".") #ENDIF IF ( bPaused = TRUE ) PAUSE_PLAYBACK_RECORDED_VEHICLE(vsCar.VehicleIndex) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Vehicle recording ", sFileName, " number ", vsCar.iRecordingNumber, " for vehicle ", GET_MODEL_NAME_FOR_DEBUG(vsCar.ModelName), " paused.") #ENDIF ENDIF ELSE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Vehicle recording number ", vsCar.iRecordingNumber, " for vehicle ", GET_MODEL_NAME_FOR_DEBUG(vsCar.ModelName), " is not loaded.") #ENDIF ENDIF ENDIF ENDIF ENDPROC //Author: Ross Wallace //PURPOSE: Returns the percentage progress of a car recording... FUNC FLOAT GET_VEHICLE_RECORDING_PLAYBACK_PERCENTAGE(VEHICLE_INDEX VehicleIndex #IF IS_DEBUG_BUILD, BOOL bPrintOutput = FALSE #ENDIF) IF DOES_ENTITY_EXIST(VehicleIndex) AND IS_VEHICLE_DRIVEABLE(VehicleIndex) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(VehicleIndex) RECORDING_ID RecordingID = GET_CURRENT_PLAYBACK_FOR_VEHICLE(VehicleIndex) #IF IS_DEBUG_BUILD INT iPercentage = ROUND( 100.0 * ( GET_TIME_POSITION_IN_RECORDING(VehicleIndex) / GET_TOTAL_DURATION_OF_VEHICLE_RECORDING_ID(RecordingID) ) ) TEXT_LABEL_63 debugName = GET_VEHICLE_RECORDING_NAME(RecordingID) debugName += ":" debugName += iPercentage SET_VEHICLE_NAME_DEBUG(VehicleIndex, debugName) #ENDIF #IF IS_DEBUG_BUILD IF ( bPrintOutput = TRUE ) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Recording ", GET_VEHICLE_RECORDING_NAME(RecordingID), " time is ", GET_TIME_POSITION_IN_RECORDING(VehicleIndex), ".") ENDIF #ENDIF RETURN ( 100.0 * ( GET_TIME_POSITION_IN_RECORDING(VehicleIndex) / GET_TOTAL_DURATION_OF_VEHICLE_RECORDING_ID(RecordingID) ) ) ELSE #IF IS_DEBUG_BUILD IF ( bPrintOutput = TRUE ) PRINTLN(GET_THIS_SCRIPT_NAME(), ": GET_VEHICLE_RECORDING_PLAYBACK_PERCENTAGE: Playback not going on for vehicle.") ENDIF #ENDIF ENDIF ELSE #IF IS_DEBUG_BUILD IF ( bPrintOutput = TRUE ) PRINTLN(GET_THIS_SCRIPT_NAME(), ": GET_VEHICLE_RECORDING_PLAYBACK_PERCENTAGE: Vehicle does not exist or is not driveable.") ENDIF #ENDIF ENDIF RETURN -1.0 ENDFUNC //|======================= END MISCELLANEOUS PROCEDURES & FUNCTIONS ======================| //|=================================== MATH FUNCTIONS ====================================| /// PURPOSE: /// Returns the lowest int value from two specified int values. /// PARAMS: /// iValueA - First int value. /// iValueB - Second int value. /// RETURNS: /// Lowest int value of the two. FUNC INT GET_MINIMUM_INT(INT iValueA, INT iValueB) IF (iValueA = iValueB) RETURN iValueA ELIF (iValueA > iValueB) RETURN iValueB ELIF (iValueA < iValueB) RETURN iValueA ENDIF RETURN iValueA ENDFUNC //|================================= END MATH FUNCTIONS ==================================| //|======================= DEBUG VARIABLES, PROCEDURES & FUNCTIONS =======================| #IF IS_DEBUG_BUILD //mission skip menu and widget variables MissionStageMenuTextStruct SkipMenu[9] INT iReturnStage = 0 BOOL bStageResetFlag BOOL bCoachStartToggle = FALSE BOOL bCoachStopToggle = FALSE BOOL bPrintDebugOutput = FALSE VECTOR vRopeTruckAttachmentOffset BOOL bDrawDebugLinesAndSpheres BOOL bDrawDebugStates BOOL bToggleVehicleExtra //debug widgets variables WIDGET_GROUP_ID Family3Widgets /// PURPOSE: /// Returns string name of the specified mission stage. /// PARAMS: /// eStage - Mission stage to get string name for. /// RETURNS: /// String name of the specified mission stage. FUNC STRING GET_MISSION_STAGE_NAME_FOR_DEBUG(MISSION_STAGES eStage) SWITCH eStage CASE MISSION_STAGE_CUTSCENE_INTRO RETURN "MISSION_STAGE_CUTSCENE_INTRO" BREAK CASE MISSION_STAGE_CAR_CHASE RETURN "MISSION_STAGE_CAR_CHASE" BREAK CASE MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE RETURN "MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE" BREAK CASE MISSION_STAGE_PULL_HOUSE_DOWN RETURN "MISSION_STAGE_PULL_HOUSE_DOWN" BREAK CASE MISSION_STAGE_ESCAPE_GOONS RETURN "MISSION_STAGE_ESCAPE_GOONS" BREAK CASE MISSION_STAGE_CUTSCENE_END RETURN "MISSION_STAGE_CUTSCENE_END" BREAK CASE MISSION_STAGE_LEADOUT RETURN "MISSION_STAGE_LEADOUT" BREAK CASE MISSION_STAGE_DEBUG_RECORD_CHASE RETURN "MISSION_STAGE_DEBUG_RECORD_CHASE" BREAK CASE MISSION_STAGE_DEBUG_PLAYBACK_CHASE RETURN "MISSION_STAGE_DEBUG_PLAYBACK_CHASE" BREAK ENDSWITCH RETURN "INCORRECT_MISSION_STAGE" ENDFUNC FUNC STRING GET_MISSION_FAIL_NAME_FOR_DEBUG(MISSION_FAILS eFailReason) SWITCH eFailReason CASE MISSION_FAIL_CAR_DESTROYED RETURN "MISSION_FAIL_CAR_DESTROYED" BREAK CASE MISSION_FAIL_CAR_STUCK RETURN "MISSION_FAIL_CAR_STUCK" BREAK CASE MISSION_FAIL_MICHAEL_DEAD RETURN "MISSION_FAIL_MICHAEL_DEAD" BREAK CASE MISSION_FAIL_MICHAEL_LEFT_BEHIND RETURN "MISSION_FAIL_MICHAEL_LEFT_BEHIND" BREAK CASE MISSION_FAIL_FRANKLIN_DEAD RETURN "MISSION_FAIL_FRANKLIN_DEAD" BREAK CASE MISSION_FAIL_FRANKLIN_LEFT_BEHIND RETURN "MISSION_FAIL_FRANKLIN_LEFT_BEHIND" BREAK CASE MISSION_FAIL_COACH_ATTACKED RETURN "MISSION_FAIL_COACH_ATTACKED" BREAK CASE MISSION_FAIL_COACH_DEAD RETURN "MISSION_FAIL_COACH_DEAD" BREAK CASE MISSION_FAIL_COACH_SPOOKED RETURN "MISSION_FAIL_COACH_SPOOKED" BREAK CASE MISSION_FAIL_FORCE_FAIL RETURN "MISSION_FAIL_FORCE_FAIL" BREAK ENDSWITCH RETURN "INCORRECT_MISSION_FAIL" ENDFUNC FUNC STRING GET_PED_STATE_NAME_FOR_DEBUG(PED_STATES eState) SWITCH eState CASE PED_STATE_IDLE RETURN "PED_STATE_IDLE" BREAK CASE PED_STATE_ON_FOOT RETURN "PED_STATE_ON_FOOT" BREAK CASE PED_STATE_COMBAT_ON_FOOT RETURN "PED_STATE_COMBAT_ON_FOOT" BREAK CASE PED_STATE_COMBAT_FROM_CAR_NO_SHOOTING RETURN "PED_STATE_COMBAT_FROM_CAR_NO_SHOOTING" BREAK CASE PED_STATE_COMBAT_FROM_CAR_SHOOTING RETURN "PED_STATE_COMBAT_FROM_CAR_SHOOTING" BREAK CASE PED_STATE_ENTERING_VEHICLE RETURN "PED_STATE_ENTERING_VEHICLE" BREAK CASE PED_STATE_SITTING_IN_VEHICLE_PASSENGER RETURN "PED_STATE_SITTING_IN_VEHICLE_PASSENGER" BREAK CASE PED_STATE_SITTING_IN_VEHICLE_DRIVER RETURN "PED_STATE_SITTING_IN_VEHICLE_DRIVER" BREAK CASE PED_STATE_SHUFFLING_VEHICLE_SEATS RETURN "PED_STATE_SHUFFLING_VEHICLE_SEATS" BREAK CASE PED_STATE_LOOKING_BEHIND_IN_VEHICLE RETURN "PED_STATE_LOOKING_BEHIND_IN_VEHICLE" BREAK CASE PED_STATE_DRIVE_FLEE_TARGETS RETURN "PED_STATE_DRIVE_FLEE_TARGETS" BREAK CASE PED_STATE_DRIVE_FLEE_COPS RETURN "PED_STATE_DRIVE_FLEE_COPS" BREAK CASE PED_STATE_DRIVE_TO_DESTINATION RETURN "PED_STATE_DRIVE_TO_DESTINATION" BREAK CASE PED_STATE_FOLLOWING_PLAYER RETURN "PED_STATE_FOLLOWING_PLAYER" BREAK CASE PED_STATE_WAITING_FOR_PLAYER RETURN "PED_STATE_WAITING_FOR_PLAYER" BREAK CASE PED_STATE_WAITING_FOR_TASK_AFTER_SWITCH RETURN "PED_STATE_WAITING_FOR_TASK_AFTER_SWITCH" BREAK DEFAULT RETURN "INVALID_PED_STATE" BREAK ENDSWITCH RETURN "INVALID_PED_STATE" ENDFUNC PROC CREATE_DEBUG_WIDGETS() Family3Widgets = START_WIDGET_GROUP("Mission: Family3") ADD_WIDGET_BOOL("Print debug output", bPrintDebugOutput) ADD_WIDGET_BOOL("bAllowHotSwap", bAllowHotSwap) ADD_WIDGET_BOOL("bToggleVehicleExtra", bToggleVehicleExtra) START_WIDGET_GROUP("Camera Hints") ADD_WIDGET_VECTOR_SLIDER("vTennisCoachHintPosition", vTennisCoachHintPosition, -2000.0, 2000.0, 1.0) ADD_WIDGET_VECTOR_SLIDER("vTennisCoachHintPosition", vTennisCoachHintPosition, -2000.0, 2000.0, 1.0) STOP_WIDGET_GROUP() START_WIDGET_GROUP("House Pull") ADD_WIDGET_VECTOR_SLIDER("Rope Truck Attachment Offset", vRopeTruckAttachmentOffset, -10.0, 10.0, 0.1) ADD_WIDGET_FLOAT_READ_ONLY("Rayfire phase", fRayfirePhase) ADD_WIDGET_FLOAT_SLIDER("fForceConverge", fForceConverge, 0.0, 1.0, 0.01) ADD_WIDGET_FLOAT_SLIDER("fSideForceValue", fSideForceValue, -500.0, 500.0, 1.0) ADD_WIDGET_FLOAT_SLIDER("fDownForceValue", fDownForceValue, -500.0, 500.0, 1.0) ADD_WIDGET_VECTOR_SLIDER("Force Back Offset", vForceBackOffset, -10.0, 10.0, 0.1) STOP_WIDGET_GROUP() START_WIDGET_GROUP("Goons chase") ADD_WIDGET_BOOL("bGoonsAllowed", bGoonsAllowed) ADD_WIDGET_FLOAT_SLIDER("BLIP_SLIDE_AMOUNT", BLIP_SLIDE_AMOUNT, 0.0, 256.0, 1.0) ADD_WIDGET_VECTOR_SLIDER("vEnemyCarsOffset[0]", vEnemyCarsOffset[0], -10.0, 10.0, 0.1) ADD_WIDGET_VECTOR_SLIDER("vEnemyCarsOffset[1]", vEnemyCarsOffset[1], -10.0, 10.0, 0.1) STOP_WIDGET_GROUP() START_WIDGET_GROUP("Uber car chase") ADD_WIDGET_BOOL("Start coach playback", bCoachStartToggle) ADD_WIDGET_BOOL("Stop coach playback", bCoachStopToggle) STOP_WIDGET_GROUP() ADD_WIDGET_INT_SLIDER("iFirstPersonFlashTime", iFirstPersonFlashTime, 0, 5000, 100) ADD_WIDGET_FLOAT_SLIDER("fFirstPersonFlashPhase1", fFirstPersonFlashPhase1, 0.0, 1.0, 0.01) ADD_WIDGET_FLOAT_SLIDER("fFirstPersonFlashPhase2", fFirstPersonFlashPhase2, 0.0, 1.0, 0.01) ADD_WIDGET_FLOAT_SLIDER("fFirstPersonFlashPhase3", fFirstPersonFlashPhase3, 0.0, 1.0, 0.01) STOP_WIDGET_GROUP() SET_UBER_PARENT_WIDGET_GROUP(Family3Widgets) SET_LOCATES_HEADER_WIDGET_GROUP(Family3Widgets) ENDPROC PROC DELETE_DEBUG_WIDGETS() IF DOES_WIDGET_GROUP_EXIST(Family3Widgets) DELETE_WIDGET_GROUP(Family3Widgets) ENDIF ENDPROC PROC RUN_DEBUG_WIDGETS(MISSION_STAGES eStage) IF ( bDrawDebugStates = TRUE ) DRAW_DEBUG_SPHERE(vTennisCoachHintPosition, 0.1, 255, 0, 0) DRAW_DEBUG_SPHERE(vBalconyHintPosition, 0.1, 0, 0, 255) ENDIF SWITCH eStage CASE MISSION_STAGE_DEBUG_RECORD_CHASE CASE MISSION_STAGE_DEBUG_PLAYBACK_CHASE IF ( bCoachStartToggle = TRUE ) START_VEHICLE_RECORDING_PLAYBACK_FOR_VEHICLE(vsCoachsCar, sVehicleRecordingsFile, 1.0) SET_ENTITY_COLLISION(vsCoachsCar.VehicleIndex, FALSE) bCoachStartToggle = FALSE ENDIF IF ( bCoachStopToggle = TRUE ) STOP_PLAYBACK_RECORDED_VEHICLE(vsCoachsCar.VehicleIndex) SET_ENTITY_COLLISION(vsCoachsCar.VehicleIndex, TRUE) bCoachStopToggle = FALSE ENDIF BREAK ENDSWITCH IF ( bToggleVehicleExtra = TRUE ) IF DOES_ENTITY_EXIST(vsPlayersCar.VehicleIndex) IF NOT IS_ENTITY_DEAD(vsPlayersCar.VehicleIndex) IF IS_VEHICLE_EXTRA_TURNED_ON(vsPlayersCar.VehicleIndex, 5) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Vehicle extra 5 is ON.") SET_VEHICLE_EXTRA(vsPlayersCar.VehicleIndex, 5, TRUE) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Switching vehicle extra OFF.") ELSE PRINTLN(GET_THIS_SCRIPT_NAME(), ": Vehicle extra 5 is OFF.") SET_VEHICLE_EXTRA(vsPlayersCar.VehicleIndex, 5, FALSE) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Switching vehicle extra ON.") ENDIF ENDIF ENDIF bToggleVehicleExtra = FALSE ENDIF ENDPROC /// PURPOSE: /// Creates debug mission stage menu. PROC CREATE_DEBUG_MISSION_STAGE_MENU() SkipMenu[0].sTxtLabel = "CUT - INTRO - FAMILY_3_INT" SkipMenu[1].sTxtLabel = "CAR CHASE" SkipMenu[2].sTxtLabel = "CUT - BALCONY - FAM_3_MCS_1" SkipMenu[3].sTxtLabel = "PULL HOUSE DOWN" SkipMenu[4].sTxtLabel = "ESCAPE GOONS" SkipMenu[5].sTxtLabel = "CUT - END - FAMILY_3_EXT" SkipMenu[6].sTxtLabel = "LEADOUT" SkipMenu[7].sTxtLabel = "DEBUG - RECORD CHASE" SkipMenu[8].sTxtLabel = "DEBUG - PLAYBACK CHASE" ENDPROC /// PURPOSE: /// Checks if any of the debug pass or fail keys has been pressed to force mission end. /// PARAMS: /// eStage - Mission stage variable /// eFailReason - Mission fail variable. PROC RUN_DEBUG_PASS_AND_FAIL_CHECK(MISSION_STAGES &eStage, MISSION_FAILS &eFailReason) IF IS_KEYBOARD_KEY_PRESSED (KEY_S) eStage = MISSION_STAGE_PASSED ENDIF IF IS_KEYBOARD_KEY_PRESSED (KEY_F) eStage = MISSION_STAGE_FAILED eFailReason = MISSION_FAIL_FORCE_FAIL ENDIF ENDPROC PROC RUN_MISSION_STAGE_CLEANUP_FOR_DEBUG() PRINTLN(GET_THIS_SCRIPT_NAME(), ": Starting mission stage cleanup.") KILL_PHONE_CONVERSATION() HANG_UP_AND_PUT_AWAY_PHONE(TRUE) KILL_ANY_CONVERSATION() KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() REMOVE_CUTSCENE() WAIT(0) STOP_STREAM() TRIGGER_MUSIC_EVENT("FAM3_MISSION_FAIL") CANCEL_MUSIC_EVENT("FAM3_HOUSE_COLLAPSE") STOP_AUDIO_SCENES() //remove mission peds SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL CLEANUP_PED(psFranklin, TRUE) BREAK CASE CHAR_FRANKLIN CLEANUP_PED(psMichael, TRUE) BREAK ENDSWITCH CLEANUP_PED(psCoach, TRUE) CLEANUP_PED(psVanDriver, TRUE) CLEANUP_PED_GROUP(psEnemyGoonsCar0, TRUE) CLEANUP_PED_GROUP(psEnemyGoonsCar1, TRUE) CLEANUP_VEHICLE(vsVan, TRUE) CLEANUP_VEHICLE(vsPlayersCar, TRUE) CLEANUP_VEHICLE(vsCoachsCar, TRUE) CLEANUP_VEHICLE(vsCutsceneCar, TRUE) CLEANUP_VEHICLE_GROUP(vsEnemyCars, TRUE) CLEANUP_UBER_PLAYBACK(TRUE) //clear locates header data CLEAR_MISSION_LOCATION_TEXT_AND_BLIPS(sLocatesData) CLEAR_TRIGGERED_LABELS() KILL_CHASE_HINT_CAM(localChaseHintCamStruct) IF DOES_CAM_EXIST(ScriptedCamera) SET_CAM_ACTIVE(ScriptedCamera, FALSE) RENDER_SCRIPT_CAMS(FALSE, FALSE) DESTROY_CAM(ScriptedCamera) DISPLAY_RADAR(TRUE) DISPLAY_HUD(TRUE) ENDIF DESTROY_ALL_CAMS() STOP_GAMEPLAY_HINT() STOP_GAMEPLAY_CAM_SHAKING() //remove particle fx attached to player's truck IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxRearLeftWheel) REMOVE_PARTICLE_FX(ptfxRearLeftWheel) ENDIF IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxRearRightWheel) REMOVE_PARTICLE_FX(ptfxRearRightWheel) ENDIF IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxDustCloud) REMOVE_PARTICLE_FX(ptfxDustCloud) ENDIF REMOVE_PTFX_ASSET() IF DOES_ROPE_EXIST(Rope) AND DOES_ENTITY_EXIST(osRopeAnchor.ObjectIndex) DETACH_ROPE_FROM_ENTITY(Rope, osRopeAnchor.ObjectIndex) DELETE_ROPE(Rope) DELETE_OBJECT(osRopeAnchor.ObjectIndex) ROPE_UNLOAD_TEXTURES() bRopeAttached = FALSE ENDIF IF DOES_ENTITY_EXIST(osRacket01.ObjectIndex) DELETE_OBJECT(osRacket01.ObjectIndex) ENDIF IF DOES_ENTITY_EXIST(osRacket02.ObjectIndex) DELETE_OBJECT(osRacket02.ObjectIndex) ENDIF IF DOES_ENTITY_EXIST(osRopeDummy.ObjectIndex) DELETE_OBJECT(osRopeDummy.ObjectIndex) ENDIF IF DOES_ENTITY_EXIST(osRopeProp.ObjectIndex) DELETE_OBJECT(osRopeProp.ObjectIndex) ENDIF IF DOES_ENTITY_EXIST(osBootCollision.ObjectIndex) DELETE_OBJECT(osBootCollision.ObjectIndex) ENDIF IF DOES_ENTITY_EXIST(osCellphone.ObjectIndex) DELETE_OBJECT(osCellphone.ObjectIndex) ENDIF IF DOES_ENTITY_EXIST(osBrokenPlantPot.ObjectIndex) DELETE_OBJECT(osBrokenPlantPot.ObjectIndex) ENDIF REMOVE_ANIM_DICT("missfam3") REMOVE_ANIM_DICT("switch@michael@bench") REMOVE_VEHICLE_ASSET(BISON2) SET_NO_LOADING_SCREEN(FALSE) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Finished mission stage cleanup.") ENDPROC /// PURPOSE: /// Controls running the debug mission stage menu. /// PARAMS: /// iSelectedStage - Variable that stores int value returned from the debug mission stage menu. /// eStage - Mission stage variable. /// bSkipActive - Skip flag. PROC RUN_DEBUG_MISSION_STAGE_MENU(INT &iSelectedStage, MISSION_STAGES &eStage, BOOL &bSkipActive, BOOL &bResetStage) IF LAUNCH_MISSION_STAGE_MENU(SkipMenu, iSelectedStage, ENUM_TO_INT(eStage), FALSE, "FAMILY 3") DO_SAFE_SCREEN_FADE_OUT(DEFAULT_FADE_TIME) DO_SAFE_STOP_CUTSCENE() CLEAR_PRINTS() CLEAR_HELP() CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID()) RUN_MISSION_STAGE_CLEANUP_FOR_DEBUG() eStage = INT_TO_ENUM(MISSION_STAGES, iSelectedStage) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Current mission stage changed to ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eStage), " via mission stage menu.") //reset the debug stage reset flag bResetStage = FALSE bSkipActive = TRUE RESET_MISSION_FLAGS() ENDIF ENDPROC PROC RUN_DEBUG_SKIPS(MISSION_STAGES &eStage, BOOL &bSkipActive, BOOL &bResetStage) INT iCurrentStage = ENUM_TO_INT(eStage) IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J) IF eStage <> MISSION_STAGE_CUTSCENE_END DO_SAFE_SCREEN_FADE_OUT(DEFAULT_FADE_TIME) DO_SAFE_STOP_CUTSCENE() CLEAR_PRINTS() CLEAR_HELP() CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID()) RUN_MISSION_STAGE_CLEANUP_FOR_DEBUG() iCurrentStage++ eStage = INT_TO_ENUM(MISSION_STAGES, iCurrentStage) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Current mission stage changed to ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eStage), " via J skip.") //reset the debug stage reset flag bResetStage = FALSE bSkipActive = TRUE RESET_MISSION_FLAGS() ENDIF ELIF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P) IF eStage <> MISSION_STAGE_CUTSCENE_INTRO DO_SAFE_SCREEN_FADE_OUT(DEFAULT_FADE_TIME) DO_SAFE_STOP_CUTSCENE() CLEAR_PRINTS() CLEAR_HELP() CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID()) RUN_MISSION_STAGE_CLEANUP_FOR_DEBUG() IF ( bResetStage = FALSE ) iCurrentStage-- eStage = INT_TO_ENUM(MISSION_STAGES, iCurrentStage) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Current mission stage changed to ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eStage), " via P skip.") ELIF ( bResetStage = TRUE ) eStage = INT_TO_ENUM(MISSION_STAGES, iCurrentStage) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Current mission stage ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eStage), " reset via P skip.") ENDIF //reset the debug stage reset flag bResetStage = FALSE bSkipActive = TRUE RESET_MISSION_FLAGS() ENDIF ENDIF ENDPROC PROC RUN_DEBUG_INFORMATION_DISPLAY() IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_NUMPAD4) IF ( bDrawDebugLinesAndSpheres = FALSE) SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE) bDrawDebugLinesAndSpheres = TRUE ELSE SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(FALSE) bDrawDebugLinesAndSpheres = FALSE ENDIF ENDIF IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_NUMPAD5) IF ( bDrawDebugStates = FALSE) bDrawDebugStates = TRUE ELSE bDrawDebugStates = FALSE ENDIF ENDIF ENDPROC #ENDIF //|===================== END DEBUG VARIABLES, PROCEDURES & FUNCTIONS =====================| //|======================= ASSET REQUESTING PROCEDURES & FUNCTIONS =======================| /// PURPOSE: /// Adds a model to model request array. /// PARAMS: /// ModelName - Model name being requested. /// array - MODEL_NAMES array to add the requested model name to. /// iArrayLength - Maximum length of the array. /// iModelsAlreadyRequested - Number of models already requested in this array. PROC ADD_MODEL_REQUEST_TO_ARRAY(MODEL_NAMES ModelName, MODEL_NAMES &array[], INT iArrayLength, INT &iModelsAlreadyRequested) INT i = 0 BOOL bModelAlreadyRequested = FALSE IF ( iModelsAlreadyRequested >= 0 ) IF ( iModelsAlreadyRequested <= ( iArrayLength - 1 ) ) //loop through the array (from 0 to number of models already requested) //to see if the array already contains the model name being requested //modify the boolean flag if the model was found in array, otherwise leave the flag unchanged FOR i = 0 TO ( iModelsAlreadyRequested ) IF ( array[i] = ModelName ) bModelAlreadyRequested = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Requested model ", GET_MODEL_NAME_FOR_DEBUG(ModelName), " is already in model array.") #ENDIF ENDIF ENDFOR IF ( bModelAlreadyRequested = FALSE ) REQUEST_MODEL(ModelName) //iModelsAlreadyRequested will be the model array index of the model being requested array[iModelsAlreadyRequested] = ModelName iModelsAlreadyRequested++ #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Requested model ", GET_MODEL_NAME_FOR_DEBUG(ModelName), " and added to model array.") PRINTLN(GET_THIS_SCRIPT_NAME(), ": Number of models requested: ", iModelsAlreadyRequested, ".") #ENDIF ENDIF ELSE SCRIPT_ASSERT("Number of requested models is greater than the length of the model array.") ENDIF ELSE SCRIPT_ASSERT("Number of requested models is less than 0.") ENDIF ENDPROC /// PURPOSE: /// Checks if all requested models from model array are loaded into memory. /// PARAMS: /// array - MODEL_NAMES array holding the models. /// iModelsAlreadyRequested - Number of already requested models. Should be greated than 0, since 0 means no models have been requested. /// RETURNS: /// TRUE if all models from model array are loaded into memory. FALSE if otherwise. FUNC BOOL ARE_REQUESTED_MODELS_LOADED(MODEL_NAMES &array[], INT &iModelsAlreadyRequested) INT i = 0 IF ( iModelsAlreadyRequested > 0 ) FOR i = 0 TO ( iModelsAlreadyRequested - 1 ) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Model in array[", i, "]: ", GET_MODEL_NAME_FOR_DEBUG(array[i]), ".") #ENDIF IF NOT HAS_MODEL_LOADED(array[i]) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Model ", GET_MODEL_NAME_FOR_DEBUG(array[i]), " is loading.") #ENDIF //if the model is not loaded keep requesting it REQUEST_MODEL(array[i]) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Requesting model ", GET_MODEL_NAME_FOR_DEBUG(array[i]), ".") #ENDIF RETURN FALSE ENDIF ENDFOR ENDIF #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Models from model array loaded. Number of models loaded: ", iModelsAlreadyRequested, ".") #ENDIF RETURN TRUE ENDFUNC /// PURPOSE: /// Cleans model array from requested models. /// PARAMS: /// array - MODEL_NAMES array. /// iModelsAlreadyRequested - Number of already requested models. Should be greated than 0, since 0 means no models have been requested. PROC CLEANUP_MODEL_ARRAY(MODEL_NAMES &array[], INT &iModelsAlreadyRequested) INT i = 0 IF ( iModelsAlreadyRequested > 0 ) FOR i = 0 TO ( iModelsAlreadyRequested - 1 ) IF array[i] <> DUMMY_MODEL_FOR_SCRIPT SET_MODEL_AS_NO_LONGER_NEEDED(array[i]) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Model ", GET_MODEL_NAME_FOR_DEBUG(array[i]), " cleaned up from model array by setting it as no longer needed.") #ENDIF array[i] = DUMMY_MODEL_FOR_SCRIPT ENDIF ENDFOR ENDIF iModelsAlreadyRequested = 0 #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Model array cleaned up. Number of requested models set to 0.") #ENDIF ENDPROC /// PURPOSE: /// Checks if two strings are equal. /// PARAMS: /// sString1 - First string. /// sString2 - Second string. /// RETURNS: /// TRUE if strings are equal, FALSE if otherwise or if any of the strings is empty or NULL. FUNC BOOL IS_STRING_EQUAL_TO_STRING(STRING sString1, STRING sString2) IF NOT Is_String_Null_Or_Empty(sString1) AND NOT Is_String_Null_Or_Empty(sString2) RETURN ARE_STRINGS_EQUAL(sString1, sString2) ELSE RETURN FALSE ENDIF ENDFUNC /// PURPOSE: /// Adds animation dictionary to animation request array. /// PARAMS: /// sAnimName - Name of the animation dictionary to request. /// array - STRING array containing requested animations. /// iArrayLength - Maximum length of the array /// iAnimationsAlreadyRequested - Number of animations already requested in this array. PROC ADD_ANIMATION_REQUEST_TO_ARRAY(STRING sAnimName, STRING &array[], INT iArrayLength, INT &iAnimationsAlreadyRequested) INT i = 0 BOOL bAnimationRequested IF ( iAnimationsAlreadyRequested >= 0 ) IF ( iAnimationsAlreadyRequested <= (iArrayLength - 1 ) ) FOR i = 0 TO ( iAnimationsAlreadyRequested ) IF IS_STRING_EQUAL_TO_STRING(sAnimName, array[i]) bAnimationRequested = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Requested animation ", sAnimName, " is already in animation array.") #ENDIF ENDIF ENDFOR IF ( bAnimationRequested = FALSE ) REQUEST_ANIM_DICT(sAnimName) array[iAnimationsAlreadyRequested] = sAnimName iAnimationsAlreadyRequested++ #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Requested animation ", sAnimName, " and added to animation array.") PRINTLN(GET_THIS_SCRIPT_NAME(), ": Number of animations requested: ", iAnimationsAlreadyRequested, ".") #ENDIF ENDIF ELSE SCRIPT_ASSERT("Number of requested animations is greater than the length of the animation array.") ENDIF ELSE SCRIPT_ASSERT("Number of requested animations is less than 0.") ENDIF ENDPROC /// PURPOSE: /// Checks if all requested animations are loaded into memory. /// PARAMS: /// array - STRING array containing requested animations. /// iAnimationsAlreadyRequested - Number of animations already requested in this array. /// RETURNS: /// TRUE if all requested animations from animation array are loaded into memory. FALSE if otherwise. FUNC BOOL ARE_REQUESTED_ANIMATIONS_LOADED(STRING &array[], INT &iAnimationsAlreadyRequested) INT i = 0 IF ( iAnimationsAlreadyRequested > 0 ) FOR i = 0 TO ( iAnimationsAlreadyRequested - 1 ) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Animation dictionary in array[", i, "]: ", array[i], ".") #ENDIF IF NOT HAS_ANIM_DICT_LOADED(array[i]) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Animation dictionary ", array[i], " is loading.") #ENDIF //if the animation dictionary is not loaded keep requesting it REQUEST_ANIM_DICT(array[i]) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Requesting animation dictionary ", array[i], ".") #ENDIF RETURN FALSE ENDIF ENDFOR ENDIF #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Animations from animation array loaded. Number of animations loaded: ", iAnimationsAlreadyRequested, ".") #ENDIF RETURN TRUE ENDFUNC /// PURPOSE: /// Cleans animation array from requested animations. /// PARAMS: /// array - STRING array of animations to clean. /// iAnimationsAlreadyRequested - Number of animations already requested in this array. PROC CLEANUP_ANIMATION_ARRAY(STRING &array[], INT &iAnimationsAlreadyRequested) INT i = 0 STRING sNull = NULL IF ( iAnimationsAlreadyRequested > 0 ) FOR i = 0 TO ( iAnimationsAlreadyRequested - 1 ) //brute force remove animation dictionary from memory REMOVE_ANIM_DICT(array[i]) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Animation dictionary ", array[i], " removed from memory and cleaned up from animation array.") #ENDIF array[i] = sNull ENDFOR ENDIF iAnimationsAlreadyRequested = 0 #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Animation array cleaned up. Number of requested animations set to 0.") #ENDIF ENDPROC /// PURPOSE: /// Adds a car recording number to recording request array. /// PARAMS: /// iRecording - Recording number being requested. /// sFile - Name of the file containing the car recording. /// array - INT arry to add the requested recording number to. /// iArrayLength - Maximum length of the array /// iRecordingsAlreadyRequested - Number of recordings already requested in this array. PROC ADD_CARREC_REQUEST_TO_ARRAY(INT iRecording, STRING sFile, INT &array[], INT iArrayLength, INT &iRecordingsAlreadyRequested) INT i = 0 BOOL bRecordingRequested = FALSE IF ( iRecordingsAlreadyRequested >= 0 ) IF ( iRecordingsAlreadyRequested <= ( iArrayLength - 1 ) ) FOR i = 0 TO ( iRecordingsAlreadyRequested ) IF array[i] = iRecording bRecordingRequested = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Requested car recording ", iRecording, " is already in recording array.") #ENDIF ENDIF ENDFOR IF ( bRecordingRequested = FALSE ) REQUEST_VEHICLE_RECORDING(iRecording, sFile) array[iRecordingsAlreadyRequested] = iRecording iRecordingsAlreadyRequested++ #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Requested car recording ", iRecording, " and added to recording array.") PRINTLN(GET_THIS_SCRIPT_NAME(), ": Number of car recordings requested: ", iRecordingsAlreadyRequested, ".") #ENDIF ENDIF ELSE SCRIPT_ASSERT("Number of requested recordings is greater than the length of the recording array.") ENDIF ELSE SCRIPT_ASSERT("Number of requested recordings is less than 0.") ENDIF ENDPROC /// PURPOSE: /// Checks if all requested car recordings are loaded into memory. /// PARAMS: /// sFile - File name of the car recording file. /// array - INT array holding the recording numbers. /// iRecordingsAlreadyRequested - Number of already requested recordings. Should be greated than 0, since 0 means no recordings have been requested. /// RETURNS: /// TRUE if all recordings from recording array are loaded into memory. FALSE if otherwise. FUNC BOOL ARE_REQUESTED_CARRECS_LOADED(STRING sFile, INT &array[], INT &iRecordingsAlreadyRequested) INT i = 0 IF ( iRecordingsAlreadyRequested > 0 ) FOR i = 0 TO ( iRecordingsAlreadyRequested - 1 ) IF NOT HAS_VEHICLE_RECORDING_BEEN_LOADED(array[i], sFile) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Car recording ", array[i], " is loading.") #ENDIF //if the vehicle recording is not loaded keep requesting it REQUEST_VEHICLE_RECORDING(array[i], sFile) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Requesting vehicle recording ", array[i], ".") #ENDIF RETURN FALSE ENDIF ENDFOR ENDIF #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Car recordings from recording array loaded. Number of car recordings loaded: ", iRecordingsAlreadyRequested, ".") #ENDIF RETURN TRUE ENDFUNC /// PURPOSE: /// Cleans recording array from requested recordings. /// PARAMS: /// sFile - File name of the car recording file. /// array - INT array holding the recording numbers. /// iRecordingsAlreadyRequested - Number of already requested recordings. Should be greated than 0, since 0 means no recordings have been requested. PROC CLEANUP_CARREC_ARRAY(STRING sFile, INT &array[], INT &iRecordingsAlreadyRequested) INT i = 0 IF ( iRecordingsAlreadyRequested > 0 ) FOR i = 0 TO ( iRecordingsAlreadyRequested - 1 ) IF HAS_VEHICLE_RECORDING_BEEN_LOADED(array[i], sFile) REMOVE_VEHICLE_RECORDING(array[i], sFile) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Car recording ", array[i], " cleaned up from recording array.") #ENDIF array[i] = 0 ENDIF ENDFOR ENDIF iRecordingsAlreadyRequested = 0 #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Recording array cleaned up. Number of requested car recordings set to 0.") #ENDIF ENDPROC //|===================== END ASSET REQUESTING PROCEDURES & FUNCTIONS =====================| PROC GO_TO_PED_STATE(PED_STRUCT &psPed, PED_STATES eState) psPed.bHasTask = FALSE psPed.eState = eState #IF IS_DEBUG_BUILD IF NOT IS_STRING_NULL_OR_EMPTY(psPed.sDebugName) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Sending ped with debug name ", psPed.sDebugName, " to state ", GET_PED_STATE_NAME_FOR_DEBUG(eState), ".") ENDIF #ENDIF ENDPROC FUNC BOOL IS_PED_IN_PED_STATE(PED_STRUCT &psPed, PED_STATES ePedState) IF DOES_ENTITY_EXIST(psPed.PedIndex) IF NOT IS_PED_INJURED(psPed.PedIndex) IF ( psPed.eState = ePedState ) RETURN TRUE ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC //|========================== MISSION STAGE LOADINGS PROCEDURES ==========================| /// PURPOSE: /// Checks for various mission fail conditions. Redirects mission flow to MISSION_STAGE_FAILED when one of fail conditions is true. /// PARAMS: /// eStage - Mission stage variable. /// eFail - Mission fail reason. PROC RUN_FAIL_CHECKS(MISSION_STAGES &eStage, MISSION_FAILS &eFail) IF eStage <> MISSION_STAGE_PASSED AND eStage <> MISSION_STAGE_FAILED IF NOT IS_CUTSCENE_PLAYING() //check pickup, the mission car IF DOES_ENTITY_EXIST(vsPlayersCar.VehicleIndex) IF ( FailFlags[MISSION_FAIL_CAR_STUCK] = TRUE ) IF IS_VEHICLE_PERMANENTLY_STUCK(vsPlayersCar.VehicleIndex) eFail = MISSION_FAIL_CAR_STUCK eStage = MISSION_STAGE_FAILED ENDIF ENDIF IF ( FailFlags[MISSION_FAIL_CAR_DESTROYED] = TRUE ) IF NOT IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex, TRUE) OR ( HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(vsPlayersCar.VehicleIndex, PLAYER_PED_ID()) AND HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON(vsPlayersCar.VehicleIndex, WEAPONTYPE_MOLOTOV) ) eFail = MISSION_FAIL_CAR_DESTROYED eStage = MISSION_STAGE_FAILED ENDIF ENDIF ENDIF //check Franklin IF DOES_ENTITY_EXIST(GET_PED_INDEX(CHAR_FRANKLIN)) IF ( FailFlags[MISSION_FAIL_FRANKLIN_DEAD] = TRUE ) IF IS_PED_INJURED(GET_PED_INDEX(CHAR_FRANKLIN)) eFail = MISSION_FAIL_FRANKLIN_DEAD eStage = MISSION_STAGE_FAILED ENDIF ENDIF IF ( FailFlags[MISSION_FAIL_FRANKLIN_LEFT_BEHIND] = TRUE ) IF NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_FRANKLIN)) IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), GET_PED_INDEX(CHAR_FRANKLIN)) > ABANDON_BUDDY_FAIL_RANGE eFail = MISSION_FAIL_FRANKLIN_LEFT_BEHIND eStage = MISSION_STAGE_FAILED ENDIF ENDIF ENDIF ENDIF //check Michael IF DOES_ENTITY_EXIST(GET_PED_INDEX(CHAR_MICHAEL)) IF ( FailFlags[MISSION_FAIL_MICHAEL_DEAD] = TRUE ) IF IS_PED_INJURED(GET_PED_INDEX(CHAR_MICHAEL)) eFail = MISSION_FAIL_MICHAEL_DEAD eStage = MISSION_STAGE_FAILED ENDIF ENDIF IF ( FailFlags[MISSION_FAIL_MICHAEL_LEFT_BEHIND] = TRUE ) IF NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_MICHAEL)) IF GET_DISTANCE_BETWEEN_PEDS(PLAYER_PED_ID(), GET_PED_INDEX(CHAR_MICHAEL)) > ABANDON_BUDDY_FAIL_RANGE eFail = MISSION_FAIL_MICHAEL_LEFT_BEHIND eStage = MISSION_STAGE_FAILED ENDIF ENDIF ENDIF ENDIF //check tennis coach IF DOES_ENTITY_EXIST(psCoach.PedIndex) IF ( FailFlags[MISSION_FAIL_COACH_DEAD] = TRUE ) IF IS_PED_INJURED(psCoach.PedIndex) eFail = MISSION_FAIL_COACH_DEAD eStage = MISSION_STAGE_FAILED ENDIF ENDIF IF ( FailFlags[MISSION_FAIL_COACH_ATTACKED] = TRUE ) IF NOT IS_PED_INJURED(psCoach.PedIndex) IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(psCoach.PedIndex, PLAYER_PED_ID(), TRUE) OR (IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) AND HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(psCoach.PedIndex, vsPlayersCar.VehicleIndex)) OR IS_PED_USING_PETROL_CAN_AT_ENTITY(PLAYER_PED_ID(), psCoach.PedIndex, 3.0) MAKE_PED_FLEE_PED(psCoach.PedIndex, PLAYER_PED_ID(), 300, -1) eFail = MISSION_FAIL_COACH_ATTACKED eStage = MISSION_STAGE_FAILED ENDIF ENDIF ENDIF IF ( FailFlags[MISSION_FAIL_COACH_SPOOKED] = TRUE ) IF NOT IS_PED_INJURED(psCoach.PedIndex) IF ( IS_ENTITY_AT_COORD(psCoach.PedIndex, <<-1024.919800,661.292053,159.575302>>, << 10.25, 8.0, 4.75 >>) AND IS_ENTITY_AT_COORD(PLAYER_PED_ID(), <<-1024.919800,661.292053,159.575302>>, << 10.25, 8.0, 4.75 >>) ) OR HAS_PED_RECEIVED_EVENT(psCoach.PedIndex, EVENT_SWITCH_2_NM_TASK) OR HAS_PED_RECEIVED_EVENT(psCoach.PedIndex, EVENT_EXPLOSION) OR HAS_PED_RECEIVED_EVENT(psCoach.PedIndex, EVENT_SHOCKING_EXPLOSION) OR IS_PED_SHOOTING_AT_ENTITY(PLAYER_PED_ID(), psCoach.PedIndex, TRUE, 5.0) MAKE_PED_FLEE_PED(psCoach.PedIndex, PLAYER_PED_ID(), 300, -1) eFail = MISSION_FAIL_COACH_SPOOKED eStage = MISSION_STAGE_FAILED ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Sets mission as failed and provides mission flow with reason to print on screen. /// PARAMS: /// eFailReason - One of MISSION_FAILS values. PROC SET_MISSION_FAILED_WITH_REASON(MISSION_FAILS &eFailReason) SWITCH eFailReason //Player's car is destroyed CASE MISSION_FAIL_CAR_DESTROYED MISSION_FLOW_MISSION_FAILED_WITH_REASON("FAM3_TDEST") BREAK //Player's is undrivable CASE MISSION_FAIL_CAR_STUCK MISSION_FLOW_MISSION_FAILED_WITH_REASON("FAM3_TUND") BREAK //Michael is dead CASE MISSION_FAIL_MICHAEL_DEAD MISSION_FLOW_MISSION_FAILED_WITH_REASON("CMN_MDIED") BREAK //Michael is left behind CASE MISSION_FAIL_MICHAEL_LEFT_BEHIND MISSION_FLOW_MISSION_FAILED_WITH_REASON("CMN_MLEFT") BREAK //Franklin is dead CASE MISSION_FAIL_FRANKLIN_DEAD MISSION_FLOW_MISSION_FAILED_WITH_REASON("CMN_FDIED") BREAK //Franklin is left behind CASE MISSION_FAIL_FRANKLIN_LEFT_BEHIND MISSION_FLOW_MISSION_FAILED_WITH_REASON("CMN_FLEFT") BREAK //Tennis coach is dead CASE MISSION_FAIL_COACH_DEAD MISSION_FLOW_MISSION_FAILED_WITH_REASON("FAM3_CDEAD") BREAK //Tennis coach attacked CASE MISSION_FAIL_COACH_ATTACKED MISSION_FLOW_MISSION_FAILED_WITH_REASON("FAM3_CATTA") BREAK //Tennis coach spooked CASE MISSION_FAIL_COACH_SPOOKED MISSION_FLOW_MISSION_FAILED_WITH_REASON("FAM3_CSPOOK") BREAK //Generic fail //Debug forced fail CASE MISSION_FAIL_EMPTY CASE MISSION_FAIL_FORCE_FAIL MISSION_FLOW_MISSION_FAILED_WITH_REASON("FAM3_FAIL") BREAK ENDSWITCH #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Mission failed with reason ", GET_MISSION_FAIL_NAME_FOR_DEBUG(eFailReason), ".") #ENDIF ENDPROC /// PURPOSE: /// Sets mission stage enum for replay. /// PARAMS: /// eStage - Mission stage enum variable. /// iValue - Mid-mission replay value returned by the script when replaying the mission. PROC SET_MISSION_STAGE_FOR_REPLAY(MISSION_STAGES &eStage, INT iValue) IF iValue = ENUM_TO_INT(MID_MISSION_STAGE_CAR_CHASE) eStage = MISSION_STAGE_CAR_CHASE ELIF iValue = ENUM_TO_INT(MID_MISSION_STAGE_PULL_HOUSE_DOWN) eStage = MISSION_STAGE_PULL_HOUSE_DOWN ELIF iValue = ENUM_TO_INT(MID_MISSION_STAGE_ESCAPE_GOONS) eStage = MISSION_STAGE_ESCAPE_GOONS ENDIF #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Mission is being replayed at stage ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eStage), ".") #ENDIF ENDPROC /// PURPOSE: /// Handles cleaning up when mission ends. PROC MISSION_CLEANUP() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Starting mission cleanup.") DELETE_DEBUG_WIDGETS() #ENDIF IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF IS_SCREEN_FADED_OUT() KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ELSE KILL_FACE_TO_FACE_CONVERSATION() ENDIF KILL_ANY_CONVERSATION() ENDIF IF IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) CLEAR_PRINTS() ENDIF IF IS_HELP_MESSAGE_BEING_DISPLAYED() CLEAR_HELP() ENDIF CLEANUP_MODEL_ARRAY(MissionModels, iModelsRequested) CLEANUP_CARREC_ARRAY(sVehicleRecordingsFile, MissionRecordings, iRecordingsRequested) CLEANUP_ANIMATION_ARRAY(MissionAnimations, iAnimationsRequested) CLEAR_MISSION_LOCATION_TEXT_AND_BLIPS(sLocatesData) CLEANUP_UBER_PLAYBACK() IF NOT IS_PED_INJURED(PLAYER_PED_ID()) CLEAR_PED_TASKS(PLAYER_PED_ID()) SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_WillFlyThroughWindscreen, TRUE) ENDIF //remove mission peds SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL IF DOES_ENTITY_EXIST(psFranklin.PedIndex) IF NOT IS_PED_INJURED(psFranklin.PedIndex) IF IS_PED_IN_COMBAT(psFranklin.PedIndex) SET_PED_KEEP_TASK(psFranklin.PedIndex, TRUE) ELSE CLEAR_PED_TASKS(psFranklin.PedIndex) ENDIF IF IS_PED_GROUP_MEMBER(psFranklin.PedIndex, PLAYER_GROUP_ID()) REMOVE_PED_FROM_GROUP(psFranklin.PedIndex) ENDIF ENDIF IF NOT IS_SCREEN_FADED_OUT() SET_PED_AS_NO_LONGER_NEEDED(psFranklin.PedIndex) ELSE DELETE_PED(psFranklin.PedIndex) ENDIF ENDIF BREAK CASE CHAR_FRANKLIN IF DOES_ENTITY_EXIST(psMichael.PedIndex) IF NOT IS_PED_INJURED(psMichael.PedIndex) IF IS_PED_IN_COMBAT(psMichael.PedIndex) SET_PED_KEEP_TASK(psMichael.PedIndex, TRUE) ELSE CLEAR_PED_TASKS(psMichael.PedIndex) ENDIF IF IS_PED_GROUP_MEMBER(psMichael.PedIndex, PLAYER_GROUP_ID()) REMOVE_PED_FROM_GROUP(psMichael.PedIndex) ENDIF ENDIF IF NOT IS_SCREEN_FADED_OUT() SET_PED_AS_NO_LONGER_NEEDED(psMichael.PedIndex) ELSE DELETE_PED(psMichael.PedIndex) ENDIF ENDIF BREAK ENDSWITCH IF DOES_ENTITY_EXIST(psCoach.PedIndex) IF NOT IS_PED_INJURED(psCoach.PedIndex) CLEAR_PED_TASKS(psCoach.PedIndex) ENDIF IF NOT IS_SCREEN_FADED_OUT() SET_PED_AS_NO_LONGER_NEEDED(psCoach.PedIndex) ELSE DELETE_PED(psCoach.PedIndex) ENDIF ENDIF IF DOES_ENTITY_EXIST(psVanDriver.PedIndex) IF NOT IS_PED_INJURED(psVanDriver.PedIndex) CLEAR_PED_TASKS(psVanDriver.PedIndex) SET_PED_AS_NO_LONGER_NEEDED(psVanDriver.PedIndex) ENDIF ENDIF //remove mission vehicles IF DOES_ENTITY_EXIST(vsPlayersCar.VehicleIndex) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) SET_VEHICLE_AUTOMATICALLY_ATTACHES(vsPlayersCar.VehicleIndex, TRUE) SET_VEHICLE_STRONG(vsPlayersCar.VehicleIndex, FALSE) SET_VEHICLE_CAN_SAVE_IN_GARAGE(vsPlayersCar.VehicleIndex, TRUE) SET_VEHICLE_AS_NO_LONGER_NEEDED(vsPlayersCar.VehicleIndex) ENDIF ENDIF CLEANUP_VEHICLE(vsVan, FALSE, FALSE) CLEANUP_VEHICLE(vsCoachsCar, FALSE, FALSE) CLEANUP_VEHICLE(vsCutsceneCar, FALSE, FALSE) //remove blips IF DOES_BLIP_EXIST(vsPlayersCar.BlipIndex) REMOVE_BLIP(vsPlayersCar.BlipIndex) ENDIF IF DOES_BLIP_EXIST(vsCoachsCar.BlipIndex) REMOVE_BLIP(vsCoachsCar.BlipIndex) ENDIF CLEANUP_PED_GROUP(psEnemyGoonsCar0, FALSE, FALSE, TRUE) CLEANUP_PED_GROUP(psEnemyGoonsCar1, FALSE, FALSE, TRUE) CLEANUP_VEHICLE_GROUP(vsEnemyCars, FALSE, FALSE) //remove relationship groups REMOVE_RELATIONSHIP_GROUP(rgEnemies) //remove rope an anchor IF DOES_ROPE_EXIST(Rope) AND DOES_ENTITY_EXIST(osRopeAnchor.ObjectIndex) DETACH_ROPE_FROM_ENTITY(Rope, osRopeAnchor.ObjectIndex) DELETE_ROPE(Rope) DELETE_OBJECT(osRopeAnchor.ObjectIndex) ROPE_UNLOAD_TEXTURES() bRopeAttached = FALSE ENDIF IF DOES_ENTITY_EXIST(osRopeDummy.ObjectIndex) DELETE_OBJECT(osRopeDummy.ObjectIndex) ENDIF IF DOES_ENTITY_EXIST(osRopeProp.ObjectIndex) DELETE_OBJECT(osRopeProp.ObjectIndex) ENDIF IF DOES_ENTITY_EXIST(osBootCollision.ObjectIndex) DELETE_OBJECT(osBootCollision.ObjectIndex) ENDIF IF DOES_ENTITY_EXIST(osCellphone.ObjectIndex) DELETE_OBJECT(osCellphone.ObjectIndex) ENDIF IF DOES_ENTITY_EXIST(osBrokenPlantPot.ObjectIndex) SET_OBJECT_AS_NO_LONGER_NEEDED(osBrokenPlantPot.ObjectIndex) ENDIF //remove particle fx attached to player's truck IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxRearLeftWheel) REMOVE_PARTICLE_FX(ptfxRearLeftWheel) ENDIF IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxRearRightWheel) REMOVE_PARTICLE_FX(ptfxRearRightWheel) ENDIF IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxDustCloud) REMOVE_PARTICLE_FX(ptfxDustCloud) ENDIF REMOVE_PTFX_ASSET() REMOVE_ANIM_DICT("missfam3") REMOVE_ANIM_DICT("switch@michael@bench") //disable mission vehicle models suppressing SET_VEHICLE_MODEL_IS_SUPPRESSED(TAILGATER, FALSE) //Michael's car SET_VEHICLE_MODEL_IS_SUPPRESSED(BISON2, FALSE) //player's car during mission SET_VEHICLE_MODEL_IS_SUPPRESSED(BISON, FALSE) //car that looks the same like mission car SET_VEHICLE_MODEL_IS_SUPPRESSED(BISON3, FALSE) //car that looks the same like mission car SET_VEHICLE_MODEL_IS_SUPPRESSED(SADLER, FALSE) //car that looks the same like mission car SET_VEHICLE_MODEL_IS_SUPPRESSED(BLISTA, FALSE) //tennis coach's car SET_VEHICLE_MODEL_IS_SUPPRESSED(BALLER, FALSE) //enemy car //disable mission ped models suppressing SET_PED_MODEL_IS_SUPPRESSED(G_M_Y_POLOGOON_01, FALSE) REMOVE_VEHICLE_ASSET(BISON2) //enable the car gen on mission cleanup DISABLE_VEHICLE_GEN_ON_MISSION(FALSE) SET_VEHICLE_GEN_AVAILABLE(VEHGEN_MICHAEL_SAVEHOUSE, TRUE) SET_MAX_WANTED_LEVEL(5) SET_CREATE_RANDOM_COPS(TRUE) SET_WANTED_LEVEL_MULTIPLIER(1.0) SET_PED_POPULATION_BUDGET(3) SET_VEHICLE_POPULATION_BUDGET(3) SET_GPS_DISABLED_ZONE(<< 0.0, 0.0, 0.0 >>, << 0.0, 0.0, 0.0 >>) DISABLE_CELLPHONE(FALSE) DISABLE_TAXI_HAILING(FALSE) //enable fire dept and ambulance dept ENABLE_DISPATCH_SERVICE(DT_FIRE_DEPARTMENT, TRUE) ENABLE_DISPATCH_SERVICE(DT_AMBULANCE_DEPARTMENT, TRUE) STOP_GAMEPLAY_CAM_SHAKING() STOP_STREAM() STOP_AUDIO_SCENES() CANCEL_MUSIC_EVENT("FAM3_HOUSE_COLLAPSE") TRIGGER_MUSIC_EVENT("FAM3_MISSION_FAIL") SET_PLAYER_CAN_CHANGE_CLOTHES_ON_MISSION(TRUE) SET_PLAYER_PED_DATA_IN_CUTSCENES(TRUE, TRUE) SET_PLAYER_PED_CAN_ENTER_SAVEHOUSE(CHAR_FRANKLIN, SAVEHOUSE_MICHAEL_BH, FALSE) RELEASE_SUPPRESSED_EMERGENCY_CALLS() IF IS_DOOR_REGISTERED_WITH_SYSTEM(ENUM_TO_INT(DOORHASH_M_MANSION_G1)) DOOR_SYSTEM_SET_OPEN_RATIO(ENUM_TO_INT(DOORHASH_M_MANSION_G1), 0.0, FALSE, FALSE) DOOR_SYSTEM_SET_DOOR_STATE(ENUM_TO_INT(DOORHASH_M_MANSION_G1), DOORSTATE_UNLOCKED, FALSE, TRUE) ENDIF LOCK_AUTOMATIC_DOOR_OPEN(AUTODOOR_MICHAEL_MANSION_GATE, FALSE) //CASCADE_SHADOWS_INIT_SESSION() SET_INSTANCE_PRIORITY_HINT(INSTANCE_HINT_NONE) STOP_GAMEPLAY_HINT() KILL_CHASE_HINT_CAM(localChaseHintCamStruct) REMOVE_NAVMESH_BLOCKING_OBJECTS() SET_NO_LOADING_SCREEN(FALSE) #IF IS_DEBUG_BUILD SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(FALSE) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Finished mission cleanup.") #ENDIF ENDPROC /// PURPOSE: /// Populates structs and arrays with data such as vectors, model names etc for a specified mission stage. /// PARAMS: /// eStage - Mission stage to initialise arrays for. PROC INITIALISE_ARRAYS_FOR_MISSION_STAGE(MISSION_STAGES eStage) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Initialising arrays for ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eStage), ".") #ENDIF SWITCH eStage CASE MISSION_STAGE_CUTSCENE_INTRO psMichael.vPosition = <<-813.8015, 179.2288, 71.1592>> psMichael.fHeading = 294.8454 psMichael.ModelName = GET_PLAYER_PED_MODEL(CHAR_MICHAEL) vsPlayersCar.vPosition = << -827.1151, 176.4370, 69.9585 >> vsPlayersCar.fHeading = 148.7250 vsPlayersCar.ModelName = BISON2 psFranklin.vPosition = <<-813.8015, 179.2288, 71.1592>> psFranklin.fHeading = 294.8454 psFranklin.ModelName = GET_PLAYER_PED_MODEL(CHAR_FRANKLIN) vsCoachsCar.vPosition = <<-826.2942, 158.1811, 68.3918>> vsCoachsCar.fHeading = 84.0848 vsCoachsCar.ModelName = BLISTA vsCoachsCar.iRecordingNumber = 53 psCoach.vPosition = << -856.0540, 149.5746, 62.2112 >> psCoach.fHeading = 3.1630 psCoach.ModelName = GET_NPC_PED_MODEL(CHAR_TENNIS_COACH) osRacket01.vPosition = <<-818.0380, 179.2600, 71.2520>> osRacket01.vRotation = <<-20.5200, -74.0200, 14.3000>> osRacket01.ModelName = PROP_TENNIS_RACK_01 osRacket02.vPosition = <<-818.1280, 179.1527, 71.2620>> osRacket02.vRotation = <<-39.2400, -75.9600, 16.2000>> osRacket02.ModelName = PROP_TENNIS_RACK_01B osBrokenPlantPot.vPosition = <<-819.6521, 176.6348, 70.7600>> osBrokenPlantPot.vRotation = <<6.1200, 0.0000, -68.4000>> osBrokenPlantPot.ModelName = PROP_WINDOWBOX_BROKEN BREAK CASE MISSION_STAGE_CAR_CHASE psMichael.vPosition = <<-824.3681, 176.9837, 70.1645>>//<< -825.9493, 175.4956, 69.8794 >> psMichael.fHeading = 135.3757//148.9250 psMichael.ModelName = GET_PLAYER_PED_MODEL(CHAR_MICHAEL) vsPlayersCar.vPosition = << -827.1151, 176.4370, 69.9585 >> vsPlayersCar.fHeading = 148.7250 vsPlayersCar.ModelName = BISON2 psFranklin.vPosition = << -828.5035, 177.0551, 69.9812 >> psFranklin.fHeading = 159.2800 psFranklin.ModelName = GET_PLAYER_PED_MODEL(CHAR_FRANKLIN) vsCoachsCar.vPosition = <<-826.2942, 158.1811, 68.3918>> vsCoachsCar.fHeading = 84.0848 vsCoachsCar.ModelName = BLISTA vsCoachsCar.iRecordingNumber = 53 psCoach.vPosition = << -856.0540, 149.5746, 62.2112 >> psCoach.fHeading = 3.1630 psCoach.ModelName = GET_NPC_PED_MODEL(CHAR_TENNIS_COACH) vsVan.vPosition = << -1386.9448, 456.5691, 104.2549 >> vsVan.fHeading = 28.1851 vsVan.ModelName = JOURNEY vsVan.iRecordingNumber = 51 psVanDriver.ModelName = A_M_M_BEVHILLS_01 osRacket01.vPosition = <<-818.0380, 179.2600, 71.2520>> osRacket01.vRotation = <<-20.5200, -74.0200, 14.3000>> osRacket01.ModelName = PROP_TENNIS_RACK_01 osRacket02.vPosition = <<-818.1280, 179.1527, 71.2620>> osRacket02.vRotation = <<-39.2400, -75.9600, 16.2000>> osRacket02.ModelName = PROP_TENNIS_RACK_01 osBrokenPlantPot.vPosition = <<-819.6521, 176.6348, 70.7600>> osBrokenPlantPot.vRotation = <<6.1200, 0.0000, -68.4000>> osBrokenPlantPot.ModelName = PROP_WINDOWBOX_BROKEN BREAK CASE MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE psMichael.vPosition = << -993.4860, 647.2808, 138.8108 >> psMichael.fHeading = 274.6140 psMichael.ModelName = GET_PLAYER_PED_MODEL(CHAR_MICHAEL) vsPlayersCar.vPosition = << -992.1501, 645.7378, 138.7702 >> vsPlayersCar.fHeading = 282.1990 vsPlayersCar.ModelName = BISON2 psFranklin.vPosition = << -991.8490, 643.7483, 138.6733 >> psFranklin.fHeading = 332.4843 psFranklin.ModelName = GET_PLAYER_PED_MODEL(CHAR_FRANKLIN) vsCoachsCar.vPosition = <<-1007.2410, 708.9224, 161.0334>> vsCoachsCar.fHeading = 358.5527 vsCoachsCar.ModelName = BLISTA psCoach.vPosition = << -1026.9159, 653.8083, 155.0754 >> psCoach.fHeading = 196.6071 psCoach.ModelName = GET_NPC_PED_MODEL(CHAR_TENNIS_COACH) osRopeAnchor.vPosition = <<-1017.8320, 660.5620, 147.1470>> osRopeAnchor.vRotation = <<15.0000, 15.0000, -0.0000>> osRopeAnchor.ModelName = PROP_LD_ROPE_T osRopeDummy.vPosition = <<-1006.0800, 652.8800, 143.6200>> osRopeDummy.vRotation = <<0.0000, 15.0100, -32.4000>> osRopeDummy.ModelName = PROP_LD_DUMMY_ROPE osRopeProp.vPosition = <<-1018.2600, 660.6490, 147.2000>> osRopeProp.vRotation = <<0.0000, 5.0000, -25.5600>> osRopeProp.ModelName = PROP_ROPE_FAMILY_3 osBootCollision.vPosition = <<-995.2775, 645.0095, 139.6500>> osBootCollision.vRotation = <<-90.0000, 0.0000, 102.0000>> osBootCollision.ModelName = PROP_TAIL_GATE_COL BREAK CASE MISSION_STAGE_PULL_HOUSE_DOWN psMichael.vPosition = << -993.4773, 647.6854, 138.7637 >> psMichael.fHeading = 255.1397 psMichael.ModelName = GET_PLAYER_PED_MODEL(CHAR_MICHAEL) vsPlayersCar.vPosition = << -992.1501, 645.7378, 138.7702 >> vsPlayersCar.fHeading = 282.1990 vsPlayersCar.ModelName = BISON2 psFranklin.vPosition = << -992.5433, 643.7088, 138.7174 >> psFranklin.fHeading = 86.0291 psFranklin.ModelName = GET_PLAYER_PED_MODEL(CHAR_FRANKLIN) vsCoachsCar.vPosition = <<-1007.2410, 708.9224, 161.0334>> vsCoachsCar.fHeading = 358.5527 vsCoachsCar.ModelName = BLISTA psCoach.vPosition = << -1014.6680, 654.4220, 155.3056 >> psCoach.fHeading = 252.4493 psCoach.ModelName = GET_NPC_PED_MODEL(CHAR_TENNIS_COACH) osRopeAnchor.vPosition = <<-1017.8320, 660.5620, 147.1470>> osRopeAnchor.vRotation = <<15.0000, 15.0000, -0.0000>> osRopeAnchor.ModelName = PROP_LD_ROPE_T osRopeDummy.vPosition = <<-1006.0800, 652.8800, 143.6200>> osRopeDummy.vRotation = <<0.0000, 15.0100, -32.4000>> osRopeDummy.ModelName = PROP_LD_DUMMY_ROPE osRopeProp.vPosition = <<-1018.2600, 660.6490, 147.2000>> osRopeProp.vRotation = <<0.0000, 5.0000, -25.5600>> osRopeProp.ModelName = PROP_ROPE_FAMILY_3 osBootCollision.vPosition = <<-995.2775, 645.0095, 139.6500>> osBootCollision.vRotation = <<-90.0000, 0.0000, 102.0000>> osBootCollision.ModelName = PROP_TAIL_GATE_COL BREAK CASE MISSION_STAGE_ESCAPE_GOONS psMichael.vPosition = << -993.4773, 647.6854, 138.7637 >> psMichael.fHeading = 255.1397 psMichael.ModelName = GET_PLAYER_PED_MODEL(CHAR_MICHAEL) vsPlayersCar.vPosition = << -977.7563, 646.6259, 137.9191 >> vsPlayersCar.fHeading = 280.3406 vsPlayersCar.ModelName = BISON2 psFranklin.vPosition = << -992.5433, 643.7088, 138.7174 >> psFranklin.fHeading = 86.0291 psFranklin.ModelName = GET_PLAYER_PED_MODEL(CHAR_FRANKLIN) vsCoachsCar.vPosition = << -1008.7057, 710.1682, 161.5234 >> vsCoachsCar.fHeading = 347.3929 vsCoachsCar.ModelName = BLISTA psCoach.vPosition = << -1020.19, 698.98, 160.9 >> psCoach.fHeading = 76.31 psCoach.ModelName = GET_NPC_PED_MODEL(CHAR_TENNIS_COACH) BREAK CASE MISSION_STAGE_CUTSCENE_END psMichael.vPosition = << -816.3374, 160.8270, 70.0828 >> psMichael.fHeading = 293.3672 psMichael.ModelName = GET_PLAYER_PED_MODEL(CHAR_MICHAEL) vsPlayersCar.vPosition = <<-822.9047, 182.4500, 70.8286>> //<< -815.4899, 159.4702, 70.1270 >> vsPlayersCar.fHeading = 305.1158 //293.2592 vsPlayersCar.ModelName = BISON2 psFranklin.vPosition = << -815.2599, 157.9198, 70.0847 >> psFranklin.fHeading = 300.3756 psFranklin.ModelName = GET_PLAYER_PED_MODEL(CHAR_FRANKLIN) vsCutsceneCar.vPosition = <<-777.6288, 161.9553, 66.4745>> vsCutsceneCar.fHeading = 359.0025 vsCutsceneCar.ModelName = BALLER BREAK CASE MISSION_STAGE_LEADOUT psMichael.vPosition = <<-95.550, -415.100, 35.6750>> psMichael.fHeading = 133.000 psMichael.ModelName = GET_PLAYER_PED_MODEL(CHAR_MICHAEL) vsMichaelsEndCar.vPosition = <<-155.8183, -423.4282, 32.8517>> vsMichaelsEndCar.fHeading = 342.5681 vsMichaelsEndCar.ModelName = GET_PLAYER_VEH_MODEL(CHAR_MICHAEL) osCellphone.vPosition = <<-95.550, -415.100, 35.6750>> osCellphone.vRotation = << 0.0, 0.0, 0.0 >> osCellphone.ModelName = Prop_phone_ING BREAK //debug stages #IF IS_DEBUG_BUILD CASE MISSION_STAGE_DEBUG_RECORD_CHASE CASE MISSION_STAGE_DEBUG_PLAYBACK_CHASE psMichael.vPosition = << -821.6009, 177.3395, 70.4432 >> psMichael.fHeading = 100.3065 psMichael.ModelName = GET_PLAYER_PED_MODEL(CHAR_MICHAEL) vsCoachsCar.vPosition = << -857.9623, 149.2353, 61.8515 >> vsCoachsCar.fHeading = 346.0251 vsCoachsCar.ModelName = BLISTA vsCoachsCar.iRecordingNumber = 53 BREAK #ENDIF ENDSWITCH #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Finished initialising arrays for ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eStage), ".") #ENDIF ENDPROC PROC BUILD_REQUEST_BANK_FOR_MISSION_STAGE(MISSION_STAGES eStage) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Building request bank for ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eStage), ".") #ENDIF SWITCH eStage CASE MISSION_STAGE_CUTSCENE_INTRO //don't request anything here BREAK CASE MISSION_STAGE_CAR_CHASE IF NOT DOES_ENTITY_EXIST(vsPlayersCar.VehicleIndex) ADD_MODEL_REQUEST_TO_ARRAY(vsPlayersCar.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL IF NOT DOES_ENTITY_EXIST(psFranklin.PedIndex) ADD_MODEL_REQUEST_TO_ARRAY(psFranklin.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN IF NOT DOES_ENTITY_EXIST(psMichael.PedIndex) ADD_MODEL_REQUEST_TO_ARRAY(psMichael.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF ENDIF IF NOT DOES_ENTITY_EXIST(vsCoachsCar.VehicleIndex) ADD_MODEL_REQUEST_TO_ARRAY(vsCoachsCar.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF IF NOT DOES_ENTITY_EXIST(psCoach.PedIndex) ADD_MODEL_REQUEST_TO_ARRAY(psCoach.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF ADD_CARREC_REQUEST_TO_ARRAY(vsCoachsCar.iRecordingNumber, sVehicleRecordingsFile, MissionRecordings, MAX_CAR_RECORDINGS, iRecordingsRequested) BREAK CASE MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE IF NOT DOES_ENTITY_EXIST(vsPlayersCar.VehicleIndex) ADD_MODEL_REQUEST_TO_ARRAY(vsPlayersCar.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL IF NOT DOES_ENTITY_EXIST(psFranklin.PedIndex) ADD_MODEL_REQUEST_TO_ARRAY(psFranklin.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN IF NOT DOES_ENTITY_EXIST(psMichael.PedIndex) ADD_MODEL_REQUEST_TO_ARRAY(psMichael.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF ENDIF IF NOT DOES_ENTITY_EXIST(psCoach.PedIndex) ADD_MODEL_REQUEST_TO_ARRAY(psCoach.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF IF NOT DOES_ENTITY_EXIST(osRopeAnchor.ObjectIndex) ADD_MODEL_REQUEST_TO_ARRAY(osRopeAnchor.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF ADD_ANIMATION_REQUEST_TO_ARRAY("missfam3", MissionAnimations, MAX_ANIMATIONS, iAnimationsRequested) BREAK CASE MISSION_STAGE_PULL_HOUSE_DOWN IF NOT DOES_ENTITY_EXIST(vsPlayersCar.VehicleIndex) ADD_MODEL_REQUEST_TO_ARRAY(vsPlayersCar.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL IF NOT DOES_ENTITY_EXIST(psFranklin.PedIndex) ADD_MODEL_REQUEST_TO_ARRAY(psFranklin.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN IF NOT DOES_ENTITY_EXIST(psMichael.PedIndex) ADD_MODEL_REQUEST_TO_ARRAY(psMichael.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF ENDIF IF NOT DOES_ENTITY_EXIST(psCoach.PedIndex) ADD_MODEL_REQUEST_TO_ARRAY(psCoach.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF IF NOT DOES_ENTITY_EXIST(osRopeAnchor.ObjectIndex) ADD_MODEL_REQUEST_TO_ARRAY(osRopeAnchor.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF IF NOT DOES_ENTITY_EXIST(osRopeProp.ObjectIndex) ADD_MODEL_REQUEST_TO_ARRAY(osRopeProp.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF IF NOT DOES_ENTITY_EXIST(osBootCollision.ObjectIndex) ADD_MODEL_REQUEST_TO_ARRAY(osBootCollision.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF ADD_ANIMATION_REQUEST_TO_ARRAY("missfam3", MissionAnimations, MAX_ANIMATIONS, iAnimationsRequested) BREAK CASE MISSION_STAGE_CUTSCENE_END IF NOT DOES_ENTITY_EXIST(vsPlayersCar.VehicleIndex) ADD_MODEL_REQUEST_TO_ARRAY(vsPlayersCar.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL IF NOT DOES_ENTITY_EXIST(psFranklin.PedIndex) ADD_MODEL_REQUEST_TO_ARRAY(psFranklin.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN IF NOT DOES_ENTITY_EXIST(psMichael.PedIndex) ADD_MODEL_REQUEST_TO_ARRAY(psMichael.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF ENDIF BREAK CASE MISSION_STAGE_LEADOUT // BREAK //debug stages #IF IS_DEBUG_BUILD CASE MISSION_STAGE_DEBUG_RECORD_CHASE CASE MISSION_STAGE_DEBUG_PLAYBACK_CHASE IF NOT DOES_ENTITY_EXIST(vsCoachsCar.VehicleIndex) ADD_MODEL_REQUEST_TO_ARRAY(vsCoachsCar.ModelName, MissionModels, MAX_MODELS, iModelsRequested) ENDIF ADD_CARREC_REQUEST_TO_ARRAY(vsCoachsCar.iRecordingNumber, sVehicleRecordingsFile, MissionRecordings, MAX_CAR_RECORDINGS, iRecordingsRequested) BREAK #ENDIF ENDSWITCH #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Finished building request bank for ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eStage), ".") #ENDIF ENDPROC PROC UPDATE_THIRD_PERSON_RUN_TO_VEHICLE_CAMERA() IF ( bStopForcingThirdPersonCamera = FALSE ) IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_IN_VEHICLE) = CAM_VIEW_MODE_THIRD_PERSON OR GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_IN_VEHICLE) = CAM_VIEW_MODE_THIRD_PERSON_NEAR OR GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_IN_VEHICLE) = CAM_VIEW_MODE_THIRD_PERSON_MEDIUM OR GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_IN_VEHICLE) = CAM_VIEW_MODE_THIRD_PERSON_FAR IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_ON_FOOT) = CAM_VIEW_MODE_FIRST_PERSON IF NOT IS_PED_SITTING_IN_THIS_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) DISABLE_ON_FOOT_FIRST_PERSON_VIEW_THIS_UPDATE() ELSE bStopForcingThirdPersonCamera = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": UPDATE_THIRD_PERSON_RUN_TO_VEHICLE_CAMERA() - Stopping forcing third person camera due to player sitting in vehicle.") #ENDIF ENDIF ELSE bStopForcingThirdPersonCamera = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": UPDATE_THIRD_PERSON_RUN_TO_VEHICLE_CAMERA() - Stopping forcing third person camera due to view cam mode selected.") #ENDIF ENDIF ELIF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_IN_VEHICLE) = CAM_VIEW_MODE_FIRST_PERSON IF NOT IS_PED_IN_THIS_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex, TRUE) DISABLE_ON_FOOT_FIRST_PERSON_VIEW_THIS_UPDATE() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": UPDATE_THIRD_PERSON_RUN_TO_VEHICLE_CAMERA() - Disabling on foot first person camera. Player not in vehicle.") #ENDIF ELSE DISABLE_ON_FOOT_FIRST_PERSON_VIEW_THIS_UPDATE() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": UPDATE_THIRD_PERSON_RUN_TO_VEHICLE_CAMERA() - Disabling on foot first person camera. Player in vehicle or getting into vehicle.") #ENDIF IF ( bFirstPersonFlashPlayed = FALSE ) IF iFirstPersonFlashTimer = 0 IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_ON_FOOT) = CAM_VIEW_MODE_FIRST_PERSON ANIMPOSTFX_PLAY(PICK_STRING(bTriggerSwitchFlash, "CamPushInMichael", "CamPushInNeutral"), 0, FALSE) PLAY_SOUND_FRONTEND(-1, "1st_Person_Transition", "PLAYER_SWITCH_CUSTOM_SOUNDSET") iFirstPersonFlashTimer = GET_GAME_TIMER() ELSE DISABLE_CINEMATIC_BONNET_CAMERA_THIS_UPDATE() IF IS_PED_SITTING_IN_THIS_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) ANIMPOSTFX_PLAY(PICK_STRING(bTriggerSwitchFlash, "CamPushInMichael", "CamPushInNeutral"), 0, FALSE) PLAY_SOUND_FRONTEND(-1, "1st_Person_Transition", "PLAYER_SWITCH_CUSTOM_SOUNDSET") iFirstPersonFlashTimer = GET_GAME_TIMER() ENDIF ENDIF ELSE IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_ON_FOOT) != CAM_VIEW_MODE_FIRST_PERSON DISABLE_CINEMATIC_BONNET_CAMERA_THIS_UPDATE() ENDIF IF HAS_TIME_PASSED(iFirstPersonFlashTime, iFirstPersonFlashTimer) bFirstPersonFlashPlayed = TRUE ENDIF ENDIF ELSE bStopForcingThirdPersonCamera = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": UPDATE_THIRD_PERSON_RUN_TO_VEHICLE_CAMERA() - Stopping forcing third person camera due to player being in vehicle.") #ENDIF ENDIF ENDIF ENDIF ENDIF ENDPROC FUNC BOOL IS_MISSION_STAGE_LOADED(MISSION_STAGES eStage, INT &iSetupProgress, BOOL &bStageLoaded, BOOL &bStageSkippedTo, BOOL &bStageReplayed) //handle initial mission setup //only run this IF block once, when the mission first loads IF ( iSetupProgress = 0 ) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Starting initial mission loading.") #ENDIF //clear the screen of any text displayed before mission started CLEAR_PRINTS() CLEAR_HELP() //load the mission text REQUEST_ADDITIONAL_TEXT("FAM3", MISSION_TEXT_SLOT) REQUEST_ADDITIONAL_TEXT("FAM3AUD", MISSION_DIALOGUE_TEXT_SLOT) WHILE NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT) OR NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_DIALOGUE_TEXT_SLOT) WAIT(0) ENDWHILE REGISTER_SCRIPT_WITH_AUDIO(TRUE) //suppress vehicle models used in mission SET_VEHICLE_MODEL_IS_SUPPRESSED(TAILGATER, TRUE) //Michael's car SET_VEHICLE_MODEL_IS_SUPPRESSED(BISON2, TRUE) SET_VEHICLE_MODEL_IS_SUPPRESSED(BISON, TRUE) //car that looks the same like mission car SET_VEHICLE_MODEL_IS_SUPPRESSED(BISON3, TRUE) //car that looks the same like mission car SET_VEHICLE_MODEL_IS_SUPPRESSED(SADLER, TRUE) //car that looks the same like mission car SET_VEHICLE_MODEL_IS_SUPPRESSED(BLISTA, TRUE) //tennis coach's car SET_VEHICLE_MODEL_IS_SUPPRESSED(BALLER, TRUE) //enemy car //suppress ped models used in mission SET_PED_MODEL_IS_SUPPRESSED(G_M_Y_POLOGOON_01, TRUE) //block car generator for player ped vehicle, it will be created in mission script DISABLE_VEHICLE_GEN_ON_MISSION(TRUE) DELETE_VEHICLE_GEN_VEHICLE(VEHGEN_MICHAEL_SAVEHOUSE) //setup relationship groups ADD_RELATIONSHIP_GROUP("ENEMIES", rgEnemies) ADD_RELATIONSHIP_GROUP("TENNISCOACH", rgTennisCoach) SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, RELGROUPHASH_PLAYER, rgEnemies) SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, rgEnemies, RELGROUPHASH_PLAYER) SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, RELGROUPHASH_PLAYER, RELGROUPHASH_PLAYER) SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, rgEnemies, rgEnemies) IF NOT IS_PED_INJURED(PLAYER_PED_ID()) SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_WillFlyThroughWindscreen, FALSE) ENDIF iCustomSwitchSoundID = GET_SOUND_ID() SET_PLAYER_PED_DATA_IN_CUTSCENES(FALSE, TRUE) SET_PLAYER_PED_CAN_ENTER_SAVEHOUSE(CHAR_FRANKLIN, SAVEHOUSE_MICHAEL_BH, TRUE) #IF IS_DEBUG_BUILD SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(FALSE) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Finished initial mission loading.") #ENDIF iSetupProgress++ ENDIF //run this each time new mission stage needs to be loaded IF ( iSetupProgress = 1 ) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Started mission stage loading for ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eStage), ".") #ENDIF bStageLoaded = FALSE //initialise arrays for peds, vehicles and objects INITIALISE_ARRAYS_FOR_MISSION_STAGE(eStage) //cleanup the asset arrays so that they are ready to be populated with assets needed for the stage being loaded CLEANUP_MODEL_ARRAY(MissionModels, iModelsRequested) CLEANUP_ANIMATION_ARRAY(MissionAnimations, iAnimationsRequested) CLEANUP_CARREC_ARRAY(sVehicleRecordingsFile, MissionRecordings, iRecordingsRequested) //clear triggered text labels CLEAR_TRIGGERED_LABELS() iSetupProgress++ ENDIF //handle player positioning when current stage is being skipped to or played normally //fade in the screen if it was faded out due to skipping IF ( iSetupProgress = 2 ) //stage was skipped to or is being replayed IF ( bStageSkippedTo = TRUE OR bStageReplayed = TRUE ) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Warping player ped to new position for mission stage being loaded due to skipping or replay.") #ENDIF SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL WARP_PED(PLAYER_PED_ID(), psMichael.vPosition, psMichael.fHeading, FALSE, TRUE, FALSE) BREAK CASE CHAR_FRANKLIN WARP_PED(PLAYER_PED_ID(), psFranklin.vPosition, psFranklin.fHeading, FALSE, TRUE, FALSE) BREAK ENDSWITCH IF ( eStage = MISSION_STAGE_CUTSCENE_INTRO ) WHILE NOT IS_INTERIOR_READY(GET_INTERIOR_AT_COORDS(vInteriorPosition)) PIN_INTERIOR_IN_MEMORY(GET_INTERIOR_AT_COORDS(vInteriorPosition)) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Pinning interior at coordinates ", vInteriorPosition, " in memory.") #ENDIF WAIT(0) ENDWHILE ENDIF IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID()) CLEAR_PED_WETNESS(PLAYER_PED_ID()) CLEAR_PED_DECORATIONS(PLAYER_PED_ID()) CLEAR_PED_BLOOD_DAMAGE(PLAYER_PED_ID()) RESET_PED_VISIBLE_DAMAGE(PLAYER_PED_ID()) RESTORE_PLAYER_PED_TATTOOS(PLAYER_PED_ID()) SET_PED_STEALTH_MOVEMENT(PLAYER_PED_ID(), FALSE) SET_PED_USING_ACTION_MODE(PLAYER_PED_ID(), FALSE) CLEAR_AREA(GET_ENTITY_COORDS(PLAYER_PED_ID()), 1000.0, TRUE) REMOVE_DECALS_IN_RANGE(GET_ENTITY_COORDS(PLAYER_PED_ID()), 1000.0) REMOVE_PARTICLE_FX_IN_RANGE(GET_ENTITY_COORDS(PLAYER_PED_ID()), 1000.0) SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, TRUE) SET_ENTITY_HEALTH(PLAYER_PED_ID(), GET_PED_MAX_HEALTH(PLAYER_PED_ID())) ENDIF IF IS_PLAYER_PLAYING(PLAYER_ID()) SET_PLAYER_CONTROL(PLAYER_ID(), FALSE) SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0) SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID()) ENDIF //flags to reset on skips and retry bVehicleReversed = FALSE ENDIF IF ( bStageReplayed = TRUE ) IF ( GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL ) START_REPLAY_SETUP(psMichael.vPosition, psMichael.fHeading) ELIF ( GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN ) START_REPLAY_SETUP(psFranklin.vPosition, psFranklin.fHeading) ENDIF ENDIF //request assets needed for current stage BUILD_REQUEST_BANK_FOR_MISSION_STAGE(eStage) iSetupProgress++ ENDIF //handle loading of mission models that have been requested in the previous stage in BUILD_REQUEST_BANK_FOR_MISSION_STAGE() //handle loading of mission animations that been requested in the previous stage in BUILD_REQUEST_BANK_FOR_MISSION_STAGE() IF ( iSetupProgress = 3 ) IF ARE_REQUESTED_MODELS_LOADED(MissionModels, iModelsRequested) IF ARE_REQUESTED_ANIMATIONS_LOADED(MissionAnimations, iAnimationsRequested) IF ARE_REQUESTED_CARRECS_LOADED(sVehicleRecordingsFile, MissionRecordings, iRecordingsRequested) iSetupProgress++ ENDIF ENDIF ENDIF ENDIF //handle the state of rayfire objects for the stilt house on replays and skips IF ( iSetupProgress = 4 ) //stage was skipped to or is being replayed IF ( bStageSkippedTo = TRUE ) OR ( bStageReplayed = TRUE ) RAYFIRE_INDEX riTest = GET_RAYFIRE_MAP_OBJECT(<<-1020.50, 663.41, 154.75>>, 50, "DES_StiltHouse") IF NOT DOES_RAYFIRE_MAP_OBJECT_EXIST(riTest) //rayfire map object does not exist #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Rayfire map object DES_StiltHouse does not exist.") #ENDIF SWITCH eStage CASE MISSION_STAGE_CUTSCENE_INTRO CASE MISSION_STAGE_CAR_CHASE CASE MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE CASE MISSION_STAGE_PULL_HOUSE_DOWN SET_BUILDING_STATE(BUILDINGNAME_RF_STILT_HOUSE, BUILDINGSTATE_NORMAL) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting BUILDINGNAME_RF_STILT_HOUSE to BUILDINGSTATE_NORMAL.") #ENDIF BREAK CASE MISSION_STAGE_ESCAPE_GOONS CASE MISSION_STAGE_CUTSCENE_END CASE MISSION_STAGE_LEADOUT SET_BUILDING_STATE(BUILDINGNAME_RF_STILT_HOUSE, BUILDINGSTATE_DESTROYED) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting BUILDINGNAME_RF_STILT_HOUSE to BUILDINGSTATE_DESTROYED.") #ENDIF BREAK ENDSWITCH iSetupProgress++ ELSE //rayfire map object exists #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Rayfire map object DES_StiltHouse exists.") #ENDIF SWITCH eStage CASE MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE CASE MISSION_STAGE_PULL_HOUSE_DOWN IF ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riTest) <> RFMO_STATE_START ) //rayfire not in start state #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Waiting for rayfire map object state to be RFMO_STATE_START.") #ENDIF IF ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riTest) <> RFMO_STATE_STARTING ) //rayfire not in starting state AND ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riTest) <> RFMO_STATE_SYNC_STARTING ) //and not in sync_starting state SET_STATE_OF_RAYFIRE_MAP_OBJECT(riTest, RFMO_STATE_STARTING) //set it to starting state then #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting rayfire map object DES_StiltHouse to state to RFMO_STATE_STARTING.") #ENDIF ENDIF ELIF ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riTest) = RFMO_STATE_START ) iSetupProgress++ #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Rayfire map object DES_StiltHouse is in state to RFMO_STATE_START.") #ENDIF ENDIF BREAK CASE MISSION_STAGE_ESCAPE_GOONS IF ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riTest) <> RFMO_STATE_END ) //rayfire not in end state #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Waiting for rayfire map object state to be RFMO_STATE_END.") #ENDIF IF ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riTest) <> RFMO_STATE_ENDING ) //rayfire not in ending state AND ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riTest) <> RFMO_STATE_SYNC_ENDING ) //and not in sync_ending state SET_STATE_OF_RAYFIRE_MAP_OBJECT(riTest, RFMO_STATE_ENDING) //set it to ending then #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Rayfire map object state set to RFMO_STATE_ENDING.") #ENDIF ENDIF ELIF ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riTest) = RFMO_STATE_END ) iSetupProgress++ #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Rayfire map object DES_StiltHouse is in state to RFMO_STATE_END.") #ENDIF ENDIF BREAK ENDSWITCH ENDIF ELSE //stage not being skipped to or replayed iSetupProgress++ ENDIF ENDIF //handle creating vehicles/peds and setting up fail flags //run this each time new mission stage needs to be loaded //THIS SETUP SECTION ASSUMES THAT ALL REQUIRED ASSETS HAVE BEEN ALREADY LOADED TO MEMORY IN PREVIOUS SETUP SECTIONS IF ( iSetupProgress = 5 ) SET_FAIL_FLAGS(FALSE) SWITCH eStage CASE MISSION_STAGE_CUTSCENE_INTRO IF IS_REPEAT_PLAY_ACTIVE() //create mission vehicles on mission repeat play only IF HAS_MISSION_VEHICLE_BEEN_CREATED(vsPlayersCar, FALSE, FALSE, NO_CHARACTER, TRUE, -1, 132, 0) IF HAS_MISSION_VEHICLE_BEEN_CREATED(vsCoachsCar, FALSE, FALSE, NO_CHARACTER, TRUE, -1, 43, 43) SET_VEHICLE_AS_RESTRICTED(vsPlayersCar.VehicleIndex, 0) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF NOT IS_VEHICLE_EXTRA_TURNED_ON(vsPlayersCar.VehicleIndex, 5) SET_VEHICLE_EXTRA(vsPlayersCar.VehicleIndex, 5, FALSE) ENDIF SET_VEHICLE_STRONG(vsPlayersCar.VehicleIndex, TRUE) SET_VEHICLE_CAN_SAVE_IN_GARAGE(vsPlayersCar.VehicleIndex, FALSE) ENDIF iSetupProgress++ ENDIF ENDIF ELSE //move on if not repeat play iSetupProgress++ ENDIF BREAK CASE MISSION_STAGE_CAR_CHASE FailFlags[MISSION_FAIL_CAR_STUCK] = TRUE FailFlags[MISSION_FAIL_CAR_DESTROYED] = TRUE FailFlags[MISSION_FAIL_COACH_DEAD] = TRUE FailFlags[MISSION_FAIL_COACH_ATTACKED] = TRUE FailFlags[MISSION_FAIL_FRANKLIN_DEAD] = TRUE FailFlags[MISSION_FAIL_FRANKLIN_LEFT_BEHIND] = TRUE IF HAS_MISSION_OBJECT_BEEN_CREATED(osRacket01, TRUE) AND HAS_MISSION_OBJECT_BEEN_CREATED(osRacket02, TRUE) IF NOT DOES_ENTITY_EXIST(osBrokenPlantPot.ObjectIndex) IF GET_PLAYER_CHARACTER_AT_MISSION_START() = CHAR_MICHAEL IF HAS_MISSION_OBJECT_BEEN_CREATED(osBrokenPlantPot, TRUE) ENDIF ENDIF ENDIF //fix for B*1897723 - set the bedroom door rayfire to start state to hide double door issue riFrenchDoorRayfire = GET_RAYFIRE_MAP_OBJECT(<< -817.1669, 178.0146, 75.7095>>, 3.0, "des_frenchdoor") IF DOES_RAYFIRE_MAP_OBJECT_EXIST(riFrenchDoorRayfire) SET_STATE_OF_RAYFIRE_MAP_OBJECT(riFrenchDoorRayfire, RFMO_STATE_STARTING) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting rayfire map object des_frenchdoor to start state.") #ENDIF ENDIF IF HAS_MISSION_VEHICLE_BEEN_CREATED(vsPlayersCar, FALSE, FALSE, NO_CHARACTER, TRUE, -1, 132, 0) SET_VEHICLE_AS_RESTRICTED(vsPlayersCar.VehicleIndex, 0) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF NOT IS_VEHICLE_EXTRA_TURNED_ON(vsPlayersCar.VehicleIndex, 5) SET_VEHICLE_EXTRA(vsPlayersCar.VehicleIndex, 5, FALSE) ENDIF SET_VEHICLE_STRONG(vsPlayersCar.VehicleIndex, TRUE) SET_VEHICLE_CAN_SAVE_IN_GARAGE(vsPlayersCar.VehicleIndex, FALSE) ENDIF IF HAS_MISSION_VEHICLE_BEEN_CREATED(vsCoachsCar, FALSE, FALSE, NO_CHARACTER, TRUE, -1, 43, 43) IF HAS_MISSION_PED_BEEN_CREATED(psCoach, FALSE, rgTennisCoach, FALSE, NO_CHARACTER, FALSE, FALSE, FALSE, vsCoachsCar.VehicleIndex) IF NOT IS_PED_INJURED(psCoach.PedIndex) SET_PED_COMPONENT_VARIATION(psCoach.PedIndex, PED_COMP_TORSO, 1, 0) SET_PED_COMPONENT_VARIATION(psCoach.PedIndex, PED_COMP_LEG, 1, 0) ENDIF OBJECT_INDEX FlowerObjectIndex FlowerObjectIndex = GET_CLOSEST_OBJECT_OF_TYPE(<< -818.88, 177.91, 76.63 >>, 0.75, PROP_WINDOWBOX_B, FALSE) IF DOES_ENTITY_EXIST(FlowerObjectIndex) IF NOT IS_ENTITY_DEAD(FlowerObjectIndex) SET_ENTITY_VISIBLE(FlowerObjectIndex, FALSE) SET_ENTITY_COLLISION(FlowerObjectIndex, FALSE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Hiding world prop object PROP_WINDOWBOX_B.") #ENDIF ENDIF ENDIF INFORM_MISSION_STATS_OF_SPEED_WATCH_ENTITY(vsPlayersCar.VehicleIndex) INFORM_MISSION_STATS_OF_DAMAGE_WATCH_ENTITY(vsPlayersCar.VehicleIndex) //track damage during car chase SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL IF HAS_MISSION_PED_BEEN_CREATED(psFranklin, TRUE, RELGROUPHASH_PLAYER, FALSE, CHAR_FRANKLIN) IF NOT IS_PED_INJURED(psFranklin.PedIndex) AND HAVE_ALL_STREAMING_REQUESTS_COMPLETED(psFranklin.PedIndex) sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN] = psFranklin.PedIndex iSetupProgress++ ENDIF ENDIF BREAK CASE CHAR_FRANKLIN IF HAS_MISSION_PED_BEEN_CREATED(psMichael, TRUE, RELGROUPHASH_PLAYER, FALSE, CHAR_MICHAEL) IF NOT IS_PED_INJURED(psMichael.PedIndex) AND HAVE_ALL_STREAMING_REQUESTS_COMPLETED(psMichael.PedIndex) sSelectorPeds.pedID[SELECTOR_PED_MICHAEL] = psMichael.PedIndex iSetupProgress++ ENDIF ENDIF BREAK ENDSWITCH ENDIF ENDIF ENDIF ENDIF BREAK CASE MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE FailFlags[MISSION_FAIL_CAR_STUCK] = TRUE FailFlags[MISSION_FAIL_CAR_DESTROYED] = TRUE FailFlags[MISSION_FAIL_COACH_DEAD] = TRUE FailFlags[MISSION_FAIL_COACH_SPOOKED] = TRUE FailFlags[MISSION_FAIL_COACH_ATTACKED] = TRUE FailFlags[MISSION_FAIL_FRANKLIN_DEAD] = TRUE FailFlags[MISSION_FAIL_FRANKLIN_LEFT_BEHIND] = TRUE IF HAS_MISSION_VEHICLE_BEEN_CREATED(vsPlayersCar, FALSE, FALSE, NO_CHARACTER, TRUE, -1, 132, 0) SET_VEHICLE_AS_RESTRICTED(vsPlayersCar.VehicleIndex, 0) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF NOT IS_VEHICLE_EXTRA_TURNED_ON(vsPlayersCar.VehicleIndex, 5) SET_VEHICLE_EXTRA(vsPlayersCar.VehicleIndex, 5, FALSE) ENDIF SET_VEHICLE_STRONG(vsPlayersCar.VehicleIndex, TRUE) SET_VEHICLE_CAN_SAVE_IN_GARAGE(vsPlayersCar.VehicleIndex, FALSE) ENDIF IF HAS_MISSION_PED_BEEN_CREATED(psCoach, FALSE, rgTennisCoach, FALSE, CHAR_TENNIS_COACH) IF HAS_MISSION_OBJECT_BEEN_CREATED(osRopeAnchor, TRUE) IF DOES_ENTITY_EXIST(osRopeAnchor.ObjectIndex) IF NOT IS_ENTITY_DEAD(osRopeAnchor.ObjectIndex) SET_ENTITY_VISIBLE(osRopeAnchor.ObjectIndex, FALSE) ENDIF ENDIF INFORM_MISSION_STATS_OF_SPEED_WATCH_ENTITY(vsPlayersCar.VehicleIndex) INFORM_MISSION_STATS_OF_DAMAGE_WATCH_ENTITY(NULL) //stop tracking damage IF NOT IS_PED_INJURED(psCoach.PedIndex) SET_PED_COMPONENT_VARIATION(psCoach.PedIndex, PED_COMP_TORSO, 1, 0) SET_PED_COMPONENT_VARIATION(psCoach.PedIndex, PED_COMP_LEG, 1, 0) ENDIF SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL IF HAS_MISSION_PED_BEEN_CREATED(psFranklin, TRUE, RELGROUPHASH_PLAYER, FALSE, CHAR_FRANKLIN, FALSE, FALSE, FALSE, vsPlayersCar.VehicleIndex, VS_FRONT_RIGHT) IF NOT IS_PED_INJURED(psFranklin.PedIndex) AND HAVE_ALL_STREAMING_REQUESTS_COMPLETED(psFranklin.PedIndex) sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN] = psFranklin.PedIndex iSetupProgress++ ENDIF ENDIF BREAK CASE CHAR_FRANKLIN IF HAS_MISSION_PED_BEEN_CREATED(psMichael, TRUE, RELGROUPHASH_PLAYER, FALSE, CHAR_MICHAEL, FALSE, FALSE, FALSE, vsPlayersCar.VehicleIndex, VS_DRIVER) IF NOT IS_PED_INJURED(psMichael.PedIndex) AND HAVE_ALL_STREAMING_REQUESTS_COMPLETED(psMichael.PedIndex) sSelectorPeds.pedID[SELECTOR_PED_MICHAEL] = psMichael.PedIndex IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex, VS_FRONT_RIGHT) ENDIF iSetupProgress++ ENDIF ENDIF BREAK ENDSWITCH ENDIF ENDIF ENDIF BREAK CASE MISSION_STAGE_PULL_HOUSE_DOWN FailFlags[MISSION_FAIL_CAR_STUCK] = FALSE //don't fail for truck getting stuck when pulling FailFlags[MISSION_FAIL_CAR_DESTROYED] = TRUE FailFlags[MISSION_FAIL_COACH_DEAD] = TRUE FailFlags[MISSION_FAIL_COACH_SPOOKED] = TRUE FailFlags[MISSION_FAIL_COACH_ATTACKED] = TRUE FailFlags[MISSION_FAIL_FRANKLIN_DEAD] = TRUE FailFlags[MISSION_FAIL_FRANKLIN_LEFT_BEHIND] = TRUE IF HAS_MISSION_VEHICLE_BEEN_CREATED(vsPlayersCar, FALSE, FALSE, NO_CHARACTER, TRUE, -1, 132, 0) SET_VEHICLE_AS_RESTRICTED(vsPlayersCar.VehicleIndex, 0) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF NOT IS_VEHICLE_EXTRA_TURNED_ON(vsPlayersCar.VehicleIndex, 5) SET_VEHICLE_EXTRA(vsPlayersCar.VehicleIndex, 5, FALSE) ENDIF SET_VEHICLE_STRONG(vsPlayersCar.VehicleIndex, TRUE) SET_VEHICLE_CAN_SAVE_IN_GARAGE(vsPlayersCar.VehicleIndex, FALSE) ENDIF IF HAS_MISSION_PED_BEEN_CREATED(psCoach, FALSE, rgTennisCoach, FALSE, CHAR_TENNIS_COACH) IF HAS_MISSION_OBJECT_BEEN_CREATED(osRopeAnchor, TRUE) AND HAS_MISSION_OBJECT_BEEN_CREATED(osRopeDummy, TRUE) AND HAS_MISSION_OBJECT_BEEN_CREATED(osRopeProp, TRUE) IF DOES_ENTITY_EXIST(osRopeAnchor.ObjectIndex) IF NOT IS_ENTITY_DEAD(osRopeAnchor.ObjectIndex) SET_ENTITY_VISIBLE(osRopeAnchor.ObjectIndex, FALSE) ENDIF ENDIF IF DOES_ENTITY_EXIST(osRopeDummy.ObjectIndex) IF NOT IS_ENTITY_DEAD(osRopeDummy.ObjectIndex) SET_ENTITY_NO_COLLISION_ENTITY(osRopeDummy.ObjectIndex, vsPlayersCar.VehicleIndex, FALSE) SET_CAN_CLIMB_ON_ENTITY(osRopeDummy.ObjectIndex, FALSE) SET_CAN_AUTO_VAULT_ON_ENTITY(osRopeDummy.ObjectIndex, FALSE) ENDIF ENDIF IF DOES_ENTITY_EXIST(osRopeProp.ObjectIndex) IF NOT IS_ENTITY_DEAD(osRopeProp.ObjectIndex) SET_CAN_CLIMB_ON_ENTITY(osRopeProp.ObjectIndex, FALSE) SET_CAN_AUTO_VAULT_ON_ENTITY(osRopeProp.ObjectIndex, FALSE) ENDIF ENDIF INFORM_MISSION_STATS_OF_SPEED_WATCH_ENTITY(vsPlayersCar.VehicleIndex) IF NOT IS_PED_INJURED(psCoach.PedIndex) SET_PED_COMPONENT_VARIATION(psCoach.PedIndex, PED_COMP_TORSO, 1, 0) SET_PED_COMPONENT_VARIATION(psCoach.PedIndex, PED_COMP_LEG, 1, 0) ENDIF SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL IF HAS_MISSION_PED_BEEN_CREATED(psFranklin, TRUE, RELGROUPHASH_PLAYER, FALSE, CHAR_FRANKLIN, FALSE, FALSE, FALSE, vsPlayersCar.VehicleIndex, VS_FRONT_RIGHT) IF NOT IS_PED_INJURED(psFranklin.PedIndex) AND HAVE_ALL_STREAMING_REQUESTS_COMPLETED(psFranklin.PedIndex) sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN] = psFranklin.PedIndex iSetupProgress++ ENDIF ENDIF BREAK CASE CHAR_FRANKLIN IF HAS_MISSION_PED_BEEN_CREATED(psMichael, TRUE, RELGROUPHASH_PLAYER, FALSE, CHAR_MICHAEL) IF NOT IS_PED_INJURED(psMichael.PedIndex) AND HAVE_ALL_STREAMING_REQUESTS_COMPLETED(psMichael.PedIndex) sSelectorPeds.pedID[SELECTOR_PED_MICHAEL] = psMichael.PedIndex IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex, VS_FRONT_RIGHT) ENDIF iSetupProgress++ ENDIF ENDIF BREAK ENDSWITCH ENDIF ENDIF ENDIF BREAK CASE MISSION_STAGE_ESCAPE_GOONS FailFlags[MISSION_FAIL_MICHAEL_DEAD] = TRUE FailFlags[MISSION_FAIL_FRANKLIN_DEAD] = TRUE FailFlags[MISSION_FAIL_MICHAEL_LEFT_BEHIND] = TRUE FailFlags[MISSION_FAIL_FRANKLIN_LEFT_BEHIND] = TRUE IF HAS_MISSION_VEHICLE_BEEN_CREATED(vsPlayersCar, FALSE, FALSE, NO_CHARACTER, TRUE, -1, 132, 0) SET_VEHICLE_AS_RESTRICTED(vsPlayersCar.VehicleIndex, 0) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) REQUEST_VEHICLE_HIGH_DETAIL_MODEL(vsPlayersCar.VehicleIndex) IF NOT IS_VEHICLE_EXTRA_TURNED_ON(vsPlayersCar.VehicleIndex, 5) SET_VEHICLE_EXTRA(vsPlayersCar.VehicleIndex, 5, FALSE) ENDIF SET_VEHICLE_STRONG(vsPlayersCar.VehicleIndex, FALSE) SET_VEHICLE_CAN_SAVE_IN_GARAGE(vsPlayersCar.VehicleIndex, FALSE) ENDIF //IF NOT DOES_PARTICLE_FX_LOOPED_EXIST(ptfxDustCloud) //make sure dust particles are created REQUEST_PTFX_ASSET() // IF HAS_PTFX_ASSET_LOADED() // #IF IS_DEBUG_BUILD // PRINTLN(GET_THIS_SCRIPT_NAME(), ": Starting particle fx ent_ray_fam3_dust_settle.") // #ENDIF // ptfxDustCloud = START_PARTICLE_FX_LOOPED_AT_COORD("ent_ray_fam3_dust_settle", << -1016.0, 642.0, 141.0 >>, << 0.0, 0.0, 0.0 >>) // ENDIF //ELSE //reset kill counters iPlayerMichaelKills = 0 iPlayerFranklinKills = 0 iBuddyMichaelKills = 0 iBuddyFranklinKills = 0 bVehicleReversed = FALSE INFORM_MISSION_STATS_OF_SPEED_WATCH_ENTITY(vsPlayersCar.VehicleIndex) SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL IF HAS_MISSION_PED_BEEN_CREATED(psFranklin, TRUE, RELGROUPHASH_PLAYER, FALSE, CHAR_FRANKLIN, FALSE, FALSE, FALSE, vsPlayersCar.VehicleIndex, VS_FRONT_RIGHT) IF NOT IS_PED_INJURED(psFranklin.PedIndex) AND HAVE_ALL_STREAMING_REQUESTS_COMPLETED(psFranklin.PedIndex) sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN] = psFranklin.PedIndex iSetupProgress++ ENDIF ENDIF BREAK CASE CHAR_FRANKLIN IF HAS_MISSION_PED_BEEN_CREATED(psMichael, TRUE, RELGROUPHASH_PLAYER, FALSE, CHAR_MICHAEL, FALSE, FALSE, FALSE, vsPlayersCar.VehicleIndex, VS_DRIVER) IF NOT IS_PED_INJURED(psMichael.PedIndex) AND HAVE_ALL_STREAMING_REQUESTS_COMPLETED(psMichael.PedIndex) sSelectorPeds.pedID[SELECTOR_PED_MICHAEL] = psMichael.PedIndex IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex, VS_FRONT_RIGHT) ENDIF iSetupProgress++ ENDIF ENDIF BREAK ENDSWITCH //ENDIF ENDIF BREAK CASE MISSION_STAGE_CUTSCENE_END IF HAS_MISSION_VEHICLE_BEEN_CREATED(vsPlayersCar, FALSE, FALSE, NO_CHARACTER, TRUE, -1, 132, 0) AND HAS_MISSION_VEHICLE_BEEN_CREATED(vsCutsceneCar, FALSE, FALSE, NO_CHARACTER, TRUE, -1, 0, 0, 3, 0 #IF IS_DEBUG_BUILD, "MadrazosCar" #ENDIF) IF IS_VEHICLE_DRIVEABLE(vsCutsceneCar.VehicleIndex) SET_ENTITY_INVINCIBLE(vsCutsceneCar.VehicleIndex, TRUE) ENDIF SET_VEHICLE_AS_RESTRICTED(vsPlayersCar.VehicleIndex, 0) INFORM_MISSION_STATS_OF_SPEED_WATCH_ENTITY(vsPlayersCar.VehicleIndex) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF NOT IS_VEHICLE_EXTRA_TURNED_ON(vsPlayersCar.VehicleIndex, 5) SET_VEHICLE_EXTRA(vsPlayersCar.VehicleIndex, 5, FALSE) ENDIF SET_VEHICLE_STRONG(vsPlayersCar.VehicleIndex, FALSE) SET_VEHICLE_CAN_SAVE_IN_GARAGE(vsPlayersCar.VehicleIndex, FALSE) ENDIF SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL IF HAS_MISSION_PED_BEEN_CREATED(psFranklin, TRUE, RELGROUPHASH_PLAYER, FALSE, CHAR_FRANKLIN, FALSE, FALSE, FALSE, vsPlayersCar.VehicleIndex, VS_FRONT_RIGHT) IF NOT IS_PED_INJURED(psFranklin.PedIndex) AND HAVE_ALL_STREAMING_REQUESTS_COMPLETED(psFranklin.PedIndex) sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN] = psFranklin.PedIndex iSetupProgress++ ENDIF ENDIF BREAK CASE CHAR_FRANKLIN IF HAS_MISSION_PED_BEEN_CREATED(psMichael, TRUE, RELGROUPHASH_PLAYER, FALSE, CHAR_MICHAEL, FALSE, FALSE, FALSE, vsPlayersCar.VehicleIndex, VS_DRIVER) IF NOT IS_PED_INJURED(psMichael.PedIndex) AND HAVE_ALL_STREAMING_REQUESTS_COMPLETED(psMichael.PedIndex) sSelectorPeds.pedID[SELECTOR_PED_MICHAEL] = psMichael.PedIndex iSetupProgress++ ENDIF ENDIF BREAK ENDSWITCH ENDIF BREAK CASE MISSION_STAGE_LEADOUT IF NOT DOES_ENTITY_EXIST(vsMichaelsEndCar.VehicleIndex) IF IS_VEHICLE_GEN_AVAILABLE(VEHGEN_MISSION_VEH) AND DOES_ENTITY_EXIST(GET_VEHICLE_GEN_VEHICLE_INDEX(VEHGEN_MISSION_VEH)) AND IS_VEHICLE_DRIVEABLE(GET_VEHICLE_GEN_VEHICLE_INDEX(VEHGEN_MISSION_VEH)) AND GET_PLAYER_CHARACTER_AT_MISSION_START() = CHAR_MICHAEL VEHICLE_INDEX VehGenVehicleIndex VehGenVehicleIndex = GET_VEHICLE_GEN_VEHICLE_INDEX(VEHGEN_MISSION_VEH) IF DOES_ENTITY_EXIST(VehGenVehicleIndex) IF NOT IS_ENTITY_DEAD(VehGenVehicleIndex) IF NOT IS_ENTITY_A_MISSION_ENTITY(VehGenVehicleIndex) OR NOT DOES_ENTITY_BELONG_TO_THIS_SCRIPT(VehGenVehicleIndex) SET_ENTITY_AS_MISSION_ENTITY(VehGenVehicleIndex, TRUE, TRUE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting Michael's mission start vehicle as mission entity.") #ENDIF ENDIF vsMichaelsEndCar.VehicleIndex = VehGenVehicleIndex SET_ENTITY_COORDS(vsMichaelsEndCar.VehicleIndex, vsMichaelsEndCar.vPosition) SET_ENTITY_HEADING(vsMichaelsEndCar.VehicleIndex, vsMichaelsEndCar.fHeading) SET_VEHICLE_ON_GROUND_PROPERLY(vsMichaelsEndCar.VehicleIndex) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Moving Michael's mission start vehicle gen to position ",vsMichaelsEndCar.vPosition, " and heading ", vsMichaelsEndCar.fHeading, " and making a mission entity.") #ENDIF ENDIF ENDIF ELSE DELETE_ALL_SCRIPT_CREATED_PLAYER_VEHICLES(CHAR_MICHAEL) IF HAS_MISSION_VEHICLE_BEEN_CREATED(vsMichaelsEndCar, TRUE, FALSE, CHAR_MICHAEL, TRUE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Creating default Michael's car due to mission vehicle gen for Michael not being available or dead.") #ENDIF ENDIF ENDIF ELSE SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL iSetupProgress++ BREAK CASE CHAR_FRANKLIN IF HAS_MISSION_PED_BEEN_CREATED(psMichael, TRUE, RELGROUPHASH_PLAYER, FALSE, CHAR_MICHAEL, FALSE, FALSE, FALSE, vsPlayersCar.VehicleIndex, VS_DRIVER) IF NOT IS_PED_INJURED(psMichael.PedIndex) AND HAVE_ALL_STREAMING_REQUESTS_COMPLETED(psMichael.PedIndex) sSelectorPeds.pedID[SELECTOR_PED_MICHAEL] = psMichael.PedIndex iSetupProgress++ ENDIF ENDIF BREAK ENDSWITCH ENDIF BREAK //debug stages #IF IS_DEBUG_BUILD CASE MISSION_STAGE_DEBUG_RECORD_CHASE CASE MISSION_STAGE_DEBUG_PLAYBACK_CHASE IF HAS_MISSION_VEHICLE_BEEN_CREATED(vsCoachsCar, FALSE, FALSE, NO_CHARACTER, TRUE, -1, 43, 43) iSetupProgress++ ENDIF BREAK #ENDIF DEFAULT iSetupProgress++ BREAK ENDSWITCH ENDIF IF ( iSetupProgress = 6 ) IF ( bStageSkippedTo = TRUE OR bStageReplayed = TRUE ) //handle switching on skips and replay SWITCH eStage CASE MISSION_STAGE_CUTSCENE_INTRO //don't force switch here BREAK CASE MISSION_STAGE_CAR_CHASE CASE MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE CASE MISSION_STAGE_PULL_HOUSE_DOWN CASE MISSION_STAGE_ESCAPE_GOONS CASE MISSION_STAGE_LEADOUT IF MAKE_SELECTOR_PED_SELECTION(sSelectorPeds, SELECTOR_PED_MICHAEL) TAKE_CONTROL_OF_SELECTOR_PED(sSelectorPeds) psFranklin.PedIndex = sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN] #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Performing script controlled hotswap to Michael for mission stage being loaded.") #ENDIF ENDIF BREAK CASE MISSION_STAGE_CUTSCENE_END //don't force switch here BREAK ENDSWITCH ENDIF LOCK_AUTOMATIC_DOOR_OPEN(AUTODOOR_MICHAEL_MANSION_GATE, FALSE) SWITCH eStage //handle garage and gate door CASE MISSION_STAGE_CUTSCENE_INTRO CASE MISSION_STAGE_ESCAPE_GOONS CASE MISSION_STAGE_CUTSCENE_END IF IS_DOOR_REGISTERED_WITH_SYSTEM(ENUM_TO_INT(DOORHASH_M_MANSION_G1)) DOOR_SYSTEM_SET_OPEN_RATIO(ENUM_TO_INT(DOORHASH_M_MANSION_G1), 0.0, FALSE, FALSE) DOOR_SYSTEM_SET_DOOR_STATE(ENUM_TO_INT(DOORHASH_M_MANSION_G1), DOORSTATE_LOCKED, FALSE, TRUE) ENDIF BREAK CASE MISSION_STAGE_CAR_CHASE LOCK_AUTOMATIC_DOOR_OPEN(AUTODOOR_MICHAEL_MANSION_GATE, TRUE) IF IS_DOOR_REGISTERED_WITH_SYSTEM(ENUM_TO_INT(DOORHASH_M_MANSION_G1)) DOOR_SYSTEM_SET_OPEN_RATIO(ENUM_TO_INT(DOORHASH_M_MANSION_G1), 0.0, FALSE, FALSE) DOOR_SYSTEM_SET_DOOR_STATE(ENUM_TO_INT(DOORHASH_M_MANSION_G1), DOORSTATE_UNLOCKED, FALSE, TRUE) ENDIF BREAK DEFAULT IF IS_DOOR_REGISTERED_WITH_SYSTEM(ENUM_TO_INT(DOORHASH_M_MANSION_G1)) DOOR_SYSTEM_SET_OPEN_RATIO(ENUM_TO_INT(DOORHASH_M_MANSION_G1), 0.0, FALSE, FALSE) DOOR_SYSTEM_SET_DOOR_STATE(ENUM_TO_INT(DOORHASH_M_MANSION_G1), DOORSTATE_UNLOCKED, FALSE, TRUE) ENDIF BREAK ENDSWITCH iSetupProgress++ ENDIF //handle adding mission peds for dialogue, cellphone and taxi hailing depending on mission stage IF ( iSetupProgress = 7 ) REMOVE_PED_FOR_DIALOGUE(sFamily3Conversation, 0) //Michael REMOVE_PED_FOR_DIALOGUE(sFamily3Conversation, 1) //Franklin REMOVE_PED_FOR_DIALOGUE(sFamily3Conversation, 3) //Tennis coach REMOVE_PED_FOR_DIALOGUE(sFamily3Conversation, 4) //Natalia REMOVE_PED_FOR_DIALOGUE(sFamily3Conversation, 5) //Van Driver REMOVE_PED_FOR_DIALOGUE(sFamily3Conversation, 6) //Lester IF NOT IS_PED_INJURED(PLAYER_PED_ID()) ADD_PED_FOR_DIALOGUE(sFamily3Conversation, 0, PLAYER_PED_ID(), "MICHAEL") ENDIF SWITCH eStage CASE MISSION_STAGE_CAR_CHASE IF NOT IS_PED_INJURED(psFranklin.PedIndex) ADD_PED_FOR_DIALOGUE(sFamily3Conversation, 1, psFranklin.PedIndex, "FRANKLIN") ENDIF IF NOT IS_PED_INJURED(psCoach.PedIndex) ADD_PED_FOR_DIALOGUE(sFamily3Conversation, 3, psCoach.PedIndex, "TENNISCOACH") ENDIF DISABLE_CELLPHONE(FALSE) DISABLE_TAXI_HAILING(TRUE) SUPPRESS_EMERGENCY_CALLS() BREAK CASE MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE CASE MISSION_STAGE_PULL_HOUSE_DOWN IF NOT IS_PED_INJURED(psFranklin.PedIndex) ADD_PED_FOR_DIALOGUE(sFamily3Conversation, 1, psFranklin.PedIndex, "FRANKLIN") ENDIF IF NOT IS_PED_INJURED(psCoach.PedIndex) ADD_PED_FOR_DIALOGUE(sFamily3Conversation, 3, psCoach.PedIndex, "TENNISCOACH") ENDIF DISABLE_CELLPHONE(TRUE) DISABLE_TAXI_HAILING(TRUE) SUPPRESS_EMERGENCY_CALLS() BREAK CASE MISSION_STAGE_ESCAPE_GOONS IF NOT IS_PED_INJURED(psFranklin.PedIndex) ADD_PED_FOR_DIALOGUE(sFamily3Conversation, 1, psFranklin.PedIndex, "FRANKLIN") ENDIF IF DOES_ENTITY_EXIST(psCoach.PedIndex) IF NOT IS_PED_INJURED(psCoach.PedIndex) ADD_PED_FOR_DIALOGUE(sFamily3Conversation, 3, psCoach.PedIndex, "TENNISCOACH") ENDIF ELSE ADD_PED_FOR_DIALOGUE(sFamily3Conversation, 3, NULL, "TENNISCOACH") ENDIF ADD_PED_FOR_DIALOGUE(sFamily3Conversation, 4, NULL, "NATHALIA") DISABLE_CELLPHONE(FALSE) DISABLE_TAXI_HAILING(TRUE) SUPPRESS_EMERGENCY_CALLS() BREAK CASE MISSION_STAGE_CUTSCENE_END DISABLE_CELLPHONE(FALSE) DISABLE_TAXI_HAILING(FALSE) RELEASE_SUPPRESSED_EMERGENCY_CALLS() BREAK CASE MISSION_STAGE_LEADOUT ADD_PED_FOR_DIALOGUE(sFamily3Conversation, 6, NULL, "LESTER") DISABLE_CELLPHONE(FALSE) DISABLE_TAXI_HAILING(FALSE) RELEASE_SUPPRESSED_EMERGENCY_CALLS() BREAK ENDSWITCH iSetupProgress++ ENDIF //handle ped and vehicle density and budget IF ( iSetupProgress = 8 ) SET_MAX_WANTED_LEVEL(5) SET_CREATE_RANDOM_COPS(TRUE) SET_WANTED_LEVEL_MULTIPLIER(1.0) ENABLE_DISPATCH_SERVICE(DT_FIRE_DEPARTMENT, TRUE) ENABLE_DISPATCH_SERVICE(DT_AMBULANCE_DEPARTMENT, TRUE) SET_ALL_SHOPS_TEMPORARILY_UNAVAILABLE(FALSE) //CASCADE_SHADOWS_INIT_SESSION() SET_INSTANCE_PRIORITY_HINT(INSTANCE_HINT_NONE) REMOVE_NAVMESH_BLOCKING_OBJECTS() SWITCH eStage CASE MISSION_STAGE_CUTSCENE_INTRO //turn ambient peds off SET_PED_POPULATION_BUDGET(0) SET_VEHICLE_POPULATION_BUDGET(0) SET_PLAYER_CAN_CHANGE_CLOTHES_ON_MISSION(TRUE) BREAK CASE MISSION_STAGE_CAR_CHASE //turn ambient peds on SET_PED_POPULATION_BUDGET(3) SET_VEHICLE_POPULATION_BUDGET(3) SET_PLAYER_CAN_CHANGE_CLOTHES_ON_MISSION(TRUE) SET_ALL_SHOPS_TEMPORARILY_UNAVAILABLE(TRUE) SET_INSTANCE_PRIORITY_HINT(INSTANCE_HINT_DRIVING) BREAK CASE MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE CASE MISSION_STAGE_PULL_HOUSE_DOWN //turn ambient peds off SET_PED_POPULATION_BUDGET(0) SET_VEHICLE_POPULATION_BUDGET(0) SET_MAX_WANTED_LEVEL(0) SET_CREATE_RANDOM_COPS(FALSE) SET_WANTED_LEVEL_MULTIPLIER(0.0) ENABLE_DISPATCH_SERVICE(DT_FIRE_DEPARTMENT, FALSE) ENABLE_DISPATCH_SERVICE(DT_AMBULANCE_DEPARTMENT, FALSE) SET_PLAYER_CAN_CHANGE_CLOTHES_ON_MISSION(TRUE) BREAK CASE MISSION_STAGE_ESCAPE_GOONS //turn ambient peds on with lower density SET_PED_POPULATION_BUDGET(3) SET_VEHICLE_POPULATION_BUDGET(3) //wanted level SET_MAX_WANTED_LEVEL(0) SET_CREATE_RANDOM_COPS(FALSE) SET_WANTED_LEVEL_MULTIPLIER(0.0) SET_PLAYER_CAN_CHANGE_CLOTHES_ON_MISSION(FALSE) SET_ALL_SHOPS_TEMPORARILY_UNAVAILABLE(TRUE) SET_INSTANCE_PRIORITY_HINT(INSTANCE_HINT_DRIVING) ADD_NAVMESH_BLOCKING_OBJECTS() BREAK CASE MISSION_STAGE_CUTSCENE_END CASE MISSION_STAGE_LEADOUT //turn ambient peds on SET_PED_POPULATION_BUDGET(3) SET_VEHICLE_POPULATION_BUDGET(3) IF IS_PLAYER_PLAYING(PLAYER_ID()) SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0) SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID()) ENDIF SET_PLAYER_CAN_CHANGE_CLOTHES_ON_MISSION(TRUE) BREAK ENDSWITCH iSetupProgress++ ENDIF IF ( iSetupProgress = 9 ) //stage was skipped to or is being replayed IF ( bStageSkippedTo = TRUE OR bStageReplayed = TRUE ) SWITCH eStage CASE MISSION_STAGE_CAR_CHASE REQUEST_VEHICLE_ASSET(vsPlayersCar.ModelName, ENUM_TO_INT(VRF_REQUEST_ENTRY_ANIMS)) IF HAS_VEHICLE_ASSET_LOADED(vsPlayersCar.ModelName) iSetupProgress++ ENDIF BREAK CASE MISSION_STAGE_PULL_HOUSE_DOWN IF ( bRopeAttached = FALSE ) IF NOT DOES_ROPE_EXIST(Rope) ROPE_LOAD_TEXTURES() IF ROPE_ARE_TEXTURES_LOADED() Rope = ADD_ROPE(<<-1017.9850, 660.4285, 147.4662>>, <<0.0, 0.0, 0.0>>, ROPE_MAX_LEN, PHYSICS_ROPE_DEFAULT, -1, 0.5, 0.5, FALSE, TRUE) LOAD_ROPE_DATA( Rope, ROPE_DATA_FILE ) ENDIF ENDIF IF DOES_ENTITY_EXIST(osRopeAnchor.ObjectIndex) AND DOES_ROPE_EXIST(rope) IF DOES_ENTITY_HAVE_PHYSICS(osRopeAnchor.ObjectIndex) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) ATTACH_ENTITIES_TO_ROPE(Rope, osRopeAnchor.ObjectIndex, vsPlayersCar.VehicleIndex, osRopeAnchor.vPosition, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vsPlayersCar.VehicleIndex, << 0.0, -2.1, 0.6 >>), 35.0, 0, 0) bRopeAttached = TRUE ENDIF ENDIF ENDIF ELSE IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) SET_VEHICLE_DOOR_OPEN(vsPlayersCar.VehicleIndex, SC_DOOR_BOOT, FALSE, TRUE) ENDIF iSetupProgress++ ENDIF BREAK DEFAULT iSetupProgress++ BREAK ENDSWITCH ELSE iSetupProgress++ ENDIF ENDIF //handle player positioning when current stage is being skipped to or played normally //fade in the screen if it was faded out due to skipping IF ( iSetupProgress = 10 ) //stage was skipped to or is being replayed IF ( bStageSkippedTo = TRUE OR bStageReplayed = TRUE ) IF ( bStageReplayed = TRUE ) END_REPLAY_SETUP(NULL, DEFAULT, FALSE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Calling END_REPLAY_SETUP().") #ENDIF ELSE NEW_LOAD_SCENE_START_SPHERE(GET_ENTITY_COORDS(PLAYER_PED_ID()), 100.0) #IF IS_DEBUG_BUILD VECTOR vNewLoadScenePosition = GET_ENTITY_COORDS(PLAYER_PED_ID()) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Calling NEW_LOAD_SCENE_START_SPHERE() at coordinates ", vNewLoadScenePosition, " for mission replay or stage skip. This might take a while to load.") #ENDIF INT iLoadSceneTimer = GET_GAME_TIMER() + 15000 WHILE IS_NEW_LOAD_SCENE_ACTIVE() AND NOT IS_NEW_LOAD_SCENE_LOADED() AND GET_GAME_TIMER() < iLoadSceneTimer #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Load scene timer: ", iLoadSceneTimer - GET_GAME_TIMER(), ".") #ENDIF WAIT(0) ENDWHILE NEW_LOAD_SCENE_STOP() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Calling NEW_LOAD_SCENE_STOP().") #ENDIF ENDIF //WAIT(1000) //add wait to hide any load scene freezes //reset objective text labels for skips and retry sLabelGIT = "FAM3_GIT" //put player in car when required during the skip SWITCH eStage CASE MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE CASE MISSION_STAGE_ESCAPE_GOONS CASE MISSION_STAGE_CUTSCENE_END IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF NOT IS_PED_INJURED(PLAYER_PED_ID()) SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex, VS_DRIVER) SET_VEHICLE_ON_GROUND_PROPERLY(vsPlayersCar.VehicleIndex) SET_VEHICLE_ENGINE_ON(vsPlayersCar.VehicleIndex, TRUE, TRUE) ENDIF ENDIF BREAK ENDSWITCH IF ( eStage = MISSION_STAGE_CAR_CHASE ) OR ( eStage = MISSION_STAGE_PULL_HOUSE_DOWN ) WAIT(500) IF ( eStage = MISSION_STAGE_CAR_CHASE ) UPDATE_THIRD_PERSON_RUN_TO_VEHICLE_CAMERA() ENDIF ENDIF SET_GAMEPLAY_CAM_RELATIVE_PITCH(0) SET_GAMEPLAY_CAM_RELATIVE_HEADING(0) //handle music for skips/retry/replay of mission stages SWITCH eStage CASE MISSION_STAGE_CAR_CHASE TRIGGER_MUSIC_EVENT("FAM3_CHASE_RESTART") BREAK CASE MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE TRIGGER_MUSIC_EVENT("FAM3_HOUSE_RESTART") BREAK CASE MISSION_STAGE_PULL_HOUSE_DOWN TRIGGER_MUSIC_EVENT("FAM3_PULL_RESTART") BREAK CASE MISSION_STAGE_ESCAPE_GOONS TRIGGER_MUSIC_EVENT("FAM3_MEX_RESTART") BREAK ENDSWITCH //handle fade in for each mission stage //some stages start with or require a fade out SWITCH eStage CASE MISSION_STAGE_CUTSCENE_INTRO CASE MISSION_STAGE_CAR_CHASE CASE MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE CASE MISSION_STAGE_CUTSCENE_END CASE MISSION_STAGE_LEADOUT //do not fade in, mission stage will handle a fade in from fade out #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Halting loading screen fade in for skip to a mission stage that will fade the screen in.") #ENDIF BREAK DEFAULT //fade in #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Calling a loading screen fade in.") #ENDIF IF IS_SCREEN_FADED_OUT() DO_SAFE_SCREEN_FADE_IN(DEFAULT_FADE_TIME) ENDIF BREAK ENDSWITCH ENDIF iSetupProgress++ ENDIF //handle setting of mid-mission replay/retry checkpoints IF ( iSetupProgress = 11 ) SWITCH eStage CASE MISSION_STAGE_CAR_CHASE SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(ENUM_TO_INT(MID_MISSION_STAGE_CAR_CHASE), "CAR CHASE", FALSE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting replay mid-mission checkpoint to ", ENUM_TO_INT(MID_MISSION_STAGE_CAR_CHASE), " for stage ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eStage), ".") #ENDIF BREAK CASE MISSION_STAGE_PULL_HOUSE_DOWN SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(ENUM_TO_INT(MID_MISSION_STAGE_PULL_HOUSE_DOWN), "PULL HOUSE DOWN", FALSE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting replay mid-mission checkpoint to ", ENUM_TO_INT(MID_MISSION_STAGE_PULL_HOUSE_DOWN), " for stage ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eStage), ".") #ENDIF BREAK CASE MISSION_STAGE_ESCAPE_GOONS SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(ENUM_TO_INT(MID_MISSION_STAGE_ESCAPE_GOONS), "ESCAPE GOONS", TRUE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting replay mid-mission checkpoint to ", ENUM_TO_INT(MID_MISSION_STAGE_ESCAPE_GOONS), " for stage ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eStage), ".") #ENDIF BREAK ENDSWITCH iSetupProgress++ ENDIF //print the message only once per mission stage //handle fades IF ( iSetupProgress = 12 ) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Finished mission stage loading for ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eStage), ".") #ENDIF //reset the stage reset flag #IF IS_DEBUG_BUILD bStageResetFlag = FALSE #ENDIF bStageLoaded = TRUE bStageReplayed = FALSE bStageSkippedTo = FALSE SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) iSetupProgress++ ENDIF IF ( iSetupProgress = 13 ) RETURN TRUE ENDIF RETURN FALSE ENDFUNC PROC SET_PED_PROPERTIES_AFTER_HOTSWAP(PED_STRUCT &ped, PED_INDEX PedIndex, BOOL bCreateBlip, REL_GROUP_HASH relGroupHash) IF NOT IS_PED_INJURED(PedIndex) ped.PedIndex = PedIndex SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PedIndex, TRUE) SET_PED_CAN_BE_TARGETTED(PedIndex, FALSE) SET_PED_AS_ENEMY(PedIndex, FALSE) SET_PED_RELATIONSHIP_GROUP_HASH(PedIndex, relGroupHash) SET_RAGDOLL_BLOCKING_FLAGS(PedIndex, RBF_BULLET_IMPACT) SET_RAGDOLL_BLOCKING_FLAGS(PedIndex, RBF_PLAYER_IMPACT) SET_PED_SUFFERS_CRITICAL_HITS(PedIndex, FALSE) SET_PED_HIGHLY_PERCEPTIVE(PedIndex, TRUE) SET_PED_CONFIG_FLAG(PedIndex, PCF_DisableHurt, TRUE) SET_PED_CONFIG_FLAG(PedIndex, PCF_DisablePanicInVehicle, TRUE) SET_PED_CONFIG_FLAG(PedIndex, PCF_WillFlyThroughWindscreen, FALSE) SET_PED_CONFIG_FLAG(PedIndex, PCF_OnlyAttackLawIfPlayerIsWanted, TRUE) SET_COMBAT_FLOAT(PedIndex, CCF_TIME_TO_INVALIDATE_INJURED_TARGET, 1.0) SET_PED_COMBAT_ATTRIBUTES(PedIndex, CA_ALWAYS_EQUIP_BEST_WEAPON, FALSE) SET_PED_COMBAT_ATTRIBUTES(PedIndex, CA_CAN_FIGHT_ARMED_PEDS_WHEN_NOT_ARMED, TRUE) SET_PED_MAX_HEALTH_WITH_SCALE(PedIndex, MAX_BUDDY_PED_HEALTH) IF GET_BEST_PED_WEAPON(PedIndex) = WEAPONTYPE_UNARMED GIVE_WEAPON_TO_PED(PedIndex, WEAPONTYPE_PISTOL, GET_MAX_AMMO_IN_CLIP(PedIndex, WEAPONTYPE_PISTOL) * 2, FALSE, FALSE) ENDIF ADD_ENTITY_TO_AUDIO_MIX_GROUP(PedIndex, "FAMILY_3_BUDDY_GROUP") IF ( bCreateBlip = TRUE ) IF NOT DOES_BLIP_EXIST(ped.BlipIndex) ped.BlipIndex = CREATE_BLIP_FOR_ENTITY(PedIndex, FALSE) ENDIF ENDIF ENDIF ENDPROC FUNC BOOL RUN_SHORT_RANGE_OR_DIRECT_SWITCH(SELECTOR_CAM_STRUCT &sCamStruct, BOOL bDirectSwitch) IF ( bDirectSwitch = FALSE ) //run default short range switch IF RUN_SWITCH_CAM_FROM_PLAYER_TO_PED_SHORT_RANGE(sCamStruct) IF sCamStruct.bOKToSwitchPed = TRUE RETURN TRUE ENDIF ENDIF ELSE //don't run the default short range switch, just move on to take control of selector ped directly RETURN TRUE ENDIF RETURN FALSE ENDFUNC PROC RUN_HOTSWAP() IF NOT sCamDetails.bRun IF UPDATE_SELECTOR_HUD(sSelectorPeds) IF NOT HAS_SELECTOR_PED_BEEN_SELECTED(sSelectorPeds, SELECTOR_PED_MULTIPLAYER) IF HAS_SOUND_FINISHED(iCustomSwitchSoundID) PLAY_SOUND_FRONTEND(iCustomSwitchSoundID, "All", "SHORT_PLAYER_SWITCH_SOUND_SET") ENDIF IF ( bFirstSwitchCompleted = FALSE ) ADD_AMMO_TO_PED(GET_PED_INDEX(CHAR_FRANKLIN), WEAPONTYPE_PISTOL, GET_MAX_AMMO_IN_CLIP(GET_PED_INDEX(CHAR_FRANKLIN), WEAPONTYPE_PISTOL) * 5) bFirstSwitchCompleted = TRUE ENDIF sCamDetails.pedTo = sSelectorPeds.pedID[sSelectorPeds.eNewSelectorPed] sCamDetails.bRun = TRUE bRunDirectSwitch = FALSE //decide which switch to run here and then stick to it until switch is over IF NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_MICHAEL)) AND NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_FRANKLIN)) IF IS_PED_IN_ANY_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL)) OR IS_PED_IN_ANY_VEHICLE(GET_PED_INDEX(CHAR_FRANKLIN)) IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_IN_VEHICLE) = CAM_VIEW_MODE_FIRST_PERSON bRunDirectSwitch = TRUE //disable short range switch and cut straight to the other ped ENDIF ENDIF ENDIF ENDIF ENDIF ELSE IF RUN_SHORT_RANGE_OR_DIRECT_SWITCH(sCamDetails, bRunDirectSwitch) IF NOT sCamDetails.bPedSwitched IF TAKE_CONTROL_OF_SELECTOR_PED(sSelectorPeds, TRUE, TRUE) //clear locates header blips and god text when switching CLEAR_MISSION_LOCATION_TEXT_AND_BLIPS(sLocatesData) SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL //player hot swapped to Michael //remove blip for the ped that is now current player ped IF DOES_BLIP_EXIST(psMichael.BlipIndex) REMOVE_BLIP(psMichael.BlipIndex) ENDIF SET_PED_PROPERTIES_AFTER_HOTSWAP(psFranklin, sSelectorPeds.pedID[sSelectorPeds.ePreviousSelectorPed], FALSE, RELGROUPHASH_PLAYER) FailFlags[MISSION_FAIL_MICHAEL_DEAD] = FALSE FailFlags[MISSION_FAIL_MICHAEL_LEFT_BEHIND] = FALSE FailFlags[MISSION_FAIL_FRANKLIN_DEAD] = TRUE FailFlags[MISSION_FAIL_FRANKLIN_LEFT_BEHIND] = TRUE GO_TO_PED_STATE(psFranklin, PED_STATE_WAITING_FOR_TASK_AFTER_SWITCH) IF ( bRunDirectSwitch = TRUE ) ANIMPOSTFX_PLAY("SwitchSceneMichael", 0, FALSE) ENDIF #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Player switched to Michael.") #ENDIF BREAK CASE CHAR_FRANKLIN //player hot swapped to Franklin //remove blip for the ped that is now current player ped IF DOES_BLIP_EXIST(psFranklin.BlipIndex) REMOVE_BLIP(psFranklin.BlipIndex) ENDIF SET_PED_PROPERTIES_AFTER_HOTSWAP(psMichael, sSelectorPeds.pedID[sSelectorPeds.ePreviousSelectorPed], FALSE, RELGROUPHASH_PLAYER) FailFlags[MISSION_FAIL_MICHAEL_DEAD] = TRUE FailFlags[MISSION_FAIL_MICHAEL_LEFT_BEHIND] = TRUE FailFlags[MISSION_FAIL_FRANKLIN_DEAD] = FALSE FailFlags[MISSION_FAIL_FRANKLIN_LEFT_BEHIND] = FALSE GO_TO_PED_STATE(psFranklin, PED_STATE_WAITING_FOR_TASK_AFTER_SWITCH) IF ( bRunDirectSwitch = TRUE ) ANIMPOSTFX_PLAY("SwitchSceneFranklin", 0, FALSE) ENDIF #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Player switched to Franklin.") #ENDIF BREAK ENDSWITCH IF NOT HAS_SOUND_FINISHED(iCustomSwitchSoundID) STOP_SOUND(iCustomSwitchSoundID) ENDIF REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(PLAYER_PED_ID()) REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_MICHAEL_MANSION_GATE, PLAYER_PED_ID()) //register current player with mansion gate //this breaks on repeat play for some reason INFORM_MISSION_STATS_OF_INCREMENT(FAM3_SWITCHES) //increments switch stat SET_SELECTOR_PED_HINT(sSelectorPeds, SELECTOR_PED_MICHAEL, FALSE) SET_SELECTOR_PED_HINT(sSelectorPeds, SELECTOR_PED_FRANKLIN, FALSE) iPlayerShootingTimer = GET_GAME_TIMER() //reset shooting timer bHotSwapTriggered = TRUE //flag that switch happened sCamDetails.bPedSwitched = TRUE IF ( bRunDirectSwitch = TRUE ) //running a direct cut other selector ped sCamDetails.bRun = FALSE //reset these flags for 1st person vehicle switch sCamDetails.bPedSwitched = FALSE //as we no longer run short range switch function ENDIF ENDIF ENDIF ENDIF ENDIF ENDPROC //|======================== END MISSION STAGE LOADINGS PROCEDURES ========================| //|=============================== MISSION STAGES FUNCTIONS ==============================| FUNC BOOL IS_MISSION_STAGE_CUTSCENE_INTRO_COMPLETED(INT &iStageProgress) SWITCH iStageProgress CASE 0 IF ( GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL ) IF HAS_REQUESTED_CUTSCENE_LOADED("family_3_int") REGISTER_ENTITY_FOR_CUTSCENE(psFranklin.PedIndex, "Franklin", CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, GET_PLAYER_PED_MODEL(CHAR_FRANKLIN)) IF DOES_ENTITY_EXIST(g_sTriggerSceneAssets.object[0]) IF NOT IS_ENTITY_DEAD(g_sTriggerSceneAssets.object[0]) SET_ENTITY_AS_MISSION_ENTITY(g_sTriggerSceneAssets.object[0], TRUE, TRUE) osRacket01.ObjectIndex = g_sTriggerSceneAssets.object[0] REGISTER_ENTITY_FOR_CUTSCENE(osRacket01.ObjectIndex, "Racket_1", CU_ANIMATE_EXISTING_SCRIPT_ENTITY, osRacket01.ModelName) ENDIF ELSE REGISTER_ENTITY_FOR_CUTSCENE(osRacket01.ObjectIndex, "Racket_1", CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, osRacket01.ModelName) ENDIF IF DOES_ENTITY_EXIST(g_sTriggerSceneAssets.object[1]) IF NOT IS_ENTITY_DEAD(g_sTriggerSceneAssets.object[1]) SET_ENTITY_AS_MISSION_ENTITY(g_sTriggerSceneAssets.object[1], TRUE, TRUE) osRacket02.ObjectIndex = g_sTriggerSceneAssets.object[1] REGISTER_ENTITY_FOR_CUTSCENE(osRacket02.ObjectIndex, "Racket_2", CU_ANIMATE_EXISTING_SCRIPT_ENTITY, osRacket02.ModelName) ENDIF ELSE REGISTER_ENTITY_FOR_CUTSCENE(osRacket02.ObjectIndex, "Racket_2", CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, osRacket02.ModelName) ENDIF SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE) IF NOT IS_PED_INJURED(PLAYER_PED_ID()) REMOVE_PED_HELMET(PLAYER_PED_ID(), TRUE) ENDIF CLEAR_HELP() CLEAR_PRINTS() START_CUTSCENE(CUTSCENE_SUPPRESS_FP_TRANSITION_FLASH) REPLAY_START_EVENT(REPLAY_IMPORTANCE_HIGHEST) iStageProgress++ ELSE IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY() IF NOT IS_PED_INJURED(PLAYER_PED_ID()) SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Michael", PLAYER_PED_ID()) //Michael's variations ENDIF SET_CUTSCENE_PED_OUTFIT("Franklin", PLAYER_ONE, OUTFIT_P1_GREEN_SHIRT_JEANS) //Franklin's variations SET_CUTSCENE_PED_COMPONENT_VARIATION("Amanda", PED_COMP_HAIR, 1, 0) //Amanda's variations SET_CUTSCENE_PED_COMPONENT_VARIATION("Amanda", PED_COMP_TORSO, 2, 0) SET_CUTSCENE_PED_COMPONENT_VARIATION("Amanda", PED_COMP_LEG, 2, 0) SET_CUTSCENE_PED_COMPONENT_VARIATION("Amanda", PED_COMP_DECL, 1, 0) SET_CUTSCENE_PED_COMPONENT_VARIATION("TennisCoach", PED_COMP_TORSO, 1, 0) //Tennis coach variations SET_CUTSCENE_PED_COMPONENT_VARIATION("TennisCoach", PED_COMP_LEG, 1, 0) ENDIF ENDIF ELIF ( GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN ) IF HAS_REQUESTED_CUTSCENE_LOADED("family_3_int", CS_SECTION_4 | CS_SECTION_5) REGISTER_ENTITY_FOR_CUTSCENE(psMichael.PedIndex, "Michael", CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, GET_PLAYER_PED_MODEL(CHAR_MICHAEL)) IF DOES_ENTITY_EXIST(g_sTriggerSceneAssets.object[0]) IF NOT IS_ENTITY_DEAD(g_sTriggerSceneAssets.object[0]) SET_ENTITY_AS_MISSION_ENTITY(g_sTriggerSceneAssets.object[0], TRUE, TRUE) osRacket01.ObjectIndex = g_sTriggerSceneAssets.object[0] REGISTER_ENTITY_FOR_CUTSCENE(osRacket01.ObjectIndex, "Racket_1", CU_ANIMATE_EXISTING_SCRIPT_ENTITY, osRacket01.ModelName) ENDIF ELSE REGISTER_ENTITY_FOR_CUTSCENE(osRacket01.ObjectIndex, "Racket_1", CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, osRacket01.ModelName) ENDIF IF DOES_ENTITY_EXIST(g_sTriggerSceneAssets.object[1]) IF NOT IS_ENTITY_DEAD(g_sTriggerSceneAssets.object[1]) SET_ENTITY_AS_MISSION_ENTITY(g_sTriggerSceneAssets.object[1], TRUE, TRUE) osRacket02.ObjectIndex = g_sTriggerSceneAssets.object[1] REGISTER_ENTITY_FOR_CUTSCENE(osRacket02.ObjectIndex, "Racket_2", CU_ANIMATE_EXISTING_SCRIPT_ENTITY, osRacket02.ModelName) ENDIF ELSE REGISTER_ENTITY_FOR_CUTSCENE(osRacket02.ObjectIndex, "Racket_2", CU_CREATE_AND_ANIMATE_NEW_SCRIPT_ENTITY, osRacket02.ModelName) ENDIF SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE) IF NOT IS_PED_INJURED(PLAYER_PED_ID()) REMOVE_PED_HELMET(PLAYER_PED_ID(), TRUE) ENDIF CLEAR_HELP() CLEAR_PRINTS() START_CUTSCENE(CUTSCENE_SUPPRESS_FP_TRANSITION_FLASH) iStageProgress++ ELSE IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY() IF NOT IS_PED_INJURED(PLAYER_PED_ID()) SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Franklin", PLAYER_PED_ID()) //Franklin's variations ENDIF SET_CUTSCENE_PED_OUTFIT("Michael", PLAYER_ZERO, OUTFIT_P0_POLOSHIRT_JEANS_1) //Michael's variations SET_CUTSCENE_PED_COMPONENT_VARIATION("Amanda", PED_COMP_HAIR, 1, 0) //Amanda's variations SET_CUTSCENE_PED_COMPONENT_VARIATION("Amanda", PED_COMP_TORSO, 2, 0) SET_CUTSCENE_PED_COMPONENT_VARIATION("Amanda", PED_COMP_LEG, 2, 0) SET_CUTSCENE_PED_COMPONENT_VARIATION("Amanda", PED_COMP_DECL, 1, 0) ENDIF ENDIF ENDIF BREAK CASE 1 //fade screen in if screen was faded out due to shit skip or debug skip IF IS_CUTSCENE_PLAYING() DELETE_VEHICLE_GEN_VEHICLE(VEHGEN_MISSION_VEH) IF IS_REPLAY_START_VEHICLE_AVAILABLE() AND DOES_ENTITY_EXIST(GET_PLAYERS_LAST_VEHICLE()) IF ( GET_MISSION_START_VEHICLE_INDEX() = GET_PLAYERS_LAST_VEHICLE() ) IF NOT IS_ENTITY_DEAD(GET_PLAYERS_LAST_VEHICLE()) AND IS_VEHICLE_DRIVEABLE(GET_PLAYERS_LAST_VEHICLE(), TRUE) AND NOT IS_THIS_MODEL_A_HELI(GET_ENTITY_MODEL(GET_PLAYERS_LAST_VEHICLE())) AND NOT IS_THIS_MODEL_A_PLANE(GET_ENTITY_MODEL(GET_PLAYERS_LAST_VEHICLE())) SET_ENTITY_COORDS(GET_PLAYERS_LAST_VEHICLE(), << -867.9103, 158.2215, 63.9014 >>) SET_ENTITY_HEADING(GET_PLAYERS_LAST_VEHICLE(), 174.2918) SET_VEHICLE_DOORS_SHUT(GET_PLAYERS_LAST_VEHICLE()) SET_VEHICLE_ON_GROUND_PROPERLY(GET_PLAYERS_LAST_VEHICLE()) SET_VEHICLE_ENGINE_ON(GET_PLAYERS_LAST_VEHICLE(), FALSE, TRUE) SET_MISSION_START_VEHICLE_AS_VEHICLE_GEN(<< -867.9103, 158.2215, 63.9014 >>, 174.2918) CLEAR_MUST_LEAVE_AREA_VEHICLE_GEN_FLAG(VEHGEN_MISSION_VEH) ENDIF ENDIF ENDIF CLEAR_AREA(psMichael.vPosition, 5000.0, TRUE) LOCK_AUTOMATIC_DOOR_OPEN(AUTODOOR_MICHAEL_MANSION_GATE, TRUE) IF IS_SCREEN_FADED_OUT() DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME) ENDIF bTriggerSwitchFlash = FALSE bTruckRepositionedForCutscene = FALSE iStageProgress++ ENDIF BREAK CASE 2 UPDATE_THIRD_PERSON_RUN_TO_VEHICLE_CAMERA() IF IS_CUTSCENE_PLAYING() IF ( GET_CUTSCENE_TIME() > 40000.0 ) IF ( bMusicEventMissionStartTriggered = FALSE ) IF TRIGGER_MUSIC_EVENT("FAM3_MISSION_START") bMusicEventMissionStartTriggered = TRUE ENDIF ENDIF ENDIF ENDIF IF NOT DOES_ENTITY_EXIST(osBrokenPlantPot.ObjectIndex) IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL REQUEST_MODEL(osBrokenPlantPot.ModelName) IF HAS_MODEL_LOADED(osBrokenPlantPot.ModelName) IF GET_CUTSCENE_TIME() > 54000 IF HAS_MISSION_OBJECT_BEEN_CREATED(osBrokenPlantPot, TRUE) SET_MODEL_AS_NO_LONGER_NEEDED(osBrokenPlantPot.ModelName) ENDIF ENDIF ENDIF ENDIF ENDIF IF NOT DOES_ENTITY_EXIST(osRacket01.ObjectIndex) IF DOES_CUTSCENE_ENTITY_EXIST("Racket_1") IF DOES_ENTITY_EXIST(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Racket_1")) osRacket01.ObjectIndex = GET_OBJECT_INDEX_FROM_ENTITY_INDEX(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Racket_1")) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created object Racket_1 in the cutscene.") #ENDIF ENDIF ENDIF ENDIF IF NOT DOES_ENTITY_EXIST(osRacket02.ObjectIndex) IF DOES_CUTSCENE_ENTITY_EXIST("Racket_2") IF DOES_ENTITY_EXIST(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Racket_2")) osRacket02.ObjectIndex = GET_OBJECT_INDEX_FROM_ENTITY_INDEX(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Racket_2")) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created object Racket_2 in the cutscene.") #ENDIF ENDIF ENDIF ENDIF //create player peds by extracting them from mocap cutscene IF ( GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL ) IF NOT DOES_ENTITY_EXIST(psFranklin.PedIndex) IF DOES_CUTSCENE_ENTITY_EXIST("Franklin") IF DOES_ENTITY_EXIST(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Franklin")) psFranklin.PedIndex = GET_PED_INDEX_FROM_ENTITY_INDEX(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Franklin")) SET_MISSION_PED_PROPERTIES(psFranklin.PedIndex, RELGROUPHASH_PLAYER, FALSE, TRUE, FALSE, FALSE) sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN] = psFranklin.PedIndex SET_RAGDOLL_BLOCKING_FLAGS(psFranklin.PedIndex, RBF_PLAYER_IMPACT) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Set up properites for mission player ped Franklin created in the intro cutscene.") #ENDIF ENDIF ENDIF ENDIF ENDIF IF ( GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN ) IF NOT DOES_ENTITY_EXIST(psMichael.PedIndex) IF DOES_CUTSCENE_ENTITY_EXIST("Michael") IF DOES_ENTITY_EXIST(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Michael")) psMichael.PedIndex = GET_PED_INDEX_FROM_ENTITY_INDEX(GET_ENTITY_INDEX_OF_REGISTERED_ENTITY("Michael")) SET_MISSION_PED_PROPERTIES(psMichael.PedIndex, RELGROUPHASH_PLAYER, FALSE, TRUE, FALSE, FALSE) sSelectorPeds.pedID[SELECTOR_PED_MICHAEL] = psMichael.PedIndex #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Set up properites for mission player ped Michael created in the intro cutscene.") #ENDIF ENDIF ENDIF ENDIF ENDIF //create vehicles during mocap cutscene or grab them from pre-mission trigger scene IF IS_CUTSCENE_PLAYING() //truck IF NOT DOES_ENTITY_EXIST(vsPlayersCar.VehicleIndex) IF DOES_ENTITY_EXIST(g_sTriggerSceneAssets.veh[0]) IF IS_VEHICLE_DRIVEABLE(g_sTriggerSceneAssets.veh[0], TRUE) SET_ENTITY_AS_MISSION_ENTITY(g_sTriggerSceneAssets.veh[0], TRUE, TRUE) vsPlayersCar.VehicleIndex = g_sTriggerSceneAssets.veh[0] SET_MISSION_VEHICLE_PROPERTIES(vsPlayersCar, TRUE, -1, 132, 0, 0, 0 #IF IS_DEBUG_BUILD, "TS_Truck" #ENDIF) IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL //SET_VEHICLE_FIXED(vsPlayersCar.VehicleIndex) IF DOES_ENTITY_EXIST(vsPlayersCar.VehicleIndex) AND NOT IS_ENTITY_DEAD(vsPlayersCar.VehicleIndex) SET_ENTITY_HEALTH(vsPlayersCar.VehicleIndex, GET_ENTITY_HEALTH(vsPlayersCar.VehicleIndex) + 1000) SET_VEHICLE_ENGINE_HEALTH(vsPlayersCar.VehicleIndex, GET_VEHICLE_ENGINE_HEALTH(vsPlayersCar.VehicleIndex) + 1000) SET_VEHICLE_PETROL_TANK_HEALTH(vsPlayersCar.VehicleIndex, GET_VEHICLE_PETROL_TANK_HEALTH(vsPlayersCar.VehicleIndex) + 1000) STOP_FIRE_IN_RANGE(GET_ENTITY_COORDS(vsPlayersCar.VehicleIndex), 2.5) IF IS_VEHICLE_TYRE_BURST(vsPlayersCar.VehicleIndex, SC_WHEEL_CAR_FRONT_LEFT) SET_VEHICLE_TYRE_FIXED(vsPlayersCar.VehicleIndex, SC_WHEEL_CAR_FRONT_LEFT) ENDIF IF IS_VEHICLE_TYRE_BURST(vsPlayersCar.VehicleIndex, SC_WHEEL_CAR_FRONT_RIGHT) SET_VEHICLE_TYRE_FIXED(vsPlayersCar.VehicleIndex, SC_WHEEL_CAR_FRONT_RIGHT) ENDIF IF IS_VEHICLE_TYRE_BURST(vsPlayersCar.VehicleIndex, SC_WHEEL_CAR_REAR_LEFT) SET_VEHICLE_TYRE_FIXED(vsPlayersCar.VehicleIndex, SC_WHEEL_CAR_REAR_LEFT) ENDIF IF IS_VEHICLE_TYRE_BURST(vsPlayersCar.VehicleIndex, SC_WHEEL_CAR_REAR_RIGHT) SET_VEHICLE_TYRE_FIXED(vsPlayersCar.VehicleIndex, SC_WHEEL_CAR_REAR_RIGHT) ENDIF IF NOT IS_VEHICLE_EXTRA_TURNED_ON(vsPlayersCar.VehicleIndex, 5) SET_VEHICLE_EXTRA(vsPlayersCar.VehicleIndex, 5, FALSE) ENDIF SET_ENTITY_COORDS(vsPlayersCar.VehicleIndex, vsPlayersCar.vPosition) //reposition truck when playing as Michael SET_ENTITY_HEADING(vsPlayersCar.VehicleIndex, vsPlayersCar.fHeading) //reposition truck later when playing as Franklin SET_VEHICLE_ON_GROUND_PROPERLY(vsPlayersCar.VehicleIndex) bTruckRepositionedForCutscene = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Repositioned truck for cutscene. Player is CHAR_MICHAEL.") #ENDIF ENDIF ENDIF ELSE SET_ENTITY_AS_MISSION_ENTITY(g_sTriggerSceneAssets.veh[0], TRUE, TRUE) DELETE_VEHICLE(g_sTriggerSceneAssets.veh[0]) CLEAR_AREA(vsPlayersCar.vPosition, 5.0, TRUE) ENDIF ELSE IF ( GET_CUTSCENE_TIME() > 8000 ) IF HAS_MISSION_VEHICLE_BEEN_CREATED(vsPlayersCar, FALSE, FALSE, NO_CHARACTER, TRUE, -1, 132, 0, 0, 0 #IF IS_DEBUG_BUILD, "M_Truck" #ENDIF) SET_VEHICLE_EXTRA(vsPlayersCar.VehicleIndex, 5, FALSE) ENDIF ENDIF ENDIF ELSE IF ( bTruckRepositionedForCutscene = FALSE ) IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN IF ( GET_CUTSCENE_TIME() > 60500.0 ) IF DOES_ENTITY_EXIST(vsPlayersCar.VehicleIndex) AND NOT IS_ENTITY_DEAD(vsPlayersCar.VehicleIndex) SET_ENTITY_HEALTH(vsPlayersCar.VehicleIndex, GET_ENTITY_HEALTH(vsPlayersCar.VehicleIndex) + 1000) SET_VEHICLE_ENGINE_HEALTH(vsPlayersCar.VehicleIndex, GET_VEHICLE_ENGINE_HEALTH(vsPlayersCar.VehicleIndex) + 1000) SET_VEHICLE_PETROL_TANK_HEALTH(vsPlayersCar.VehicleIndex, GET_VEHICLE_PETROL_TANK_HEALTH(vsPlayersCar.VehicleIndex) + 1000) STOP_FIRE_IN_RANGE(GET_ENTITY_COORDS(vsPlayersCar.VehicleIndex), 2.5) IF IS_VEHICLE_TYRE_BURST(vsPlayersCar.VehicleIndex, SC_WHEEL_CAR_FRONT_LEFT) SET_VEHICLE_TYRE_FIXED(vsPlayersCar.VehicleIndex, SC_WHEEL_CAR_FRONT_LEFT) ENDIF IF IS_VEHICLE_TYRE_BURST(vsPlayersCar.VehicleIndex, SC_WHEEL_CAR_FRONT_RIGHT) SET_VEHICLE_TYRE_FIXED(vsPlayersCar.VehicleIndex, SC_WHEEL_CAR_FRONT_RIGHT) ENDIF IF IS_VEHICLE_TYRE_BURST(vsPlayersCar.VehicleIndex, SC_WHEEL_CAR_REAR_LEFT) SET_VEHICLE_TYRE_FIXED(vsPlayersCar.VehicleIndex, SC_WHEEL_CAR_REAR_LEFT) ENDIF IF IS_VEHICLE_TYRE_BURST(vsPlayersCar.VehicleIndex, SC_WHEEL_CAR_REAR_RIGHT) SET_VEHICLE_TYRE_FIXED(vsPlayersCar.VehicleIndex, SC_WHEEL_CAR_REAR_RIGHT) ENDIF IF NOT IS_VEHICLE_EXTRA_TURNED_ON(vsPlayersCar.VehicleIndex, 5) SET_VEHICLE_EXTRA(vsPlayersCar.VehicleIndex, 5, FALSE) ENDIF SET_ENTITY_COORDS(vsPlayersCar.VehicleIndex, vsPlayersCar.vPosition) //reposition truck later when playing as Franklin SET_ENTITY_HEADING(vsPlayersCar.VehicleIndex, vsPlayersCar.fHeading) SET_VEHICLE_ON_GROUND_PROPERLY(vsPlayersCar.VehicleIndex) bTruckRepositionedForCutscene = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Repositioned truck for cutscene. Player is CHAR_FRANKLIN.") #ENDIF ENDIF ENDIF ENDIF ENDIF IF NOT IS_ENTITY_DEAD(vsPlayersCar.VehicleIndex) REQUEST_VEHICLE_HIGH_DETAIL_MODEL(vsPlayersCar.VehicleIndex) ENDIF ENDIF //Tennis Coach's car IF NOT DOES_ENTITY_EXIST(vsCoachsCar.VehicleIndex) IF DOES_ENTITY_EXIST(g_sTriggerSceneAssets.veh[1]) IF IS_VEHICLE_DRIVEABLE(g_sTriggerSceneAssets.veh[1]) SET_ENTITY_AS_MISSION_ENTITY(g_sTriggerSceneAssets.veh[1], TRUE, TRUE) SET_VEHICLE_FIXED(g_sTriggerSceneAssets.veh[1]) vsCoachsCar.VehicleIndex = g_sTriggerSceneAssets.veh[1] SET_MISSION_VEHICLE_PROPERTIES(vsCoachsCar, TRUE, -1, 43, 43, 0, 0 #IF IS_DEBUG_BUILD, "TS_Coachs_Car" #ENDIF) SET_ENTITY_COORDS(vsCoachsCar.VehicleIndex, vsCoachsCar.vPosition) SET_ENTITY_HEADING(vsCoachsCar.VehicleIndex, vsCoachsCar.fHeading) SET_VEHICLE_ON_GROUND_PROPERLY(vsCoachsCar.VehicleIndex) ELSE SET_ENTITY_AS_MISSION_ENTITY(g_sTriggerSceneAssets.veh[1], TRUE, TRUE) DELETE_VEHICLE(g_sTriggerSceneAssets.veh[1]) CLEAR_AREA(vsCoachsCar.vPosition, 5.0, TRUE) ENDIF ELSE IF ( GET_CUTSCENE_TIME() > 8000 ) HAS_MISSION_VEHICLE_BEEN_CREATED(vsCoachsCar, FALSE, FALSE, NO_CHARACTER, TRUE, -1, 43, 43, 0, 0 #IF IS_DEBUG_BUILD, "M_Coachs_Car" #ENDIF) ENDIF ENDIF ENDIF ENDIF IF NOT DOES_ENTITY_EXIST(psCoach.PedIndex) IF DOES_ENTITY_EXIST(g_sTriggerSceneAssets.ped[0]) SET_ENTITY_AS_MISSION_ENTITY(g_sTriggerSceneAssets.ped[0], TRUE, TRUE) psCoach.PedIndex = g_sTriggerSceneAssets.ped[0] SET_MISSION_PED_PROPERTIES(psCoach.PedIndex, rgTennisCoach, FALSE, TRUE, FALSE, FALSE) IF DOES_ENTITY_EXIST(vsCoachsCar.VehicleIndex) IF NOT IS_ENTITY_DEAD(vsCoachsCar.VehicleIndex) CLEAR_PED_TASKS(psCoach.PedIndex) SET_ENTITY_VISIBLE(psCoach.PedIndex, TRUE) IF NOT IS_PED_IN_VEHICLE(psCoach.PedIndex, vsCoachsCar.VehicleIndex) SET_PED_INTO_VEHICLE(psCoach.PedIndex, vsCoachsCar.VehicleIndex, VS_DRIVER) ENDIF ENDIF ENDIF #IF IS_DEBUG_BUILD SET_PED_NAME_DEBUG(psCoach.PedIndex, "TS_TennisCoach") PRINTLN(GET_THIS_SCRIPT_NAME(), ": Grabbing Tennis Coach ped from trigger scene script.") #ENDIF ELSE IF DOES_ENTITY_EXIST(vsCoachsCar.VehicleIndex) IF HAS_MISSION_PED_BEEN_CREATED(psCoach, FALSE, rgTennisCoach, FALSE, NO_CHARACTER, FALSE, FALSE, FALSE, vsCoachsCar.VehicleIndex) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(psCoach.PedIndex, TRUE) ENDIF ENDIF ENDIF ENDIF IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Michael") #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY() returned true for Michael.") #ENDIF //hot swap to Michael if not currently controlling Michael IF ( GET_CURRENT_PLAYER_PED_ENUM() <> CHAR_MICHAEL ) IF MAKE_SELECTOR_PED_SELECTION(sSelectorPeds, SELECTOR_PED_MICHAEL) TAKE_CONTROL_OF_SELECTOR_PED(sSelectorPeds, TRUE, TRUE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Taking control of player ped Michael when CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY() returned true for Michael.") #ENDIF IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_ON_FOOT) = CAM_VIEW_MODE_FIRST_PERSON OR GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_IN_VEHICLE) = CAM_VIEW_MODE_FIRST_PERSON bTriggerSwitchFlash = TRUE //trigger switch flash later, after the cutscene ELSE ANIMPOSTFX_PLAY("SwitchSceneMichael", 0, FALSE) PLAY_SOUND_FRONTEND(-1, "Hit_1", "LONG_PLAYER_SWITCH_SOUNDS") ENDIF IF DOES_ENTITY_EXIST(GET_PED_INDEX(CHAR_FRANKLIN)) psFranklin.PedIndex = GET_PED_INDEX(CHAR_FRANKLIN) SET_MISSION_PED_PROPERTIES(psFranklin.PedIndex, RELGROUPHASH_PLAYER, FALSE, TRUE, FALSE, FALSE) sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN] = psFranklin.PedIndex #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Set up properites for mission player ped Franklin for hot swap during intro cutscene when CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY() returned true for Michael.") #ENDIF ENDIF ENDIF ENDIF IF ( bCutsceneSkipped = FALSE ) IF NOT IS_PED_INJURED(PLAYER_PED_ID()) SET_PED_STEALTH_MOVEMENT(PLAYER_PED_ID(), FALSE) WARP_PED(PLAYER_PED_ID(), <<-824.3681, 176.9837, 70.1645>>, 135.3757, FALSE, FALSE, FALSE) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) TASK_ENTER_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, PEDMOVE_RUN, ECF_USE_LEFT_ENTRY | ECF_RESUME_IF_INTERRUPTED) FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_RUN, FALSE, FAUS_CUTSCENE_EXIT) ENDIF ENDIF ENDIF ENDIF IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Franklin") #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY() returned true for Franklin.") #ENDIF REPLAY_STOP_EVENT() IF ( bCutsceneSkipped = FALSE ) IF NOT IS_PED_INJURED(psFranklin.PedIndex) SET_RAGDOLL_BLOCKING_FLAGS(psFranklin.PedIndex, RBF_PLAYER_IMPACT) SET_PED_STEALTH_MOVEMENT(psFranklin.PedIndex, FALSE) WARP_PED(psFranklin.PedIndex, << -828.5035, 177.0551, 69.9812 >>, 159.2800, FALSE, FALSE, FALSE) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) TASK_ENTER_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex, DEFAULT_TIME_BEFORE_WARP, VS_FRONT_RIGHT, PEDMOVE_RUN, ECF_USE_RIGHT_ENTRY | ECF_RESUME_IF_INTERRUPTED) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Giving Franklin ped task to enter vehicle when CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY() returned true for Franklin.") #ENDIF ENDIF ENDIF ENDIF ENDIF IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Racket_1") #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY() returned true for Racket_1.") #ENDIF IF DOES_ENTITY_EXIST(osRacket01.ObjectIndex) IF NOT IS_ENTITY_DEAD(osRacket01.ObjectIndex) SET_ENTITY_COORDS_NO_OFFSET(osRacket01.ObjectIndex, osRacket01.vPosition) SET_ENTITY_ROTATION(osRacket01.ObjectIndex, osRacket01.vRotation) FREEZE_ENTITY_POSITION(osRacket01.ObjectIndex, TRUE) ENDIF ENDIF ENDIF IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Racket_2") #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY() returned true for Racket_2.") #ENDIF IF DOES_ENTITY_EXIST(osRacket02.ObjectIndex) IF NOT IS_ENTITY_DEAD(osRacket02.ObjectIndex) SET_ENTITY_COORDS_NO_OFFSET(osRacket02.ObjectIndex, osRacket02.vPosition) SET_ENTITY_ROTATION(osRacket02.ObjectIndex, osRacket02.vRotation) FREEZE_ENTITY_POSITION(osRacket02.ObjectIndex, TRUE) ENDIF ENDIF ENDIF IF HAS_CUTSCENE_FINISHED() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Intro cutscene has finished.") #ENDIF IF HAS_MISSION_VEHICLE_BEEN_CREATED(vsPlayersCar, FALSE, FALSE, NO_CHARACTER, TRUE, -1, 132, 0, 0, 0 #IF IS_DEBUG_BUILD, "M_Truck" #ENDIF) AND HAS_MISSION_VEHICLE_BEEN_CREATED(vsCoachsCar, FALSE, FALSE, NO_CHARACTER, TRUE, -1, 43, 43, 0, 0 #IF IS_DEBUG_BUILD, "M_Coachs_Car" #ENDIF) AND HAS_VEHICLE_ASSET_LOADED(vsPlayersCar.ModelName) AND DOES_ENTITY_EXIST(psCoach.PedIndex) AND HAS_VEHICLE_RECORDING_BEEN_LOADED(vsCoachsCar.iRecordingNumber, sVehicleRecordingsFile) AND DOES_ENTITY_EXIST(GET_PED_INDEX(CHAR_FRANKLIN)) AND ( GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL ) IF ( bCutsceneSkipped = TRUE ) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Repositioning peds and giving new tasks due to into cutscene skip.") #ENDIF IF NOT IS_PED_INJURED(PLAYER_PED_ID()) SET_PED_STEALTH_MOVEMENT(PLAYER_PED_ID(), FALSE) WARP_PED(PLAYER_PED_ID(), <<-824.3681, 176.9837, 70.1645>>, 135.3757, FALSE, FALSE, FALSE) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) TASK_ENTER_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, PEDMOVE_RUN, ECF_USE_LEFT_ENTRY | ECF_RESUME_IF_INTERRUPTED) FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_RUN) ENDIF ENDIF IF NOT IS_PED_INJURED(psFranklin.PedIndex) SET_PED_STEALTH_MOVEMENT(psFranklin.PedIndex, FALSE) WARP_PED(psFranklin.PedIndex, << -828.5035, 177.0551, 69.9812 >>, 159.2800, FALSE, FALSE, FALSE) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) TASK_ENTER_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex, DEFAULT_TIME_BEFORE_WARP, VS_FRONT_RIGHT, PEDMOVE_RUN, ECF_USE_RIGHT_ENTRY | ECF_RESUME_IF_INTERRUPTED) ENDIF ENDIF SET_GAMEPLAY_CAM_RELATIVE_PITCH(0) SET_GAMEPLAY_CAM_RELATIVE_HEADING(0) WAIT(150) UPDATE_THIRD_PERSON_RUN_TO_VEHICLE_CAMERA() ENDIF //close front doors at 0.0 open ratio IF IS_DOOR_REGISTERED_WITH_SYSTEM(ENUM_TO_INT(DOORHASH_M_MANSION_F_L)) DOOR_SYSTEM_SET_OPEN_RATIO(ENUM_TO_INT(DOORHASH_M_MANSION_F_L), 0.0, FALSE, FALSE) DOOR_SYSTEM_SET_DOOR_STATE(ENUM_TO_INT(DOORHASH_M_MANSION_F_L), DOORSTATE_FORCE_UNLOCKED_THIS_FRAME, FALSE, TRUE) ENDIF IF IS_DOOR_REGISTERED_WITH_SYSTEM(ENUM_TO_INT(DOORHASH_M_MANSION_F_R)) DOOR_SYSTEM_SET_OPEN_RATIO(ENUM_TO_INT(DOORHASH_M_MANSION_F_R), 0.0, FALSE, FALSE) DOOR_SYSTEM_SET_DOOR_STATE(ENUM_TO_INT(DOORHASH_M_MANSION_F_R), DOORSTATE_FORCE_UNLOCKED_THIS_FRAME, FALSE, TRUE) ENDIF OBJECT_INDEX FlowerObjectIndex FlowerObjectIndex = GET_CLOSEST_OBJECT_OF_TYPE(<< -818.88, 177.91, 76.63 >>, 0.75, PROP_WINDOWBOX_B, FALSE) IF DOES_ENTITY_EXIST(FlowerObjectIndex) IF NOT IS_ENTITY_DEAD(FlowerObjectIndex) SET_ENTITY_VISIBLE(FlowerObjectIndex, FALSE) SET_ENTITY_COLLISION(FlowerObjectIndex, FALSE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Hiding world prop object PROP_WINDOWBOX_B.") #ENDIF ENDIF ENDIF //start uber recording playback when the cutscene ends IF IS_VEHICLE_DRIVEABLE(vsCoachsCar.VehicleIndex) SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(vsCoachsCar.VehicleIndex, TRUE) ENDIF IF NOT IS_PED_INJURED(psCoach.PedIndex) SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(psCoach.PedIndex, TRUE) SET_PED_CONFIG_FLAG(psCoach.PedIndex, PCF_WillFlyThroughWindscreen, FALSE) SET_PED_CONFIG_FLAG(psCoach.PedIndex, PCF_GetOutBurningVehicle, FALSE) SET_PED_CONFIG_FLAG(psCoach.PedIndex, PCF_GetOutUndriveableVehicle, FALSE) ENDIF INITIALISE_UBER_PLAYBACK(sVehicleRecordingsFile, vsCoachsCar.iRecordingNumber) INITIALISE_UBER_ARRAY() CREATE_ALL_WAITING_UBER_CARS() #IF IS_DEBUG_BUILD bTrafficDebugOn = TRUE #ENDIF fUberPlaybackDensitySwitchOffRange = 200.0 bPlayTrafficRecordingEvenIfPlayerIsAheadOfChase = TRUE IF IS_VEHICLE_DRIVEABLE(vsCoachsCar.VehicleIndex) START_VEHICLE_RECORDING_PLAYBACK_FOR_VEHICLE(vsCoachsCar, sVehicleRecordingsFile, fChaseSpeed, FALSE, 1500.0) FORCE_PLAYBACK_RECORDED_VEHICLE_UPDATE(vsCoachsCar.VehicleIndex) ENDIF IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) SET_VEHICLE_CAN_SAVE_IN_GARAGE(vsPlayersCar.VehicleIndex, FALSE) IF NOT IS_VEHICLE_EXTRA_TURNED_ON(vsPlayersCar.VehicleIndex, 5) SET_VEHICLE_EXTRA(vsPlayersCar.VehicleIndex, 5, FALSE) ENDIF ENDIF SET_VEHICLE_AS_RESTRICTED(vsPlayersCar.VehicleIndex, 0) UPDATE_UBER_PLAYBACK(vsCoachsCar.VehicleIndex, 1.0) IF IS_INTERIOR_READY(GET_INTERIOR_AT_COORDS(vInteriorPosition)) UNPIN_INTERIOR(GET_INTERIOR_AT_COORDS(vInteriorPosition)) ENDIF SET_SCRIPTS_SAFE_FOR_CUTSCENE(FALSE) IF ( bMusicEventMissionStartTriggered = FALSE ) IF TRIGGER_MUSIC_EVENT("FAM3_MISSION_START") bMusicEventMissionStartTriggered = TRUE ENDIF ENDIF STORE_PLAYER_PED_VARIATIONS(PLAYER_PED_ID(), TRUE) STORE_PLAYER_PED_VARIATIONS(psFranklin.PedIndex, TRUE) MISSION_FLOW_RELEASE_TRIGGER_SCENE_ASSETS(SP_MISSION_FAMILY_3) IF IS_SCREEN_FADED_OUT() DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME) ENDIF RETURN TRUE ELSE //if not all entities exits, make sure player peds are created in script if the cutscene did not create them SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL IF NOT DOES_ENTITY_EXIST(GET_PED_INDEX(CHAR_FRANKLIN)) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Creating Franklin ped when cutscene has finished.") #ENDIF IF HAS_MISSION_PED_BEEN_CREATED(psFranklin, TRUE, RELGROUPHASH_PLAYER, FALSE, CHAR_FRANKLIN) SET_MISSION_PED_PROPERTIES(psFranklin.PedIndex, RELGROUPHASH_PLAYER, FALSE, TRUE, FALSE, FALSE) sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN] = psFranklin.PedIndex #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Set up properites for mission player ped Franklin created when intro cutscene has finished.") #ENDIF ENDIF ENDIF BREAK CASE CHAR_FRANKLIN IF NOT DOES_ENTITY_EXIST(GET_PED_INDEX(CHAR_MICHAEL)) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Creating Michael ped when cutscene has finished.") #ENDIF IF HAS_MISSION_PED_BEEN_CREATED(psMichael, TRUE, RELGROUPHASH_PLAYER, FALSE, CHAR_MICHAEL) SET_MISSION_PED_PROPERTIES(psMichael.PedIndex, RELGROUPHASH_PLAYER, FALSE, TRUE, FALSE, FALSE) sSelectorPeds.pedID[SELECTOR_PED_MICHAEL] = psMichael.PedIndex #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Set up properites for mission player ped Michael created when intro cutscene has finished.") #ENDIF ENDIF ENDIF BREAK ENDSWITCH //tennis coach IF NOT DOES_ENTITY_EXIST(psCoach.PedIndex) IF DOES_ENTITY_EXIST(vsCoachsCar.VehicleIndex) IF HAS_MISSION_PED_BEEN_CREATED(psCoach, FALSE, rgTennisCoach, FALSE, NO_CHARACTER, FALSE, FALSE, FALSE, vsCoachsCar.VehicleIndex) SET_PED_COMPONENT_VARIATION(psCoach.PedIndex, PED_COMP_TORSO, 1, 0) SET_PED_COMPONENT_VARIATION(psCoach.PedIndex, PED_COMP_LEG, 1, 0) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(psCoach.PedIndex, TRUE) ENDIF ENDIF ENDIF ENDIF ELSE //if cutscene is skipped, fade out and remain cutscene on faded out screen IF ( bCutsceneSkipped = FALSE ) IF WAS_CUTSCENE_SKIPPED() SET_CUTSCENE_FADE_VALUES(FALSE, FALSE, FALSE, FALSE) bCutsceneSkipped = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Intro mocap cutscene was skipped by the player.") #ENDIF ENDIF ENDIF ENDIF //request assets for player vehicle REQUEST_VEHICLE_ASSET(vsPlayersCar.ModelName, ENUM_TO_INT(VRF_REQUEST_ENTRY_ANIMS)) //request assets for uber recording REQUEST_VEHICLE_RECORDING(vsCoachsCar.iRecordingNumber, sVehicleRecordingsFile) BREAK ENDSWITCH RETURN FALSE ENDFUNC PROC RUN_RUBBER_BAND_BETWEEN_VEHICLES(VEHICLE_INDEX VehicleIndex, VEHICLE_INDEX VehicleIndexTarget, FLOAT &fPlaybackSpeed, FLOAT fOptimalDistance, FLOAT fMinSpeed = 0.5, FLOAT fMaxSpeed = 1.5) FLOAT fSpeed IF IS_VEHICLE_DRIVEABLE(VehicleIndex) AND IS_VEHICLE_DRIVEABLE(VehicleIndexTarget) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(VehicleIndexTarget) fSpeed = fOptimalDistance / GET_DISTANCE_BETWEEN_ENTITIES(VehicleIndex, VehicleIndexTarget) IF ( fSpeed >= fMaxSpeed ) fSpeed = fMaxSpeed ENDIF IF ( fSpeed < fMinSpeed ) fSpeed = fMinSpeed ENDIF SET_PLAYBACK_SPEED(VehicleIndexTarget, fSpeed) fPlaybackSpeed = fSpeed ENDIF ENDIF ENDPROC PROC CONVERGE_VALUE(FLOAT &val, FLOAT fDesiredVal, FLOAT fAmountToConverge, BOOL bAdjustForFramerate = FALSE) IF val != fDesiredVal FLOAT fConvergeAmountThisFrame = fAmountToConverge IF bAdjustForFramerate fConvergeAmountThisFrame = 0.0 +@ (fAmountToConverge * 30.0) ENDIF IF val - fDesiredVal > fConvergeAmountThisFrame val -= fConvergeAmountThisFrame ELIF val - fDesiredVal < -fConvergeAmountThisFrame val += fConvergeAmountThisFrame ELSE val = fDesiredVal ENDIF ENDIF ENDPROC PROC RUBBER_BAND_PLAYBACK_SPEED_FOR_TRIGGER_VEHICLE(VEHICLE_INDEX TriggerVehicleIndex, VEHICLE_INDEX VehicleIndex, FLOAT &fCurrentPlaybackSpeed, FLOAT &fCurrentPlaybackTime #IF IS_DEBUG_BUILD, BOOL bPrintOutput = FALSE, STRING sTriggerVehicleDebugName = NULL, STRING sVehicleDebugName = NULL #ENDIF) IF IS_VEHICLE_DRIVEABLE(TriggerVehicleIndex) AND IS_VEHICLE_DRIVEABLE(VehicleIndex) VECTOR vTriggerVehiclePosition = GET_ENTITY_COORDS(TriggerVehicleIndex) VECTOR vVehiclePosition = GET_ENTITY_COORDS(VehicleIndex) FLOAT fDistance = GET_DISTANCE_BETWEEN_COORDS(vTriggerVehiclePosition, vVehiclePosition) FLOAT fCloseDistance = 15.0 FLOAT fIdealDistance = 30.0 FLOAT fMaxDistance = 45.0 FLOAT fSuperMaxDistance = 75.0 FLOAT fDesiredPlaybackSpeed = 1.0 FLOAT fPlaybackTime IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(TriggerVehicleIndex) fPlaybackTime = GET_TIME_POSITION_IN_RECORDING(TriggerVehicleIndex) fCurrentPlaybackTime = fPlaybackTime ENDIF VECTOR vOffset = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(TriggerVehicleIndex, vVehiclePosition) IF ( vOffset.y > 1.0 ) //trigger vehicle is behind the vehicle, need to increase recording playback speed #IF IS_DEBUG_BUILD IF ( bPrintOutput = TRUE ) PRINTLN(GET_THIS_SCRIPT_NAME(), ": ", sTriggerVehicleDebugName, " vehicle is behind ", sVehicleDebugName, " vehicle.") ENDIF #ENDIF IF ( fDistance > fSuperMaxDistance ) fDesiredPlaybackSpeed = 5.0 ELIF ( fDistance > fMaxDistance ) fDesiredPlaybackSpeed = 4.0 ELIF ( fDistance > fIdealDistance ) fDesiredPlaybackSpeed = 3.0 ELSE fDesiredPlaybackSpeed = 2.5 ENDIF ELSE //trigger vehicle is front of the vehicle, lower recording playback speed when needed #IF IS_DEBUG_BUILD IF ( bPrintOutput = TRUE ) PRINTLN(GET_THIS_SCRIPT_NAME(), ": ", sTriggerVehicleDebugName, " vehicle is in front of ", sVehicleDebugName, " vehicle.") ENDIF #ENDIF IF ( fDistance > fSuperMaxDistance ) fDesiredPlaybackSpeed = 0.6 ELIF ( fDistance > fMaxDistance ) fDesiredPlaybackSpeed = 1.05 ELIF ( fDistance > fIdealDistance ) fDesiredPlaybackSpeed = 1.225 ELIF ( fDistance > fCloseDistance ) fDesiredPlaybackSpeed = 1.385 ELSE fDesiredPlaybackSpeed = 1.45 ENDIF ENDIF IF ( fPlaybackTime < 26000.0 ) //when the player is going through the park, increase the playback speed IF IS_ENTITY_AT_COORD(VehicleIndex, << -948.42, 399.24, 76.69 >>, << 118.0, 112.0, 16.0 >>) OR IS_ENTITY_IN_ANGLED_AREA(VehicleIndex, << -1002.70, 306.26, 65.30 >>, << -886.05, 263.07, 89.96 >>, 32.0) //check speed difference between trigger vehicle and player vehicle FLOAT fSpeedDifference = GET_ENTITY_SPEED(TriggerVehicleIndex) - GET_ENTITY_SPEED(VehicleIndex) FLOAT fExtraBoost //if the trigger vehicle is slower then add extra boost IF fSpeedDifference < 0.0 fExtraBoost = 0.125 ENDIF fDesiredPlaybackSpeed = 1.275 + fExtraBoost ELSE IF ( fPlaybackTime > 19000.0 ) fDesiredPlaybackSpeed = fDesiredPlaybackSpeed + 0.3 ENDIF ENDIF ENDIF IF ( fPlaybackTime > 27000.0 ) //when the coach is on the road up the hill after making the turn left fDesiredPlaybackSpeed = fDesiredPlaybackSpeed + 0.35 ENDIF CONVERGE_VALUE(fCurrentPlaybackSpeed, fDesiredPlaybackSpeed, 0.01, TRUE) #IF IS_DEBUG_BUILD IF ( bDrawDebugLinesAndSpheres = TRUE ) DRAW_DEBUG_TEXT_ABOVE_ENTITY(TriggerVehicleIndex, GET_STRING_FROM_FLOAT(fPlaybackTime), 1.5) DRAW_DEBUG_TEXT_ABOVE_ENTITY(TriggerVehicleIndex, GET_STRING_FROM_FLOAT(fDistance), 2.5) DRAW_DEBUG_TEXT_ABOVE_ENTITY(TriggerVehicleIndex, GET_STRING_FROM_FLOAT(fCurrentPlaybackSpeed), 3.5) ENDIF #ENDIF ENDIF ENDPROC PROC MANAGE_SET_PIECE_VAN(INT &iProgress) FLOAT fPlaybackTime FLOAT fVanPlaybackSpeed //check for player horn and van driver horn IF ( bVanDriverCrashSpeechTriggered = FALSE ) IF DOES_ENTITY_EXIST(vsVan.VehicleIndex) AND DOES_ENTITY_EXIST(psVanDriver.PedIndex) IF IS_VEHICLE_DRIVEABLE(vsVan.VehicleIndex) AND IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vsVan.VehicleIndex) OR IS_PLAYBACK_USING_AI_GOING_ON_FOR_VEHICLE(vsVan.VehicleIndex) IF IS_ENTITY_AT_ENTITY(vsPlayersCar.VehicleIndex, vsVan.VehicleIndex, vVanLocateSize) IF IS_PLAYER_PLAYING(PLAYER_ID()) IF IS_PLAYER_PRESSING_HORN(PLAYER_ID()) //play ped ambient speech on player using the horn IF NOT IS_PED_INJURED(psVanDriver.PedIndex) IF NOT IS_AMBIENT_SPEECH_PLAYING(psVanDriver.PedIndex) PLAY_PED_AMBIENT_SPEECH(psVanDriver.PedIndex, "GENERIC_INSULT_HIGH", SPEECH_PARAMS_FORCE) ENDIF //also start a horn START_VEHICLE_HORN(vsVan.VehicleIndex, 3000) bVanDriverCrashSpeechTriggered = TRUE ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF #IF IS_DEBUG_BUILD IF ( bDrawDebugLinesAndSpheres = TRUE ) DRAW_DEBUG_TEXT_ABOVE_ENTITY(vsVan.VehicleIndex, GET_STRING_FROM_INT(vsVan.iProgress), 1.75) DRAW_DEBUG_TEXT_ABOVE_ENTITY(vsVan.VehicleIndex, GET_STRING_FROM_INT(psVanDriver.iProgress), 1.5) ENDIF #ENDIF SWITCH iProgress CASE 0 //request the models and vehicle recording, create vehicle and driver IF ( bChaseInProgress = TRUE ) REQUEST_MODEL(vsVan.ModelName) REQUEST_MODEL(psVanDriver.ModelName) REQUEST_VEHICLE_RECORDING(vsVan.iRecordingNumber, sVehicleRecordingsFile) IF HAS_MODEL_LOADED(vsVan.ModelName) AND HAS_MODEL_LOADED(psVanDriver.ModelName) AND HAS_VEHICLE_RECORDING_BEEN_LOADED(vsVan.iRecordingNumber, sVehicleRecordingsFile) IF HAS_MISSION_VEHICLE_BEEN_CREATED(vsVan, FALSE, FALSE, NO_CHARACTER, FALSE, -1, 62, 131) IF HAS_MISSION_PED_BEEN_CREATED(psVanDriver, FALSE, rgEnemies, FALSE, NO_CHARACTER, TRUE, TRUE, FALSE, vsVan.VehicleIndex, VS_DRIVER, FALSE) IF NOT IS_PED_INJURED(psVanDriver.PedIndex) SET_PED_COMBAT_ATTRIBUTES(psVanDriver.PedIndex, CA_CAN_TAUNT_IN_VEHICLE, TRUE) //ADD_PED_FOR_DIALOGUE(sFamily3Conversation, 5, psVanDriver.PedIndex, "FAM3DRIVER") ENDIF SET_MODEL_AS_NO_LONGER_NEEDED(vsVan.ModelName) SET_MODEL_AS_NO_LONGER_NEEDED(psVanDriver.ModelName) iProgress++ ENDIF ENDIF ENDIF ENDIF BREAK CASE 1 //wait until it is time to start playback of vehicle recording, then start the playback IF ( bChaseInProgress = TRUE ) IF IS_ENTITY_AT_COORD(vsPlayersCar.VehicleIndex, << -1355.5088, 469.1981, 102.2932 >>, << 200, 200, 200 >>) IF IS_VEHICLE_DRIVEABLE(vsCoachsCar.VehicleIndex) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vsCoachsCar.VehicleIndex) IF GET_TIME_POSITION_IN_RECORDING(vsCoachsCar.VehicleIndex) >= 45750.0 IF NOT IS_PED_INJURED(psVanDriver.PedIndex) AND IS_VEHICLE_DRIVEABLE(vsVan.VehicleIndex) START_VEHICLE_RECORDING_PLAYBACK_FOR_VEHICLE(vsVan, sVehicleRecordingsFile, 1.1, FALSE, 800.0, FALSE, TRUE) START_AUDIO_SCENE("FAMILY_3_RV_BLOCKS_ROAD") ADD_ENTITY_TO_AUDIO_MIX_GROUP(vsVan.VehicleIndex, "FAMILY_3_RV") psVanDriver.iProgress = 0 iProgress++ ENDIF ENDIF ENDIF ENDIF ENDIF ELSE IF DOES_ENTITY_EXIST(psVanDriver.PedIndex) SET_PED_AS_NO_LONGER_NEEDED(psVanDriver.PedIndex) ENDIF IF DOES_ENTITY_EXIST(vsVan.VehicleIndex) SET_VEHICLE_AS_NO_LONGER_NEEDED(vsVan.VehicleIndex) ENDIF iProgress++ ENDIF BREAK CASE 2 //keep updating the van recording playback based on the distance from the player car IF IS_VEHICLE_DRIVEABLE(vsVan.VehicleIndex) AND NOT IS_PED_INJURED(psVanDriver.PedIndex) SWITCH psVanDriver.iProgress CASE 0 //recording playback IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vsVan.VehicleIndex) fPlaybackTime = GET_TIME_POSITION_IN_RECORDING(vsVan.VehicleIndex) #IF IS_DEBUG_BUILD IF ( bDrawDebugLinesAndSpheres = TRUE ) DRAW_DEBUG_TEXT_ABOVE_ENTITY(vsVan.VehicleIndex, GET_STRING_FROM_FLOAT(fPlaybackTime), 1.25) ENDIF #ENDIF //check collision with player's truck IF IS_ENTITY_TOUCHING_ENTITY(vsVan.VehicleIndex, vsPlayersCar.VehicleIndex) REPLAY_RECORD_BACK_FOR_TIME(3, 0, REPLAY_IMPORTANCE_HIGH) STOP_PLAYBACK_RECORDED_VEHICLE(vsVan.VehicleIndex) START_PLAYBACK_RECORDED_VEHICLE_USING_AI(vsVan.VehicleIndex, vsVan.iRecordingNumber, sVehicleRecordingsFile, 5, DRIVINGMODE_STOPFORCARS) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Set piece van is now playing vehicle recording using AI due to collision with player vehicle.") #ENDIF psVanDriver.iProgress = 1 ENDIF //check when to stop rubber banding IF ( fPlaybackTime < 8510.0) RUN_RUBBER_BAND_BETWEEN_VEHICLES(vsPlayersCar.VehicleIndex, vsVan.VehicleIndex, fVanPlaybackSpeed, 50.0, 1.05, 1.55) ENDIF //check when to switch to recording playback using AI IF ( fPlaybackTime > 10085.0 ) STOP_PLAYBACK_RECORDED_VEHICLE(vsVan.VehicleIndex) START_PLAYBACK_RECORDED_VEHICLE_USING_AI(vsVan.VehicleIndex, vsVan.iRecordingNumber, sVehicleRecordingsFile, 5, DRIVINGMODE_AVOIDCARS) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Set piece van is now playing vehicle recording using AI due to reaching recording playback target time.") #ENDIF psVanDriver.iProgress = 1 ENDIF ENDIF BREAK CASE 1 //recording playback using AI, no player vehicle collision IF NOT IS_PLAYBACK_USING_AI_GOING_ON_FOR_VEHICLE(vsVan.VehicleIndex) TASK_VEHICLE_DRIVE_WANDER(psVanDriver.PedIndex, vsVan.VehicleIndex, 15.0, DRIVINGMODE_AVOIDCARS) psVanDriver.iProgress = 2 ENDIF BREAK CASE 2 IF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), vsVan.VehicleIndex, vVanLocateSize) STOP_AUDIO_SCENE("FAMILY_3_RV_BLOCKS_ROAD") IF IS_VEHICLE_DRIVEABLE(vsVan.VehicleIndex) SET_VEHICLE_AS_NO_LONGER_NEEDED(vsVan.VehicleIndex) ENDIF IF NOT IS_PED_INJURED(psVanDriver.PedIndex) SET_PED_AS_NO_LONGER_NEEDED(psVanDriver.PedIndex) ENDIF REMOVE_VEHICLE_RECORDING(vsVan.iRecordingNumber, sVehicleRecordingsFile) ENDIF BREAK ENDSWITCH ENDIF BREAK ENDSWITCH ENDPROC FUNC BOOL IS_CHASE_REMINDER_NEEDED(FLOAT fChaseDistance, FLOAT fWarningDistance) IF ( fChaseDistance > fWarningDistance) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": IS_CHASE_REMINDER_NEEDED() returning TRUE.") #ENDIF RETURN TRUE ENDIF RETURN FALSE ENDFUNC PROC MANAGE_CONVERSATIONS_DURING_CHASE(STRING sMainConversationRootLabel) IF NOT IS_PED_INJURED(PLAYER_PED_ID()) AND NOT IS_PED_INJURED(psFranklin.PedIndex) AND IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF ( bChaseInProgress = TRUE ) IF ( bRandomConversationAllowed = FALSE ) //handle "FAM3_WARN" conversation when tennis coach is about to get away IF IS_CHASE_REMINDER_NEEDED(fChaseDistanceFromPlayerToCoach, 175.0) IF ( bConversationPaused = FALSE ) IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() lConversationLabel = GET_STANDARD_CONVERSATION_LABEL_FOR_FUTURE_RESUMPTION() KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_WARN", CONV_PRIORITY_VERY_HIGH) bConversationPaused = TRUE ENDIF ENDIF ENDIF ELSE IF NOT HAS_LABEL_BEEN_TRIGGERED(sMainConversationRootLabel) IF IS_PED_SITTING_IN_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex) AND IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", sMainConversationRootLabel, CONV_PRIORITY_MEDIUM) bAllowConvsersationOutsideOfCar = FALSE SET_LABEL_AS_TRIGGERED(sMainConversationRootLabel, TRUE) ENDIF ENDIF ENDIF ENDIF ELSE IF ( bConversationPaused = TRUE ) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF CREATE_CONVERSATION_FROM_SPECIFIC_LINE(sFamily3Conversation, "FAM3AUD", sMainConversationRootLabel, lConversationLabel, CONV_PRIORITY_MEDIUM) bConversationPaused = FALSE ENDIF ENDIF ELIF ( bConversationPaused = FALSE ) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() psFranklin.iConversationTimer = GET_GAME_TIMER() //reset Franklin's timer for random dialogue bRandomConversationAllowed = TRUE ENDIF ENDIF ENDIF ENDIF ELSE //allow random conversations //Franklin sees tennis coach seen turing left or right (is player is trying to cut through the park) IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_LEFT") AND NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_RIGHT") IF ( fChaseTime > 30725.0 AND fChaseTime < 33500.0) IF IS_PED_SITTING_IN_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex) AND IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF ( bCoachVisible = TRUE ) IF ( fChaseDistanceFromPlayerToCoach < 75.0 ) IF IS_ENTITY_IN_ANGLED_AREA(vsPlayersCar.VehicleIndex, <<-1076.606445,431.189056,63.721909>>, <<-1077.557373,345.405121,78.379799>>, 24.0) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_LEFT", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_LEFT", TRUE) psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF ELIF IS_ENTITY_IN_ANGLED_AREA(vsPlayersCar.VehicleIndex, <<-1019.407349,397.151489,62.308754>>, <<-1064.459839,394.310486,79.967346>>, 24.0) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_RIGHT", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_RIGHT", TRUE) psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF IF bStopRandomChaseConversations = FALSE IF IS_PED_SITTING_IN_THIS_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-1288.665894,459.231873,94.684250>>, <<-1392.720093,466.896729,113.118851>>, 32.0) IF DOES_ENTITY_EXIST(vsVan.VehicleIndex) AND NOT IS_ENTITY_DEAD(vsVan.VehicleIndex) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vsVan.VehicleIndex) AND NOT IS_PLAYBACK_USING_AI_GOING_ON_FOR_VEHICLE(vsVan.VehicleIndex) IF GET_TIME_POSITION_IN_RECORDING(vsVan.VehicleIndex) < 8350.0 KILL_FACE_TO_FACE_CONVERSATION() bStopRandomChaseConversations = TRUE ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF IF bStopRandomChaseConversations = FALSE IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF HAS_TIME_PASSED(10000, psFranklin.iConversationTimer) IF IS_PED_SITTING_IN_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex) AND IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) //player far, coach is getting away IF fChaseDistanceFromPlayerToCoach > 185.0 IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_WARN", CONV_PRIORITY_MEDIUM) psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF ELIF fChaseDistanceFromPlayerToCoach > 150.0 IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_LOSE", CONV_PRIORITY_MEDIUM) psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF //player close to coach ELIF fChaseDistanceFromPlayerToCoach < 75.0 IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_SEE", CONV_PRIORITY_MEDIUM) psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF ELSE IF ( bCoachVisible = TRUE ) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_AHEAD", CONV_PRIORITY_MEDIUM) psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF ELIF ( bCoachVisible = FALSE ) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_LOSE", CONV_PRIORITY_MEDIUM) psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF IF bStopRandomChaseConversations = TRUE IF bStartPreloadingVanConversation = FALSE IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() PRELOAD_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_VAN", CONV_PRIORITY_MEDIUM) bStartPreloadingVanConversation = TRUE ENDIF ENDIF ENDIF ENDIF ELSE IF ( bChaseFinished = TRUE ) //play van blocking the road conversations IF eChaseFinishReason = CHASE_FINISHED_END_REACHED IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_VAN") AND NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_LOST") IF DOES_ENTITY_EXIST(vsVan.VehicleIndex) IF NOT IS_ENTITY_DEAD(vsVan.VehicleIndex) IF IS_ENTITY_AT_ENTITY(vsPlayersCar.VehicleIndex, vsVan.VehicleIndex, vVanLocateSize) //check if the blocking van is actually still blocking the road in the recording //and not driving forward using recording playback with AI IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vsVan.VehicleIndex) AND NOT IS_PLAYBACK_USING_AI_GOING_ON_FOR_VEHICLE(vsVan.VehicleIndex) //IF ( GET_VEHICLE_RECORDING_PLAYBACK_PERCENTAGE(vsVan.VehicleIndex #IF IS_DEBUG_BUILD, bPrintDebugOutput #ENDIF) < 59.25 ) IF GET_TIME_POSITION_IN_RECORDING(vsVan.VehicleIndex) < 8350.0 IF IS_PED_SITTING_IN_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex) AND IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) IF bStartPreloadingVanConversation = FALSE IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_VAN", CONV_PRIORITY_MEDIUM) bRandomConversationAllowed = FALSE SET_LABEL_AS_TRIGGERED("FAM3_VAN", TRUE) ENDIF ENDIF ELSE KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF ELSE BEGIN_PRELOADED_CONVERSATION() bRandomConversationAllowed = FALSE SET_LABEL_AS_TRIGGERED("FAM3_VAN", TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF //play van collision conversation IF eChaseFinishReason = CHASE_FINISHED_END_REACHED IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_VANM2") AND NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_LOST") IF ( bPlayerCrashedIntoVan = FALSE ) IF DOES_ENTITY_EXIST(vsVan.VehicleIndex) AND DOES_ENTITY_EXIST(psVanDriver.PedIndex) IF IS_VEHICLE_DRIVEABLE(vsVan.VehicleIndex) AND NOT IS_PED_INJURED(psVanDriver.PedIndex) IF IS_ENTITY_TOUCHING_ENTITY(vsVan.VehicleIndex, vsPlayersCar.VehicleIndex) //disable phone conversation immediately upon collision IF IS_PHONE_ONSCREEN() HANG_UP_AND_PUT_AWAY_PHONE(TRUE) ENDIF IF ( bVanDriverCrashSpeechTriggered = FALSE ) //play ped ambient speech and use vehicle horn on player crashing IF NOT IS_PED_INJURED(psVanDriver.PedIndex) PLAY_PED_AMBIENT_SPEECH(psVanDriver.PedIndex, "GENERIC_CURSE_HIGH", SPEECH_PARAMS_FORCE) //also start a horn START_VEHICLE_HORN(vsVan.VehicleIndex, 5000) bVanDriverCrashSpeechTriggered = TRUE ENDIF ENDIF IF ( bConversationPaused = FALSE ) IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() //IF ( bAllowConvsersationOutsideOfCar = FALSE ) //lConversationLabel = GET_STANDARD_CONVERSATION_LABEL_FOR_FUTURE_RESUMPTION() //KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() //ELSE KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() bAllowConvsersationOutsideOfCar = FALSE //ENDIF ENDIF IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_VANM2", CONV_PRIORITY_HIGH) bPlayerCrashedIntoVan = TRUE SET_LABEL_AS_TRIGGERED("FAM3_VANM2", TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF //play 'I think we lost him' conversation IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_LOST") IF ( bStartPreloadingVanConversation = TRUE ) IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_VAN") KILL_FACE_TO_FACE_CONVERSATION() ENDIF ENDIF IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF IS_PED_SITTING_IN_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex) AND IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_LOST", CONV_PRIORITY_VERY_HIGH) REPLAY_RECORD_BACK_FOR_TIME(3.0, 3.0) SET_LABEL_AS_TRIGGERED("FAM3_LOST", TRUE) psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF ENDIF ELSE //player gets close to the canyon turn IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_TURN") IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF IS_ENTITY_AT_COORD(vsPlayersCar.VehicleIndex, <<-1195.872559,706.979980,149.748108>>, <<34.0,34.0,7.0>>) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_TURN", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_LOOK", TRUE) //make sure the "FAM3_LOOK" random dialogue does not play anymore SET_LABEL_AS_TRIGGERED("FAM3_TURN", TRUE) ENDIF ENDIF ELSE KILL_FACE_TO_FACE_CONVERSATION() ENDIF ENDIF ENDIF ENDIF //player drives onto canynon road IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_FIND") IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF IS_ENTITY_AT_COORD(vsPlayersCar.VehicleIndex, <<-1183.073120,704.413208,150.805725>>, <<16.0, 16.0, 7.0>>) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_FIND", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_LOOK", TRUE) //make sure the "FAM3_LOOK" random dialogue does not play anymore SET_LABEL_AS_TRIGGERED("FAM3_TURN", TRUE) //make sure the "FAM3_TURN" random dialogue does not play anymore SET_LABEL_AS_TRIGGERED("FAM3_FIND", TRUE) ENDIF ENDIF ELSE KILL_FACE_TO_FACE_CONVERSATION() ENDIF ENDIF ENDIF ENDIF IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_CAR") IF HAS_LABEL_BEEN_TRIGGERED("FAM3_FIND") IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF ( bCoachVisible = TRUE ) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_CAR", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_CAR", TRUE) ENDIF ENDIF ELSE KILL_FACE_TO_FACE_CONVERSATION() ENDIF ENDIF ENDIF ENDIF ENDIF //Michael's random dialogue for looking out for coach as player drives to the canyon IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_LOOK") IF ( eChaseFinishReason = CHASE_FINISHED_END_REACHED ) IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) //locates blip has to exists IF HAS_LABEL_BEEN_TRIGGERED(sLabelDCAN) OR IS_STRING_NULL_OR_EMPTY(sLabelDCAN) //and objective was displayed IF HAS_TIME_PASSED(8000, psFranklin.iConversationTimer) //use Franklin's timer to trigger random dialogue IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), vUnderBalconyPosition) < 425.0 IF NOT IS_VEHICLE_STOPPED(vsPlayersCar.VehicleIndex) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_LOOK", CONV_PRIORITY_MEDIUM) iRandomLinesTriggered++ psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF IF ( iRandomLinesTriggered = 1 ) SET_LABEL_AS_TRIGGERED("FAM3_LOOK", TRUE) //just play one variation of these lines ENDIF ELSE IF NOT IS_AMBIENT_SPEECH_PLAYING(PLAYER_PED_ID()) PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(PLAYER_PED_ID(), "FAM3_AIAA", "MICHAEL", SPEECH_PARAMS_FORCE_NORMAL) SET_LABEL_AS_TRIGGERED("FAM3_LOOK", TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF //Michael and Franklin spot the tennis coach IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_SPOT") IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF ( bCoachSpotted = TRUE ) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) //IF PLAY_SINGLE_LINE_FROM_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_SPOT", "FAM3_SPOT_1", CONV_PRIORITY_MEDIUM) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_SPOT", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_SPOT", TRUE) ENDIF ENDIF ELSE KILL_FACE_TO_FACE_CONVERSATION() ENDIF ELSE IF ( bMichaelStartedShouting = TRUE ) SET_LABEL_AS_TRIGGERED("FAM3_SPOT", TRUE) ENDIF ENDIF ENDIF ELSE IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() bSpotConversationFinished = TRUE ENDIF ENDIF //Michael shouts from the car to the tennis coach on the balcony IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_BALC") IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF ( bMichaelStartedShouting = TRUE ) IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "missfam3", "shout_out_window_michael") AND GET_ENTITY_ANIM_CURRENT_TIME(PLAYER_PED_ID(), "missfam3", "shout_out_window_michael") > 0.05 IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_BALC", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_BALC", TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF //Michael's random line after the mini cutscene with coach on balcony IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_BALCR") IF HAS_LABEL_BEEN_TRIGGERED("FAM3_BALC") //play if after the preceding conversation IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF ( bMichaelStartedShouting = TRUE AND bRecordingPlaybackStarted = TRUE ) IF NOT IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "missfam3", "shout_out_window_michael") IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_BALCR", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_BALCR", TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF IF eChaseFinishReason = CHASE_FINISHED_TARGET_LOST IF HAS_LABEL_BEEN_TRIGGERED(sMainConversationRootLabel) IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_MST2") AND NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_FST2") IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF ARE_STRINGS_EQUAL(sMainConversationRootLabel, "FAM3_MST1") IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_MST2", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_MST2", TRUE) ENDIF ENDIF IF ARE_STRINGS_EQUAL(sMainConversationRootLabel, "FAM3_FST1") IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_FST2", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_FST2", TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDPROC PROC MANAGE_TENNIS_COACH_IN_CHASE(INT &iProgress) SEQUENCE_INDEX PedSequence SWITCH iProgress CASE 0 IF IS_VEHICLE_DRIVEABLE(vsCoachsCar.VehicleIndex) //start uber recording playback if it is not going on IF NOT IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vsCoachsCar.VehicleIndex) //after intro cutscene or stage replay SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(vsCoachsCar.VehicleIndex, TRUE) IF NOT IS_PED_INJURED(psCoach.PedIndex) SET_ENTITY_VISIBLE(psCoach.PedIndex, TRUE) SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(psCoach.PedIndex, TRUE) SET_PED_CONFIG_FLAG(psCoach.PedIndex, PCF_WillFlyThroughWindscreen, FALSE) SET_PED_CONFIG_FLAG(psCoach.PedIndex, PCF_GetOutBurningVehicle, FALSE) SET_PED_CONFIG_FLAG(psCoach.PedIndex, PCF_GetOutUndriveableVehicle, FALSE) ENDIF INITIALISE_UBER_PLAYBACK(sVehicleRecordingsFile, vsCoachsCar.iRecordingNumber) INITIALISE_UBER_ARRAY() CREATE_ALL_WAITING_UBER_CARS() #IF IS_DEBUG_BUILD bTrafficDebugOn = TRUE #ENDIF fUberPlaybackDensitySwitchOffRange = 200.0 bPlayTrafficRecordingEvenIfPlayerIsAheadOfChase = TRUE START_VEHICLE_RECORDING_PLAYBACK_FOR_VEHICLE(vsCoachsCar, sVehicleRecordingsFile, fChaseSpeed, FALSE, 1500.0) FORCE_PLAYBACK_RECORDED_VEHICLE_UPDATE(vsCoachsCar.VehicleIndex) UPDATE_UBER_PLAYBACK(vsCoachsCar.VehicleIndex, 1.0) ENDIF ADD_ENTITY_TO_AUDIO_MIX_GROUP(vsCoachsCar.VehicleIndex, "FAMILY_3_TENNIS_COACH_GROUP") ENDIF TRIGGER_MUSIC_EVENT("FAM3_CHASE_START") bChaseInProgress = TRUE iProgress++ BREAK CASE 1 //if the player reaches the van blocking the way, end the uber chase and speed up the coach IF ( bChaseInProgress = TRUE ) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) AND IS_VEHICLE_DRIVEABLE(vsCoachsCar.VehicleIndex) RUBBER_BAND_PLAYBACK_SPEED_FOR_TRIGGER_VEHICLE(vsCoachsCar.VehicleIndex, vsPlayersCar.VehicleIndex, fChaseSpeed, fChaseTime #IF IS_DEBUG_BUILD, FALSE, "Coach", "Player" #ENDIF) CREATE_ALL_WAITING_UBER_CARS() UPDATE_UBER_PLAYBACK(vsCoachsCar.VehicleIndex, fChaseSpeed) //uber playback flags allow_veh_to_stop_on_PLAYER_impact = TRUE //switches set piece vehicles to playback using ai on player impact ENDIF ELSE CLEANUP_UBER_PLAYBACK() IF IS_VEHICLE_DRIVEABLE(vsCoachsCar.VehicleIndex) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vsCoachsCar.VehicleIndex) SET_PLAYBACK_SPEED(vsCoachsCar.VehicleIndex, 1.4) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting playback speed to 1.4 on cleanup_uber_playback.") #ENDIF ENDIF SET_ENTITY_INVINCIBLE(vsCoachsCar.VehicleIndex, TRUE) SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(vsCoachsCar.VehicleIndex, TRUE) SET_ENTITY_COLLISION(vsCoachsCar.VehicleIndex, FALSE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting coach's car invincible, only damaged by player and no collision flag on cleanup_uber_playback.") #ENDIF ENDIF IF NOT IS_PED_INJURED(psCoach.PedIndex) SET_ENTITY_INVINCIBLE(psCoach.PedIndex, TRUE) SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(psCoach.PedIndex, TRUE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting coach invincible, only damaged by player on cleanup_uber_playback.") #ENDIF ENDIF iProgress++ ENDIF BREAK CASE 2 //after the chase has finished and coach's blip is off, make him drive super fast to the end of his recording IF ( bChaseFinished = TRUE ) IF NOT DOES_BLIP_EXIST(vsCoachsCar.BlipIndex) IF IS_VEHICLE_DRIVEABLE(vsCoachsCar.VehicleIndex) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vsCoachsCar.VehicleIndex) SET_PLAYBACK_SPEED(vsCoachsCar.VehicleIndex, 2.0) SET_ENTITY_INVINCIBLE(vsCoachsCar.VehicleIndex, TRUE) SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(vsCoachsCar.VehicleIndex, TRUE) SET_ENTITY_COLLISION(vsCoachsCar.VehicleIndex, FALSE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting coach's car invincible, only damaged by player and no collision flag when chase is ended.") #ENDIF ENDIF REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(vsCoachsCar.VehicleIndex) ENDIF IF NOT IS_PED_INJURED(psCoach.PedIndex) SET_ENTITY_INVINCIBLE(psCoach.PedIndex, TRUE) SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(psCoach.PedIndex, TRUE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting coach invincible, only damaged by player when chase is ended.") #ENDIF ENDIF //request the IPL for balcony #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Requesting IPL DES_StiltHouse_imapstart.") #ENDIF REQUEST_IPL("DES_StiltHouse_imapstart") iProgress++ ENDIF ENDIF BREAK CASE 3 //when coach's car ends vehicle recording, coach needs to be warped to the balcony at the back of the house IF IS_VEHICLE_DRIVEABLE(vsCoachsCar.VehicleIndex) REQUEST_ANIM_DICT("missfam3") IF NOT IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vsCoachsCar.VehicleIndex) //check if map section for balcony is loaded IF IS_IPL_ACTIVE("DES_StiltHouse_imapstart") #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": IPL DES_StiltHouse_imapstart is active.") #ENDIF IF NOT IS_PED_INJURED(psCoach.PedIndex) WARP_PED(psCoach.PedIndex, << -1034.6083, 653.9794, 155.0754 >>, 90.0561, FALSE, FALSE, FALSE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Warping coach to the balcony.") #ENDIF SET_ENTITY_VISIBLE(psCoach.PedIndex, TRUE) SET_ENTITY_INVINCIBLE(psCoach.PedIndex, FALSE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Calling SET_ENTITY_INVINCIBLE(FALSE) for tennis coach.") #ENDIF SET_ENTITY_COLLISION(psCoach.PedIndex, TRUE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Calling SET_ENTITY_COLLISION(TRUE) for tennis coach.") #ENDIF CLEAR_PED_TASKS(psCoach.PedIndex) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Calling CLEAR_PED_TASKS() for tennis coach.") #ENDIF SET_ENTITY_LOAD_COLLISION_FLAG(psCoach.PedIndex, TRUE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Calling SET_ENTITY_LOAD_COLLISION_FLAG(TRUE) for tennis coach.") #ENDIF //SET_ENTITY_LOD_DIST(psCoach.PedIndex, 125) SET_PED_LOD_MULTIPLIER(psCoach.PedIndex, 5.0) SET_PED_COMPONENT_VARIATION(psCoach.PedIndex, PED_COMP_TORSO, 1, 0) SET_PED_COMPONENT_VARIATION(psCoach.PedIndex, PED_COMP_LEG, 1, 0) IF HAS_ANIM_DICT_LOADED("missfam3") TASK_PLAY_ANIM_ADVANCED(psCoach.PedIndex, "missfam3", "coach_idle", << -1034.630, 654.114, 156.080 >>, << 0.0, 0.0, 85.0 >>, INSTANT_BLEND_IN, SLOW_BLEND_OUT, -1, AF_EXTRACT_INITIAL_OFFSET | AF_LOOPING | AF_OVERRIDE_PHYSICS) ENDIF ENDIF IF IS_VEHICLE_DRIVEABLE(vsCoachsCar.VehicleIndex) SET_ENTITY_INVINCIBLE(vsCoachsCar.VehicleIndex, FALSE) SET_ENTITY_COLLISION(vsCoachsCar.VehicleIndex, TRUE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting coach's car to not be invincible and have collision.") #ENDIF SET_VEHICLE_ENGINE_ON(vsCoachsCar.VehicleIndex, FALSE, TRUE) SET_VEHICLE_LIGHTS(vsCoachsCar.VehicleIndex, FORCE_VEHICLE_LIGHTS_ON) //SET_ENTITY_COORDS(vsCoachsCar.VehicleIndex, <<-1007.2410, 708.9224, 161.0334>>) //old position //SET_ENTITY_HEADING(vsCoachsCar.VehicleIndex, 358.5527) SET_ENTITY_COORDS(vsCoachsCar.VehicleIndex, <<-1069.1571, 672.9374, 141.3214>>) SET_ENTITY_HEADING(vsCoachsCar.VehicleIndex, 275.7670) SET_VEHICLE_ON_GROUND_PROPERLY(vsCoachsCar.VehicleIndex) //SET_VEHICLE_DOORS_LOCKED(vsCoachsCar.VehicleIndex, VEHICLELOCK_LOCKED) SET_VEHICLE_DOOR_OPEN(vsCoachsCar.VehicleIndex, SC_DOOR_FRONT_LEFT, FALSE, TRUE) SET_VEHICLE_DOOR_OPEN(vsCoachsCar.VehicleIndex, SC_DOOR_FRONT_LEFT, TRUE) SET_VEHICLE_IS_CONSIDERED_BY_PLAYER(vsCoachsCar.VehicleIndex, FALSE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Repositioning coach's car.") #ENDIF ENDIF FailFlags[MISSION_FAIL_COACH_DEAD] = TRUE FailFlags[MISSION_FAIL_COACH_ATTACKED] = TRUE FailFlags[MISSION_FAIL_COACH_SPOOKED] = TRUE iProgress++ ENDIF ENDIF ENDIF BREAK CASE 4 //run a check for coach falling under the balcony #IF IS_DEBUG_BUILD VECTOR vCurrentCoachPosition vCurrentCoachPosition = GET_ENTITY_COORDS(psCoach.PedIndex) IF ( vCurrentCoachPosition.z < 155.0 ) //compare with warp coords << -1034.6083, 653.9794, 155.0754 >> SCRIPT_ASSERT("Tennis coach ped is falling down.") PRINTLN(GET_THIS_SCRIPT_NAME(), ": Tennis coach ped is falling down.") ENDIF #ENDIF IF ( bCoachSpotted = TRUE ) IF HAS_ANIM_DICT_LOADED("missfam3") IF NOT IS_PED_INJURED(psCoach.PedIndex) FREEZE_ENTITY_POSITION(psCoach.PedIndex, FALSE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Calling FREEZE_ENTITY_POSITION(FALSE) for tennis coach.") #ENDIF TASK_PLAY_ANIM(psCoach.PedIndex, "missfam3", "coach_idle", SLOW_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Coach playing coach_idle animation on balcony.") #ENDIF iProgress++ ENDIF ENDIF ENDIF BREAK CASE 5 //coach's anim shout_out_window_coach is started in main mission stage function, check here for when it ends IF ( bCoachSpotted = TRUE ) IF ( bMichaelStartedShouting = TRUE ) IF NOT IS_PED_INJURED(psCoach.PedIndex) IF NOT IS_ENTITY_PLAYING_ANIM(psCoach.PedIndex, "missfam3", "shout_out_window_coach") OPEN_SEQUENCE_TASK(PedSequence) TASK_GO_STRAIGHT_TO_COORD(NULL, << -1026.9159, 653.8083, 155.0754 >>, PEDMOVE_WALK, -1, 196.607) TASK_PLAY_ANIM(NULL, "missfam3", "coach_idle", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING) CLOSE_SEQUENCE_TASK(PedSequence) TASK_PERFORM_SEQUENCE(psCoach.PedIndex, PedSequence) CLEAR_SEQUENCE_TASK(PedSequence) iProgress++ ENDIF ENDIF ENDIF ENDIF BREAK ENDSWITCH ENDPROC PROC CHECK_LINE_OF_SIGHT_BETWEEN_ENTITIES(ENTITY_INDEX EntityIndex1, ENTITY_INDEX EntityIndex2, BOOL &bLOSFlag, INT &iTimer, INT iTime) IF DOES_ENTITY_EXIST(EntityIndex1) AND DOES_ENTITY_EXIST(EntityIndex2) IF NOT IS_ENTITY_DEAD(EntityIndex1) AND NOT IS_ENTITY_DEAD(EntityIndex2) IF HAS_TIME_PASSED(iTime, iTimer) bLOSFlag = HAS_ENTITY_CLEAR_LOS_TO_ENTITY(EntityIndex1, EntityIndex2) iTimer = GET_GAME_TIMER() ENDIF ELSE bLOSFlag = FALSE ENDIF ELSE bLOSFlag = FALSE ENDIF ENDPROC FUNC BOOL IS_MISSION_STAGE_CAR_CHASE_COMPLETED(INT &iStageProgress) SET_BIT(sLocatesData.iLocatesBitSet, BS_DONT_DO_J_SKIP) fChaseDistanceFromPlayerToCoach = GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), psCoach.PedIndex) MANAGE_SET_PIECE_VAN(vsVan.iProgress) MANAGE_TENNIS_COACH_IN_CHASE(psCoach.iProgress) CHECK_LINE_OF_SIGHT_BETWEEN_ENTITIES(vsPlayersCar.VehicleIndex, vsCoachsCar.VehicleIndex, bCoachVisible, psCoach.iTimer, 1000) UPDATE_CHASE_BLIP(vsCoachsCar.BlipIndex, vsCoachsCar.VehicleIndex, CHASE_TARGET_LOST_DISTANCE, 0.7, bChaseFinished) SWITCH GET_PLAYER_CHARACTER_AT_MISSION_START() CASE CHAR_MICHAEL MANAGE_CONVERSATIONS_DURING_CHASE("FAM3_MST1") BREAK CASE CHAR_FRANKLIN MANAGE_CONVERSATIONS_DURING_CHASE("FAM3_FST1") BREAK ENDSWITCH UPDATE_TRIGGERED_LABEL(sLabelDCAN) UPDATE_TRIGGERED_LABEL(sLabelGETBCK) IF ( bShouldUseDefaultRoute = FALSE ) IF ( bCustomRouteActive = FALSE ) IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) SET_GPS_DISABLED_ZONE(<< -742.680298 - 48.0, 539.209961 - 48.0, 115.340584 - 18.0>>, << -742.680298 + 48.0, 539.209961 + 48.0, 115.340584 + 18.0>>) bCustomRouteActive = TRUE ENDIF ELSE IF NOT DOES_BLIP_EXIST(sLocatesData.LocationBlip) SET_GPS_DISABLED_ZONE(<< 0.0, 0.0, 0.0 >>, << 0.0, 0.0, 0.0 >>) bCustomRouteActive = FALSE ENDIF IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), <<-742.680298,539.209961,115.340584>>, << 48.0, 48.0, 18.0 >>) OR IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), << -1184.89, 709.60, 132.38 >>, << -1133.41, 679.84, 161.10 >>, 36.0) OR IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), << -1062.28, 662.22, 125.02 >>, << -1138.02, 681.84, 161.37 >>, 36.0) OR IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), << -1065.68, 661.26, 121.10 >>, << -976.84, 641.13, 153.91 >>, 36.0) OR IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), << -894.49, 655.77, 113.47 >>, << -985.13, 640.53, 154.35 >>, 36.0) OR IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), << -898.85, 657.44, 113.60 >>, << -823.46, 645.49, 144.01 >>, 36.0) OR IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), << -770.93, 551.06, 101.91 >>, << -827.24, 649.55, 144.36 >>, 36.0) OR IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), << -770.974, 557.36, 102.67 >>, << -700.16, 501.75, 124.60 >>, 36.0) SET_GPS_DISABLED_ZONE(<< 0.0, 0.0, 0.0 >>, << 0.0, 0.0, 0.0 >>) bShouldUseDefaultRoute = TRUE ENDIF ENDIF ENDIF ENDIF SWITCH iStageProgress CASE 0 IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF NOT IS_PED_INJURED(psFranklin.PedIndex) IF NOT IS_PED_IN_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex) AND NOT IS_PED_GETTING_INTO_A_VEHICLE(psFranklin.PedIndex) IF ( GET_SCRIPT_TASK_STATUS(psFranklin.PedIndex, SCRIPT_TASK_ENTER_VEHICLE) <> PERFORMING_TASK ) TASK_ENTER_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex, DEFAULT_TIME_BEFORE_WARP, VS_FRONT_RIGHT, PEDMOVE_RUN, ECF_USE_RIGHT_ENTRY | ECF_RESUME_IF_INTERRUPTED) ENDIF ENDIF SET_PED_CONFIG_FLAG(psFranklin.PedIndex, PCF_GetOutUndriveableVehicle, FALSE) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(psFranklin.PedIndex, TRUE) ENDIF IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) AND NOT IS_PED_GETTING_INTO_A_VEHICLE(PLAYER_PED_ID()) IF ( GET_SCRIPT_TASK_STATUS(PLAYER_PED_ID(), SCRIPT_TASK_ENTER_VEHICLE) <> PERFORMING_TASK ) WARP_PED(PLAYER_PED_ID(), psMichael.vPosition, psMichael.fHeading, FALSE, FALSE, FALSE) FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_RUN, FALSE) TASK_ENTER_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, PEDMOVE_RUN, ECF_USE_LEFT_ENTRY | ECF_RESUME_IF_INTERRUPTED) ENDIF ENDIF SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(psFranklin.PedIndex, TRUE) ENDIF ENDIF IF IS_SCREEN_FADED_OUT() WAIT(150) DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME) ENDIF REPLAY_RECORD_BACK_FOR_TIME(0.0, 7.0, REPLAY_IMPORTANCE_HIGHEST) iStageProgress++ BREAK CASE 1 //player chases after tennis coach #IF IS_DEBUG_BUILD IF ( bDrawDebugStates = TRUE ) DRAW_DEBUG_TEXT_ABOVE_ENTITY(PLAYER_PED_ID(), GET_STRING_FROM_FLOAT(fChaseDistanceFromPlayerToCoach), 1.25) DRAW_DEBUG_TEXT_ABOVE_ENTITY(vsPlayersCar.VehicleIndex, PICK_STRING(bCoachVisible, "TRUE", "FALSE"), 1.5) ENDIF #ENDIF HANDLE_BUDDY_HEAD_TRACK_WHILE_ENTERING_VEHICLE() //handle player's truck blip IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex)//player is in the truck //remove player's car blip IF DOES_BLIP_EXIST(vsPlayersCar.BlipIndex) IF IS_THIS_PRINT_BEING_DISPLAYED("FAM3_GIT") OR IS_THIS_PRINT_BEING_DISPLAYED("FAM3_GBIT") CLEAR_PRINTS() ENDIF REMOVE_BLIP(vsPlayersCar.BlipIndex) ENDIF IF ( bPlayerVehicleEntered = FALSE ) IF NOT IS_AUDIO_SCENE_ACTIVE("FAMILY_3_FOLLOW_THE_COACH") START_AUDIO_SCENE("FAMILY_3_FOLLOW_THE_COACH") ENDIF bPlayerVehicleEntered = TRUE ENDIF IF ( bChaseFinished = FALSE ) IF IS_VEHICLE_DRIVEABLE(vsCoachsCar.VehicleIndex) IF NOT DOES_BLIP_EXIST(vsCoachsCar.BlipIndex) vsCoachsCar.BlipIndex = CREATE_BLIP_FOR_VEHICLE(vsCoachsCar.VehicleIndex, TRUE) ENDIF IF DOES_BLIP_EXIST(vsCoachsCar.BlipIndex) IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_FTC") CLEAR_PRINTS() PRINT_GOD_TEXT_ADVANCED("FAM3_FTC", DEFAULT_GOD_TEXT_TIME, TRUE) ENDIF ENDIF ENDIF ENDIF ELSE //player is not in the truck //display blip for player car and display objective to get in IF NOT DOES_BLIP_EXIST(vsPlayersCar.BlipIndex) vsPlayersCar.BlipIndex = CREATE_BLIP_FOR_VEHICLE(vsPlayersCar.VehicleIndex) ENDIF IF DOES_BLIP_EXIST(vsPlayersCar.BlipIndex) //display initial objective to get in for the first time IF NOT HAS_LABEL_BEEN_TRIGGERED(sLabelGIT) IF ( bPlayerVehicleEntered = FALSE ) CLEAR_PRINTS() PRINT_GOD_TEXT_ADVANCED(sLabelGIT, DEFAULT_GOD_TEXT_TIME, TRUE) ENDIF ELSE //display objective for getting back in after the initial get in objective was printed IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_GBIT") IF ( bPlayerVehicleEntered = TRUE ) CLEAR_PRINTS() PRINT_GOD_TEXT_ADVANCED("FAM3_GBIT", DEFAULT_GOD_TEXT_TIME, TRUE) ENDIF ENDIF ENDIF ENDIF IF DOES_BLIP_EXIST(vsCoachsCar.BlipIndex) REMOVE_BLIP(vsCoachsCar.BlipIndex) ENDIF ENDIF ENDIF IF ( bChaseInProgress = TRUE ) IF ( bChaseHintCamAllowed = FALSE ) IF ( fChaseTime >= 7500.0 ) bChaseHintCamAllowed = TRUE ENDIF ENDIF //handle blips and god text depending on player being in the truck or not IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex)//player is in the truck IF ( bChaseHintCamAllowed = TRUE ) CONTROL_VEHICLE_CHASE_HINT_CAM_IN_VEHICLE(localChaseHintCamStruct, vsCoachsCar.VehicleIndex, PICK_STRING(ShouldDisplayChaseHelpText(), "FAM3_HCAM", "")) ENDIF IF IS_GAMEPLAY_HINT_ACTIVE() IF NOT IS_AUDIO_SCENE_ACTIVE("FAMILY_3_FOCUS_ON_COACH") START_AUDIO_SCENE("FAMILY_3_FOCUS_ON_COACH") ENDIF ELSE IF IS_AUDIO_SCENE_ACTIVE("FAMILY_3_FOCUS_ON_COACH") STOP_AUDIO_SCENE("FAMILY_3_FOCUS_ON_COACH") ENDIF ENDIF ELSE //player is not in the truck //clear help message IF HAS_LABEL_BEEN_TRIGGERED("FAM3_HCAM") IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("FAM3_HCAM") CLEAR_HELP() ENDIF ENDIF ENDIF ENDIF //check for chase finish IF ( bChaseFinished = FALSE ) //player gets close to the van blocking the way, van can be dead or alive, player might shoot it up IF DOES_ENTITY_EXIST(vsVan.VehicleIndex) IF NOT IS_ENTITY_DEAD(vsVan.VehicleIndex) IF IS_ENTITY_AT_ENTITY(vsPlayersCar.VehicleIndex, vsVan.VehicleIndex, vVanLocateSize) KILL_CHASE_HINT_CAM(localChaseHintCamStruct) IF IS_AUDIO_SCENE_ACTIVE("FAMILY_3_FOCUS_ON_COACH") STOP_AUDIO_SCENE("FAMILY_3_FOCUS_ON_COACH") ENDIF bChaseInProgress = FALSE bChaseFinished = TRUE eChaseFinishReason = CHASE_FINISHED_END_REACHED IF IS_THIS_PRINT_BEING_DISPLAYED("FAM3_FTC") CLEAR_PRINTS() ENDIF //set the mission to be reset to the start when P-skip occurs from this point #IF IS_DEBUG_BUILD bStageResetFlag = TRUE #ENDIF ENDIF ENDIF ENDIF //if player somehow destroyed the van, or the van does not exist as expected, do a locate check along the chase route //use a locate check, should be more reliable than entity check as the van and driver might be dead IF IS_ENTITY_IN_ANGLED_AREA(vsPlayersCar.VehicleIndex, <<-1381.268311,474.786530,103.054825>>, <<-1390.820190,457.381134,110.486206>>, 8.0) KILL_CHASE_HINT_CAM(localChaseHintCamStruct) IF IS_AUDIO_SCENE_ACTIVE("FAMILY_3_FOCUS_ON_COACH") STOP_AUDIO_SCENE("FAMILY_3_FOCUS_ON_COACH") ENDIF bChaseInProgress = FALSE bChaseFinished = TRUE eChaseFinishReason = CHASE_FINISHED_END_REACHED IF IS_THIS_PRINT_BEING_DISPLAYED("FAM3_FTC") CLEAR_PRINTS() ENDIF //if player is making a phone call after destroying the van //and entering the end of chase locate IF IS_PHONE_ONSCREEN() HANG_UP_AND_PUT_AWAY_PHONE(TRUE) ENDIF //set the mission to be reset to the start when P-skip occurs from this point #IF IS_DEBUG_BUILD bStageResetFlag = TRUE #ENDIF ENDIF IF fChaseDistanceFromPlayerToCoach > CHASE_TARGET_LOST_DISTANCE IF DOES_BLIP_EXIST(vsCoachsCar.BlipIndex) REMOVE_BLIP(vsCoachsCar.BlipIndex) ENDIF KILL_CHASE_HINT_CAM(localChaseHintCamStruct) IF IS_AUDIO_SCENE_ACTIVE("FAMILY_3_FOCUS_ON_COACH") STOP_AUDIO_SCENE("FAMILY_3_FOCUS_ON_COACH") ENDIF bChaseInProgress = FALSE bChaseFinished = TRUE eChaseFinishReason = CHASE_FINISHED_TARGET_LOST IF IS_THIS_PRINT_BEING_DISPLAYED("FAM3_FTC") CLEAR_PRINTS() ENDIF //set the mission to be reset to the start when P-skip occurs from this point #IF IS_DEBUG_BUILD bStageResetFlag = TRUE #ENDIF ENDIF ENDIF ELSE IF ( bChaseFinished = TRUE ) IF IS_AUDIO_SCENE_ACTIVE("FAMILY_3_FOLLOW_THE_COACH") STOP_AUDIO_SCENE("FAMILY_3_FOLLOW_THE_COACH") ENDIF IF NOT IS_AUDIO_SCENE_ACTIVE("FAMILY_3_FIND_THE_COACH") START_AUDIO_SCENE("FAMILY_3_FIND_THE_COACH") ENDIF SWITCH eChaseFinishReason CASE CHASE_FINISHED_END_REACHED BREAK CASE CHASE_FINISHED_TARGET_LOST BREAK ENDSWITCH IF HAS_LABEL_BEEN_TRIGGERED("FAM3_LOST") //if the conversation "FAM3_LOST" managed to be created and played //remove coach's red blip when Michael and Franklin mention they lost him IF DOES_BLIP_EXIST(vsCoachsCar.BlipIndex) REMOVE_BLIP(vsCoachsCar.BlipIndex) ENDIF //when the "FAM3_LOST" conversation is playing IF IS_THIS_CONVERSATION_PLAYING("FAM3_LOST") bCoachLostConversationStarted = TRUE //mark the conversation FAM3_LOST as triggered and started playing //when second line of that conversation triggers, create a blip for destination IF ( GET_CURRENT_SCRIPTED_CONVERSATION_LINE() = 1 ) IF NOT DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) IF NOT IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0) //sLocatesData.LocationBlip = CREATE_BLIP_FOR_COORD(<<-991.654724,645.382141,140.642548>>, TRUE) bDisplayDestinationBlip = TRUE ENDIF ENDIF ENDIF ENDIF ENDIF ELSE //conversation FAM3_LOST not playing, could be due to being finished or still building IF ( bCoachLostConversationStarted = TRUE ) //only move on if FAM3_LOST started playing and finished //move on once the coach lost conversation is over iStageProgress++ ENDIF ENDIF ENDIF ENDIF ENDIF IF ( bDisplayDestinationBlip = TRUE ) IS_PLAYER_AT_LOCATION_WITH_BUDDY_IN_VEHICLE(sLocatesData, vUnderBalconyPosition, <<4.0, 8.0, LOCATE_SIZE_HEIGHT>>, TRUE, psFranklin.PedIndex, vsPlayersCar.VehicleIndex, sLabelDCAN, "CMN_FLEAVE", "", sLabelGETBCK,FALSE, TRUE) ENDIF BREAK CASE 2 //player drives to the canyon destination //make sure shout anim for Michael is loaded REQUEST_ANIM_DICT("missfam3") IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "missfam3", "shout_out_window_michael") OR GET_SCRIPT_TASK_STATUS(PLAYER_PED_ID(), SCRIPT_TASK_VEHICLE_MISSION) = PERFORMING_TASK DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_EXIT) ENDIF ENDIF IF ( bCoachSpotted = FALSE ) IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) AND IS_PED_SITTING_IN_THIS_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) AND IS_PED_SITTING_IN_THIS_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex) AND IS_ENTITY_IN_ANGLED_AREA(vsPlayersCar.VehicleIndex, <<-1116.003296,693.004333,140.496552>>, <<-1040.929321,667.397583,157.254593>>, 36.000000) //hacky fix for B*1407985 & B*1513220 IF NOT IS_ENTITY_AT_COORD(vsPlayersCar.VehicleIndex, <<-1054.042480,681.179077,152.773621>>,<<20.000000,16.000000,12.000000>>) DISABLE_CELLPHONE(TRUE) SETTIMERA(0) SET_GAMEPLAY_COORD_HINT(vTennisCoachHintPosition, -1, iTennisCoachHintDuration, DEFAULT_INTERP_OUT_TIME, HINTTYPE_FAMILY3_COACH_ON_BALCONY_VEHICLE_HINT_HELPER) TASK_VEHICLE_MISSION_COORS_TARGET(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex, <<-991.654724,645.382141,140.642548>>, MISSION_GOTO, 6.0, DF_SteerAroundStationaryCars, 1.0, 2.0, FALSE) ENDIF TRIGGER_MUSIC_EVENT("FAM3_BALCONY") bCoachSpotted = TRUE ELSE IF NOT DOES_BLIP_EXIST(sLocatesData.LocationBlip) AND IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0) AND IS_PED_SITTING_IN_THIS_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) AND IS_PED_SITTING_IN_THIS_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex) AND IS_ENTITY_IN_ANGLED_AREA(vsPlayersCar.VehicleIndex, <<-1116.003296,693.004333,140.496552>>, <<-1040.929321,667.397583,157.254593>>, 36.000000) TRIGGER_MUSIC_EVENT("FAM3_BALCONY") bCoachSpotted = TRUE ENDIF ENDIF ELIF ( bCoachSpotted = TRUE ) IF ( bMichaelStartedShouting = FALSE ) IF IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0) SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0) SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID()) ENDIF IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) AND IS_PED_SITTING_IN_THIS_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) AND IS_PED_SITTING_IN_THIS_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex) IF HAS_LABEL_BEEN_TRIGGERED("FAM3_SPOT") IF ( bSpotConversationFinished = TRUE ) REMOVE_VEHICLE_WINDOW(vsPlayersCar.VehicleIndex, SC_WINDOW_FRONT_LEFT) TASK_PLAY_ANIM(PLAYER_PED_ID(), "missfam3", "shout_out_window_michael", SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_UPPERBODY | AF_SECONDARY) TASK_PLAY_ANIM(psFranklin.PedIndex, "missfam3", "shout_out_window_franklin", SLOW_BLEND_IN, WALK_BLEND_OUT, -1, AF_UPPERBODY | AF_SECONDARY) TASK_PLAY_ANIM_ADVANCED(psCoach.PedIndex, "missfam3", "shout_out_window_coach", << -1034.630, 654.114, 156.080 >>, << 0.0, 0.0, 85.0 >>, SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_EXTRACT_INITIAL_OFFSET | AF_OVERRIDE_PHYSICS | AF_NOT_INTERRUPTABLE) TASK_LOOK_AT_ENTITY(psCoach.PedIndex, PLAYER_PED_ID(), INFINITE_TASK_TIME) REPLAY_RECORD_BACK_FOR_TIME(7.0, 7.0, REPLAY_IMPORTANCE_HIGHEST) bMichaelStartedShouting = TRUE ENDIF ENDIF ENDIF ELIF ( bMichaelStartedShouting = TRUE ) IF HAS_LABEL_BEEN_TRIGGERED("FAM3_BALC") IF ( bRecordingPlaybackStarted = FALSE ) IF IS_THIS_CONVERSATION_PLAYING("FAM3_BALC") //when the "FAM3_BALC" conversation is playing IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) AND IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "missfam3", "shout_out_window_michael") IF ( GET_CURRENT_SCRIPTED_CONVERSATION_LINE() >= 0 ) OR IS_ENTITY_IN_ANGLED_AREA(vsPlayersCar.VehicleIndex, <<-1116.163086,681.841125,135.569122>>, <<-1066.322632,665.023315,149.062729>>, 24.0) IF IS_AUDIO_SCENE_ACTIVE("FAMILY_3_FIND_THE_COACH") STOP_AUDIO_SCENE("FAMILY_3_FIND_THE_COACH") ENDIF IF NOT IS_AUDIO_SCENE_ACTIVE("FAMILY_3_ARRIVE_AT_HOUSE") START_AUDIO_SCENE("FAMILY_3_ARRIVE_AT_HOUSE") ENDIF bRecordingPlaybackStarted = TRUE ENDIF ENDIF ENDIF ENDIF ENDIF IF IS_GAMEPLAY_HINT_ACTIVE() IF IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0) SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0) SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID()) ENDIF IF ( TIMERA() > iTennisCoachHintDuration) OR ( IS_ENTITY_PLAYING_ANIM(psCoach.PedIndex, "missfam3", "shout_out_window_coach") AND GET_ENTITY_ANIM_CURRENT_TIME(psCoach.PedIndex, "missfam3", "shout_out_window_coach") > 0.8 ) OR ( HAS_LABEL_BEEN_TRIGGERED("FAM3_BALC") AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() ) OR IS_ENTITY_IN_ANGLED_AREA(vsPlayersCar.VehicleIndex, <<-1056.988770,652.465698,140.027237>>, <<-1047.219238,668.414063,153.151367>>, 16.0) DISABLE_CELLPHONE(FALSE) //clear Michael's tasks IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "missfam3", "shout_out_window_michael") CLEAR_PED_SECONDARY_TASK(PLAYER_PED_ID()) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Stopping Michael's animation shout_out_window_michael.") #ENDIF ENDIF ENDIF //clear Franklin's tasks IF NOT IS_PED_INJURED(psFranklin.PedIndex) IF IS_ENTITY_PLAYING_ANIM(psFranklin.PedIndex, "missfam3", "shout_out_window_franklin") CLEAR_PED_SECONDARY_TASK(psFranklin.PedIndex) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Stopping Franklin's animation shout_out_window_franklin.") #ENDIF ENDIF ENDIF STOP_GAMEPLAY_HINT() CLEAR_PED_TASKS(PLAYER_PED_ID()) SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) IF IS_AUDIO_SCENE_ACTIVE("FAMILY_3_ARRIVE_AT_HOUSE") STOP_AUDIO_SCENE("FAMILY_3_ARRIVE_AT_HOUSE") ENDIF IF IS_AUDIO_SCENE_ACTIVE("FAMILY_3_FIND_THE_COACH") STOP_AUDIO_SCENE("FAMILY_3_FIND_THE_COACH") ENDIF IF NOT IS_AUDIO_SCENE_ACTIVE("FAMILY_3_DRIVE_IN_TO_POSITION") START_AUDIO_SCENE("FAMILY_3_DRIVE_IN_TO_POSITION") ENDIF ENDIF ENDIF ENDIF ENDIF IF DOES_BLIP_EXIST(vsPlayersCar.BlipIndex) //remove player's car blip if it exists, locates header will handle it now IF GET_BLIP_FROM_ENTITY(vsPlayersCar.VehicleIndex) = vsPlayersCar.BlipIndex REMOVE_BLIP(vsPlayersCar.BlipIndex) ENDIF ENDIF //check for when player arrives at the back of the house locate IF IS_PLAYER_AT_LOCATION_WITH_BUDDY_IN_VEHICLE(sLocatesData, vUnderBalconyPosition, <<4.0, 8.0, LOCATE_SIZE_HEIGHT>>, TRUE, psFranklin.PedIndex, vsPlayersCar.VehicleIndex, sLabelDCAN, "CMN_FLEAVE", "", sLabelGETBCK,FALSE, TRUE) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF IS_VEHICLE_ON_ALL_WHEELS(vsPlayersCar.VehicleIndex) IF DOES_CAM_EXIST(ScriptedCamera) SET_CAM_ACTIVE(ScriptedCamera, FALSE) RENDER_SCRIPT_CAMS(FALSE, FALSE) DESTROY_CAM(ScriptedCamera) ENDIF //clear Michael's tasks if he is still playing the shout animation IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "missfam3", "shout_out_window_michael") CLEAR_PED_SECONDARY_TASK(PLAYER_PED_ID()) ENDIF ENDIF //clear Franklin's tasks if he is still playing the shout animation IF NOT IS_PED_INJURED(psFranklin.PedIndex) IF IS_ENTITY_PLAYING_ANIM(psFranklin.PedIndex, "missfam3", "shout_out_window_franklin") CLEAR_PED_SECONDARY_TASK(psFranklin.PedIndex) ENDIF ENDIF //clear coach's tasks if he is still playing the shout animation IF NOT IS_PED_INJURED(psCoach.PedIndex) IF IS_ENTITY_PLAYING_ANIM(psCoach.PedIndex, "missfam3", "shout_out_window_coach") CLEAR_PED_TASKS(psCoach.PedIndex) ENDIF TASK_CLEAR_LOOK_AT(psCoach.PedIndex) ENDIF IF DOES_ENTITY_EXIST(osRacket01.ObjectIndex) DELETE_OBJECT(osRacket01.ObjectIndex) ENDIF IF DOES_ENTITY_EXIST(osRacket02.ObjectIndex) DELETE_OBJECT(osRacket02.ObjectIndex) ENDIF IF DOES_ENTITY_EXIST(osBrokenPlantPot.ObjectIndex) DELETE_OBJECT(osBrokenPlantPot.ObjectIndex) ENDIF CLEANUP_VEHICLE(vsCoachsCar, TRUE) //remove coach's car KILL_ANY_CONVERSATION() KILL_FACE_TO_FACE_CONVERSATION() //kill conversations and let last line play out SETTIMERA(0) //start backup timer in case the conversations are busted by streaming iStageProgress++ ENDIF ENDIF ENDIF IF IS_PLAYER_BROWSING_ITEMS_IN_ANY_SHOP() OR IS_PLAYER_CHANGING_CLOTHES() //check if player changed clothes before cutscene IF HAS_THIS_CUTSCENE_LOADED("fam_3_mcs_1") OR HAS_CUTSCENE_LOADED() OR IS_CUTSCENE_ACTIVE() REMOVE_CUTSCENE() //remove cutscene from memory if player changed clothes #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Player browsing items in a shop or changing clothes. Removing cutscene.") #ENDIF ENDIF ELSE IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), vUnderBalconyPosition) < DEFAULT_CUTSCENE_LOAD_DIST REQUEST_CUTSCENE("fam_3_mcs_1") //request cutscene and variations IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY() IF NOT IS_PED_INJURED(PLAYER_PED_ID()) SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Michael", PLAYER_PED_ID()) ENDIF IF NOT IS_PED_INJURED(psFranklin.PedIndex) SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Franklin", psFranklin.PedIndex) ENDIF SET_CUTSCENE_PED_COMPONENT_VARIATION("TennisCoach", PED_COMP_TORSO, 1, 0) SET_CUTSCENE_PED_COMPONENT_VARIATION("TennisCoach", PED_COMP_LEG, 1, 0) ENDIF ELSE IF HAS_THIS_CUTSCENE_LOADED("fam_3_mcs_1") OR HAS_CUTSCENE_LOADED() OR IS_CUTSCENE_ACTIVE() REMOVE_CUTSCENE() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Player too far away from destination to keep cutscene in memory. Removing cutscene.") #ENDIF ENDIF ENDIF ENDIF //disable player climbing onto the balcony IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), <<-1036.479858,671.642395,155.457687>>, << 4.0, 7.0, 4.5>>) OR IS_ENTITY_AT_COORD(PLAYER_PED_ID(), <<-1006.946838,667.282104,154.917389>>, << 5.0, 8.0, 4.5 >>) SET_PED_RESET_FLAG(PLAYER_PED_ID(), PRF_DisablePlayerAutoVaulting, TRUE) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_JUMP) ENDIF BREAK CASE 3 IF BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(vsPlayersCar.VehicleIndex, 3.0) IF NOT IS_SCRIPTED_CONVERSATION_ONGOING() //check if scripted conversations are not ongoing using native command OR NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() //check if any conversations are not ongoing using script command OR ( TIMERA() > 5000 ) //check backup timer in case the conversations are busted by streaming CLEANUP_PED(psVanDriver, TRUE) CLEANUP_VEHICLE(vsVan, TRUE) REMOVE_VEHICLE_RECORDING(vsVan.iRecordingNumber, sVehicleRecordingsFile) STOP_AUDIO_SCENE("FAMILY_3_FIND_THE_COACH") STOP_AUDIO_SCENE("FAMILY_3_ARRIVE_AT_HOUSE") STOP_AUDIO_SCENE("FAMILY_3_DRIVE_IN_TO_POSITION") STOP_GAMEPLAY_HINT() REPLAY_RECORD_BACK_FOR_TIME(7.0, 0.0, REPLAY_IMPORTANCE_HIGHEST) RETURN TRUE ENDIF ENDIF BREAK ENDSWITCH RETURN FALSE ENDFUNC FUNC BOOL IS_MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE_COMPLETED(INT &iStageProgress) SWITCH iStageProgress CASE 0 //register peds for cutscene and start the cutscene when loaded IF HAS_REQUESTED_CUTSCENE_LOADED("fam_3_mcs_1") IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF IS_VEHICLE_DOOR_DAMAGED(vsPlayersCar.VehicleIndex, SC_DOOR_FRONT_LEFT) SET_VEHICLE_DOOR_CONTROL(vsPlayersCar.VehicleIndex, SC_DOOR_FRONT_LEFT, DT_DOOR_INTACT, 0.0) ENDIF IF IS_VEHICLE_DOOR_DAMAGED(vsPlayersCar.VehicleIndex, SC_DOOR_FRONT_RIGHT) SET_VEHICLE_DOOR_CONTROL(vsPlayersCar.VehicleIndex, SC_DOOR_FRONT_RIGHT, DT_DOOR_INTACT, 0.0) ENDIF REGISTER_ENTITY_FOR_CUTSCENE(vsPlayersCar.VehicleIndex, "Fam3_tow_truck", CU_ANIMATE_EXISTING_SCRIPT_ENTITY, BISON2) SET_VEHICLE_ENGINE_ON(vsPlayersCar.VehicleIndex, TRUE, TRUE) ENDIF IF NOT IS_PED_INJURED(psFranklin.PedIndex) REGISTER_ENTITY_FOR_CUTSCENE(psFranklin.PedIndex, "Franklin", CU_ANIMATE_EXISTING_SCRIPT_ENTITY, GET_PLAYER_PED_MODEL(CHAR_FRANKLIN)) ENDIF IF NOT IS_PED_INJURED(psCoach.PedIndex) REGISTER_ENTITY_FOR_CUTSCENE(psCoach.PedIndex, "TennisCoach", CU_ANIMATE_EXISTING_SCRIPT_ENTITY, CS_TENNISCOACH) ENDIF SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE) CLEAR_HELP() CLEAR_PRINTS() START_CUTSCENE(CUTSCENE_SUPPRESS_FP_TRANSITION_FLASH) REPLAY_START_EVENT(REPLAY_IMPORTANCE_HIGHEST) //CASCADE_SHADOWS_SET_CASCADE_BOUNDS_SCALE(0.3) iStageProgress++ ELSE IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY() IF NOT IS_PED_INJURED(PLAYER_PED_ID()) SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Michael", PLAYER_PED_ID()) ENDIF IF NOT IS_PED_INJURED(psFranklin.PedIndex) SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Franklin", psFranklin.PedIndex) ENDIF SET_CUTSCENE_PED_COMPONENT_VARIATION("TennisCoach", PED_COMP_TORSO, 1, 0) SET_CUTSCENE_PED_COMPONENT_VARIATION("TennisCoach", PED_COMP_LEG, 1, 0) ENDIF ENDIF BREAK CASE 1 //fade screen in if screen was faded out due to shit skip or debug skip IF IS_CUTSCENE_PLAYING() TRIGGER_MUSIC_EVENT("FAM3_ARRIVE_HOUSE") STOP_GAMEPLAY_HINT(TRUE) CLEAR_AREA(psMichael.vPosition, 100.0, TRUE) CLEAR_AREA_OF_VEHICLES(psMichael.vPosition, 100.0) IF IS_SCREEN_FADED_OUT() DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME) ENDIF iStageProgress++ ENDIF BREAK CASE 2 ROPE_LOAD_TEXTURES() REQUEST_ANIM_DICT("missfam3") REQUEST_MODEL(osRopeProp.ModelName) REQUEST_MODEL(osRopeDummy.ModelName) REQUEST_MODEL(osBootCollision.ModelName) DISABLE_ON_FOOT_FIRST_PERSON_VIEW_THIS_UPDATE() IF CAN_SET_EXIT_STATE_FOR_CAMERA() STOP_GAMEPLAY_HINT() SET_GAMEPLAY_CAM_RELATIVE_PITCH(0) SET_GAMEPLAY_CAM_RELATIVE_HEADING(0) ENDIF IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Michael") #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY() returned true for Michael.") #ENDIF IF ( bCutsceneSkipped = FALSE ) IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF HAS_ANIM_DICT_LOADED("missfam3") TASK_PLAY_ANIM_ADVANCED(PLAYER_PED_ID(), "missfam3", "argument_outro_michael", << -993.200, 646.188, 139.520 >>, << 0.0, 0.0, -93.24 >>, INSTANT_BLEND_IN, SLOW_BLEND_OUT, -1, AF_EXTRACT_INITIAL_OFFSET | AF_USE_KINEMATIC_PHYSICS | AF_HOLD_LAST_FRAME | AF_TAG_SYNC_OUT) FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID(), TRUE) ENDIF ENDIF ENDIF ENDIF IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Franklin") #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY() returned true for Franklin.") #ENDIF IF ( bCutsceneSkipped = FALSE ) IF NOT IS_PED_INJURED(psFranklin.PedIndex) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) SET_PED_INTO_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex, VS_FRONT_RIGHT) ENDIF ENDIF ENDIF ENDIF IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Fam3_tow_truck") #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY() returned true for Fam3_tow_truck.") #ENDIF IF ( bCutsceneSkipped = FALSE ) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) SET_VEHICLE_DOOR_OPEN(vsPlayersCar.VehicleIndex, SC_DOOR_BOOT, FALSE, TRUE) ENDIF ENDIF ENDIF IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("TennisCoach") #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY() returned true for TennisCoach.") #ENDIF IF NOT IS_PED_INJURED(psCoach.PedIndex) TASK_PLAY_ANIM(psCoach.PedIndex, "missfam3", "coach_idle", SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_LOOPING) ENDIF ENDIF IF NOT DOES_ENTITY_EXIST(osRopeDummy.ObjectIndex) IF HAS_MISSION_OBJECT_BEEN_CREATED(osRopeDummy, TRUE) SET_ENTITY_COLLISION(osRopeDummy.ObjectIndex, TRUE) SET_ENTITY_NO_COLLISION_ENTITY(osRopeDummy.ObjectIndex, PLAYER_PED_ID(), FALSE) SET_ENTITY_NO_COLLISION_ENTITY(vsPlayersCar.VehicleIndex, osRopeDummy.ObjectIndex, FALSE) SET_CAN_CLIMB_ON_ENTITY(osRopeDummy.ObjectIndex, FALSE) SET_CAN_AUTO_VAULT_ON_ENTITY(osRopeDummy.ObjectIndex, FALSE) ENDIF ENDIF IF ( bMusicEventHookedUpTriggered = FALSE ) IF GET_CUTSCENE_TIME() > 39500 IF TRIGGER_MUSIC_EVENT("FAM3_HOOKED_UP") bMusicEventHookedUpTriggered = TRUE ENDIF ENDIF ENDIF IF ( bRopeAttached = FALSE ) IF ( bCutsceneSkipped = FALSE ) IF GET_CUTSCENE_TIME() > 58000.0 IF NOT DOES_ENTITY_EXIST(osRopeProp.ObjectIndex) IF HAS_MISSION_OBJECT_BEEN_CREATED(osRopeProp, TRUE) SET_CAN_CLIMB_ON_ENTITY(osRopeProp.ObjectIndex, FALSE) SET_CAN_AUTO_VAULT_ON_ENTITY(osRopeProp.ObjectIndex, FALSE) ENDIF ENDIF IF NOT DOES_ROPE_EXIST(Rope) ROPE_LOAD_TEXTURES() IF ROPE_ARE_TEXTURES_LOADED() Rope = ADD_ROPE(<<-1017.9850, 660.4285, 147.4662>>, <<0.0, 0.0, 0.0>>, ROPE_MAX_LEN, PHYSICS_ROPE_DEFAULT, -1, 0.5, 0.5, FALSE, TRUE) LOAD_ROPE_DATA(Rope, ROPE_DATA_FILE ) ENDIF ENDIF IF DOES_ENTITY_EXIST(osRopeAnchor.ObjectIndex) AND DOES_ROPE_EXIST(rope) IF DOES_ENTITY_HAVE_PHYSICS(osRopeAnchor.ObjectIndex) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) SET_VEHICLE_DOORS_SHUT(vsPlayersCar.VehicleIndex, TRUE) ATTACH_ENTITIES_TO_ROPE(Rope, osRopeAnchor.ObjectIndex, vsPlayersCar.VehicleIndex, osRopeAnchor.vPosition, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vsPlayersCar.VehicleIndex, << 0.0, -2.1, 0.6 >>), 35.0, 0, 0) bRopeAttached = TRUE ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF IF HAS_CUTSCENE_FINISHED() SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) SET_SCRIPTS_SAFE_FOR_CUTSCENE(FALSE) IF ( bCutsceneSkipped = TRUE ) //cutscene was skipped IF ROPE_ARE_TEXTURES_LOADED() AND HAS_ANIM_DICT_LOADED("missfam3") AND HAS_MODEL_LOADED(osRopeDummy.ModelName) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) SET_VEHICLE_DOORS_SHUT(vsPlayersCar.VehicleIndex, TRUE) SET_VEHICLE_DOOR_OPEN(vsPlayersCar.VehicleIndex, SC_DOOR_BOOT) SET_VEHICLE_ON_GROUND_PROPERLY(vsPlayersCar.VehicleIndex) ENDIF IF ( bRopeAttached = FALSE ) IF NOT DOES_ENTITY_EXIST(osRopeProp.ObjectIndex) IF HAS_MISSION_OBJECT_BEEN_CREATED(osRopeProp, TRUE) SET_CAN_CLIMB_ON_ENTITY(osRopeProp.ObjectIndex, FALSE) SET_CAN_AUTO_VAULT_ON_ENTITY(osRopeProp.ObjectIndex, FALSE) ENDIF ENDIF IF NOT DOES_ROPE_EXIST(Rope) IF ROPE_ARE_TEXTURES_LOADED() Rope = ADD_ROPE(<<-1017.9850, 660.4285, 147.4662>>, <<0.0, 0.0, 0.0>>, ROPE_MAX_LEN, PHYSICS_ROPE_DEFAULT, -1, 0.5, 0.5, FALSE, TRUE) LOAD_ROPE_DATA(Rope, ROPE_DATA_FILE) ENDIF ENDIF IF DOES_ENTITY_EXIST(osRopeAnchor.ObjectIndex) AND DOES_ROPE_EXIST(rope) IF DOES_ENTITY_HAVE_PHYSICS(osRopeAnchor.ObjectIndex) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) ATTACH_ENTITIES_TO_ROPE(Rope, osRopeAnchor.ObjectIndex, vsPlayersCar.VehicleIndex, osRopeAnchor.vPosition, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vsPlayersCar.VehicleIndex, << 0.0, -2.1, 0.6 >>), 35.0, 0, 0) bRopeAttached = TRUE ENDIF ENDIF ENDIF ENDIF IF NOT DOES_ENTITY_EXIST(osRopeDummy.ObjectIndex) IF HAS_MISSION_OBJECT_BEEN_CREATED(osRopeDummy, TRUE) SET_ENTITY_COLLISION(osRopeDummy.ObjectIndex, TRUE) SET_ENTITY_NO_COLLISION_ENTITY(osRopeDummy.ObjectIndex, PLAYER_PED_ID(), FALSE) SET_ENTITY_NO_COLLISION_ENTITY(vsPlayersCar.VehicleIndex, osRopeDummy.ObjectIndex, FALSE) SET_CAN_CLIMB_ON_ENTITY(osRopeDummy.ObjectIndex, FALSE) SET_CAN_AUTO_VAULT_ON_ENTITY(osRopeDummy.ObjectIndex, FALSE) ENDIF ENDIF WAIT(1000) IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF HAS_ANIM_DICT_LOADED("missfam3") TASK_PLAY_ANIM_ADVANCED(PLAYER_PED_ID(), "missfam3", "argument_outro_michael", << -993.200, 646.188, 139.520 >>, << 0.0, 0.0, -93.240 >>, INSTANT_BLEND_IN, SLOW_BLEND_OUT, -1, AF_EXTRACT_INITIAL_OFFSET | AF_USE_KINEMATIC_PHYSICS | AF_HOLD_LAST_FRAME | AF_TAG_SYNC_OUT) FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID(), TRUE) ENDIF ENDIF IF NOT IS_PED_INJURED(psFranklin.PedIndex) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF NOT IS_PED_IN_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex) SET_PED_INTO_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex, VS_FRONT_RIGHT) ENDIF ENDIF ENDIF STOP_GAMEPLAY_HINT(TRUE) SET_GAMEPLAY_CAM_RELATIVE_PITCH(0) SET_GAMEPLAY_CAM_RELATIVE_HEADING(0) IF IS_SCREEN_FADED_OUT() DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME) ENDIF iStageProgress++ ENDIF ELSE //cutscene not skipped IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "missfam3", "argument_outro_michael") iStageProgress++ ENDIF ENDIF ELSE //if cutscene is skipped, fade out and remain cutscene on faded out screen IF ( bCutsceneSkipped = FALSE ) IF WAS_CUTSCENE_SKIPPED() SET_CUTSCENE_FADE_VALUES(FALSE, FALSE, FALSE, FALSE) bCutsceneSkipped = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Mocap cutscene was skipped by the player.") #ENDIF ENDIF ENDIF ENDIF BREAK CASE 3 IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "missfam3", "argument_outro_michael") DISABLE_ON_FOOT_FIRST_PERSON_VIEW_THIS_UPDATE() DISABLE_CONTROL_ACTION(CAMERA_CONTROL, INPUT_NEXT_CAMERA) IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_HKD") IF CREATE_CONVERSATION_FROM_SPECIFIC_LINE(sFamily3Conversation, "FAM3AUD", "FAM3_HKD", "FAM3_HKD_3", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_HKD", TRUE) ENDIF ENDIF IF GET_ENTITY_ANIM_CURRENT_TIME(PLAYER_PED_ID(), "missfam3", "argument_outro_michael") >= 0.95 CLEAR_PED_TASKS(PLAYER_PED_ID()) SET_PED_STEALTH_MOVEMENT(PLAYER_PED_ID(), FALSE) SET_PED_USING_ACTION_MODE(PLAYER_PED_ID(), FALSE) FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_WALK, FALSE, FAUS_DEFAULT) SIMULATE_PLAYER_INPUT_GAIT(PLAYER_ID(), PEDMOVE_WALK, 500) ELIF GET_ENTITY_ANIM_CURRENT_TIME(PLAYER_PED_ID(), "missfam3", "argument_outro_michael") >= fFirstPersonFlashPhase1 IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_ON_FOOT) = CAM_VIEW_MODE_FIRST_PERSON IF ( bFirstPersonFlashPlayed = FALSE ) ANIMPOSTFX_PLAY("CamPushInNeutral", 0, FALSE) PLAY_SOUND_FRONTEND(-1, "1st_Person_Transition", "PLAYER_SWITCH_CUSTOM_SOUNDSET") bFirstPersonFlashPlayed = TRUE ENDIF ENDIF ENDIF ELSE IF DOES_ENTITY_EXIST(osRopeDummy.ObjectIndex) IF NOT IS_ENTITY_DEAD(osRopeDummy.ObjectIndex) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) SET_ENTITY_COLLISION(osRopeDummy.ObjectIndex, TRUE) SET_ENTITY_NO_COLLISION_ENTITY(osRopeDummy.ObjectIndex, PLAYER_PED_ID(), TRUE) SET_ENTITY_NO_COLLISION_ENTITY(vsPlayersCar.VehicleIndex, osRopeDummy.ObjectIndex, FALSE) ENDIF ENDIF ENDIF IF NOT DOES_ENTITY_EXIST(osBootCollision.ObjectIndex) IF HAS_MISSION_OBJECT_BEEN_CREATED(osBootCollision, TRUE) SET_ENTITY_COLLISION(osBootCollision.ObjectIndex, TRUE) SET_ENTITY_NO_COLLISION_ENTITY(osBootCollision.ObjectIndex, vsPlayersCar.VehicleIndex, FALSE) ENDIF ENDIF //fix for B*2028269 - force the player to look at the truck on cut to first person on foot IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_ON_FOOT) = CAM_VIEW_MODE_FIRST_PERSON SET_ENTITY_HEADING(PLAYER_PED_ID(), 247.8959) SET_GAMEPLAY_CAM_RELATIVE_PITCH(-15.0) SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0) //ANIMPOSTFX_PLAY("SwitchSceneMichael", 0, FALSE) ENDIF SET_MODEL_AS_NO_LONGER_NEEDED(osRopeDummy.ModelName) TRIGGER_MUSIC_EVENT("FAM3_TRUCK_PULL") REPLAY_STOP_EVENT() RETURN TRUE ENDIF ENDIF BREAK ENDSWITCH RETURN FALSE ENDFUNC PROC MANAGE_TENNIS_COACH_DURING_PULL_HOUSE_DOWN() IF DOES_ENTITY_EXIST(psCoach.PedIndex) IF NOT IS_ENTITY_DEAD(psCoach.PedIndex) SWITCH psCoach.iProgress CASE 0 IF NOT IS_ENTITY_PLAYING_ANIM(psCoach.PedIndex, "missfam3", "coach_idle") TASK_PLAY_ANIM(psCoach.PedIndex, "missfam3", "coach_idle", INSTANT_BLEND_IN, INSTANT_BLEND_OUT, -1, AF_LOOPING) ENDIF //PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(psCoach.PedIndex, "FAM3_AAAA", "TENNISCOACH", SPEECH_PARAMS_FORCE_PRELOAD_ONLY_SHOUTED) psCoach.iProgress++ BREAK CASE 1 IF ( bRayfireStarted = TRUE ) IF NOT IS_SYNCHRONIZED_SCENE_RUNNING(iSyncedSceneCoachID) CLEAR_PED_TASKS(psCoach.PedIndex) iSyncedSceneCoachID = CREATE_SYNCHRONIZED_SCENE(<< -1014.525, 654.250, 156.175 >>, << 0.000, 0.000, -103.320 >>) TASK_SYNCHRONIZED_SCENE(psCoach.PedIndex, iSyncedSceneCoachID, "missfam3", "argument_outro_coach", INSTANT_BLEND_IN, INSTANT_BLEND_OUT) SET_SYNCHRONIZED_SCENE_PHASE(iSyncedSceneCoachID, 0.6125) ENDIF psCoach.iProgress++ ENDIF BREAK CASE 2 IF IS_SYNCHRONIZED_SCENE_RUNNING(iSyncedSceneCoachID) /* IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_AAAA_1") //IF NOT IS_AMBIENT_SPEECH_PLAYING(psCoach.PedIndex) //PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(psCoach.PedIndex, "FAM3_AAAA", "TENNISCOACH", SPEECH_PARAMS_FORCE_FRONTEND) PLAY_PRELOADED_SPEECH(psCoach.PedIndex) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Trying to play ped ambient speech FAM3_AAAA.") #ENDIF //ELSE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Playing ped ambient speech FAM3_AAAA.") #ENDIF SET_LABEL_AS_TRIGGERED("FAM3_AAAA_1", TRUE) //ENDIF ENDIF */ IF ( GET_SYNCHRONIZED_SCENE_PHASE(iSyncedSceneCoachID) > 0.95 ) STOP_SYNCHRONIZED_ENTITY_ANIM(psCoach.PedIndex, INSTANT_BLEND_OUT, TRUE) CLEAR_PED_TASKS(psCoach.PedIndex) WARP_PED(psCoach.PedIndex, <<-1021.5886, 663.7698, 155.2747>>, 178.5320, FALSE, FALSE, FALSE) //PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(psCoach.PedIndex, "FAM3_AAAA", "TENNISCOACH", SPEECH_PARAMS_FORCE_PRELOAD_ONLY_SHOUTED) psCoach.iProgress++ ENDIF ENDIF BREAK CASE 3 IF ( iRayfireSequenceProgress >= 2 ) IF NOT IS_SYNCHRONIZED_SCENE_RUNNING(iSyncedSceneCoachID) CLEAR_PED_TASKS(psCoach.PedIndex) iSyncedSceneCoachID = CREATE_SYNCHRONIZED_SCENE(<< -1034.000, 662.100, 156.100 >>, << 0.000, 0.000, -165.960 >>) TASK_SYNCHRONIZED_SCENE(psCoach.PedIndex, iSyncedSceneCoachID, "missfam3", "argument_outro_coach", INSTANT_BLEND_IN, INSTANT_BLEND_OUT) SET_SYNCHRONIZED_SCENE_PHASE(iSyncedSceneCoachID, 0.830) psCoach.iProgress++ ENDIF ENDIF BREAK CASE 4 IF NOT IS_PED_INJURED(psCoach.PedIndex) IF IS_SYNCHRONIZED_SCENE_RUNNING(iSyncedSceneCoachID) /* IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_AAAA_2") IF NOT IS_AMBIENT_SPEECH_PLAYING(psCoach.PedIndex) //PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(psCoach.PedIndex, "FAM3_AAAA", "TENNISCOACH", SPEECH_PARAMS_FORCE_FRONTEND) PLAY_PRELOADED_SPEECH(psCoach.PedIndex) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Trying to play ped ambient speech FAM3_AAAA.") #ENDIF ELSE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Playing ped ambient speech FAM3_AAAA.") #ENDIF SET_LABEL_AS_TRIGGERED("FAM3_AAAA_2", TRUE) ENDIF ENDIF */ IF ( GET_SYNCHRONIZED_SCENE_PHASE(iSyncedSceneCoachID) > 0.98 ) STOP_SYNCHRONIZED_ENTITY_ANIM(psCoach.PedIndex, INSTANT_BLEND_OUT, TRUE) CLEAR_PED_TASKS(psCoach.PedIndex) DELETE_PED(psCoach.PedIndex) psCoach.iProgress++ ENDIF ENDIF ENDIF BREAK ENDSWITCH ENDIF ENDIF ENDPROC PROC MANAGE_PLAYERS_VEHICLE_IN_RAYFIRE_SEQUENCE(INT &iProgress) SWITCH iProgress CASE 0 IF ( bHousePullCompleted = TRUE ) BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(vsPlayersCar.VehicleIndex, 3.0, 3) IF ( iRayfireMapObjectProgress = 8 ) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) TASK_PLAY_LOOK_BEHIND_ANIM(PLAYER_PED_ID(), VS_DRIVER, 5000) TASK_PLAY_LOOK_BEHIND_ANIM(psFranklin.PedIndex, VS_FRONT_RIGHT, 6000) iProgress++ ENDIF ENDIF ENDIF BREAK ENDSWITCH ENDPROC PROC MANAGE_RAYFIRE_MAP_OBJECT(INT &iProgress, BOOL &bStarted, BOOL &bPaused, BOOL &bPrimed, BOOL &bFinished, FLOAT &fPhase) IF DOES_RAYFIRE_MAP_OBJECT_EXIST(riHouseFallRayfire) IF ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire) = RFMO_STATE_ANIMATING ) fPhase = GET_RAYFIRE_MAP_OBJECT_ANIM_PHASE(riHouseFallRayfire) ENDIF ENDIF SWITCH iProgress CASE 0 //priming rayfire map object until it is primed riHouseFallRayfire = GET_RAYFIRE_MAP_OBJECT(<<-1020.50, 663.41, 154.75>>, 50, "DES_StiltHouse") IF DOES_RAYFIRE_MAP_OBJECT_EXIST(riHouseFallRayfire) IF ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire) <> RFMO_STATE_PRIMED ) //rayfire not primed #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Waiting for rayfire map object state to be RFMO_STATE_PRIMED.") #ENDIF IF ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire) <> RFMO_STATE_PRIMING ) //rayfire not priming SET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire, RFMO_STATE_PRIMING) //prime the rayfire #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Rayfire map object state set to RFMO_STATE_PRIMING.") #ENDIF ENDIF ELIF ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire) = RFMO_STATE_PRIMED ) //rayfire is primed, move on #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Rayfire map object state is RFMO_STATE_PRIMED.") #ENDIF bPrimed = TRUE iProgress++ ENDIF ENDIF BREAK CASE 1 //rayfire map object primed, start the animation IF DOES_RAYFIRE_MAP_OBJECT_EXIST(riHouseFallRayfire) IF GET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire) = RFMO_STATE_PRIMED IF ( bStarted = TRUE ) SET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire, RFMO_STATE_START_ANIM) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Rayfire map object state set to RFMO_STATE_START_ANIM.") #ENDIF iProgress++ ENDIF ENDIF ENDIF BREAK CASE 2 //rayfire started animating, set the first pause at 0.120 of animation phase IF DOES_RAYFIRE_MAP_OBJECT_EXIST(riHouseFallRayfire) IF ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire) = RFMO_STATE_ANIMATING ) IF ( bPaused = FALSE ) IF ( GET_RAYFIRE_MAP_OBJECT_ANIM_PHASE(riHouseFallRayfire) > 0.1475 )//0.120 ) SET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire, RFMO_STATE_PAUSE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Rayfire map object state set to RFMO_STATE_PAUSE.") #ENDIF bPaused = TRUE SETTIMERB(0) iProgress++ ENDIF ENDIF ENDIF ENDIF BREAK CASE 3 //first pause in progress, wait until pause flag is set to false IF DOES_RAYFIRE_MAP_OBJECT_EXIST(riHouseFallRayfire) IF ( bPaused = FALSE ) IF ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire) = RFMO_STATE_PAUSE ) SET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire, RFMO_STATE_RESUME) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Rayfire map object state set to RFMO_STATE_RESUME.") #ENDIF iProgress++ ENDIF ENDIF ENDIF BREAK CASE 4 //rayfire resumed animating after first pause, set the second pause at 0.350 of animation phase IF DOES_RAYFIRE_MAP_OBJECT_EXIST(riHouseFallRayfire) IF ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire) = RFMO_STATE_ANIMATING ) IF ( bPaused = FALSE ) IF ( GET_RAYFIRE_MAP_OBJECT_ANIM_PHASE(riHouseFallRayfire) >= 0.433 ) //0.350 ) SET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire, RFMO_STATE_PAUSE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Rayfire map object state set to RFMO_STATE_PAUSE.") #ENDIF bPaused = TRUE SETTIMERB(0) iProgress++ ENDIF ENDIF ENDIF ENDIF BREAK CASE 5 //second pause in progress, wait until pause flag is set to false IF DOES_RAYFIRE_MAP_OBJECT_EXIST(riHouseFallRayfire) IF ( bPaused = FALSE ) IF ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire) = RFMO_STATE_PAUSE ) SET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire, RFMO_STATE_RESUME) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Rayfire map object state set to RFMO_STATE_RESUME.") #ENDIF iProgress++ ENDIF ENDIF ENDIF BREAK CASE 6 //set the ending state of rayfire map object when specific phase is reached or when rayfire cutscene is skipped //keep requesting ptfx assets, this should be in memory already since it was needed for wheel spin dirt REQUEST_PTFX_ASSET() IF DOES_RAYFIRE_MAP_OBJECT_EXIST(riHouseFallRayfire) IF ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire) = RFMO_STATE_ANIMATING ) IF ( GET_RAYFIRE_MAP_OBJECT_ANIM_PHASE(riHouseFallRayfire) > 0.875 ) OR ( bCutsceneSkipped = TRUE ) IF ( bCutsceneSkipped = TRUE ) SET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire, RFMO_STATE_ENDING) ENDIF IF NOT DOES_PARTICLE_FX_LOOPED_EXIST(ptfxDustCloud) IF HAS_PTFX_ASSET_LOADED() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Starting particle fx ent_ray_fam3_dust_settle.") #ENDIF ptfxDustCloud = START_PARTICLE_FX_LOOPED_AT_COORD("ent_ray_fam3_dust_settle", << -1016.0, 642.0, 141.0 >>, << 0.0, 0.0, 0.0 >>) ENDIF ENDIF #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Rayfire map object state set to RFMO_STATE_ENDING.") #ENDIF iProgress++ ENDIF ENDIF ENDIF BREAK CASE 7 //check if end state was reached IF DOES_RAYFIRE_MAP_OBJECT_EXIST(riHouseFallRayfire) IF ( GET_STATE_OF_RAYFIRE_MAP_OBJECT(riHouseFallRayfire) = RFMO_STATE_END ) bFinished = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Rayfire map object state is RFMO_STATE_END.") #ENDIF PLAY_SOUND_FROM_COORD(-1, "FAMILY3_POST_DEBRIS_MASTER", << -1016.0, 642.0, 141.0 >>) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Playing sound FAMILY3_POST_DEBRIS_MASTER.") #ENDIF iProgress++ ENDIF ENDIF BREAK CASE 8 //rayfire map object can only be in end state at this point BREAK ENDSWITCH ENDPROC PROC UPDATE_FORCES(VEHICLE_INDEX VehicleIndex) IF DOES_ENTITY_EXIST(VehicleIndex) IF NOT IS_ENTITY_DEAD(VehicleIndex) IF IS_ENTITY_UPRIGHT(VehicleIndex) AND IS_VEHICLE_ON_ALL_WHEELS(VehicleIndex) VECTOR vForce FLOAT fForceModifier = 0.0 +@ (fForceConverge * 30.0)//CLAMP(0.0 +@ (fForceConverge * 30.0), 0.0, 1.0) INT iTurnValue = ROUND(GET_CONTROL_NORMAL(PLAYER_CONTROL, INPUT_VEH_MOVE_LR) * 255.0) INT iAccelerateValue = ROUND(GET_CONTROL_NORMAL(PLAYER_CONTROL, INPUT_VEH_ACCELERATE) * 255.0) IF IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_BRAKE) OR IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_HANDBRAKE) OR IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_DUCK) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ACCELERATE) iAccelerateValue = 0 ENDIF #IF IS_DEBUG_BUILD IF ( bDrawDebugLinesAndSpheres = TRUE ) DRAW_DEBUG_TEXT_ABOVE_ENTITY(VehicleIndex, GET_STRING_FROM_FLOAT(fForceModifier), 1.5) DRAW_DEBUG_TEXT_ABOVE_ENTITY(vsPlayersCar.VehicleIndex, GET_STRING_FROM_FLOAT(GET_ENTITY_HEADING(vsPlayersCar.VehicleIndex)), 1.25) DRAW_DEBUG_SPHERE(GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(VehicleIndex, vForceBackOffset), 0.3, 0, 0, 255) ENDIF #ENDIF IF ( iAccelerateValue >= 250 ) IF GET_ENTITY_HEADING(VehicleIndex) >= 287.0 #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Heading more than 290.") #ENDIF vForce = << - ABSF(fSideForceValue * fForceModifier), 0.0, 0.0 >> APPLY_FORCE_TO_ENTITY(VehicleIndex, APPLY_TYPE_IMPULSE, vForce, vForceBackOffset, 0, TRUE, TRUE, FALSE) iApplyForceTimer = 0 ENDIF IF ( iTurnValue >=225 ) IF GET_ENTITY_HEADING(VehicleIndex) > 265.0 vForce = << - ABSF(fSideForceValue * fForceModifier), 0.0, 0.0 >> APPLY_FORCE_TO_ENTITY(VehicleIndex, APPLY_TYPE_IMPULSE, vForce, vForceBackOffset, 0, TRUE, TRUE, FALSE) iApplyForceTimer = 0 ENDIF ELIF ( iTurnValue <= -225 ) IF GET_ENTITY_HEADING(VehicleIndex) < 285.0 vForce = << ABSF(fSideForceValue * fForceModifier), 0.0, 0.0 >> APPLY_FORCE_TO_ENTITY(VehicleIndex, APPLY_TYPE_IMPULSE, vForce, vForceBackOffset, 0, TRUE, TRUE, FALSE) iApplyForceTimer = 0 ENDIF ENDIF IF ( iTurnValue = 0) IF ( iApplyForceTimer = 0 ) iApplyForceTimer = GET_GAME_TIMER() SWITCH GET_RANDOM_INT_IN_RANGE(0, 2) CASE 0 iApplyForceSide = 1 BREAK CASE 1 iApplyForceSide = -1 BREAK ENDSWITCH ELSE IF GET_GAME_TIMER() - iApplyForceTimer < 1000 vForce = << ABSF(fSideForceValue * fForceModifier) * iApplyForceSide, 0.0, 0.0 >> APPLY_FORCE_TO_ENTITY(VehicleIndex, APPLY_TYPE_IMPULSE, vForce, vForceBackOffset, 0, TRUE, TRUE, FALSE) iApplyForceTimer = 0 ENDIF ENDIF ENDIF vForce = << 0.0, 0.0, - ABSF(fDownForceValue * fForceModifier) >> APPLY_FORCE_TO_ENTITY(VehicleIndex, APPLY_TYPE_IMPULSE, vForce, vForceBackOffset, 0, TRUE, TRUE, FALSE) ELSE iApplyForceTimer = 0 ENDIF ENDIF ENDIF ENDIF ENDPROC FUNC BOOL IS_PULL_COMPLETED(BOOL &bPullInProgress, FLOAT fBurnoutTime, VECTOR vPullStartPosition, FLOAT fPullDistance) VECTOR vPlayerCarPosition = GET_ENTITY_COORDS(vsPlayersCar.VehicleIndex) INT iAccelerateValue = ROUND(GET_CONTROL_NORMAL(PLAYER_CONTROL, INPUT_VEH_ACCELERATE) * 255.0) FLOAT fDistanceFromStart = GET_DISTANCE_BETWEEN_COORDS(<< vPullStartPosition.X, vPullStartPosition.Y, vPlayerCarPosition.Z >>, vPlayerCarPosition) IF IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_BRAKE) OR IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_HANDBRAKE) OR IS_DISABLED_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_DUCK) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ACCELERATE) iAccelerateValue = 0 ENDIF #IF IS_DEBUG_BUILD IF ( bDrawDebugLinesAndSpheres = TRUE ) DRAW_DEBUG_TEXT_ABOVE_ENTITY(vsPlayersCar.VehicleIndex, GET_STRING_FROM_FLOAT(fDistanceFromStart), 0.5) ENDIF #ENDIF IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF ( IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_ACCELERATE) AND iAccelerateValue <> 0 ) OR ( iAccelerateValue >= 250 ) IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("FAM3_HPULL") CLEAR_HELP() ENDIF IF ( bPullInProgress = FALSE ) SETTIMERA(0) //used to shake the pad SHAKE_GAMEPLAY_CAM("SKY_DIVING_SHAKE", 0.0) bPullInProgress = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Player started pulling.") #ENDIF ENDIF ELSE IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_HPULL") IF NOT IS_HELP_MESSAGE_BEING_DISPLAYED() PRINT_HELP_FOREVER("FAM3_HPULL") SET_LABEL_AS_TRIGGERED("FAM3_HPULL", TRUE) ENDIF ENDIF IF ( bPullInProgress = TRUE ) bPullInProgress = FALSE IF ( bPTFXStarted = TRUE ) IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxRearLeftWheel) SET_PARTICLE_FX_LOOPED_EVOLUTION(ptfxRearLeftWheel, "wheelspin", fWheelspinValue) STOP_PARTICLE_FX_LOOPED(ptfxRearLeftWheel) ENDIF IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxRearRightWheel) SET_PARTICLE_FX_LOOPED_EVOLUTION(ptfxRearRightWheel, "wheelspin", fWheelspinValue) STOP_PARTICLE_FX_LOOPED(ptfxRearRightWheel) ENDIF bPTFXStarted = FALSE ENDIF STOP_GAMEPLAY_CAM_SHAKING() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Player stopped pulling.") #ENDIF ENDIF ENDIF IF ( bPullInProgress = TRUE ) //temporary shake value, this needs a proper value setting SET_CONTROL_SHAKE(PLAYER_CONTROL, 100, GET_MINIMUM_INT(FLOOR(TO_FLOAT(TIMERA()) / 12.5), 255)) IF ( bPTFXStarted = FALSE ) IF HAS_PTFX_ASSET_LOADED() IF NOT DOES_PARTICLE_FX_LOOPED_EXIST(ptfxRearLeftWheel) AND NOT DOES_PARTICLE_FX_LOOPED_EXIST(ptfxRearRightWheel) ptfxRearLeftWheel = START_PARTICLE_FX_LOOPED_ON_ENTITY("scr_fam3_wheelspin_dirt", vsPlayersCar.VehicleIndex, vRearLeftWheelOffset, vPTFXRotation) ptfxRearRightWheel = START_PARTICLE_FX_LOOPED_ON_ENTITY("scr_fam3_wheelspin_dirt", vsPlayersCar.VehicleIndex, vRearRightWheelOffset, vPTFXRotation) bPTFXStarted = TRUE //play rope straining sound PLAY_SOUND_FROM_ENTITY(-1, "FAMILY3_CABLE_STRAIN_MASTER", vsPlayersCar.VehicleIndex) ENDIF ENDIF ELIF ( bPTFXStarted = TRUE ) IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxRearLeftWheel) AND DOES_PARTICLE_FX_LOOPED_EXIST(ptfxRearRightWheel) SET_PARTICLE_FX_LOOPED_EVOLUTION(ptfxRearLeftWheel, "wheelspin", fWheelspinValue) SET_PARTICLE_FX_LOOPED_EVOLUTION(ptfxRearRightWheel, "wheelspin", fWheelspinValue) ENDIF ENDIF #IF IS_DEBUG_BUILD IF ( bPrintDebugOutput = TRUE ) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Pulling time is ", TIMERA()) ENDIF #ENDIF ENDIF IF ( bPullInProgress = TRUE ) IF ( TIMERA() > fBurnoutTime ) SET_VEHICLE_BURNOUT(vsPlayersCar.VehicleIndex, FALSE) ENDIF IF ( TIMERA() > fBurnoutTime AND fDistanceFromStart > fPullDistance ) OR ( fDistanceFromStart > fPullDistance * 2 ) OR ( TIMERA() > fBurnoutTime + 1500) SET_VEHICLE_BURNOUT(vsPlayersCar.VehicleIndex, FALSE) SET_VEHICLE_FORWARD_SPEED(vsPlayersCar.VehicleIndex, 2.0) IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxRearLeftWheel) AND DOES_PARTICLE_FX_LOOPED_EXIST(ptfxRearRightWheel) fWheelspinValue = 0.0 SET_PARTICLE_FX_LOOPED_EVOLUTION(ptfxRearLeftWheel, "wheelspin", fWheelspinValue) SET_PARTICLE_FX_LOOPED_EVOLUTION(ptfxRearRightWheel, "wheelspin", fWheelspinValue) STOP_PARTICLE_FX_LOOPED(ptfxRearLeftWheel) STOP_PARTICLE_FX_LOOPED(ptfxRearRightWheel) bPTFXStarted = FALSE ENDIF bPullInProgress = FALSE RETURN TRUE ENDIF ENDIF //update camera shake values and ptfx evolution IF ( bPullInProgress = TRUE ) fCameraShakeAmplitude = CLAMP(fCameraShakeAmplitude +@0.2, 0.0, 0.3) fWheelspinValue = CLAMP(fWheelspinValue +@0.25, 0.0, 1.0) ELIF ( bPullInProgress = FALSE ) fCameraShakeAmplitude = CLAMP(fCameraShakeAmplitude -@0.4, 0.0, 0.3) fWheelspinValue = 0.0 ENDIF SET_AUDIO_SCENE_VARIABLE("FAMILY_3_PULL_DOWN_HOUSE_SCENE", "apply", fWheelspinValue) #IF IS_DEBUG_BUILD DRAW_DEBUG_SPHERE(<< vPullStartPosition.X, vPullStartPosition.Y, vPlayerCarPosition.Z >>, 0.2, 0, 0, 255) #ENDIF ENDIF RETURN FALSE ENDFUNC PROC MANAGE_CAMERA_IN_RAYFIRE_SEQUENCE(INT &iProgress) SWITCH iProgress CASE 0 IF ( bHousePullCompleted = TRUE ) IF ( fRayfirePhase >= 0.560 ) IF NOT DOES_CAM_EXIST(ScriptedCamera) ScriptedCamera = CREATE_CAMERA(CAMTYPE_SCRIPTED, TRUE) SET_CAM_PARAMS(ScriptedCamera, <<-1009.953247,633.596191,140.483414>>,<<22.945997,-0.125925,21.448517>>,43.510220) SET_CAM_PARAMS(ScriptedCamera, <<-1010.459290,633.923157,140.598160>>,<<13.298273,-0.125925,21.364548>>,43.510220, 5000, GRAPH_TYPE_LINEAR, GRAPH_TYPE_LINEAR) SHAKE_CAM(ScriptedCamera, "MEDIUM_EXPLOSION_SHAKE", 0.1) STOP_GAMEPLAY_HINT(TRUE) SET_GAMEPLAY_CAM_RELATIVE_PITCH(0) SET_GAMEPLAY_CAM_RELATIVE_HEADING(0) DISPLAY_HUD(FALSE) DISPLAY_RADAR(FALSE) RENDER_SCRIPT_CAMS(TRUE, FALSE) iProgress++ ENDIF ENDIF ENDIF BREAK CASE 1 IF DOES_ROPE_EXIST(Rope) AND DOES_ENTITY_EXIST(osRopeAnchor.ObjectIndex) DETACH_ROPE_FROM_ENTITY(Rope, osRopeAnchor.ObjectIndex) DETACH_ROPE_FROM_ENTITY(Rope, vsPlayersCar.VehicleIndex) DELETE_OBJECT(osRopeAnchor.ObjectIndex) DELETE_ROPE(Rope) ROPE_UNLOAD_TEXTURES() bRopeAttached = FALSE ENDIF IF DOES_ENTITY_EXIST(osRopeProp.ObjectIndex) DELETE_OBJECT(osRopeProp.ObjectIndex) ENDIF IF ( fRayfirePhase >= 0.683 ) IF DOES_CAM_EXIST(ScriptedCamera) SET_CAM_PARAMS(ScriptedCamera, <<-1009.381226,658.445251,152.820923>>,<<-39.496250,-0.125924,138.363358>>,43.510220) SET_CAM_PARAMS(ScriptedCamera, <<-1010.491943,655.028503,150.779419>>,<<-30.668579,-0.125923,143.799835>>,43.510220, 4000, GRAPH_TYPE_LINEAR, GRAPH_TYPE_LINEAR) SHAKE_CAM(ScriptedCamera, "HAND_SHAKE", 0.25) STOP_GAMEPLAY_HINT(TRUE) SET_GAMEPLAY_CAM_RELATIVE_PITCH(0) SET_GAMEPLAY_CAM_RELATIVE_HEADING(0) iProgress++ ENDIF ENDIF BREAK CASE 2 IF ( fRayfirePhase >= 0.730 )//0.771 ) IF DOES_CAM_EXIST(ScriptedCamera) SET_CAM_PARAMS(ScriptedCamera, <<-1029.067017,622.262329,125.477417>>,<<45.378109,-0.125924,1.607233>>,50.256042) SET_CAM_PARAMS(ScriptedCamera, <<-1029.405396,621.632324,126.455505>>,<<40.449352,-0.078049,1.812782>>,50.256042, 5000, GRAPH_TYPE_LINEAR, GRAPH_TYPE_LINEAR) SHAKE_CAM(ScriptedCamera, "HAND_SHAKE", 0.25) STOP_GAMEPLAY_HINT(TRUE) SET_GAMEPLAY_CAM_RELATIVE_PITCH(0) SET_GAMEPLAY_CAM_RELATIVE_HEADING(0) iProgress++ ENDIF ENDIF BREAK CASE 3 IF ( iRayfireMapObjectProgress = 8 ) //rayfire map object is in end state at this point in progress SET_CAM_PARAMS(ScriptedCamera, <<-1013.909851,632.159729,140.131577>>,<<22.288286,-0.125923,0.959580>>,50.256042) SET_CAM_PARAMS(ScriptedCamera, <<-1014.135071,633.341919,140.977386>>,<<20.564297,-0.125923,1.779718>>,50.256042, 9000, GRAPH_TYPE_LINEAR, GRAPH_TYPE_LINEAR) SHAKE_CAM(ScriptedCamera, "HAND_SHAKE", 0.25) STOP_GAMEPLAY_HINT(TRUE) SET_GAMEPLAY_CAM_RELATIVE_PITCH(0) SET_GAMEPLAY_CAM_RELATIVE_HEADING(0) psMichael.iTimer = GET_GAME_TIMER() IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) bShutVehicleBoot = TRUE SET_VEHICLE_DOORS_SHUT(vsPlayersCar.VehicleIndex, TRUE) SET_ENTITY_COORDS(vsPlayersCar.VehicleIndex, <<-994.4631, 643.6545, 138.8214>>) SET_ENTITY_HEADING(vsPlayersCar.VehicleIndex, 277.0580) SET_VEHICLE_ON_GROUND_PROPERLY(vsPlayersCar.VehicleIndex) ENDIF iProgress++ ENDIF BREAK CASE 4 IF HAS_TIME_PASSED(5500, psMichael.iTimer) IF DOES_CAM_EXIST(ScriptedCamera) SET_CAM_PARAMS(ScriptedCamera,<<-991.098938,642.266174,140.002777>>,<<15.862850,-0.000000,67.177223>>,50.000000) SHAKE_CAM(ScriptedCamera, "HAND_SHAKE", 0.25) STOP_GAMEPLAY_HINT(TRUE) psMichael.iTimer = GET_GAME_TIMER() iProgress++ ENDIF ENDIF BREAK CASE 5 IF HAS_TIME_PASSED(500, psMichael.iTimer) IF DOES_CAM_EXIST(ScriptedCamera) DISPLAY_HUD(TRUE) DISPLAY_RADAR(TRUE) STOP_RENDERING_SCRIPT_CAMS_USING_CATCH_UP() DISABLE_FIRST_PERSON_FLASH_EFFECT_THIS_UPDATE() DESTROY_CAM(ScriptedCamera) DESTROY_ALL_CAMS() ENDIF iProgress++ ENDIF BREAK ENDSWITCH ENDPROC FUNC BOOL IS_RAYFIRE_SEQUENCE_AND_CUTSCENE_COMPLETED(INT &iProgress) IF ( bHousePullCompleted = FALSE ) UPDATE_FORCES(vsPlayersCar.VehicleIndex) ENDIF REPLAY_DISABLE_CAMERA_MOVEMENT_THIS_FRAME() SWITCH iProgress CASE 0 bRandomConversationAllowed = TRUE LOAD_STREAM("FAMILY3_DECK_PULL_01_MASTER") SET_VEHICLE_BURNOUT(vsPlayersCar.VehicleIndex, TRUE) vPullStartVehiclePosition = vsPlayersCar.vPosition IF IS_PULL_COMPLETED(bHousePullStarted, 3500, vPullStartVehiclePosition, 0.75) AND LOAD_STREAM("FAMILY3_DECK_PULL_01_MASTER") IF ( iRayfireMapObjectProgress = 1 ) //rayfire map object primed CLEAR_HELP() START_AUDIO_SCENE("FAMILY_3_RAYFIRE") PLAY_STREAM_FROM_POSITION(<< -1020.98, 657.72, 154.51 >>) SHAKE_GAMEPLAY_CAM("SMALL_EXPLOSION_SHAKE", 0.25) SET_LABEL_AS_TRIGGERED("FAM3_HPULL", FALSE) REPLAY_START_EVENT(REPLAY_IMPORTANCE_HIGHEST) bRayfireStarted = TRUE iProgress++ ENDIF ENDIF BREAK CASE 1 IF ( bRayfireStarted ) IF ( bRayfirePaused = FALSE ) bRandomConversationAllowed = FALSE SET_VEHICLE_BURNOUT(vsPlayersCar.VehicleIndex, TRUE) vPullStartVehiclePosition = GET_ENTITY_COORDS(vsPlayersCar.VehicleIndex) ELIF ( bRayfirePaused = TRUE ) bRandomConversationAllowed = TRUE LOAD_STREAM("FAMILY3_DECK_PULL_02_MASTER") IF IS_AUDIO_SCENE_ACTIVE("FAMILY_3_RAYFIRE") STOP_AUDIO_SCENE("FAMILY_3_RAYFIRE") ENDIF SET_VEHICLE_BURNOUT(vsPlayersCar.VehicleIndex, TRUE) IF IS_PULL_COMPLETED(bHousePullStarted, 4000, vPullStartVehiclePosition, 0.75) AND LOAD_STREAM("FAMILY3_DECK_PULL_02_MASTER") CLEAR_HELP() START_AUDIO_SCENE("FAMILY_3_RAYFIRE") PLAY_STREAM_FROM_POSITION(<< -1020.98, 657.72, 154.51 >>) SHAKE_GAMEPLAY_CAM("MEDIUM_EXPLOSION_SHAKE", 0.15) SET_LABEL_AS_TRIGGERED("FAM3_HPULL", FALSE) bRayfirePaused = FALSE iProgress++ ENDIF ENDIF ENDIF BREAK CASE 2 IF ( bRayfireStarted ) IF ( bRayfirePaused = FALSE ) bRandomConversationAllowed = FALSE SET_VEHICLE_BURNOUT(vsPlayersCar.VehicleIndex, TRUE) vPullStartVehiclePosition = GET_ENTITY_COORDS(vsPlayersCar.VehicleIndex) ELIF ( bRayfirePaused = TRUE ) SET_VEHICLE_BURNOUT(vsPlayersCar.VehicleIndex, TRUE) bRandomConversationAllowed = TRUE LOAD_STREAM("FAMILY3_DECK_PULL_03_MASTER") PREPARE_MUSIC_EVENT("FAM3_HOUSE_COLLAPSE") IF IS_AUDIO_SCENE_ACTIVE("FAMILY_3_RAYFIRE") STOP_AUDIO_SCENE("FAMILY_3_RAYFIRE") ENDIF IF IS_PULL_COMPLETED(bHousePullStarted, 4500, vPullStartVehiclePosition, 0.75) AND LOAD_STREAM("FAMILY3_DECK_PULL_03_MASTER") AND PREPARE_MUSIC_EVENT("FAM3_HOUSE_COLLAPSE") //Start the multihead screen fade SET_MULTIHEAD_SAFE(TRUE,FALSE) CLEAR_HELP() SET_VEHICLE_RADIO_ENABLED(vsPlayersCar.VehicleIndex, FALSE) START_AUDIO_SCENE("FAMILY_3_RAYFIRE") TRIGGER_MUSIC_EVENT("FAM3_HOUSE_COLLAPSE") PLAY_STREAM_FROM_POSITION(<< -1020.98, 657.72, 154.51 >>) SHAKE_GAMEPLAY_CAM("MEDIUM_EXPLOSION_SHAKE", 0.25) REPLAY_RECORD_BACK_FOR_TIME(3, 0, REPLAY_IMPORTANCE_HIGH) bRayfirePaused = FALSE bHousePullStarted = FALSE bHousePullCompleted = TRUE iProgress++ ENDIF ENDIF ENDIF BREAK CASE 3 //rayfire cutscene IF ( bRayfireStarted ) IF ( bRayfirePaused = FALSE ) bRandomConversationAllowed = FALSE IF ( iRayfireMapObjectProgress = 8 ) //rayfire map object is in end state at this point in progress bRandomConversationAllowed = TRUE IF NOT DOES_CAM_EXIST(ScriptedCamera) IF IS_AUDIO_SCENE_ACTIVE("FAMILY_3_RAYFIRE") STOP_AUDIO_SCENE("FAMILY_3_RAYFIRE") ENDIF IF ( bCutsceneSkipped = TRUE ) DO_SAFE_SCREEN_FADE_IN(DEFAULT_FADE_TIME) ENDIF //Stop the multihead screen fade SET_MULTIHEAD_SAFE(FALSE,FALSE) SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) REPLAY_STOP_EVENT() RETURN TRUE ENDIF ELSE IF ( bCutsceneSkipped = FALSE ) IF DOES_CAM_EXIST(ScriptedCamera) IF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Rayfire cutscene is being skipped by the player.") #ENDIF DO_SAFE_SCREEN_FADE_OUT(DEFAULT_FADE_TIME) IF ( iRayfireMapObjectProgress < 6 ) iRayfireMapObjectProgress = 6 //send the rayfire map object to the progress case that ends it ENDIF IF DOES_ROPE_EXIST(Rope) AND DOES_ENTITY_EXIST(osRopeAnchor.ObjectIndex) DETACH_ROPE_FROM_ENTITY(Rope, osRopeAnchor.ObjectIndex) DETACH_ROPE_FROM_ENTITY(Rope, vsPlayersCar.VehicleIndex) DELETE_OBJECT(osRopeAnchor.ObjectIndex) DELETE_ROPE(Rope) ROPE_UNLOAD_TEXTURES() bRopeAttached = FALSE ENDIF IF DOES_ENTITY_EXIST(osRopeProp.ObjectIndex) DELETE_OBJECT(osRopeProp.ObjectIndex) ENDIF IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) bShutVehicleBoot = TRUE SET_VEHICLE_DOORS_SHUT(vsPlayersCar.VehicleIndex, TRUE) SET_ENTITY_COORDS(vsPlayersCar.VehicleIndex, <<-994.4631, 643.6545, 138.8214>>) SET_ENTITY_HEADING(vsPlayersCar.VehicleIndex, 277.0580) SET_VEHICLE_ON_GROUND_PROPERLY(vsPlayersCar.VehicleIndex) ENDIF IF NOT IS_PED_INJURED(PLAYER_PED_ID()) CLEAR_PED_TASKS(PLAYER_PED_ID()) ENDIF IF NOT IS_PED_INJURED(psFranklin.PedIndex) CLEAR_PED_TASKS(psFranklin.PedIndex) ENDIF //Stop the multihead screen fade SET_MULTIHEAD_SAFE(FALSE,FALSE) //destroy scripted camera due to rayfire cutscene skip IF DOES_CAM_EXIST(ScriptedCamera) STOP_GAMEPLAY_HINT(TRUE) SET_GAMEPLAY_CAM_RELATIVE_PITCH(0) SET_GAMEPLAY_CAM_RELATIVE_HEADING(0) RENDER_SCRIPT_CAMS(FALSE, FALSE) DESTROY_CAM(ScriptedCamera) DESTROY_ALL_CAMS() DISPLAY_HUD(TRUE) DISPLAY_RADAR(TRUE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Destroy scripted camera due to rayfire cutscene skip.") #ENDIF ENDIF STOP_STREAM() bCutsceneSkipped = TRUE ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF BREAK ENDSWITCH RETURN FALSE ENDFUNC PROC MANAGE_CONVERSATIONS_DURING_PULL_HOUSE_DOWN(BOOL bConversationAllowed, BOOL bPlayerPulling, INT iRayfireProgress, INT &iIdleTimer, INT &iPullTimer) IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_PULLS") IF IS_PED_SITTING_IN_THIS_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) AND IS_PED_SITTING_IN_THIS_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_PULLS", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_PULLS", TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF IF ( bConversationAllowed = TRUE ) SWITCH iRayfireProgress CASE 1 IF ( bRayfirePaused = TRUE) IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_PULLC1") IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_PULLC1", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_PULLC1", TRUE) iIdleTimer = GET_GAME_TIMER() iPullTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF BREAK CASE 2 IF ( bRayfirePaused = TRUE) IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_PULLC2") IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_PULLC2", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_PULLC2", TRUE) iIdleTimer = GET_GAME_TIMER() iPullTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF BREAK ENDSWITCH IF ( bPlayerPulling = FALSE ) IF HAS_TIME_PASSED(8000, iIdleTimer) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_PULLI", CONV_PRIORITY_MEDIUM) iIdleTimer = GET_GAME_TIMER() ENDIF ENDIF ELSE IF IS_THIS_CONVERSATION_PLAYING("FAM3_PULLS") iIdleTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF iPullTimer = GET_GAME_TIMER() ELSE iIdleTimer = GET_GAME_TIMER() IF HAS_TIME_PASSED(3000, iPullTimer) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_PULLE", CONV_PRIORITY_MEDIUM) iPullTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF ENDIF ENDIF ELSE iIdleTimer = GET_GAME_TIMER() iPullTimer = GET_GAME_TIMER() ENDIF IF ( bHousePullCompleted = TRUE ) IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_PULLC3") IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_PULLC3", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_PULLC3", TRUE) ENDIF ENDIF ENDIF IF ( bConversationAllowed = TRUE ) IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_DOWN") AND NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_DOWNA") IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF ( iRayfireMapObjectProgress = 8 ) SWITCH GET_PLAYER_CHARACTER_AT_MISSION_START() CASE CHAR_MICHAEL //FAM3_DOWN IF CREATE_CONVERSATION_FROM_SPECIFIC_LINE(sFamily3Conversation, "FAM3AUD", "FAM3_DOWN", "FAM3_DOWN_1", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_DOWN", TRUE) ENDIF BREAK CASE CHAR_FRANKLIN //FAM3_DOWNA IF CREATE_CONVERSATION_FROM_SPECIFIC_LINE(sFamily3Conversation, "FAM3AUD", "FAM3_DOWNA", "FAM3_DOWNA_1", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_DOWNA", TRUE) ENDIF BREAK ENDSWITCH ENDIF ENDIF ENDIF ENDIF ENDIF ENDPROC PROC MANAGE_FRANKLIN_IN_VEHICLE(PED_INDEX PedIndex, VEHICLE_INDEX VehicleIndex, PED_STRUCT &ped, BOOL bPullInProgress) IF DOES_ENTITY_EXIST(PedIndex) AND NOT IS_ENTITY_DEAD(PedIndex) IF DOES_ENTITY_EXIST(VehicleIndex) AND NOT IS_ENTITY_DEAD(VehicleIndex) #IF IS_DEBUG_BUILD IF ( bDrawDebugStates = TRUE ) DRAW_DEBUG_TEXT_ABOVE_ENTITY(PedIndex, GET_STRING_FROM_INT(ped.iProgress), 0.0) ENDIF #ENDIF SWITCH ped.iProgress CASE 0 IF IS_PED_IN_VEHICLE(PedIndex, VehicleIndex) AND IS_PED_IN_VEHICLE(PLAYER_PED_ID(), VehicleIndex) REQUEST_ANIM_DICT("missfam3") IF HAS_ANIM_DICT_LOADED("missfam3") SEQUENCE_INDEX SequenceIndex OPEN_SEQUENCE_TASK(SequenceIndex) TASK_PLAY_ANIM(NULL, "missfam3", "react_incar_brace_enter_f", SLOW_BLEND_IN, INSTANT_BLEND_OUT, -1, AF_UPPERBODY) TASK_PLAY_ANIM(NULL, "missfam3", "react_incar_brace_loop_f", INSTANT_BLEND_IN, SLOW_BLEND_OUT, -1, AF_UPPERBODY | AF_LOOPING) CLOSE_SEQUENCE_TASK(SequenceIndex) TASK_PERFORM_SEQUENCE(PedIndex, SequenceIndex) CLEAR_SEQUENCE_TASK(SequenceIndex) ped.bHasTask = FALSE ped.iProgress = 1 ENDIF ENDIF BREAK CASE 1 //brace loop IF ( ped.bHasTask = FALSE ) IF NOT IS_ENTITY_PLAYING_ANIM(PedIndex, "missfam3", "react_incar_brace_loop_f") AND GET_SCRIPT_TASK_STATUS(PedIndex, SCRIPT_TASK_PERFORM_SEQUENCE) != PERFORMING_TASK TASK_PLAY_ANIM(PedIndex, "missfam3", "react_incar_brace_loop_f", SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_UPPERBODY | AF_LOOPING) ENDIF ped.bHasTask = TRUE ENDIF IF ( bPullInProgress = TRUE ) ped.bHasTask = FALSE ped.iProgress = 2 ELSE IF ( iRayfireSequenceProgress >= 3) ped.bHasTask = FALSE ped.iProgress = 4 ENDIF ENDIF BREAK CASE 2 //bump loop IF ( ped.bHasTask = FALSE ) IF NOT IS_ENTITY_PLAYING_ANIM(PedIndex, "missfam3", "react_incar_bumps_loop_f") TASK_PLAY_ANIM(PedIndex, "missfam3", "react_incar_bumps_loop_f", SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_UPPERBODY | AF_LOOPING) ENDIF ped.iTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(2000, 3000) ped.bHasTask = TRUE ENDIF IF ( bPullInProgress = TRUE ) IF GET_GAME_TIMER() - ped.iTimer > 0 ped.bHasTask = FALSE ped.iProgress = 3 ENDIF ELSE ped.bHasTask = FALSE ped.iProgress = 1 ENDIF BREAK CASE 3 IF ( ped.bHasTask = FALSE ) TASK_PLAY_ANIM(PedIndex, "missfam3", "incar_lookbehind_idle_passenger", SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_UPPERBODY | AF_LOOPING) ped.iTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(1000, 1750) ped.bHasTask = TRUE ENDIF IF ( ped.bHasTask = TRUE ) IF GET_GAME_TIMER() - ped.iTimer > 0 IF IS_ENTITY_PLAYING_ANIM(PedIndex, "missfam3", "incar_lookbehind_idle_passenger") IF ( bPullInProgress = TRUE ) ped.bHasTask = FALSE ped.iProgress = 2 ELSE ped.bHasTask = FALSE ped.iProgress = 1 ENDIF ENDIF ENDIF ENDIF BREAK CASE 4 //end brace pose IF ( ped.bHasTask = FALSE ) IF NOT IS_ENTITY_PLAYING_ANIM(PedIndex, "missfam3", "react_incar_brace_exit_f") TASK_PLAY_ANIM(PedIndex, "missfam3", "react_incar_brace_exit_f", SLOW_BLEND_IN, SLOW_BLEND_OUT, -1, AF_UPPERBODY) ENDIF ped.bHasTask = TRUE ENDIF IF ( bHousePullCompleted = TRUE ) ped.bHasTask = FALSE ped.iProgress++ ENDIF BREAK CASE 5 IF ( ped.bHasTask = FALSE ) TASK_PLAY_LOOK_BEHIND_ANIM(PLAYER_PED_ID(), VS_DRIVER, 10000) TASK_PLAY_LOOK_BEHIND_ANIM(psFranklin.PedIndex, VS_FRONT_RIGHT, 10500) ped.bHasTask = TRUE ENDIF BREAK ENDSWITCH ENDIF ENDIF ENDPROC PROC MANAGE_HINT_CAMERA(VECTOR vHintCoordinate) IF IS_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_LOOK_LR) OR IS_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_LOOK_UP) IF IS_GAMEPLAY_HINT_ACTIVE() bGameplayHintTimer = GET_GAME_TIMER() STOP_GAMEPLAY_HINT() ENDIF ELSE IF NOT IS_GAMEPLAY_HINT_ACTIVE() IF ( bGameplayHintTimer != 0 ) IF HAS_TIME_PASSED(1000, bGameplayHintTimer) SET_GAMEPLAY_COORD_HINT(vHintCoordinate, -1, 8000, DEFAULT_INTERP_OUT_TIME, HINTTYPE_FAMILY3_HOUSE_VEHICLE) ENDIF ENDIF ENDIF ENDIF ENDPROC PROC DISABLE_CINEMATIC_BONNET_CAMERA_FOR_LOOK_BEHIND_ANIMATION() DISABLE_FIRST_PERSON_FLASH_EFFECT_THIS_UPDATE() IF IS_PED_SITTING_IN_THIS_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) IF IS_ENTITY_PLAYING_LOOK_BEHIND_ANIM(PLAYER_PED_ID()) DISABLE_CONTROL_ACTION(CAMERA_CONTROL, INPUT_NEXT_CAMERA) IF ( bResetFirstPersonCamera = TRUE ) IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_IN_VEHICLE) = CAM_VIEW_MODE_FIRST_PERSON SET_GAMEPLAY_CAM_RELATIVE_PITCH() SET_GAMEPLAY_CAM_RELATIVE_HEADING() ENDIF bResetFirstPersonCamera = FALSE ENDIF IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_IN_VEHICLE) = CAM_VIEW_MODE_FIRST_PERSON IF ( bFirstPersonFlashPlayed = FALSE ) DISABLE_CINEMATIC_BONNET_CAMERA_THIS_UPDATE() DISABLE_FIRST_PERSON_FLASH_EFFECT_THIS_UPDATE() IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "missfam3", "incar_lookbehind_exit_driver") IF GET_ENTITY_ANIM_CURRENT_TIME(PLAYER_PED_ID(), "missfam3", "incar_lookbehind_exit_driver") >= fFirstPersonFlashPhase2 IF iFirstPersonFlashTimer = 0 ANIMPOSTFX_PLAY("CamPushInNeutral", 0, FALSE) PLAY_SOUND_FRONTEND(-1, "1st_Person_Transition", "PLAYER_SWITCH_CUSTOM_SOUNDSET") iFirstPersonFlashTimer = GET_GAME_TIMER() ELSE IF HAS_TIME_PASSED(iFirstPersonFlashTime, iFirstPersonFlashTimer) bResetFirstPersonCamera = TRUE bFirstPersonFlashPlayed = TRUE ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDPROC FUNC BOOL IS_MISSION_STAGE_PULL_HOUSE_DOWN_COMPLETED(INT &iStageProgress) SET_BIT(sLocatesData.iLocatesBitSet, BS_DONT_DO_J_SKIP) REQUEST_SCRIPT_AUDIO_BANK("FAMILY3_1") MANAGE_TENNIS_COACH_DURING_PULL_HOUSE_DOWN() MANAGE_FRANKLIN_IN_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex, psFranklin, bHousePullStarted) MANAGE_RAYFIRE_MAP_OBJECT(iRayfireMapObjectProgress, bRayfireStarted, bRayfirePaused, bRayfirePrimed, bRayfireFinished, fRayfirePhase) MANAGE_CONVERSATIONS_DURING_PULL_HOUSE_DOWN(bRandomConversationAllowed, bHousePullStarted, iRayfireSequenceProgress, iConversationIdleTimer, psFranklin.iConversationTimer) DISABLE_CINEMATIC_BONNET_CAMERA_FOR_LOOK_BEHIND_ANIMATION() IF IS_PED_SITTING_IN_THIS_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) DISABLE_SELECTOR_THIS_FRAME() DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_EXIT) //block most of the vehicle inputs 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_AIM) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ATTACK) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ATTACK2) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SELECT_WEAPON) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_SELECT_NEXT_WEAPON) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_SELECT_PREV_WEAPON) ENDIF IF ( bShutVehicleBoot = FALSE ) IF DOES_ENTITY_EXIST(vsPlayersCar.VehicleIndex) IF NOT IS_ENTITY_DEAD(vsPlayersCar.VehicleIndex) SET_VEHICLE_DOOR_CONTROL(vsPlayersCar.VehicleIndex, SC_DOOR_BOOT, DT_DOOR_INTACT, 1.0) //keep boot door open ENDIF ENDIF ENDIF SWITCH iStageProgress CASE 0 IF NOT IS_PED_INJURED(psFranklin.PedIndex) AND IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF NOT IS_PED_IN_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex) TASK_ENTER_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex, DEFAULT_TIME_BEFORE_WARP, VS_FRONT_RIGHT, PEDMOVE_WALK) ENDIF ENDIF IF ( bRopeAttached = FALSE ) IF NOT DOES_ROPE_EXIST(Rope) ROPE_LOAD_TEXTURES() IF ROPE_ARE_TEXTURES_LOADED() Rope = ADD_ROPE(<<-1017.9850, 660.4285, 147.4662>>, <<0.0, 0.0, 0.0>>, ROPE_MAX_LEN, PHYSICS_ROPE_DEFAULT, -1, 0.5, 0.5, FALSE, TRUE) LOAD_ROPE_DATA( Rope, ROPE_DATA_FILE ) ENDIF ENDIF IF DOES_ENTITY_EXIST(osRopeAnchor.ObjectIndex) AND DOES_ENTITY_EXIST(osRopeProp.ObjectIndex) AND DOES_ROPE_EXIST(rope) IF DOES_ENTITY_HAVE_PHYSICS(osRopeAnchor.ObjectIndex) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) ATTACH_ENTITIES_TO_ROPE(Rope, osRopeAnchor.ObjectIndex, vsPlayersCar.VehicleIndex, osRopeAnchor.vPosition, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vsPlayersCar.VehicleIndex, << 0.0, -2.1, 0.6 >>), 35.0, 0, 0) bRopeAttached = TRUE ENDIF ENDIF ENDIF ENDIF IF NOT DOES_ENTITY_EXIST(osBootCollision.ObjectIndex) IF HAS_MISSION_OBJECT_BEEN_CREATED(osBootCollision, TRUE) SET_ENTITY_COLLISION(osBootCollision.ObjectIndex, TRUE) SET_ENTITY_NO_COLLISION_ENTITY(osBootCollision.ObjectIndex, vsPlayersCar.VehicleIndex, FALSE) ENDIF ENDIF iStageProgress++ BREAK CASE 1 DISABLE_CINEMATIC_BONNET_CAMERA_THIS_UPDATE() //fixes a pop between first person and gameplay hint when player enters the car IF NOT IS_PED_INJURED(psFranklin.PedIndex) AND NOT IS_PED_INJURED(PLAYER_PED_ID()) AND IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex, TRUE) SET_GAMEPLAY_COORD_HINT(vBalconyHintPosition, -1, 8000, DEFAULT_INTERP_OUT_TIME, HINTTYPE_FAMILY3_HOUSE_VEHICLE) ENDIF IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) IF DOES_BLIP_EXIST(vsPlayersCar.BlipIndex) REMOVE_BLIP(vsPlayersCar.BlipIndex) CLEAR_PRINTS() ENDIF ELSE IF NOT DOES_BLIP_EXIST(vsPlayersCar.BlipIndex) vsPlayersCar.BlipIndex = CREATE_BLIP_FOR_VEHICLE(vsPlayersCar.VehicleIndex) ENDIF IF NOT HAS_LABEL_BEEN_TRIGGERED(sLabelGIT) OR NOT IS_STRING_NULL_OR_EMPTY(sLabelGIT) IF DOES_BLIP_EXIST(vsPlayersCar.BlipIndex) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData) PRINT_GOD_TEXT_ADVANCED(sLabelGIT, DEFAULT_GOD_TEXT_TIME, TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF IF IS_PED_SITTING_IN_VEHICLE(psFranklin.PedIndex, vsPlayersCar.VehicleIndex) AND IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), vsPlayersCar.VehicleIndex) REPLAY_RECORD_BACK_FOR_TIME(5.0, 5.0, REPLAY_IMPORTANCE_HIGHEST) IF DOES_ENTITY_EXIST(osRopeDummy.ObjectIndex) DELETE_OBJECT(osRopeDummy.ObjectIndex) ENDIF IF DOES_ENTITY_EXIST(osBootCollision.ObjectIndex) DELETE_OBJECT(osBootCollision.ObjectIndex) ENDIF SET_VEHICLE_BURNOUT(vsPlayersCar.VehicleIndex, TRUE) CLEAR_AREA_OF_PEDS(psMichael.vPosition, 100.0) CLEAR_AREA_OF_VEHICLES(psMichael.vPosition, 100.0) START_AUDIO_SCENE("FAMILY_3_PULL_DOWN_HOUSE_SCENE") iStageProgress++ ENDIF ENDIF BREAK CASE 2 IF ( bCutsceneSkipped = FALSE ) //MANAGE_HINT_CAMERA(vBalconyHintPosition) MANAGE_CAMERA_IN_RAYFIRE_SEQUENCE(iScriptedCameraProgress) MANAGE_PLAYERS_VEHICLE_IN_RAYFIRE_SEQUENCE(vsPlayersCar.iProgress) ENDIF REQUEST_PTFX_ASSET() REQUEST_ANIM_DICT("missfam3") IF IS_RAYFIRE_SEQUENCE_AND_CUTSCENE_COMPLETED(iRayfireSequenceProgress) IF IS_VEHICLE_DRIVEABLE(vsPlayersCar.VehicleIndex) SET_VEHICLE_RADIO_ENABLED(vsPlayersCar.VehicleIndex, TRUE) SET_VEHICLE_BURNOUT(vsPlayersCar.VehicleIndex, FALSE) REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(vsPlayersCar.VehicleIndex) ENDIF STOP_AUDIO_SCENE("FAMILY_3_RAYFIRE") STOP_AUDIO_SCENE("FAMILY_3_PULL_DOWN_HOUSE_SCENE") STOP_GAMEPLAY_HINT() RETURN TRUE ENDIF BREAK ENDSWITCH RETURN FALSE ENDFUNC FUNC BOOL IS_MISSION_STAGE_CUTSCENE_END_COMPLETED(INT &iStageProgress) SWITCH iStageProgress CASE 0 IF HAS_REQUESTED_CUTSCENE_LOADED("family_3_ext") SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL IF NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_FRANKLIN)) REGISTER_ENTITY_FOR_CUTSCENE(GET_PED_INDEX(CHAR_FRANKLIN), "Franklin", CU_ANIMATE_EXISTING_SCRIPT_ENTITY, GET_PLAYER_PED_MODEL(CHAR_FRANKLIN)) ENDIF BREAK CASE CHAR_FRANKLIN IF NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_MICHAEL)) REGISTER_ENTITY_FOR_CUTSCENE(GET_PED_INDEX(CHAR_MICHAEL), "Michael", CU_ANIMATE_EXISTING_SCRIPT_ENTITY, GET_PLAYER_PED_MODEL(CHAR_MICHAEL)) ENDIF BREAK ENDSWITCH IF DOES_ENTITY_EXIST(vsCutsceneCar.VehicleIndex) IF NOT IS_ENTITY_DEAD(vsCutsceneCar.VehicleIndex) SET_ENTITY_INVINCIBLE(vsCutsceneCar.VehicleIndex, TRUE) //SET_VEHICLE_ENGINE_ON(vsCutsceneCar.VehicleIndex, TRUE, TRUE) //SET_VEHICLE_LIGHTS(vsCutsceneCar.VehicleIndex, SET_VEHICLE_LIGHTS_ON) REGISTER_ENTITY_FOR_CUTSCENE(vsCutsceneCar.VehicleIndex, "Madrazos_Car", CU_ANIMATE_AND_DELETE_EXISTING_SCRIPT_ENTITY, BALLER) ENDIF ENDIF SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE) IF NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_MICHAEL)) REMOVE_PED_HELMET(GET_PED_INDEX(CHAR_MICHAEL), TRUE) ENDIF IF NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_FRANKLIN)) REMOVE_PED_HELMET(GET_PED_INDEX(CHAR_FRANKLIN), TRUE) ENDIF CLEAR_HELP() CLEAR_PRINTS() IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF STOP_AUDIO_SCENES() //stop all audio scenes TRIGGER_MUSIC_EVENT("FAM3_END") //stop all music playing START_CUTSCENE() REPLAY_START_EVENT(REPLAY_IMPORTANCE_HIGHEST) SET_CUTSCENE_FADE_VALUES(FALSE, FALSE, TRUE, FALSE) //make sure cutscene ends with a fade iStageProgress++ ELSE IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY() IF NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_MICHAEL)) SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Michael", GET_PED_INDEX(CHAR_MICHAEL)) //Michael's variations ENDIF IF NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_FRANKLIN)) SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Franklin", GET_PED_INDEX(CHAR_FRANKLIN)) //Franklin's variations ENDIF bCutsceneAssetsRequested = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting cutscene ped components for cutscene ped Michael and Franklin from peds during stage ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eMissionStage), ".") PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting bCutsceneAssetsRequested to ", bCutsceneAssetsRequested, ".") #ENDIF ENDIF ENDIF BREAK CASE 1 //fade screen in if screen was faded out due to shit skip or debug skip IF IS_CUTSCENE_PLAYING() VEHICLE_INDEX LastPlayerVehicleIndex LastPlayerVehicleIndex = GET_PLAYERS_LAST_VEHICLE() IF DOES_ENTITY_EXIST(LastPlayerVehicleIndex) IF NOT IS_ENTITY_DEAD(LastPlayerVehicleIndex) //if last player vehicle is parked in the gate area or driveway where the cutscene car would drive IF IS_ENTITY_AT_COORD(LastPlayerVehicleIndex, <<-846.192993,159.141159,66.499069>>, <<10.0,4.0,4.0>>) OR IS_ENTITY_IN_ANGLED_AREA(LastPlayerVehicleIndex, <<-835.589661,158.536118,65.894333>>, <<-827.645386,177.585007,73.087891>>, 8.0) IF NOT IS_ENTITY_A_MISSION_ENTITY(LastPlayerVehicleIndex) SET_ENTITY_AS_MISSION_ENTITY(LastPlayerVehicleIndex) ENDIF STOP_VEHICLE_FIRE(LastPlayerVehicleIndex) IF IS_VEHICLE_GEN_AVAILABLE(VEHGEN_MISSION_VEH) AND DOES_ENTITY_EXIST(GET_VEHICLE_GEN_VEHICLE_INDEX(VEHGEN_MISSION_VEH)) //reposition last player vehicle to the other side of the driveway SET_ENTITY_COORDS(LastPlayerVehicleIndex, <<-821.2841, 157.5416, 69.2754>>) SET_ENTITY_HEADING(LastPlayerVehicleIndex, 95.1204) ELSE //reposition last player vehicle across the street SET_ENTITY_COORDS(LastPlayerVehicleIndex, << -867.9103, 158.2215, 63.9014 >>) SET_ENTITY_HEADING(LastPlayerVehicleIndex, 174.2918) ENDIF SET_VEHICLE_ON_GROUND_PROPERLY(LastPlayerVehicleIndex) SET_VEHICLE_DOORS_SHUT(LastPlayerVehicleIndex, TRUE) SET_VEHICLE_ENGINE_ON(LastPlayerVehicleIndex, FALSE, TRUE) ENDIF //if last player vehicle is close to the house blip IF GET_DISTANCE_BETWEEN_COORDS(vMichaelsHousePosition, GET_ENTITY_COORDS(LastPlayerVehicleIndex)) < 15.0 IF NOT IS_ENTITY_A_MISSION_ENTITY(LastPlayerVehicleIndex) SET_ENTITY_AS_MISSION_ENTITY(LastPlayerVehicleIndex) ENDIF STOP_VEHICLE_FIRE(LastPlayerVehicleIndex) //repostion last player vehicle into the end locate //so that it can be seen in the end cutscene SET_ENTITY_COORDS(LastPlayerVehicleIndex, vsPlayersCar.vPosition) SET_ENTITY_HEADING(LastPlayerVehicleIndex, PICK_FLOAT(bVehicleReversed, 126.8534, vsPlayersCar.fHeading)) SET_VEHICLE_ON_GROUND_PROPERLY(LastPlayerVehicleIndex) SET_VEHICLE_DOORS_SHUT(LastPlayerVehicleIndex, TRUE) SET_VEHICLE_ENGINE_ON(LastPlayerVehicleIndex, FALSE, TRUE) SET_ENTITY_LOD_DIST(LastPlayerVehicleIndex, 50) SET_VEHICLE_LOD_MULTIPLIER(LastPlayerVehicleIndex, 2.0) //if last player vehicle does not fit into the end locate and could collide with cutscene vehicle IF DOES_VEHICLE_OVERLAP_ANGLED_AREA(LastPlayerVehicleIndex, <<-824.815613,185.378525,69.954208>>, <<-820.613281,179.789505,73.639229>>, 7.5) IF IS_VEHICLE_GEN_AVAILABLE(VEHGEN_MISSION_VEH) AND DOES_ENTITY_EXIST(GET_VEHICLE_GEN_VEHICLE_INDEX(VEHGEN_MISSION_VEH)) //reposition last player vehicle to the other side of the driveway SET_ENTITY_COORDS(LastPlayerVehicleIndex, <<-821.2841, 157.5416, 69.2754>>) SET_ENTITY_HEADING(LastPlayerVehicleIndex, 95.1204) ELSE //reposition last player vehicle across the street SET_ENTITY_COORDS(LastPlayerVehicleIndex, << -867.9103, 158.2215, 63.9014 >>) SET_ENTITY_HEADING(LastPlayerVehicleIndex, 174.2918) ENDIF SET_VEHICLE_ON_GROUND_PROPERLY(LastPlayerVehicleIndex) SET_VEHICLE_DOORS_SHUT(LastPlayerVehicleIndex, TRUE) SET_VEHICLE_ENGINE_ON(LastPlayerVehicleIndex, FALSE, TRUE) ENDIF ENDIF ENDIF IF ( LastPlayerVehicleIndex != vsPlayersCar.VehicleIndex ) SET_VEHICLE_AS_NO_LONGER_NEEDED(vsPlayersCar.VehicleIndex) ENDIF ENDIF //remove blood damage decals, see TODO B*1492682 IF NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_MICHAEL)) CLEAR_PED_BLOOD_DAMAGE(GET_PED_INDEX(CHAR_MICHAEL)) RESET_PED_VISIBLE_DAMAGE(GET_PED_INDEX(CHAR_MICHAEL)) ENDIF IF NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_FRANKLIN)) CLEAR_PED_BLOOD_DAMAGE(GET_PED_INDEX(CHAR_FRANKLIN)) RESET_PED_VISIBLE_DAMAGE(GET_PED_INDEX(CHAR_FRANKLIN)) ENDIF CLEAR_AREA_OF_PEDS(vMichaelsHousePosition, 1000.0) CLEAR_AREA_OF_COPS(vMichaelsHousePosition, 1000.0) CLEAR_AREA_OF_VEHICLES(vMichaelsHousePosition, 1000.0) CLEAR_AREA_OF_PROJECTILES(vMichaelsHousePosition, 1000.0, TRUE) //shut the mansion front doors, they can be seen open sometimes, see B*1470757 IF IS_DOOR_REGISTERED_WITH_SYSTEM(ENUM_TO_INT(DOORHASH_M_MANSION_F_L)) DOOR_SYSTEM_SET_OPEN_RATIO(ENUM_TO_INT(DOORHASH_M_MANSION_F_L), 0.0, FALSE, FALSE) DOOR_SYSTEM_SET_DOOR_STATE(ENUM_TO_INT(DOORHASH_M_MANSION_F_L), DOORSTATE_FORCE_UNLOCKED_THIS_FRAME, FALSE, TRUE) ENDIF IF IS_DOOR_REGISTERED_WITH_SYSTEM(ENUM_TO_INT(DOORHASH_M_MANSION_F_R)) DOOR_SYSTEM_SET_OPEN_RATIO(ENUM_TO_INT(DOORHASH_M_MANSION_F_R), 0.0, FALSE, FALSE) DOOR_SYSTEM_SET_DOOR_STATE(ENUM_TO_INT(DOORHASH_M_MANSION_F_R), DOORSTATE_FORCE_UNLOCKED_THIS_FRAME, FALSE, TRUE) ENDIF SET_NO_LOADING_SCREEN(TRUE) IF IS_SCREEN_FADED_OUT() DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME) ENDIF iStageProgress++ ENDIF BREAK CASE 2 VEHICLE_INDEX LastPlayerVehicleIndex LastPlayerVehicleIndex = GET_PLAYERS_LAST_VEHICLE() IF DOES_ENTITY_EXIST(LastPlayerVehicleIndex) //IF ( LastPlayerVehicleIndex != vsPlayersCar.VehicleIndex ) IF IS_ENTITY_A_MISSION_ENTITY(LastPlayerVehicleIndex) SET_VEHICLE_AS_NO_LONGER_NEEDED(LastPlayerVehicleIndex) ENDIF //ENDIF ENDIF IF IS_CUTSCENE_PLAYING() SWITCH iCutsceneCarLightsProgress CASE 0 //cutscene car turns up in the cutscene IF GET_CUTSCENE_TIME() > 14500.0 IF IS_VEHICLE_DRIVEABLE(vsCutsceneCar.VehicleIndex) SET_VEHICLE_ENGINE_ON(vsCutsceneCar.VehicleIndex, TRUE, TRUE) SET_VEHICLE_LIGHTS(vsCutsceneCar.VehicleIndex, SET_VEHICLE_LIGHTS_ON) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Turning cutscene car baller lights on.") #ENDIF iCutsceneCarLightsProgress++ ENDIF ENDIF BREAK CASE 1 //driver gets out IF GET_CUTSCENE_TIME() > 19200.0 IF IS_VEHICLE_DRIVEABLE(vsCutsceneCar.VehicleIndex) SET_VEHICLE_ENGINE_ON(vsCutsceneCar.VehicleIndex, FALSE, FALSE) SET_VEHICLE_LIGHTS(vsCutsceneCar.VehicleIndex, SET_VEHICLE_LIGHTS_OFF) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Turning cutscene car baller lights off.") #ENDIF iCutsceneCarLightsProgress++ ENDIF ENDIF BREAK CASE 2 IF GET_CUTSCENE_TIME() > 127760.0 IF IS_VEHICLE_DRIVEABLE(vsCutsceneCar.VehicleIndex) SET_VEHICLE_ENGINE_ON(vsCutsceneCar.VehicleIndex, TRUE, TRUE) SET_VEHICLE_LIGHTS(vsCutsceneCar.VehicleIndex, SET_VEHICLE_LIGHTS_ON) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Turning cutscene car baller lights on.") #ENDIF iCutsceneCarLightsProgress++ ENDIF ENDIF BREAK CASE 3 IF GET_CUTSCENE_TIME() > 131850.0 IF IS_VEHICLE_DRIVEABLE(vsCutsceneCar.VehicleIndex) SET_VEHICLE_LIGHTS(vsCutsceneCar.VehicleIndex, SET_VEHICLE_LIGHTS_OFF) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Turning cutscene car baller lights off.") #ENDIF iCutsceneCarLightsProgress++ ENDIF ENDIF BREAK ENDSWITCH ENDIF IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Michael") //hot swap to Michael if not currently controlling Michael IF ( GET_CURRENT_PLAYER_PED_ENUM() <> CHAR_MICHAEL ) IF MAKE_SELECTOR_PED_SELECTION(sSelectorPeds, SELECTOR_PED_MICHAEL) TAKE_CONTROL_OF_SELECTOR_PED(sSelectorPeds, TRUE, TRUE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Taking control of player ped Michael when CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY() returned true for Michael.") #ENDIF ENDIF ENDIF ENDIF IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Madrazos_Car") #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY() returned true for Madrazos_Car.") #ENDIF CLEANUP_VEHICLE(vsCutsceneCar, TRUE) ENDIF IF HAS_CUTSCENE_FINISHED() REPLAY_STOP_EVENT() IF IS_DOOR_REGISTERED_WITH_SYSTEM(ENUM_TO_INT(DOORHASH_M_MANSION_G1)) DOOR_SYSTEM_SET_OPEN_RATIO(ENUM_TO_INT(DOORHASH_M_MANSION_G1), 0.0, FALSE, FALSE) DOOR_SYSTEM_SET_DOOR_STATE(ENUM_TO_INT(DOORHASH_M_MANSION_G1), DOORSTATE_UNLOCKED, FALSE, TRUE) ENDIF SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) SET_GAMEPLAY_CAM_RELATIVE_PITCH(0) SET_GAMEPLAY_CAM_RELATIVE_HEADING(0) SET_SCRIPTS_SAFE_FOR_CUTSCENE(FALSE) //move player's mission start car to Franklin's safe house if mission started by Franklin IF GET_PLAYER_CHARACTER_AT_MISSION_START() = CHAR_FRANKLIN VEHICLE_INDEX VehGenVehicleIndex VehGenVehicleIndex = GET_VEHICLE_GEN_VEHICLE_INDEX(VEHGEN_MISSION_VEH) IF DOES_ENTITY_EXIST(VehGenVehicleIndex) IF NOT IS_ENTITY_DEAD(VehGenVehicleIndex) STORE_VEH_DATA_FROM_VEH(GET_PED_INDEX(CHAR_FRANKLIN), VehGenVehicleIndex, //make the vehicle gen vehicle Franklin's last known vehicle g_sPlayerLastVeh[SELECTOR_PED_FRANKLIN], g_vPlayerLastVehCoord[SELECTOR_PED_FRANKLIN], g_fPlayerLastVehHead[SELECTOR_PED_FRANKLIN], g_ePlayerLastVehState[SELECTOR_PED_FRANKLIN], g_ePlayerLastVehGen[SELECTOR_PED_FRANKLIN]) SET_MISSION_VEHICLE_GEN_VEHICLE(VehGenVehicleIndex, << -25.02, -1467.7142, 29.7815>>, 275.6534) //move Franklin's start car to area in Franklin's safe house CLEAR_AREA(<< -867.91, 158.22, 63.90 >>, 5.0, TRUE) //clear area where the car was parked for the mission #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting Franklin's mission start vehicle as vehicle gen in position << -25.02, -1467.7142, 29.7815>> and heading 275.6534.") #ENDIF ENDIF ENDIF ENDIF IF DOES_ENTITY_EXIST(GET_PED_INDEX(CHAR_FRANKLIN)) psFranklin.PedIndex = GET_PED_INDEX(CHAR_FRANKLIN) sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN] = psFranklin.PedIndex DELETE_PED(psFranklin.PedIndex) ENDIF CLEANUP_VEHICLE(vsCutsceneCar, TRUE) iStageProgress++ ELSE #IF IS_DEBUG_BUILD IF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED_WITH_DELAY() STOP_CUTSCENE() ENDIF #ENDIF ENDIF BREAK CASE 3 TRIGGER_MISSION_STATS_UI(TRUE, TRUE) iStageProgress++ BREAK CASE 4 IF ( g_bResultScreenDisplaying = TRUE ) iStageProgress++ ENDIF BREAK CASE 5 IF NOT IS_REPEAT_PLAY_ACTIVE() RETURN TRUE ELSE IF ( g_bResultScreenDisplaying = FALSE ) RETURN TRUE ENDIF ENDIF BREAK ENDSWITCH RETURN FALSE ENDFUNC FUNC BOOL IS_MISSION_STAGE_LEADOUT_COMPLETED(INT &iStageProgress) SWITCH iStageProgress CASE 0 WARP_PED(PLAYER_PED_ID(), psMichael.vPosition, psMichael.fHeading, FALSE, TRUE, FALSE) IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID()) CLEAR_PED_WETNESS(PLAYER_PED_ID()) CLEAR_PED_DECORATIONS(PLAYER_PED_ID()) CLEAR_PED_BLOOD_DAMAGE(PLAYER_PED_ID()) RESET_PED_VISIBLE_DAMAGE(PLAYER_PED_ID()) RESTORE_PLAYER_PED_TATTOOS(PLAYER_PED_ID()) SET_PED_STEALTH_MOVEMENT(PLAYER_PED_ID(), FALSE) SET_PED_USING_ACTION_MODE(PLAYER_PED_ID(), FALSE) CLEAR_AREA(GET_ENTITY_COORDS(PLAYER_PED_ID()), 1000.0, TRUE) REMOVE_DECALS_IN_RANGE(GET_ENTITY_COORDS(PLAYER_PED_ID()), 1000.0) REMOVE_PARTICLE_FX_IN_RANGE(GET_ENTITY_COORDS(PLAYER_PED_ID()), 1000.0) SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, TRUE) SET_ENTITY_HEALTH(PLAYER_PED_ID(), GET_PED_MAX_HEALTH(PLAYER_PED_ID())) ENDIF SET_PLAYER_CONTROL(PLAYER_ID(), FALSE) SET_WEATHER_TYPE_NOW("CLOUDS") ADVANCE_CLOCK_TIME_TO(11, 0, 0) iLeadOutLoadSceneTimer = GET_GAME_TIMER() iStageProgress++ BREAK CASE 1 IF NOT IS_NEW_LOAD_SCENE_ACTIVE() NEW_LOAD_SCENE_START(<< -97.12, -410.58, 35.89 >>, << 0.31, -0.9, 0.5 >>, 500.0) iLeadOutLoadSceneTimer = GET_GAME_TIMER() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Calling NEW_LOAD_SCENE_START().") #ENDIF ENDIF #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Leadout load scene timer: ", GET_GAME_TIMER() - iLeadOutLoadSceneTimer, ".") #ENDIF IF IS_NEW_LOAD_SCENE_LOADED() OR HAS_TIME_PASSED(10000, iLeadOutLoadSceneTimer) #IF IS_DEBUG_BUILD IF HAS_TIME_PASSED(10000, iLeadOutLoadSceneTimer) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Calling NEW_LOAD_SCENE_STOP() due to iLoadSceneTimer timeout.") ELSE PRINTLN(GET_THIS_SCRIPT_NAME(), ": Calling NEW_LOAD_SCENE_STOP() due to IS_NEW_LOAD_SCENE_LOADED() returning TRUE.") ENDIF #ENDIF NEW_LOAD_SCENE_STOP() iLeadOutTimer = 0 iStageProgress++ ENDIF BREAK CASE 2 REQUEST_MODEL(osCellphone.ModelName) REQUEST_ANIM_DICT("switch@michael@bench") IF HAS_MODEL_LOADED(osCellphone.ModelName) AND HAS_ANIM_DICT_LOADED("switch@michael@bench") IF ( g_bResultScreenDisplaying = FALSE ) IF ( iLeadOutTimer = 0 ) iLeadOutTimer = GET_GAME_TIMER() ENDIF IF iLeadOutTimer != 0 AND HAS_TIME_PASSED(1000, iLeadOutTimer) IF NOT IS_SYNCHRONIZED_SCENE_RUNNING(iPhoneCallSceneID) iPhoneCallSceneID = CREATE_SYNCHRONIZED_SCENE(<< -95.550, -415.100, 35.6750 >>, << 0.0, 0.0, 133.0 >>) SET_SYNCHRONIZED_SCENE_LOOPED(iPhoneCallSceneID, TRUE) IF HAS_MISSION_OBJECT_BEEN_CREATED(osCellphone, FALSE) SET_OBJECT_TINT_INDEX(osCellphone.ObjectIndex, GET_PHONE_SURROUND_TINT_FOR_SP_PLAYER_CHARACTER(GET_CURRENT_PLAYER_PED_ENUM())) ATTACH_ENTITY_TO_ENTITY(osCellphone.ObjectIndex, PLAYER_PED_ID(), GET_PED_BONE_INDEX(PLAYER_PED_ID(), BONETAG_PH_R_HAND), << 0.0, 0.0, 0.0 >>, << 0.0, 0.0, 0.0 >>) ENDIF TASK_SYNCHRONIZED_SCENE(PLAYER_PED_ID(), iPhoneCallSceneID, "switch@michael@bench", "bench_on_phone_idle_listen", INSTANT_BLEND_IN, WALK_BLEND_OUT, SYNCED_SCENE_USE_PHYSICS) FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID(), TRUE) SET_MODEL_AS_NO_LONGER_NEEDED(osCellphone.ModelName) SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON) DISPLAY_HUD(FALSE) DISPLAY_RADAR(FALSE) DISABLE_CELLPHONE(TRUE) DESTROY_ALL_CAMS() ScriptedCamera = CREATE_CAMERA(CAMTYPE_SCRIPTED, TRUE) SET_CAM_PARAMS(ScriptedCamera, <<-90.226990,-417.333160,45.110085>>,<<37.580025,-0.041530,-165.663498>>,50.0) SHAKE_CAM(ScriptedCamera, "HAND_SHAKE", 0.15) RENDER_SCRIPT_CAMS(TRUE, FALSE) iStageProgress++ ENDIF ENDIF ENDIF ENDIF BREAK CASE 3 IF IS_SYNCHRONIZED_SCENE_RUNNING(iPhoneCallSceneID) SET_CAM_PARAMS(ScriptedCamera, <<-90.226990,-417.333160,45.110085>>,<<37.580025,-0.041530,-165.663498>>,50.0) SET_NO_LOADING_SCREEN(FALSE) IF IS_SCREEN_FADED_OUT() DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME_LONG) ENDIF IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_LOUT_1") IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_LOUT", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_LOUT_1", TRUE) iCameraTimer = GET_GAME_TIMER() iCameraProgress = 0 iStageProgress++ ENDIF ENDIF ENDIF BREAK CASE 4 DISABLE_ON_FOOT_FIRST_PERSON_VIEW_THIS_UPDATE() DISABLE_FIRST_PERSON_FLASH_EFFECT_THIS_UPDATE() IF IS_SYNCHRONIZED_SCENE_RUNNING(iPhoneCallSceneID) SWITCH iCameraProgress CASE 0 IF GET_GAME_TIMER() - iCameraTimer > 250 SET_CAM_PARAMS(ScriptedCamera, <<-90.226990,-417.333160,45.110085>>,<<37.580025,-0.041530,-165.663498>>,50.0) SET_CAM_PARAMS(ScriptedCamera, <<-93.942017,-413.060974,36.347176>>, <<7.278719,0.000000,134.331406>>, 50.0, 14000, GRAPH_TYPE_SIN_ACCEL_DECEL, GRAPH_TYPE_SIN_ACCEL_DECEL) iCameraTimer = GET_GAME_TIMER() iCameraProgress = 1 ENDIF BREAK CASE 1 IF GET_GAME_TIMER() - iCameraTimer > 14000 STOP_RENDERING_SCRIPT_CAMS_USING_CATCH_UP() DESTROY_CAM(ScriptedCamera) iPhoneCallSceneID = CREATE_SYNCHRONIZED_SCENE(<< -95.550, -415.100, 35.6750 >>, << 0.0, 0.0, 133.0 >>) SET_SYNCHRONIZED_SCENE_LOOPED(iPhoneCallSceneID, FALSE) TASK_SYNCHRONIZED_SCENE(PLAYER_PED_ID(), iPhoneCallSceneID, "switch@michael@bench", "exit_forward", WALK_BLEND_IN, SLOW_BLEND_OUT, SYNCED_SCENE_USE_PHYSICS|SYNCED_SCENE_DONT_INTERRUPT|SYNCED_SCENE_TAG_SYNC_OUT) FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID(), TRUE) iStageProgress++ ENDIF BREAK ENDSWITCH ENDIF BREAK CASE 5 DISABLE_ON_FOOT_FIRST_PERSON_VIEW_THIS_UPDATE() DISABLE_FIRST_PERSON_FLASH_EFFECT_THIS_UPDATE() DISABLE_CONTROL_ACTION(CAMERA_CONTROL, INPUT_NEXT_CAMERA) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_DUCK) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_JUMP) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ENTER) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_COVER) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SPRINT) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_WHISTLE) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_CONTEXT) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SELECT_WEAPON) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SPECIAL_ABILITY) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_CHARACTER_WHEEL) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_AIM) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ATTACK) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ATTACK2) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_MELEE_ATTACK_HEAVY) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_MELEE_ATTACK_LIGHT) IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF IS_SYNCHRONIZED_SCENE_RUNNING(iPhoneCallSceneID) IF GET_SYNCHRONIZED_SCENE_PHASE(iPhoneCallSceneID) > 0.99 IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_ON_FOOT) = CAM_VIEW_MODE_FIRST_PERSON bResetFirstPersonCamera = TRUE ELSE DISPLAY_HUD(TRUE) DISPLAY_RADAR(TRUE) ENDIF CLEAR_PED_TASKS(PLAYER_PED_ID()) SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) TASK_PLAY_ANIM(PLAYER_PED_ID(), "switch@michael@bench", "cellphone_call_listen_base", INSTANT_BLEND_IN, WALK_BLEND_OUT, -1, AF_SECONDARY | AF_LOOPING | AF_UPPERBODY) FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID()) iStageProgress++ ELIF GET_SYNCHRONIZED_SCENE_PHASE(iPhoneCallSceneID) > fFirstPersonFlashPhase3 IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_ON_FOOT) = CAM_VIEW_MODE_FIRST_PERSON IF bFirstPersonFlashPlayed = FALSE ANIMPOSTFX_PLAY("CamPushInNeutral", 0, FALSE) PLAY_SOUND_FRONTEND(-1, "1st_Person_Transition", "PLAYER_SWITCH_CUSTOM_SOUNDSET") bFirstPersonFlashPlayed = TRUE ENDIF ENDIF ENDIF ENDIF ENDIF BREAK CASE 6 IF ( bResetFirstPersonCamera = TRUE ) IF GET_CAM_VIEW_MODE_FOR_CONTEXT(CAM_VIEW_MODE_CONTEXT_ON_FOOT) = CAM_VIEW_MODE_FIRST_PERSON DISPLAY_HUD(TRUE) DISPLAY_RADAR(TRUE) SET_GAMEPLAY_CAM_RELATIVE_PITCH() SET_GAMEPLAY_CAM_RELATIVE_HEADING() bResetFirstPersonCamera = FALSE ENDIF ENDIF IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "switch@michael@bench", "cellphone_call_listen_base") DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_DUCK) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_JUMP) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ENTER) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_COVER) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SPRINT) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_WHISTLE) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_CONTEXT) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SELECT_WEAPON) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SPECIAL_ABILITY) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_CHARACTER_WHEEL) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_AIM) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ATTACK) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ATTACK2) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_MELEE_ATTACK_HEAVY) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_MELEE_ATTACK_LIGHT) SET_PED_MAX_MOVE_BLEND_RATIO(PLAYER_PED_ID(), PEDMOVE_WALK) IF ( bLeadoutConversationEnded = FALSE ) IF HAS_LABEL_BEEN_TRIGGERED("FAM3_LOUT_1") IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() TEXT_LABEL_23 CurrentRoot, CurrentLabel CurrentRoot = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT() CurrentLabel = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_LABEL() IF NOT IS_STRING_NULL_OR_EMPTY(CurrentRoot) AND NOT IS_STRING_NULL_OR_EMPTY(CurrentLabel) IF ARE_STRINGS_EQUAL(CurrentRoot, "FAM3_LOUT") AND ARE_STRINGS_EQUAL(CurrentLabel, "FAM3_LOUT_17") KILL_ANY_CONVERSATION() KILL_FACE_TO_FACE_CONVERSATION() bLeadoutConversationEnded = TRUE ENDIF ENDIF ENDIF ENDIF ENDIF IF HAS_LABEL_BEEN_TRIGGERED("FAM3_LOUT_1") IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() ANIM_DATA LocalAnimData, EmptyAnimData LocalAnimData.type = APT_SINGLE_ANIM LocalAnimData.dictionary0 = "switch@michael@bench" LocalAnimData.anim0 = "cellphone_call_out" LocalAnimData.flags = AF_SECONDARY LocalAnimData.blendInDelta = WALK_BLEND_IN LocalAnimData.blendOutDelta = WALK_BLEND_OUT LocalAnimData.filter = GET_HASH_KEY("bonemask_head_neck_and_r_arm") TASK_SCRIPTED_ANIMATION(PLAYER_PED_ID(), LocalAnimData, EmptyAnimData, EmptyAnimData, SLOW_BLEND_DURATION, SLOW_BLEND_DURATION) FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID()) iStageProgress++ ENDIF ENDIF ENDIF ENDIF BREAK CASE 7 IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "switch@michael@bench", "cellphone_call_out") DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_DUCK) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_JUMP) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ENTER) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_COVER) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SPRINT) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_WHISTLE) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_CONTEXT) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SELECT_WEAPON) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SPECIAL_ABILITY) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_CHARACTER_WHEEL) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_AIM) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ATTACK) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ATTACK2) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_MELEE_ATTACK_HEAVY) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_MELEE_ATTACK_LIGHT) SET_PED_MAX_MOVE_BLEND_RATIO(PLAYER_PED_ID(), PEDMOVE_WALK) IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_LOUT_2") IF CREATE_CONVERSATION_FROM_SPECIFIC_LINE(sFamily3Conversation, "FAM3AUD", "FAM3_LOUT", "FAM3_LOUT_19", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_LOUT_2", TRUE) ENDIF ENDIF IF GET_ENTITY_ANIM_CURRENT_TIME(PLAYER_PED_ID(), "switch@michael@bench", "cellphone_call_out") > 0.3 IF DOES_ENTITY_EXIST(osCellphone.ObjectIndex) IF IS_ENTITY_ATTACHED(osCellphone.ObjectIndex) DETACH_ENTITY(osCellphone.ObjectIndex, FALSE) ENDIF DELETE_OBJECT(osCellphone.ObjectIndex) ENDIF CLEAR_PED_TASKS(PLAYER_PED_ID()) iStageProgress++ ENDIF ENDIF ENDIF BREAK CASE 8 IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF DOES_ENTITY_EXIST(vsMichaelsEndCar.VehicleIndex) IF NOT IS_ENTITY_DEAD(vsMichaelsEndCar.VehicleIndex) SET_MISSION_VEHICLE_GEN_VEHICLE(vsMichaelsEndCar.VehicleIndex, vsMichaelsEndCar.vPosition, vsMichaelsEndCar.fHeading) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting Michael's mission start vehicle as vehicle gen in position ", vsMichaelsEndCar.vPosition, " and heading ", vsMichaelsEndCar.fHeading, ".") #ENDIF ENDIF ENDIF DISPLAY_HUD(TRUE) DISPLAY_RADAR(TRUE) DISABLE_CELLPHONE(FALSE) SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) REMOVE_ANIM_DICT("switch@michael@bench") RETURN TRUE ENDIF BREAK ENDSWITCH RETURN FALSE ENDFUNC PROC UPDATE_BLIPS_FOR_GOONS_AND_VEHICLE(PED_STRUCT &array[], VEH_STRUCT &vehicle) INT i BOOL bAtLeastOnePedInVehicle IF DOES_ENTITY_EXIST(vehicle.VehicleIndex) IF IS_VEHICLE_DRIVEABLE(vehicle.VehicleIndex) FOR i = 0 TO ( COUNT_OF(array) - 1 ) IF NOT IS_PED_INJURED(array[i].PedIndex) IF IS_PED_IN_VEHICLE(array[i].PedIndex, vehicle.VehicleIndex) IF DOES_BLIP_EXIST(array[i].BlipIndex) REMOVE_BLIP(array[i].BlipIndex) ENDIF bAtLeastOnePedInVehicle = TRUE ELSE IF NOT DOES_BLIP_EXIST(array[i].BlipIndex) array[i].BlipIndex = CREATE_BLIP_FOR_PED(array[i].PedIndex, TRUE) ENDIF ENDIF ENDIF ENDFOR IF NOT DOES_BLIP_EXIST(vehicle.BlipIndex) IF ( bAtLeastOnePedInVehicle = TRUE ) vehicle.BlipIndex = CREATE_BLIP_FOR_COORD(GET_ENTITY_COORDS(vehicle.VehicleIndex)) SET_BLIP_COLOUR(vehicle.BlipIndex, BLIP_COLOUR_RED) SET_BLIP_PRIORITY(vehicle.BlipIndex, BLIPPRIORITY_HIGHEST) SET_BLIP_NAME_FROM_TEXT_FILE(vehicle.BlipIndex, "BLIP_VEH") ENDIF ELSE VECTOR vBlipPosition = GET_BLIP_COORDS(vehicle.BlipIndex) VECTOR vVehiclePosition = GET_ENTITY_COORDS(vehicle.VehicleIndex) vBlipPosition.X = vBlipPosition.X +@((vVehiclePosition.X - vBlipPosition.X) / BLIP_SLIDE_AMOUNT) vBlipPosition.Y = vBlipPosition.Y +@((vVehiclePosition.Y - vBlipPosition.Y) / BLIP_SLIDE_AMOUNT) vBlipPosition.Z = vBlipPosition.Z +@((vVehiclePosition.Z - vBlipPosition.Z) / BLIP_SLIDE_AMOUNT) SET_BLIP_COORDS(vehicle.BlipIndex, vBlipPosition) IF ( bAtLeastOnePedInVehicle = FALSE ) REMOVE_BLIP(vehicle.BlipIndex) ENDIF ENDIF ELSE IF DOES_BLIP_EXIST(vehicle.BlipIndex) REMOVE_BLIP(vehicle.BlipIndex) ENDIF FOR i = 0 TO ( COUNT_OF(array) - 1 ) IF NOT IS_PED_INJURED(array[i].PedIndex) IF NOT DOES_BLIP_EXIST(array[i].BlipIndex) array[i].BlipIndex = CREATE_BLIP_FOR_PED(array[i].PedIndex, TRUE) ENDIF ENDIF ENDFOR ENDIF ENDIF ENDPROC PROC CLEANUP_GOONS_AND_VEHICLE(PED_STRUCT &array[], VEH_STRUCT &vehicle, FLOAT fCleanupDistanceInVehicle = 300.0, FLOAT fCleanupDistanceOnFoot = 150.0) INT i BOOL bAtLeastOnePedAlive BOOL bAtLeastOnePedInVehicle FOR i = 0 TO ( COUNT_OF(array) - 1 ) IF DOES_ENTITY_EXIST(array[i].PedIndex) IF IS_PED_INJURED(array[i].PedIndex) IF ( array[i].eCleanupReason = PED_CLEANUP_NO_CLEANUP ) //ped has no cleanup reason array[i].eCleanupReason = GET_PED_CLEANUP_REASON(array[i]) UPDATE_PLAYER_AND_BUDDY_KILL_COUNTERS(array[i].eCleanupReason, iPlayerMichaelKills, iPlayerFranklinKills, iBuddyMichaelKills, iBuddyFranklinKills) IF DOES_BLIP_EXIST(array[i].BlipIndex) REMOVE_BLIP(array[i].BlipIndex) ENDIF ELSE //ped has a valid cleanup reason REPLAY_RECORD_BACK_FOR_TIME(3, 0, REPLAY_IMPORTANCE_HIGH) SET_PED_AS_NO_LONGER_NEEDED(array[i].PedIndex) ENDIF ELSE bAtLeastOnePedAlive = TRUE IF NOT IS_PED_IN_ANY_VEHICLE(array[i].PedIndex) IF ( GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), array[i].PedIndex) > fCleanupDistanceOnFoot ) array[i].eCleanupReason = PED_CLEANUP_LOST //flag ped cleanup reason as lost #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Ped on foot ", array[i].sDebugName, " cleaned up with reason PED_CLEANUP_LOST.") #ENDIF SET_PED_AS_NO_LONGER_NEEDED(array[i].PedIndex) IF DOES_BLIP_EXIST(array[i].BlipIndex) REMOVE_BLIP(array[i].BlipIndex) ENDIF ENDIF ELSE IF DOES_ENTITY_EXIST(vehicle.VehicleIndex) IF IS_VEHICLE_DRIVEABLE(vehicle.VehicleIndex) IF IS_PED_IN_VEHICLE(array[i].PedIndex, vehicle.VehicleIndex) bAtLeastOnePedInVehicle = TRUE IF ( GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), array[i].PedIndex) > fCleanupDistanceInVehicle ) array[i].eCleanupReason = PED_CLEANUP_LOST //flag ped cleanup reason as lost #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Ped in vehicle ", vehicle.sDebugName, " ", array[i].sDebugName, " cleaned up with reason PED_CLEANUP_LOST.") #ENDIF SET_PED_AS_NO_LONGER_NEEDED(array[i].PedIndex) IF DOES_BLIP_EXIST(array[i].BlipIndex) REMOVE_BLIP(array[i].BlipIndex) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDFOR IF DOES_ENTITY_EXIST(vehicle.VehicleIndex) IF IS_VEHICLE_DRIVEABLE(vehicle.VehicleIndex) IF ( bAtLeastOnePedAlive = TRUE ) OR ( bAtLeastOnePedInVehicle = TRUE ) IF ( GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), vehicle.VehicleIndex) > fCleanupDistanceInVehicle ) REMOVE_VEHICLE_STUCK_CHECK(vehicle.VehicleIndex) REMOVE_VEHICLE_UPSIDEDOWN_CHECK(vehicle.VehicleIndex) REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(vehicle.VehicleIndex) SET_VEHICLE_AS_NO_LONGER_NEEDED(vehicle.VehicleIndex) IF DOES_BLIP_EXIST(vehicle.BlipIndex) REMOVE_BLIP(vehicle.BlipIndex) ENDIF ENDIF ELSE REMOVE_VEHICLE_STUCK_CHECK(vehicle.VehicleIndex) REMOVE_VEHICLE_UPSIDEDOWN_CHECK(vehicle.VehicleIndex) REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(vehicle.VehicleIndex) SET_VEHICLE_AS_NO_LONGER_NEEDED(vehicle.VehicleIndex) IF DOES_BLIP_EXIST(vehicle.BlipIndex) REMOVE_BLIP(vehicle.BlipIndex) ENDIF ENDIF ELSE REMOVE_VEHICLE_STUCK_CHECK(vehicle.VehicleIndex) REMOVE_VEHICLE_UPSIDEDOWN_CHECK(vehicle.VehicleIndex) REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(vehicle.VehicleIndex) SET_VEHICLE_AS_NO_LONGER_NEEDED(vehicle.VehicleIndex) IF DOES_BLIP_EXIST(vehicle.BlipIndex) REMOVE_BLIP(vehicle.BlipIndex) ENDIF ENDIF ENDIF ENDPROC PROC MANAGE_GOON_PED_IN_VEHICLE(PED_STRUCT &ped, VEH_STRUCT &vehicle, PED_INDEX TargetPedIndex, VEHICLE_INDEX TargetVehicleIndex, BOOL &bAggressive) IF NOT IS_PED_INJURED(ped.PedIndex) AND NOT IS_PED_INJURED(TargetPedIndex) #IF IS_DEBUG_BUILD IF ( bDrawDebugStates = TRUE ) DRAW_DEBUG_TEXT_ABOVE_ENTITY(ped.PedIndex, GET_PED_STATE_NAME_FOR_DEBUG(ped.eState), 1.25) DRAW_DEBUG_TEXT_ABOVE_ENTITY(ped.PedIndex, GET_STRING_FROM_FLOAT(ped.fDistanceToTarget), 1.5) ENDIF #ENDIF //calculate distance to target ped every frame ped.fDistanceToTarget = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(ped.PedIndex), GET_ENTITY_COORDS(TargetPedIndex)) //check if target ped (the player) damaged the security ped or vehicle with a weapon IF ( bAggressive = FALSE ) IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(ped.PedIndex, TargetPedIndex, TRUE) IF HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON(ped.PedIndex, WEAPONTYPE_INVALID, GENERALWEAPON_TYPE_ANYWEAPON) CLEAR_ENTITY_LAST_DAMAGE_ENTITY(ped.PedIndex) bAggressive = TRUE ENDIF ENDIF IF DOES_ENTITY_EXIST(vehicle.VehicleIndex) IF NOT IS_ENTITY_DEAD(vehicle.VehicleIndex) IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(vehicle.VehicleIndex, TargetPedIndex, TRUE) IF HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON(vehicle.VehicleIndex, WEAPONTYPE_INVALID, GENERALWEAPON_TYPE_ANYWEAPON) CLEAR_ENTITY_LAST_DAMAGE_ENTITY(vehicle.VehicleIndex) bAggressive = TRUE ENDIF ENDIF ENDIF ENDIF IF ( ped.iAgressiveTimer <> 0 ) IF HAS_TIME_PASSED(10000, ped.iAgressiveTimer) bAggressive = TRUE ENDIF ENDIF ENDIF IF ( ped.eState != PED_STATE_COMBAT_ON_FOOT ) IF IS_PED_FLEEING(ped.PedIndex) OR IS_PED_BEING_JACKED(ped.PedIndex) GO_TO_PED_STATE(ped, PED_STATE_COMBAT_ON_FOOT) ENDIF ENDIF SWITCH ped.eState CASE PED_STATE_IDLE GO_TO_PED_STATE(ped, PED_STATE_COMBAT_FROM_CAR_SHOOTING) BREAK CASE PED_STATE_COMBAT_ON_FOOT IF ( ped.bHasTask = FALSE ) SET_PED_COMBAT_RANGE(ped.PedIndex, CR_NEAR) SET_PED_COMBAT_MOVEMENT(ped.PedIndex, CM_WILLADVANCE) SET_PED_COMBAT_ABILITY(ped.PedIndex, CAL_PROFESSIONAL) SET_PED_COMBAT_ATTRIBUTES(ped.PedIndex, CA_CAN_FLANK, TRUE) SET_PED_COMBAT_ATTRIBUTES(ped.PedIndex, CA_CAN_CHARGE, TRUE) SET_PED_COMBAT_ATTRIBUTES(ped.PedIndex, CA_AGGRESSIVE, TRUE) SET_PED_COMBAT_ATTRIBUTES(ped.PedIndex, CA_USE_VEHICLE, FALSE) SET_PED_COMBAT_ATTRIBUTES(ped.PedIndex, CA_LEAVE_VEHICLES, TRUE) SET_PED_COMBAT_ATTRIBUTES(ped.PedIndex, CA_CAN_CHASE_TARGET_ON_FOOT, TRUE) SET_COMBAT_FLOAT(ped.PedIndex, CCF_WALK_WHEN_STRAFING_CHANCE, 0.1) SET_PED_ACCURACY(ped.PedIndex, 6) SET_PED_SHOOT_RATE(ped.PedIndex, 125) TASK_COMBAT_HATED_TARGETS_AROUND_PED(ped.PedIndex, 200.0) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped.PedIndex, FALSE) ped.bHasTask = TRUE ENDIF IF IS_PED_DRIVING_VEHICLE(TargetPedIndex, TargetVehicleIndex) IF ( ped.fDistanceToTarget > 20.0) IF DOES_ENTITY_EXIST(vehicle.VehicleIndex) IF IS_VEHICLE_DRIVEABLE(vehicle.VehicleIndex) AND GET_ENTITY_HEALTH(vehicle.VehicleIndex) > 0 AND GET_VEHICLE_ENGINE_HEALTH(vehicle.VehicleIndex) > 0 AND NOT IS_VEHICLE_STUCK_ON_ROOF(vehicle.VehicleIndex) AND NOT IS_VEHICLE_PERMANENTLY_STUCK(vehicle.VehicleIndex) AND NOT IS_ENTITY_UPSIDEDOWN(vehicle.VehicleIndex) IF NOT IS_PED_IN_VEHICLE(ped.PedIndex, vehicle.VehicleIndex) IF IS_VEHICLE_SEAT_FREE(vehicle.VehicleIndex, VS_DRIVER) OR IS_VEHICLE_SEAT_FREE(vehicle.VehicleIndex, VS_FRONT_RIGHT) GO_TO_PED_STATE(ped, PED_STATE_ENTERING_VEHICLE) ENDIF ELSE IF IS_PED_SITTING_IN_VEHICLE(ped.PedIndex, vehicle.VehicleIndex) IF ( bAggressive = TRUE ) GO_TO_PED_STATE(ped, PED_STATE_COMBAT_FROM_CAR_SHOOTING) ELSE GO_TO_PED_STATE(ped, PED_STATE_COMBAT_FROM_CAR_NO_SHOOTING) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF BREAK CASE PED_STATE_COMBAT_FROM_CAR_NO_SHOOTING IF ( ped.bHasTask = FALSE ) IF IS_PED_SITTING_IN_VEHICLE_SEAT(ped.PedIndex, vehicle.VehicleIndex, VS_DRIVER) IF NOT IS_VEHICLE_SEAT_FREE(vehicle.VehicleIndex, VS_FRONT_RIGHT) PED_INDEX PedInFrontRightSeat PedInFrontRightSeat = GET_PED_IN_VEHICLE_SEAT(vehicle.VehicleIndex, VS_FRONT_RIGHT) IF DOES_ENTITY_EXIST(PedInFrontRightSeat) AND NOT IS_ENTITY_DEAD(PedInFrontRightSeat) SET_PED_CONFIG_FLAG(ped.PedIndex, PCF_FallsOutOfVehicleWhenKilled, TRUE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting goon ped ", ped.sDebugName, " config flag PCF_FallsOutOfVehicleWhenKilled to TRUE.") #ENDIF ELSE SET_PED_CONFIG_FLAG(ped.PedIndex, PCF_FallsOutOfVehicleWhenKilled, FALSE) ENDIF ELSE SET_PED_CONFIG_FLAG(ped.PedIndex, PCF_FallsOutOfVehicleWhenKilled, FALSE) ENDIF ENDIF SET_PED_COMBAT_ATTRIBUTES(ped.PedIndex, CA_LEAVE_VEHICLES, FALSE) SET_PED_COMBAT_ATTRIBUTES(ped.PedIndex, CA_USE_VEHICLE, TRUE) SET_PED_COMBAT_ATTRIBUTES(ped.PedIndex, CA_DO_DRIVEBYS, FALSE) TASK_COMBAT_HATED_TARGETS_AROUND_PED(ped.PedIndex, 200.0) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped.PedIndex, FALSE) ped.iAgressiveTimer = GET_GAME_TIMER() ped.bHasTask = TRUE ENDIF SET_PED_RESET_FLAG(ped.PedIndex, PRF_BlockWeaponFire, TRUE) //block weapon fire in no shooting state each frame IF ( bAggressive = TRUE ) GO_TO_PED_STATE(ped, PED_STATE_COMBAT_FROM_CAR_SHOOTING) ENDIF IF IS_VEHICLE_DRIVEABLE(vehicle.VehicleIndex) IF IS_PED_SITTING_IN_VEHICLE(ped.PedIndex, vehicle.VehicleIndex) IF ( ped.fDistanceToTarget < 17.5 ) IF NOT IS_PED_DRIVING_VEHICLE(TargetPedIndex, TargetVehicleIndex) GO_TO_PED_STATE(ped, PED_STATE_COMBAT_ON_FOOT) ENDIF ENDIF IF IS_VEHICLE_SEAT_FREE(vehicle.VehicleIndex, VS_DRIVER) GO_TO_PED_STATE(ped, PED_STATE_SHUFFLING_VEHICLE_SEATS) ENDIF ENDIF ENDIF IF NOT IS_VEHICLE_DRIVEABLE(vehicle.VehicleIndex) GO_TO_PED_STATE(ped, PED_STATE_COMBAT_ON_FOOT) ELSE IF IS_VEHICLE_STOPPED(vehicle.VehicleIndex) IF IS_VEHICLE_STUCK_ON_ROOF(vehicle.VehicleIndex) OR IS_ENTITY_UPSIDEDOWN(vehicle.VehicleIndex) OR NOT IS_VEHICLE_ON_ALL_WHEELS(vehicle.VehicleIndex) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Enemy vehicle ", vehicle.sDebugName, " is stopped upside down, stuck on roof or not all wheels.") #ENDIF IF IS_PED_IN_VEHICLE(ped.PedIndex, vehicle.VehicleIndex) TASK_LEAVE_ANY_VEHICLE(ped.PedIndex, 0, ECF_DONT_CLOSE_DOOR) ENDIF GO_TO_PED_STATE(ped, PED_STATE_COMBAT_ON_FOOT) ENDIF ENDIF ENDIF BREAK CASE PED_STATE_COMBAT_FROM_CAR_SHOOTING IF ( ped.bHasTask = FALSE ) IF IS_PED_SITTING_IN_VEHICLE_SEAT(ped.PedIndex, vehicle.VehicleIndex, VS_DRIVER) IF NOT IS_VEHICLE_SEAT_FREE(vehicle.VehicleIndex, VS_FRONT_RIGHT) PED_INDEX PedInFrontRightSeat PedInFrontRightSeat = GET_PED_IN_VEHICLE_SEAT(vehicle.VehicleIndex, VS_FRONT_RIGHT) IF DOES_ENTITY_EXIST(PedInFrontRightSeat) AND NOT IS_ENTITY_DEAD(PedInFrontRightSeat) SET_PED_CONFIG_FLAG(ped.PedIndex, PCF_FallsOutOfVehicleWhenKilled, TRUE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting goon ped ", ped.sDebugName, " config flag PCF_FallsOutOfVehicleWhenKilled to TRUE.") #ENDIF ELSE SET_PED_CONFIG_FLAG(ped.PedIndex, PCF_FallsOutOfVehicleWhenKilled, FALSE) ENDIF ELSE SET_PED_CONFIG_FLAG(ped.PedIndex, PCF_FallsOutOfVehicleWhenKilled, FALSE) ENDIF ENDIF SET_PED_COMBAT_ATTRIBUTES(ped.PedIndex, CA_LEAVE_VEHICLES, FALSE) SET_PED_COMBAT_ATTRIBUTES(ped.PedIndex, CA_USE_VEHICLE, TRUE) SET_PED_COMBAT_ATTRIBUTES(ped.PedIndex, CA_DO_DRIVEBYS, TRUE) SET_PED_ACCURACY(ped.PedIndex, 3) SET_PED_SHOOT_RATE(ped.PedIndex, 80) TASK_COMBAT_HATED_TARGETS_AROUND_PED(ped.PedIndex, 200.0) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped.PedIndex, FALSE) ped.bHasTask = TRUE ENDIF IF IS_VEHICLE_DRIVEABLE(vehicle.VehicleIndex) IF IS_PED_SITTING_IN_VEHICLE(ped.PedIndex, vehicle.VehicleIndex) IF IS_VEHICLE_SEAT_FREE(vehicle.VehicleIndex, VS_DRIVER) GO_TO_PED_STATE(ped, PED_STATE_SHUFFLING_VEHICLE_SEATS) ENDIF IF ( ped.fDistanceToTarget < 17.5 ) IF NOT IS_PED_DRIVING_VEHICLE(TargetPedIndex, TargetVehicleIndex) GO_TO_PED_STATE(ped, PED_STATE_COMBAT_ON_FOOT) ENDIF ENDIF ENDIF ENDIF IF NOT IS_VEHICLE_DRIVEABLE(vehicle.VehicleIndex) GO_TO_PED_STATE(ped, PED_STATE_COMBAT_ON_FOOT) ELSE IF IS_VEHICLE_STOPPED(vehicle.VehicleIndex) IF IS_VEHICLE_STUCK_ON_ROOF(vehicle.VehicleIndex) OR IS_ENTITY_UPSIDEDOWN(vehicle.VehicleIndex) OR NOT IS_VEHICLE_ON_ALL_WHEELS(vehicle.VehicleIndex) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Enemy vehicle ", vehicle.sDebugName, " is stopped upside down, stuck on roof or not all wheels.") #ENDIF IF IS_PED_IN_VEHICLE(ped.PedIndex, vehicle.VehicleIndex) TASK_LEAVE_ANY_VEHICLE(ped.PedIndex, 0, ECF_DONT_CLOSE_DOOR) ENDIF GO_TO_PED_STATE(ped, PED_STATE_COMBAT_ON_FOOT) ENDIF ENDIF ENDIF BREAK CASE PED_STATE_SHUFFLING_VEHICLE_SEATS IF ( ped.bHasTask = FALSE ) IF IS_VEHICLE_DRIVEABLE(vehicle.VehicleIndex) TASK_SHUFFLE_TO_NEXT_VEHICLE_SEAT(ped.PedIndex, vehicle.VehicleIndex) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped.PedIndex, TRUE) ENDIF ped.bHasTask = TRUE ENDIF IF NOT IS_VEHICLE_DRIVEABLE(vehicle.VehicleIndex) GO_TO_PED_STATE(ped, PED_STATE_COMBAT_ON_FOOT) ELSE IF IS_PED_SITTING_IN_VEHICLE(ped.PedIndex, vehicle.VehicleIndex) IF IS_PED_SITTING_IN_VEHICLE_SEAT(ped.PedIndex, vehicle.VehicleIndex, VS_DRIVER) IF NOT IS_VEHICLE_SEAT_FREE(vehicle.VehicleIndex, VS_FRONT_RIGHT) PED_INDEX PedInFrontRightSeat PedInFrontRightSeat = GET_PED_IN_VEHICLE_SEAT(vehicle.VehicleIndex, VS_FRONT_RIGHT) IF DOES_ENTITY_EXIST(PedInFrontRightSeat) AND NOT IS_ENTITY_DEAD(PedInFrontRightSeat) SET_PED_CONFIG_FLAG(ped.PedIndex, PCF_FallsOutOfVehicleWhenKilled, TRUE) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting goon ped ", ped.sDebugName, " config flag PCF_FallsOutOfVehicleWhenKilled to TRUE.") #ENDIF ELSE SET_PED_CONFIG_FLAG(ped.PedIndex, PCF_FallsOutOfVehicleWhenKilled, FALSE) ENDIF ELSE SET_PED_CONFIG_FLAG(ped.PedIndex, PCF_FallsOutOfVehicleWhenKilled, FALSE) ENDIF IF ( bAggressive = TRUE ) GO_TO_PED_STATE(ped, PED_STATE_COMBAT_FROM_CAR_SHOOTING) ELSE GO_TO_PED_STATE(ped, PED_STATE_COMBAT_FROM_CAR_NO_SHOOTING) ENDIF ELSE //IF IS_VEHICLE_SEAT_FREE(vehicle.VehicleIndex, VS_DRIVER) // IF GET_SCRIPT_TASK_STATUS(ped.PedIndex, SCRIPT_TASK_SHUFFLE_TO_NEXT_VEHICLE_SEAT) != PERFORMING_TASK // GO_TO_PED_STATE(ped, PED_STATE_SHUFFLING_VEHICLE_SEATS) // ENDIF //ENDIF IF ( ped.fDistanceToTarget < 17.5 ) IF NOT IS_PED_DRIVING_VEHICLE(TargetPedIndex, TargetVehicleIndex) GO_TO_PED_STATE(ped, PED_STATE_COMBAT_ON_FOOT) ENDIF ENDIF ENDIF ENDIF ENDIF IF NOT IS_PED_IN_ANY_VEHICLE(ped.PedIndex) IF NOT IS_PED_DRIVING_VEHICLE(TargetPedIndex, TargetVehicleIndex) IF ( ped.fDistanceToTarget < 17.5 ) GO_TO_PED_STATE(ped, PED_STATE_COMBAT_ON_FOOT) ENDIF ELSE GO_TO_PED_STATE(ped, PED_STATE_ENTERING_VEHICLE) ENDIF ENDIF BREAK CASE PED_STATE_ENTERING_VEHICLE //use warp when off camera IF ( ped.bHasTask = FALSE ) IF DOES_ENTITY_EXIST(vehicle.VehicleIndex) IF IS_VEHICLE_DRIVEABLE(vehicle.VehicleIndex) SET_PED_COMBAT_ATTRIBUTES(ped.PedIndex, CA_LEAVE_VEHICLES, FALSE) SET_PED_COMBAT_ATTRIBUTES(ped.PedIndex, CA_USE_VEHICLE, TRUE) IF IS_VEHICLE_SEAT_FREE(vehicle.VehicleIndex, VS_DRIVER) TASK_ENTER_VEHICLE(ped.PedIndex, vehicle.VehicleIndex, DEFAULT_TIME_BEFORE_WARP, VS_DRIVER, PEDMOVE_RUN, ECF_JACK_ANYONE | ECF_RESUME_IF_INTERRUPTED) ELIF IS_VEHICLE_SEAT_FREE(vehicle.VehicleIndex, VS_FRONT_RIGHT) TASK_ENTER_VEHICLE(ped.PedIndex, vehicle.VehicleIndex, DEFAULT_TIME_BEFORE_WARP, VS_FRONT_RIGHT, PEDMOVE_RUN, ECF_JACK_ANYONE | ECF_RESUME_IF_INTERRUPTED) ENDIF SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped.PedIndex, TRUE) ped.iTimer = GET_GAME_TIMER() ENDIF ENDIF ped.bHasTask = TRUE ENDIF IF DOES_ENTITY_EXIST(vehicle.VehicleIndex) AND IS_VEHICLE_DRIVEABLE(vehicle.VehicleIndex) AND GET_ENTITY_HEALTH(vehicle.VehicleIndex) > 0 AND GET_VEHICLE_ENGINE_HEALTH(vehicle.VehicleIndex) > 0 IF IS_PED_IN_VEHICLE(ped.PedIndex, vehicle.VehicleIndex) IF ( bAggressive = TRUE ) GO_TO_PED_STATE(ped, PED_STATE_COMBAT_FROM_CAR_SHOOTING) ELSE GO_TO_PED_STATE(ped, PED_STATE_COMBAT_FROM_CAR_NO_SHOOTING) ENDIF ELSE IF ( ped.bHasTask = TRUE ) IF HAS_TIME_PASSED(5000, ped.iTimer) IF ( ped.fDistanceToTarget > 25.0 ) AND ( GET_DISTANCE_BETWEEN_ENTITIES(ped.PedIndex, vehicle.VehicleIndex) < 10.0 ) IF NOT IS_ENTITY_ON_SCREEN(ped.PedIndex) AND NOT IS_ENTITY_ON_SCREEN(vehicle.VehicleIndex) IF IS_VEHICLE_SEAT_FREE(vehicle.VehicleIndex, VS_DRIVER) SET_PED_INTO_VEHICLE(ped.PedIndex, vehicle.VehicleIndex, VS_DRIVER) ELIF IS_VEHICLE_SEAT_FREE(vehicle.VehicleIndex, VS_FRONT_RIGHT) SET_PED_INTO_VEHICLE(ped.PedIndex, vehicle.VehicleIndex, VS_FRONT_RIGHT) ENDIF ENDIF ELSE GO_TO_PED_STATE(ped, PED_STATE_COMBAT_ON_FOOT) ENDIF ENDIF ENDIF //if seat is no longer free while ped is running to the seat, pick a seat again //also if while entering vehicle player is close and not driving then go to combat IF GET_SCRIPT_TASK_STATUS(ped.PedIndex, SCRIPT_TASK_ENTER_VEHICLE) = PERFORMING_TASK IF NOT IS_PED_GETTING_INTO_A_VEHICLE(ped.PedIndex) IF NOT IS_VEHICLE_SEAT_FREE(vehicle.VehicleIndex, VS_DRIVER) OR NOT IS_VEHICLE_SEAT_FREE(vehicle.VehicleIndex, VS_FRONT_RIGHT) GO_TO_PED_STATE(ped, PED_STATE_ENTERING_VEHICLE) ENDIF IF ( ped.fDistanceToTarget < 17.5 ) IF NOT IS_PED_DRIVING_VEHICLE(TargetPedIndex, TargetVehicleIndex) GO_TO_PED_STATE(ped, PED_STATE_COMBAT_ON_FOOT) ENDIF ENDIF ENDIF ENDIF ENDIF ELSE GO_TO_PED_STATE(ped, PED_STATE_COMBAT_ON_FOOT) ENDIF BREAK ENDSWITCH ENDIF ENDPROC FUNC BOOL CAN_GET_CLOSEST_NTH_VEHICLE_NODE_TO_ENTITY_BETWEEN_ANGLES(ENTITY_INDEX EntityIndex, VECTOR &vCurrentClosestNodePosition, FLOAT &fOutHeading, INT iNodeNumber, FLOAT fMinAngle, FLOAT fMaxAngle, NODE_FLAGS eNodeFlags = NF_NONE) /// /// Angles /// use 0 - 90 for vehicle nodes in front of the entity /// use 90 - 180 for vehicle nodes behind the player IF DOES_ENTITY_EXIST(EntityIndex) IF NOT IS_ENTITY_DEAD(EntityIndex) VECTOR vEntityPosition VECTOR vEntityForwardVector VECTOR vVectorFromNodeToEntity VECTOR vClosestNodePosition FLOAT fClosestNodeHeading FLOAT fAngle INT iTotalLanes vEntityPosition = GET_ENTITY_COORDS(EntityIndex) vEntityForwardVector = GET_ENTITY_FORWARD_VECTOR(EntityIndex) IF GET_NTH_CLOSEST_VEHICLE_NODE_WITH_HEADING(vEntityPosition, iNodeNumber, vClosestNodePosition, fClosestNodeHeading, iTotalLanes, eNodeFlags) vVectorFromNodeToEntity = vClosestNodePosition - vEntityPosition fAngle = GET_ANGLE_BETWEEN_2D_VECTORS(vVectorFromNodeToEntity.X, vVectorFromNodeToEntity.Y, vEntityForwardVector.X, vEntityForwardVector.Y) IF ( fAngle > fMinAngle AND fAngle < fMaxAngle ) IF NOT ARE_VECTORS_EQUAL(vCurrentClosestNodePosition, vClosestNodePosition) vCurrentClosestNodePosition = vClosestNodePosition fOutHeading = fClosestNodeHeading #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), "************* CAN_GET_CLOSEST_NTH_VEHICLE_NODE_TO_VEHICLE_BETWEEN_ANGLES **************") PRINTLN(GET_THIS_SCRIPT_NAME(), ": Closest vehicle node found at ", vClosestNodePosition, " and heading ", fClosestNodeHeading , ".") PRINTLN(GET_THIS_SCRIPT_NAME(), "***************************************************************************************") DRAW_DEBUG_SPHERE(vClosestNodePosition, 1.0) #ENDIF RETURN TRUE ENDIF ENDIF #IF IS_DEBUG_BUILD IF ( bDrawDebugLinesAndSpheres = TRUE ) DRAW_DEBUG_SPHERE(vClosestNodePosition, 1.0, 255, 0, 0) ENDIF #ENDIF ENDIF #IF IS_DEBUG_BUILD IF ( bDrawDebugLinesAndSpheres = TRUE ) DRAW_DEBUG_TEXT_ABOVE_ENTITY(EntityIndex, GET_STRING_FROM_FLOAT(fAngle), 1.5) ENDIF #ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC PROC STORE_ENTITY_POSITION_AND_HEADING(ENTITY_INDEX EntityIndex, VECTOR &vPosition, FLOAT &fHeading) IF DOES_ENTITY_EXIST(EntityIndex) IF NOT IS_ENTITY_DEAD(EntityIndex) vPosition = GET_ENTITY_COORDS(EntityIndex) fHeading = GET_ENTITY_HEADING(EntityIndex) ENDIF ENDIF ENDPROC PROC RUN_VEHICLE_IMPACT_SOUND_CHECK(VEHICLE_INDEX PlayerVehicleIndex, VEHICLE_INDEX EnemyVehicleIndex) IF DOES_ENTITY_EXIST(PlayerVehicleIndex) IF NOT IS_ENTITY_DEAD(PlayerVehicleIndex) IF IS_THIS_MODEL_A_CAR(GET_ENTITY_MODEL(PlayerVehicleIndex)) IF DOES_ENTITY_EXIST(EnemyVehicleIndex) IF NOT IS_ENTITY_DEAD(EnemyVehicleIndex) IF GET_GAME_TIMER() - iVehicleImpactSoundTimer > 0 IF IS_ENTITY_TOUCHING_ENTITY(EnemyVehicleIndex, PlayerVehicleIndex) OR HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(PlayerVehicleIndex, EnemyVehicleIndex) IF IS_ENTITY_IN_ANGLED_AREA(EnemyVehicleIndex, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(PlayerVehicleIndex, <<0.0, -1.0, -1.5>>), GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(PlayerVehicleIndex, <<0.0, -6.0, 3.0>>), 4.0) PLAY_SOUND_FROM_ENTITY(-1, "FAMILY3_REAR_END_MASTER", PlayerVehicleIndex) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Playing sound FAMILY3_REAR_END_MASTER.") #ENDIF ENDIF CLEAR_ENTITY_LAST_DAMAGE_ENTITY(PlayerVehicleIndex) iVehicleImpactSoundTimer = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(3000, 5000) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDPROC PROC RUN_VEHICLE_DAMAGE_CHECK(VEHICLE_INDEX VehicleIndex, INT iSmokeHealth) IF DOES_ENTITY_EXIST(VehicleIndex) IF NOT IS_ENTITY_DEAD(VehicleIndex) #IF IS_DEBUG_BUILD IF ( bDrawDebugLinesAndSpheres = TRUE ) DRAW_DEBUG_TEXT_ABOVE_ENTITY(VehicleIndex, GET_STRING_FROM_INT(GET_ENTITY_HEALTH(VehicleIndex)), 2.25) DRAW_DEBUG_TEXT_ABOVE_ENTITY(VehicleIndex, GET_STRING_FROM_FLOAT(GET_VEHICLE_ENGINE_HEALTH(VehicleIndex)), 2.0) DRAW_DEBUG_TEXT_ABOVE_ENTITY(VehicleIndex, GET_STRING_FROM_FLOAT(GET_VEHICLE_PETROL_TANK_HEALTH(VehicleIndex)), 1.75) ENDIF #ENDIF IF ( GET_ENTITY_HEALTH(VehicleIndex) < iSmokeHealth ) SET_ENTITY_HEALTH(VehicleIndex, 0) SET_VEHICLE_ENGINE_HEALTH(VehicleIndex, 0) ENDIF ENDIF ENDIF ENDPROC PROC ADD_POSITION(VECTOR &array[], FLOAT &farray[]) INT i FOR i = ( COUNT_OF(array) - 1 ) TO 1 STEP -1 array[i] = array[i - 1] farray[i] = farray[i - 1] ENDFOR STORE_ENTITY_POSITION_AND_HEADING(PLAYER_PED_ID(), array[0], farray[0]) // #IF IS_DEBUG_BUILD // PRINTLN(GET_THIS_SCRIPT_NAME(), ": ************************************************************") // FOR i = 0 TO ( COUNT_OF(array) - 1 ) // PRINTLN(GET_THIS_SCRIPT_NAME(), ": array[", i, "] ", array[i], " farray[", i, "] ", farray[i], ".") // ENDFOR // PRINTLN(GET_THIS_SCRIPT_NAME(), ": ************************************************************") // #ENDIF ENDPROC PROC UPDATE_PLAYER_POSITIONS(VECTOR &array[], FLOAT &farray[]) IF IS_VECTOR_ZERO(array[0]) STORE_ENTITY_POSITION_AND_HEADING(PLAYER_PED_ID(), array[0], farray[0]) ELSE IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), array[0]) > 30.0 ADD_POSITION(array, farray) ENDIF INT i FOR i = 0 TO ( COUNT_OF(array) - 1 ) #IF IS_DEBUG_BUILD IF ( bDrawDebugLinesAndSpheres = TRUE ) IF NOT IS_VECTOR_ZERO(array[i]) DRAW_DEBUG_SPHERE(array[i], 0.5, 0, 255, 0, 255) DRAW_DEBUG_TEXT_ABOVE_COORDS(array[i], GET_STRING_FROM_INT(i), 1.0, 0, 255, 0, 255) ENDIF ENDIF #ENDIF ENDFOR ENDIF ENDPROC PROC RUN_VEHICLE_WARP_CHECK_BASED_ON_TARGET_VEHICLE(VEHICLE_INDEX VehicleIndex, VEHICLE_INDEX TargetVehicleIndex, VECTOR &vWarpPosition, FLOAT &fWarpHeading, VECTOR &vLastTargetPosition, FLOAT &fLastTargetHeading, INT &iWarpTimer, VECTOR vWarpOffset, INT iWarpTimeDelay, FLOAT fWarpDistance, FLOAT &fLastKnownDistance #IF IS_DEBUG_BUILD, STRING sDebugName = NULL #ENDIF) UPDATE_PLAYER_POSITIONS(vPlayerPositions, fPlayerHeadings) IF DOES_ENTITY_EXIST(VehicleIndex) AND IS_VEHICLE_DRIVEABLE(VehicleIndex) IF DOES_ENTITY_EXIST(TargetVehicleIndex) AND ( VehicleIndex != TargetVehicleIndex) AND NOT IS_THIS_MODEL_A_BOAT(GET_ENTITY_MODEL(TargetVehicleIndex)) AND NOT IS_THIS_MODEL_A_PLANE(GET_ENTITY_MODEL(TargetVehicleIndex)) AND NOT IS_THIS_MODEL_A_HELI(GET_ENTITY_MODEL(TargetVehicleIndex)) AND NOT IS_THIS_MODEL_A_TRAIN(GET_ENTITY_MODEL(TargetVehicleIndex)) AND IS_VEHICLE_ON_ALL_WHEELS(TargetVehicleIndex) AND NOT IS_VEHICLE_STOPPED(TargetVehicleIndex) AND DOES_VEHICLE_HAVE_A_DRIVER(VehicleIndex) AND GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(TargetVehicleIndex), GET_ENTITY_COORDS(VehicleIndex)) > fLastKnownDistance IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(TargetVehicleIndex), vLastTargetPosition) > 20.0 vWarpPosition = vLastTargetPosition //store last target vehicle positon as the new warp position fWarpHeading = fLastTargetHeading //store last target vehicle heading as the new warp heading vWarpPosition = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vWarpPosition, fWarpHeading, vWarpOffset) STORE_ENTITY_POSITION_AND_HEADING(TargetVehicleIndex, vLastTargetPosition, fLastTargetHeading) ENDIF #IF IS_DEBUG_BUILD IF ( bDrawDebugLinesAndSpheres = TRUE ) DRAW_DEBUG_TEXT_ABOVE_ENTITY(VehicleIndex, GET_STRING_FROM_FLOAT(GET_DISTANCE_BETWEEN_ENTITIES(VehicleIndex, TargetVehicleIndex)), 1.5) DRAW_DEBUG_SPHERE(vWarpPosition, 0.25) DRAW_DEBUG_TEXT_ABOVE_COORDS(vWarpPosition, sDebugName, 1.75) ENDIF #ENDIF IF NOT IS_ENTITY_OCCLUDED(VehicleIndex) iWarpTimer = GET_GAME_TIMER() ELIF GET_GAME_TIMER() - iWarpTimer > iWarpTimeDelay IF GET_DISTANCE_BETWEEN_ENTITIES(VehicleIndex, TargetVehicleIndex) > fWarpDistance AND GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(TargetVehicleIndex), vWarpPosition) > 25.0 IF NOT IS_VECTOR_ZERO(vWarpPosition) IF NOT IS_SPHERE_VISIBLE(vWarpPosition, 3.0) CLEAR_AREA_OF_PEDS(vWarpPosition, 1.5) CLEAR_AREA_OF_VEHICLES(vWarpPosition, 3.0) SET_ENTITY_COORDS(VehicleIndex, vWarpPosition) SET_ENTITY_HEADING(VehicleIndex, fWarpHeading) SET_VEHICLE_ON_GROUND_PROPERLY(VehicleIndex) SET_VEHICLE_FORWARD_SPEED(VehicleIndex, 10.0) SET_VEHICLE_ENGINE_ON(VehicleIndex, TRUE, TRUE) iWarpTimer = GET_GAME_TIMER() fLastKnownDistance = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(TargetVehicleIndex), GET_ENTITY_COORDS(VehicleIndex)) iReplayCameraWarpTimer = GET_GAME_TIMER() + 1000 #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Warping vehicle ", sDebugName, " to new position ", vWarpPosition, " and heading ", fWarpHeading, ".") #ENDIF ELSE INT i VECTOR vNewWarpPosition REPEAT COUNT_OF(vPlayerPositions) i vNewWarpPosition = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vPlayerPositions[i], fPlayerHeadings[i], vWarpOffset) IF NOT IS_VECTOR_ZERO(vNewWarpPosition) IF NOT IS_SPHERE_VISIBLE(vNewWarpPosition, 2.0) CLEAR_AREA_OF_PEDS(vNewWarpPosition, 1.5) CLEAR_AREA_OF_VEHICLES(vNewWarpPosition, 3.0) SET_ENTITY_COORDS(VehicleIndex, vNewWarpPosition) SET_ENTITY_HEADING(VehicleIndex, fPlayerHeadings[i]) SET_VEHICLE_ON_GROUND_PROPERLY(VehicleIndex) SET_VEHICLE_FORWARD_SPEED(VehicleIndex, 10.0) SET_VEHICLE_ENGINE_ON(VehicleIndex, TRUE, TRUE) iWarpTimer = GET_GAME_TIMER() fLastKnownDistance = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(TargetVehicleIndex), GET_ENTITY_COORDS(VehicleIndex)) EXIT #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Warping vehicle ", sDebugName, " to new position ", vNewWarpPosition, " at index ", i, ".") SCRIPT_ASSERT("Warping to new position") #ENDIF iReplayCameraWarpTimer = GET_GAME_TIMER() + 1000 ENDIF ENDIF ENDREPEAT ENDIF ENDIF ENDIF ENDIF ELSE iWarpTimer = GET_GAME_TIMER() ENDIF ENDIF ENDPROC PROC MANAGE_GOONS(INT &iProgress) IF ( bGoonsAllowed = FALSE ) //player has to leave the dirt road under the balcony IF NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), << -1184.89, 709.60, 132.38 >>, << -1133.41, 679.84, 161.10 >>, 36.0) AND NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), << -1062.28, 662.22, 125.02 >>, << -1138.02, 681.84, 161.37 >>, 36.0) AND NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), << -1065.68, 661.26, 121.10 >>, << -976.84, 641.13, 153.91 >>, 36.0) AND NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), << -894.49, 655.77, 113.47 >>, << -985.13, 640.53, 154.35 >>, 36.0) AND NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), << -898.85, 657.44, 113.60 >>, << -823.46, 645.49, 144.01 >>, 36.0) AND NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), << -770.93, 551.06, 101.91 >>, << -827.24, 649.55, 144.36 >>, 36.0) AND NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), << -770.974, 557.36, 102.67 >>, << -700.16, 501.75, 124.60 >>, 36.0) //use timer to allow goons with time delay once the dirt road is left behind IF ( iGoonsChaseDelayTimer = 0 ) IF ( bStartGoonTimerDelay = TRUE ) iGoonsChaseDelayTimer = GET_GAME_TIMER() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Starting goons delay timer.") #ENDIF ENDIF ELSE IF HAS_TIME_PASSED(10000, iGoonsChaseDelayTimer) bGoonsAllowed = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Goons are allowed to spawn due to timer.") #ENDIF ENDIF ENDIF //allow goons if player reaches Michael's house before the goons were allowed to spawn IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), vMichaelsHousePosition) < 100.0//175.0 bGoonsAllowed = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Goons are allowed to spawn due to proximity to Michael's house.") #ENDIF ENDIF ENDIF ENDIF SWITCH iProgress CASE 0 //request models REQUEST_MODEL(BALLER) REQUEST_MODEL(G_M_Y_POLOGOON_01) IF HAS_MODEL_LOADED(BALLER) AND HAS_MODEL_LOADED(G_M_Y_POLOGOON_01) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Models ", GET_MODEL_NAME_FOR_DEBUG(BALLER), " and ", GET_MODEL_NAME_FOR_DEBUG(G_M_Y_POLOGOON_01), " are loaded.") #ENDIF vEnemyCarsOffset[0] = << -2.15, -3.0, 0.0 >> vEnemyCarsOffset[1] = << 2.15, 3.0, 0.0 >> iProgress++ ENDIF BREAK CASE 1 IF ( bGoonsAllowed = TRUE ) VECTOR vPlayerPosition VECTOR vClosestNodeToPlayer vPlayerPosition = GET_ENTITY_COORDS(PLAYER_PED_ID()) //fix for spawning when inside the problematic junction in B*1821876 IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), <<-857.873779,220.178818,73.882767>>,<<20.000000,28.000000,8.000000>>) IF GET_CLOSEST_VEHICLE_NODE(vPlayerPosition, vClosestNodeToPlayer, NF_NONE) #IF IS_DEBUG_BUILD IF ( bDrawDebugLinesAndSpheres = TRUE ) DRAW_DEBUG_SPHERE(vClosestNodeToPlayer, 1.0, 0, 255, 0, 128) ENDIF #ENDIF IF ( GET_DISTANCE_BETWEEN_COORDS(vPlayerPosition, vClosestNodeToPlayer) < 7.0 ) #IF IS_DEBUG_BUILD IF ( bDrawDebugLinesAndSpheres = TRUE ) DRAW_DEBUG_SPHERE(vClosestNodeToPlayer, 0.5, 255, 255, 255, 255) ENDIF #ENDIF IF CAN_GET_CLOSEST_NTH_VEHICLE_NODE_TO_ENTITY_BETWEEN_ANGLES(PLAYER_PED_ID(), vClosestRoadNode, fClosestRoadNodeHeading, 18, PICK_FLOAT(IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_LOOK_BEHIND), 10.0, 100.0), PICK_FLOAT(IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_LOOK_BEHIND), 60.0, 180.0)) IF NOT IS_SPHERE_VISIBLE(vClosestRoadNode, 3.0) INT i FLOAT fHeadingDifference FLOAT fPlayerHeading FLOAT fSpawnHeading fPlayerHeading = GET_ENTITY_HEADING(PLAYER_PED_ID()) fHeadingDifference = ABSF(fPlayerHeading - fClosestRoadNodeHeading) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), " fPlayerHeading: ", fPlayerHeading, " fClosestRoadNodeHeading: ", fClosestRoadNodeHeading, " fHeadingDifference: ", fHeadingDifference, ".") #ENDIF IF ( fHeadingDifference > 180.0 ) fHeadingDifference = ABSF(fHeadingDifference - 360.0) ENDIF IF ( fHeadingDifference < 90.0 ) fSpawnHeading = fClosestRoadNodeHeading ELSE fSpawnHeading = fClosestRoadNodeHeading + 180 ENDIF REPEAT COUNT_OF(vsEnemyCars) i vsEnemyCars[i].ModelName = BALLER vsEnemyCars[i].vPosition = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vClosestRoadNode, fClosestRoadNodeHeading, vEnemyCarsOffset[i]) vsEnemyCars[i].fHeading = fSpawnHeading vsEnemyCars[i].bLOSFlag = FALSE CLEAR_AREA_OF_VEHICLES(vsEnemyCars[i].vPosition, 3.0) ENDREPEAT #IF IS_DEBUG_BUILD bStageResetFlag = TRUE #ENDIF iProgress++ ENDIF ENDIF ENDIF ENDIF ELSE //normal spawning when outside the problematic junction in B*1821876 IF GET_CLOSEST_VEHICLE_NODE(vPlayerPosition, vClosestNodeToPlayer, NF_NONE) #IF IS_DEBUG_BUILD IF ( bDrawDebugLinesAndSpheres = TRUE ) DRAW_DEBUG_SPHERE(vClosestNodeToPlayer, 1.0, 0, 255, 0, 128) ENDIF #ENDIF IF ( GET_DISTANCE_BETWEEN_COORDS(vPlayerPosition, vClosestNodeToPlayer) < 5.0 ) #IF IS_DEBUG_BUILD IF ( bDrawDebugLinesAndSpheres = TRUE ) DRAW_DEBUG_SPHERE(vClosestNodeToPlayer, 0.5, 255, 255, 255, 255) ENDIF #ENDIF IF CAN_GET_CLOSEST_NTH_VEHICLE_NODE_TO_ENTITY_BETWEEN_ANGLES(PLAYER_PED_ID(), vClosestRoadNode, fClosestRoadNodeHeading, 18, PICK_FLOAT(IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_LOOK_BEHIND), 15.0, 125.0), PICK_FLOAT(IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_LOOK_BEHIND), 60.0, 180.0)) IF NOT IS_SPHERE_VISIBLE(vClosestRoadNode, 3.0) INT i FLOAT fHeadingDifference FLOAT fPlayerHeading FLOAT fSpawnHeading fPlayerHeading = GET_ENTITY_HEADING(PLAYER_PED_ID()) fHeadingDifference = ABSF(fPlayerHeading - fClosestRoadNodeHeading) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), " fPlayerHeading: ", fPlayerHeading, " fClosestRoadNodeHeading: ", fClosestRoadNodeHeading, " fHeadingDifference: ", fHeadingDifference, ".") #ENDIF IF ( fHeadingDifference > 180.0 ) fHeadingDifference = ABSF(fHeadingDifference - 360.0) ENDIF IF ( fHeadingDifference < 90.0 ) fSpawnHeading = fClosestRoadNodeHeading ELSE fSpawnHeading = fClosestRoadNodeHeading + 180 ENDIF REPEAT COUNT_OF(vsEnemyCars) i vsEnemyCars[i].ModelName = BALLER vsEnemyCars[i].vPosition = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vClosestRoadNode, fClosestRoadNodeHeading, vEnemyCarsOffset[i]) vsEnemyCars[i].fHeading = fSpawnHeading vsEnemyCars[i].bLOSFlag = FALSE CLEAR_AREA_OF_VEHICLES(vsEnemyCars[i].vPosition, 3.0) ENDREPEAT #IF IS_DEBUG_BUILD bStageResetFlag = TRUE #ENDIF iProgress++ ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF BREAK CASE 2 //create enemies in vehicles REPLAY_DISABLE_CAMERA_MOVEMENT_THIS_FRAME() //Fix for bug 2229077 IF HAS_MISSION_VEHICLE_BEEN_CREATED(vsEnemyCars[0], FALSE, FALSE, NO_CHARACTER, FALSE, -1, 0, 0, 3, 0 #IF IS_DEBUG_BUILD, "EnemyCar 0" #ENDIF) AND HAS_MISSION_VEHICLE_BEEN_CREATED(vsEnemyCars[1], FALSE, FALSE, NO_CHARACTER, FALSE, -1, 0, 0, 3, 0 #IF IS_DEBUG_BUILD, "EnemyCar 1" #ENDIF) psEnemyGoonsCar0[0].PedIndex = CREATE_ENEMY_PED_IN_VEHICLE(vsEnemyCars[0].VehicleIndex, G_M_Y_POLOGOON_01, VS_DRIVER, 200, WEAPONTYPE_PISTOL #IF IS_DEBUG_BUILD, "EnemyCar0 0" #ENDIF) psEnemyGoonsCar0[1].PedIndex = CREATE_ENEMY_PED_IN_VEHICLE(vsEnemyCars[0].VehicleIndex, G_M_Y_POLOGOON_01, VS_FRONT_RIGHT, 200, WEAPONTYPE_PISTOL #IF IS_DEBUG_BUILD, "EnemyCar0 1" #ENDIF) psEnemyGoonsCar1[0].PedIndex = CREATE_ENEMY_PED_IN_VEHICLE(vsEnemyCars[1].VehicleIndex, G_M_Y_POLOGOON_01, VS_DRIVER, 200, WEAPONTYPE_PISTOL #IF IS_DEBUG_BUILD, "EnemyCar1 0" #ENDIF) psEnemyGoonsCar1[1].PedIndex = CREATE_ENEMY_PED_IN_VEHICLE(vsEnemyCars[1].VehicleIndex, G_M_Y_POLOGOON_01, VS_FRONT_RIGHT, 200, WEAPONTYPE_PISTOL #IF IS_DEBUG_BUILD, "EnemyCar1 1" #ENDIF) IF IS_VEHICLE_DRIVEABLE(vsEnemyCars[0].VehicleIndex) SET_ENTITY_HEALTH(vsEnemyCars[0].VehicleIndex, 1000) SET_VEHICLE_ENGINE_HEALTH(vsEnemyCars[0].VehicleIndex, 1000) SET_VEHICLE_PETROL_TANK_HEALTH(vsEnemyCars[0].VehicleIndex, 1000) ADD_VEHICLE_UPSIDEDOWN_CHECK(vsEnemyCars[0].VehicleIndex) ADD_VEHICLE_STUCK_CHECK_WITH_WARP(vsEnemyCars[0].VehicleIndex, 10, 1000, FALSE, FALSE, FALSE, -1) SET_VEHICLE_ON_GROUND_PROPERLY(vsEnemyCars[0].VehicleIndex) SET_VEHICLE_FORWARD_SPEED(vsEnemyCars[0].VehicleIndex, 5.0) ADD_ENTITY_TO_AUDIO_MIX_GROUP(vsEnemyCars[0].VehicleIndex, "FAMILY_3_ENEMY_CARS_GROUP") ENDIF IF IS_VEHICLE_DRIVEABLE(vsEnemyCars[1].VehicleIndex) SET_ENTITY_HEALTH(vsEnemyCars[1].VehicleIndex, 1000) SET_VEHICLE_ENGINE_HEALTH(vsEnemyCars[1].VehicleIndex, 1000) SET_VEHICLE_PETROL_TANK_HEALTH(vsEnemyCars[1].VehicleIndex, 1000) ADD_VEHICLE_UPSIDEDOWN_CHECK(vsEnemyCars[1].VehicleIndex) ADD_VEHICLE_STUCK_CHECK_WITH_WARP(vsEnemyCars[1].VehicleIndex, 10, 1000, FALSE, FALSE, FALSE, -1) SET_VEHICLE_ON_GROUND_PROPERLY(vsEnemyCars[1].VehicleIndex) SET_VEHICLE_FORWARD_SPEED(vsEnemyCars[1].VehicleIndex, 5.0) ADD_ENTITY_TO_AUDIO_MIX_GROUP(vsEnemyCars[1].VehicleIndex, "FAMILY_3_ENEMY_CARS_GROUP") ENDIF #IF IS_DEBUG_BUILD vsEnemyCars[0].sDebugName = "EnemyCar 0" vsEnemyCars[1].sDebugName = "EnemyCar 1" psEnemyGoonsCar0[0].sDebugName = "EnemyCar0 0" psEnemyGoonsCar0[1].sDebugName = "EnemyCar0 1" psEnemyGoonsCar1[0].sDebugName = "EnemyCar1 0" psEnemyGoonsCar1[1].sDebugName = "EnemyCar1 1" #ENDIF psEnemyGoonsCar0[0].iConversationTimer = 0 psEnemyGoonsCar0[1].iConversationTimer = 0 psEnemyGoonsCar1[0].iConversationTimer = 0 psEnemyGoonsCar1[1].iConversationTimer = 0 GO_TO_PED_STATE(psEnemyGoonsCar0[0], PED_STATE_IDLE) GO_TO_PED_STATE(psEnemyGoonsCar0[1], PED_STATE_IDLE) GO_TO_PED_STATE(psEnemyGoonsCar1[0], PED_STATE_IDLE) GO_TO_PED_STATE(psEnemyGoonsCar1[1], PED_STATE_IDLE) SET_MODEL_AS_NO_LONGER_NEEDED(BALLER) SET_MODEL_AS_NO_LONGER_NEEDED(G_M_Y_POLOGOON_01) INFORM_MISSION_STATS_OF_HEADSHOT_WATCH_ENTITY(psEnemyGoonsCar0[0].PedIndex) //track headshots on goons INFORM_MISSION_STATS_OF_HEADSHOT_WATCH_ENTITY(psEnemyGoonsCar0[1].PedIndex) INFORM_MISSION_STATS_OF_HEADSHOT_WATCH_ENTITY(psEnemyGoonsCar1[0].PedIndex) INFORM_MISSION_STATS_OF_HEADSHOT_WATCH_ENTITY(psEnemyGoonsCar1[1].PedIndex) INFORM_MISSION_STATS_SYSTEM_OF_TIME_WINDOW_OPEN(FAM3_GOON_LOSS_TIME) //start goon chase stat timer vsEnemyCars[0].vWarpOffset = << -2.15, -3.0, 0.0 >> vsEnemyCars[1].vWarpOffset = << 2.15, 3.0, 0.0 >> vsEnemyCars[0].fDistanceToTarget = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(vsEnemyCars[0].VehicleIndex)) vsEnemyCars[1].fDistanceToTarget = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(vsEnemyCars[1].VehicleIndex)) STORE_ENTITY_POSITION_AND_HEADING(GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()), vsEnemyCars[0].vTargetPosition, vsEnemyCars[0].fTargetHeading) STORE_ENTITY_POSITION_AND_HEADING(GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()), vsEnemyCars[1].vTargetPosition, vsEnemyCars[1].fTargetHeading) TRIGGER_MUSIC_EVENT("FAM3_MEX_CHASE") //give some pistol ammo to the player when goons spawn, give 2 clips ADD_AMMO_TO_PED(PLAYER_PED_ID(), WEAPONTYPE_PISTOL, GET_MAX_AMMO_IN_CLIP(PLAYER_PED_ID(), WEAPONTYPE_PISTOL) * 2) bGoonsChaseInProgress = TRUE iGoonsChaseInitialTimer = GET_GAME_TIMER() bGoonsChaseInitialTimePassed = FALSE iProgress++ ENDIF BREAK CASE 3 //update enemies INT i IF ( bGoonsChaseInitialTimePassed = FALSE ) IF HAS_TIME_PASSED(10000, iGoonsChaseInitialTimer) bGoonsChaseInitialTimePassed = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting bGoonsChaseInitialTimePassed to TRUE as iGoonsChaseInitialTimer has passed 10000 ms.") #ENDIF ENDIF ENDIF UPDATE_BLIPS_FOR_GOONS_AND_VEHICLE(psEnemyGoonsCar0, vsEnemyCars[0]) UPDATE_BLIPS_FOR_GOONS_AND_VEHICLE(psEnemyGoonsCar1, vsEnemyCars[1]) CLEANUP_GOONS_AND_VEHICLE(psEnemyGoonsCar0, vsEnemyCars[0], 300.0, PICK_FLOAT(bGoonsChaseInitialTimePassed, 150.0, 200.0)) CLEANUP_GOONS_AND_VEHICLE(psEnemyGoonsCar1, vsEnemyCars[1], 300.0, PICK_FLOAT(bGoonsChaseInitialTimePassed, 150.0, 200.0)) MANAGE_GOON_PED_IN_VEHICLE(psEnemyGoonsCar0[0], vsEnemyCars[0], PLAYER_PED_ID(), GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()), bGoonsAggressive) MANAGE_GOON_PED_IN_VEHICLE(psEnemyGoonsCar0[1], vsEnemyCars[0], PLAYER_PED_ID(), GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()), bGoonsAggressive) MANAGE_GOON_PED_IN_VEHICLE(psEnemyGoonsCar1[0], vsEnemyCars[1], PLAYER_PED_ID(), GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()), bGoonsAggressive) MANAGE_GOON_PED_IN_VEHICLE(psEnemyGoonsCar1[1], vsEnemyCars[1], PLAYER_PED_ID(), GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()), bGoonsAggressive) IF ( vsEnemyCars[0].bLOSFlag = FALSE AND vsEnemyCars[1].bLOSFlag = FALSE ) //check enemy cars line of sight to Franklin IF DOES_ENTITY_EXIST(vsEnemyCars[0].VehicleIndex) vsEnemyCars[0].bLOSFlag = HAS_ENTITY_CLEAR_LOS_TO_ENTITY(vsEnemyCars[0].VehicleIndex, GET_PED_INDEX(CHAR_FRANKLIN)) vsEnemyCars[0].bLOSFlag = HAS_ENTITY_CLEAR_LOS_TO_ENTITY(vsEnemyCars[0].VehicleIndex, GET_PED_INDEX(CHAR_MICHAEL)) ENDIF IF DOES_ENTITY_EXIST(vsEnemyCars[1].VehicleIndex) vsEnemyCars[1].bLOSFlag = HAS_ENTITY_CLEAR_LOS_TO_ENTITY(vsEnemyCars[1].VehicleIndex, GET_PED_INDEX(CHAR_FRANKLIN)) vsEnemyCars[1].bLOSFlag = HAS_ENTITY_CLEAR_LOS_TO_ENTITY(vsEnemyCars[1].VehicleIndex, GET_PED_INDEX(CHAR_MICHAEL)) ENDIF ENDIF FOR i = 0 TO 1 RUN_VEHICLE_DAMAGE_CHECK(vsEnemyCars[i].VehicleIndex, 200) RUN_VEHICLE_IMPACT_SOUND_CHECK(GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()), vsEnemyCars[i].VehicleIndex) RUN_VEHICLE_WARP_CHECK_BASED_ON_TARGET_VEHICLE(vsEnemyCars[i].VehicleIndex, GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()), vsEnemyCars[i].vPosition, vsEnemyCars[i].fHeading, vsEnemyCars[i].vTargetPosition, vsEnemyCars[i].fTargetHeading, vsEnemyCars[i].iWarpTimer, vsEnemyCars[i].vWarpOffset, 3500, 45.0, vsEnemyCars[i].fDistanceToTarget #IF IS_DEBUG_BUILD, vsEnemyCars[i].sDebugName #ENDIF) ENDFOR IF NOT DOES_ENTITY_EXIST(vsEnemyCars[0].VehicleIndex) AND NOT DOES_ENTITY_EXIST(vsEnemyCars[1].VehicleIndex) AND NOT DOES_ENTITY_EXIST(psEnemyGoonsCar0[0].PedIndex) AND NOT DOES_ENTITY_EXIST(psEnemyGoonsCar0[1].PedIndex) AND NOT DOES_ENTITY_EXIST(psEnemyGoonsCar1[0].PedIndex) AND NOT DOES_ENTITY_EXIST(psEnemyGoonsCar1[1].PedIndex) INFORM_MISSION_STATS_SYSTEM_OF_TIME_WINDOW_CLOSED() //end goon chase stat timer bGoonsChaseFinished = TRUE bGoonsChaseInProgress = FALSE bRunLocatesHeaderCheck = TRUE SET_MAX_WANTED_LEVEL(5) SET_CREATE_RANDOM_COPS(TRUE) //restore wanted level default settings SET_WANTED_LEVEL_MULTIPLIER(1.0) SET_PLAYER_CAN_CHANGE_CLOTHES_ON_MISSION(TRUE) //allow player to change clothes after goons chase SET_ALL_SHOPS_TEMPORARILY_UNAVAILABLE(FALSE) //allow shops RELEASE_SUPPRESSED_EMERGENCY_CALLS() //allow emergency calls REMOVE_ANIM_DICT("missfam3") //no need for anim dict after losing goons TRIGGER_MUSIC_EVENT("FAM3_MEX_LOST") iProgress++ ENDIF BREAK ENDSWITCH ENDPROC PROC MANAGE_CONVERSATIONS_DURING_ESCAPE_GOONS(INT &iProgress) INT i TEXT_LABEL_23 CurrentRoot TEXT_LABEL_23 CurrentLabel IF ( bRunLocatesHeaderCheck = TRUE ) IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF IS_FACE_TO_FACE_CONVERSATION_PAUSED() PAUSE_FACE_TO_FACE_CONVERSATION(FALSE) ENDIF ENDIF ELSE IF IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0) //when wanted, kill conversation and play wanted conversation IF ( bConversationPaused = FALSE ) IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() lConversationRoot = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT() lConversationLabel = GET_STANDARD_CONVERSATION_LABEL_FOR_FUTURE_RESUMPTION() KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_WNTD2", CONV_PRIORITY_MEDIUM) bConversationPaused = TRUE ENDIF ENDIF ENDIF ELSE //player not wanted, must be out of the car, pause face to face conversations IF ( bAllowConvsersationOutsideOfCar = FALSE ) IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_FACE_TO_FACE_CONVERSATION_PAUSED() PAUSE_FACE_TO_FACE_CONVERSATION(TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF SWITCH iProgress CASE 0 IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() CurrentLabel = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_LABEL() IF NOT IS_STRING_NULL_OR_EMPTY(CurrentLabel) IF ARE_STRINGS_EQUAL(CurrentLabel, "FAM3_DOWN_10") OR ARE_STRINGS_EQUAL(CurrentLabel, "FAM3_DOWNA_17") KILL_ANY_CONVERSATION() KILL_FACE_TO_FACE_CONVERSATION() PAUSE_FACE_TO_FACE_CONVERSATION(FALSE) ENDIF ENDIF ELSE bRunLocatesHeaderCheck = TRUE SETTIMERA(0) iProgress++ ENDIF BREAK CASE 1 IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF TIMERA() > 6000 IF NOT IS_PED_INJURED(PLAYER_PED_ID()) AND NOT IS_PED_INJURED(psFranklin.PedIndex) IF CHAR_CALL_PLAYER_CELLPHONE_FORCE_ANSWER(sFamily3Conversation, CHAR_TENNIS_COACH, "FAM3AUD", "FAM3_TCPC", CONV_PRIORITY_MEDIUM) REPLAY_RECORD_BACK_FOR_TIME(3.0, 10.0, REPLAY_IMPORTANCE_HIGHEST) SET_LABEL_AS_TRIGGERED("FAM3_TCPC", TRUE) bPhoneCallInterruptedByPlayer = FALSE bAllowConvsersationOutsideOfCar = TRUE iProgress++ ENDIF ENDIF ENDIF ENDIF BREAK CASE 2 IF HAS_LABEL_BEEN_TRIGGERED("FAM3_TCPC") IF NOT IS_THIS_CONVERSATION_PLAYING("FAM3_TCPC") iProgress++ ENDIF IF WAS_LAST_CELLPHONE_CALL_INTERRUPTED() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Last phone call was interrupted.") #ENDIF bPhoneCallInterruptedByPlayer = TRUE ENDIF ENDIF BREAK CASE 3 IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_MAD") IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF ( bPhoneCallInterruptedByPlayer = FALSE ) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_MAD", CONV_PRIORITY_MEDIUM) REPLAY_RECORD_BACK_FOR_TIME(4.0, 10.0, REPLAY_IMPORTANCE_HIGHEST) SET_LABEL_AS_TRIGGERED("FAM3_MAD", TRUE) ENDIF ELSE bStartGoonTimerDelay = TRUE bRunLocatesHeaderCheck = TRUE iProgress++ ENDIF ENDIF ELSE IF NOT IS_THIS_CONVERSATION_PLAYING("FAM3_MAD") bStartGoonTimerDelay = TRUE bRunLocatesHeaderCheck = TRUE iProgress++ ELSE IF NOT IS_FACE_TO_FACE_CONVERSATION_PAUSED() IF DOES_BLIP_EXIST(sLocatesData.BuddyBlipID[0]) PAUSE_FACE_TO_FACE_CONVERSATION(TRUE) ENDIF ELSE IF NOT DOES_BLIP_EXIST(sLocatesData.BuddyBlipID[0]) PAUSE_FACE_TO_FACE_CONVERSATION(FALSE) ENDIF ENDIF IF ( bGoonsChaseInProgress = TRUE ) //if the goons spawn during the FAM3_MAD conversations (can happen if player rushes home quickly) iProgress++ ENDIF ENDIF ENDIF BREAK CASE 4 IF ( bGoonsChaseInProgress = FALSE ) IF ( bGoonsChaseFinished = TRUE ) //handle conversation for ending the goons chase and presenting the reason why chase has ended IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_GCEK") AND NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_GCEL") FOR i = 0 TO 1 //#IF IS_DEBUG_BUILD // PRINTLN(GET_THIS_SCRIPT_NAME(), ": psEnemyGoonsCar0[", i, "].bCleanupConversationTriggered is ", psEnemyGoonsCar0[i].bCleanupConversationTriggered) // PRINTLN(GET_THIS_SCRIPT_NAME(), ": psEnemyGoonsCar0[", i, "].eCleanupReason is ", ENUM_TO_INT(psEnemyGoonsCar0[i].eCleanupReason)) // PRINTLN(GET_THIS_SCRIPT_NAME(), ": psEnemyGoonsCar1[", i, "].bCleanupConversationTriggered is ", psEnemyGoonsCar1[i].bCleanupConversationTriggered) // PRINTLN(GET_THIS_SCRIPT_NAME(), ": psEnemyGoonsCar1[", i, "].eCleanupReason is ", ENUM_TO_INT(psEnemyGoonsCar1[i].eCleanupReason)) //#ENDIF //loop through first vehicle group IF ( psEnemyGoonsCar0[i].bCleanupConversationTriggered = FALSE ) IF ( psEnemyGoonsCar0[i].eCleanupReason <> PED_CLEANUP_NO_CLEANUP ) SWITCH psEnemyGoonsCar0[i].eCleanupReason CASE PED_CLEANUP_KILLED_BY_MICHAEL CASE PED_CLEANUP_KILLED_BY_FRANKLIN CASE PED_CLEANUP_KILLED_BY_PLAYER_AS_MICHAEL CASE PED_CLEANUP_KILLED_BY_PLAYER_AS_FRANKLIN CASE PED_CLEANUP_KILLED_BY_VEHICLE IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCEK", CONV_PRIORITY_MEDIUM) psEnemyGoonsCar0[i].bCleanupConversationTriggered = TRUE SET_LABEL_AS_TRIGGERED("FAM3_GCEK", TRUE) ENDIF BREAK CASE PED_CLEANUP_LOST IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCEL", CONV_PRIORITY_MEDIUM) psEnemyGoonsCar0[i].bCleanupConversationTriggered = TRUE SET_LABEL_AS_TRIGGERED("FAM3_GCEL", TRUE) ENDIF BREAK ENDSWITCH ENDIF ENDIF //loop through second vehicle group IF ( psEnemyGoonsCar1[i].bCleanupConversationTriggered = FALSE ) IF ( psEnemyGoonsCar1[i].eCleanupReason <> PED_CLEANUP_NO_CLEANUP ) SWITCH psEnemyGoonsCar1[i].eCleanupReason CASE PED_CLEANUP_KILLED_BY_MICHAEL CASE PED_CLEANUP_KILLED_BY_FRANKLIN CASE PED_CLEANUP_KILLED_BY_PLAYER_AS_MICHAEL CASE PED_CLEANUP_KILLED_BY_PLAYER_AS_FRANKLIN CASE PED_CLEANUP_KILLED_BY_VEHICLE IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCEK", CONV_PRIORITY_MEDIUM) psEnemyGoonsCar1[i].bCleanupConversationTriggered = TRUE SET_LABEL_AS_TRIGGERED("FAM3_GCEK", TRUE) ENDIF BREAK CASE PED_CLEANUP_LOST IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCEL", CONV_PRIORITY_MEDIUM) psEnemyGoonsCar1[i].bCleanupConversationTriggered = TRUE SET_LABEL_AS_TRIGGERED("FAM3_GCEL", TRUE) ENDIF BREAK ENDSWITCH ENDIF ENDIF ENDFOR IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() //if for all enemies cleanup conversation IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData) //were somehow triggered earlier IF ( psEnemyGoonsCar0[0].bCleanupConversationTriggered = TRUE ) //play this conversation as a backup AND ( psEnemyGoonsCar0[1].bCleanupConversationTriggered = TRUE ) AND ( psEnemyGoonsCar1[0].bCleanupConversationTriggered = TRUE ) AND ( psEnemyGoonsCar1[1].bCleanupConversationTriggered = TRUE ) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": All enemies have their cleanup conversations triggered.") #ENDIF IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCEL", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_GCEL", TRUE) ENDIF ENDIF ENDIF ENDIF ELSE //play conversation after killing or losing the goons when player ends as Michael or Franklin IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_GCEM") AND NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_GCEH") IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<-768.763489,167.945328,58.474373>>, <<-848.048279,171.888687,77.934120>>, 50) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCEH", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_GCEH", TRUE) ENDIF ELSE IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCEM", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_GCEM", TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF //play shooting stat conversation IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_STATA") AND NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_STATB") IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF ( iPlayerFranklinKills + iBuddyFranklinKills > 0 ) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_STATA", CONV_PRIORITY_MEDIUM) bAllowConvsersationOutsideOfCar = FALSE SET_LABEL_AS_TRIGGERED("FAM3_STATA", TRUE) bAllowConvsersationOutsideOfCar = TRUE bConversationPaused = FALSE ENDIF ELSE IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_STATB", CONV_PRIORITY_MEDIUM) bAllowConvsersationOutsideOfCar = FALSE SET_LABEL_AS_TRIGGERED("FAM3_STATB", TRUE) bAllowConvsersationOutsideOfCar = TRUE bConversationPaused = FALSE ENDIF ENDIF ENDIF ENDIF ENDIF ELSE IF NOT IS_THIS_CONVERSATION_PLAYING("FAM3_STATA") AND NOT IS_THIS_CONVERSATION_PLAYING("FAM3_STATB") bStatConversationFinished = TRUE ENDIF ENDIF IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_DBHA") IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF ARE_PEDS_IN_THE_SAME_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL), GET_PED_INDEX(CHAR_FRANKLIN)) IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_DBHA", CONV_PRIORITY_MEDIUM) bAllowConvsersationOutsideOfCar = TRUE bConversationPaused = FALSE SET_LABEL_AS_TRIGGERED("FAM3_DBHA", TRUE) ENDIF ENDIF ENDIF ENDIF ELSE IF ( bConversationPaused = TRUE ) IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) //wanted level off IF ARE_STRINGS_EQUAL(lConversationRoot, "FAM3_DBHA") IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF CREATE_CONVERSATION_FROM_SPECIFIC_LINE(sFamily3Conversation, "FAM3AUD", "FAM3_DBHA", lConversationLabel, CONV_PRIORITY_MEDIUM) bAllowConvsersationOutsideOfCar = TRUE bConversationPaused = FALSE ENDIF ENDIF ENDIF ENDIF ELSE IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() CurrentRoot = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT() IF NOT IS_STRING_NULL_OR_EMPTY(CurrentRoot) IF ARE_STRINGS_EQUAL(CurrentRoot, "FAM3_DBHA") IF ( psFranklin.fDistanceToTarget > BUDDY_SEPARATION_DIST / 2 ) KILL_FACE_TO_FACE_CONVERSATION() ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_DBHB") IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF ARE_PEDS_IN_THE_SAME_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL), GET_PED_INDEX(CHAR_FRANKLIN)) IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_DBHB", CONV_PRIORITY_MEDIUM) bAllowConvsersationOutsideOfCar = TRUE bConversationPaused = FALSE SET_LABEL_AS_TRIGGERED("FAM3_DBHB", TRUE) ENDIF ENDIF ENDIF ENDIF ELSE IF ( bConversationPaused = TRUE ) IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) //wanted level off IF ARE_STRINGS_EQUAL(lConversationRoot, "FAM3_DBHB") IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF CREATE_CONVERSATION_FROM_SPECIFIC_LINE(sFamily3Conversation, "FAM3AUD", "FAM3_DBHB", lConversationLabel, CONV_PRIORITY_MEDIUM) bAllowConvsersationOutsideOfCar = TRUE bConversationPaused = FALSE ENDIF ENDIF ENDIF ENDIF ELSE IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() CurrentRoot = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT() IF NOT IS_STRING_NULL_OR_EMPTY(CurrentRoot) IF ARE_STRINGS_EQUAL(CurrentRoot, "FAM3_DBHB") IF ( psFranklin.fDistanceToTarget > BUDDY_SEPARATION_DIST / 2 ) KILL_FACE_TO_FACE_CONVERSATION() ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ELSE //play conversations after god text to go back to Michael's house has been displayed but goons chase has not yet started IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_DBHC") IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF HAS_LABEL_BEEN_TRIGGERED(sLabelDHOUSE) OR IS_STRING_NULL_OR_EMPTY(sLabelDHOUSE) IF ARE_PEDS_IN_THE_SAME_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL), GET_PED_INDEX(CHAR_FRANKLIN)) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_DBHC", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_DBHC", TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ELSE IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() CurrentRoot = GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT() IF NOT IS_STRING_NULL_OR_EMPTY(CurrentRoot) IF ARE_STRINGS_EQUAL(CurrentRoot, "FAM3_DBHC") IF ( psFranklin.fDistanceToTarget > BUDDY_SEPARATION_DIST / 2 ) KILL_FACE_TO_FACE_CONVERSATION() ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ELSE //goons chase is in progress IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_GCFSG") //play conversation for Franklin spotting the goons INT k, j IF ( vsEnemyCars[0].bLOSFlag = TRUE OR vsEnemyCars[1].bLOSFlag = TRUE ) OR DOES_ENTITY_EXIST(GET_CLOSEST_PED_FROM_GROUP(psEnemyGoonsCar0, k)) AND psEnemyGoonsCar0[k].fDistanceToTarget < 10.0 OR DOES_ENTITY_EXIST(GET_CLOSEST_PED_FROM_GROUP(psEnemyGoonsCar1, j)) AND psEnemyGoonsCar1[j].fDistanceToTarget < 10.0 IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() //don't check for god text here, allow god text to be interrupted, spawning goons is the priority IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCFSG", CONV_PRIORITY_MEDIUM) IF NOT IS_PED_IN_ANY_VEHICLE(GET_PED_INDEX(CHAR_FRANKLIN)) VEHICLE_INDEX ClosestEnemyCar ClosestEnemyCar = GET_CLOSEST_MISSION_VEHICLE_TO_ENTITY(GET_PED_INDEX(CHAR_FRANKLIN), 100.0, BALLER) IF DOES_ENTITY_EXIST(ClosestEnemyCar) IF NOT IS_ENTITY_DEAD(ClosestEnemyCar) SEQUENCE_INDEX PedSequence OPEN_SEQUENCE_TASK(PedSequence) TASK_TURN_PED_TO_FACE_ENTITY(NULL, ClosestEnemyCar) TASK_LOOK_AT_ENTITY(NULL, ClosestEnemyCar, 3000) CLOSE_SEQUENCE_TASK(PedSequence) TASK_PERFORM_SEQUENCE(GET_PED_INDEX(CHAR_FRANKLIN), PedSequence) CLEAR_SEQUENCE_TASK(PedSequence) ENDIF ENDIF ENDIF REPLAY_RECORD_BACK_FOR_TIME(3.0, 3.0) SET_LABEL_AS_TRIGGERED("FAM3_GCFSG", TRUE) ENDIF ELSE KILL_FACE_TO_FACE_CONVERSATION() ENDIF ENDIF ELSE IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_GCSM") //play conversation for Michael asking Franklin for help dealing with goons IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCSM", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_GCSM", TRUE) ENDIF ENDIF ENDIF ELSE IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_GCSFA") //play Franklins response while they are in the car AND NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_GCSFB") //play Franklins response while they are on foot IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF IS_PED_SITTING_IN_ANY_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL)) AND IS_PED_SITTING_IN_ANY_VEHICLE(GET_PED_INDEX(CHAR_FRANKLIN)) //converstaion when Michael and Franklin are in the car, Franklin tells Michael to drive IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCSFA", CONV_PRIORITY_MEDIUM) iPlayerShootingTimer = GET_GAME_TIMER() SET_LABEL_AS_TRIGGERED("FAM3_GCSFA", TRUE) ENDIF ELSE //converstaion when Michael or Franklin is not in the car, Franklin tells Michael he will help IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCSFB", CONV_PRIORITY_MEDIUM) iPlayerShootingTimer = GET_GAME_TIMER() SET_LABEL_AS_TRIGGERED("FAM3_GCSFB", TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_GCSGS") AND NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_GCSPS") IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) //converstaion when player as Michael attacks the goons first IF ( bGoonsAttacked = TRUE ) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCSPS", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_GCSPS", TRUE) ENDIF ENDIF //converstaion when Michael or Franklin are being shot at by the goons IF IS_BULLET_IN_AREA(GET_ENTITY_COORDS(GET_PED_INDEX(CHAR_MICHAEL), FALSE), 7.5, FALSE) OR IS_BULLET_IN_AREA(GET_ENTITY_COORDS(GET_PED_INDEX(CHAR_FRANKLIN), FALSE), 7.5, FALSE) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCSGS", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_GCSGS", TRUE) ENDIF ENDIF //converstaion when Michael or Franklin are still chased by the goons and time for goons to shoot has expired IF HAS_TIME_PASSED(12500, iPlayerShootingTimer) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCSGS", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_GCSGS", TRUE) ENDIF ENDIF ELSE IF IS_THIS_PRINT_BEING_DISPLAYED("FAM3_LGOONS") //converstaion when Michael or Franklin are being shot at by the goons IF IS_BULLET_IN_AREA(GET_ENTITY_COORDS(GET_PED_INDEX(CHAR_MICHAEL), FALSE), 7.5, FALSE) OR IS_BULLET_IN_AREA(GET_ENTITY_COORDS(GET_PED_INDEX(CHAR_FRANKLIN), FALSE), 7.5, FALSE) IF NOT IS_AMBIENT_SPEECH_PLAYING(GET_PED_INDEX(CHAR_MICHAEL)) PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(GET_PED_INDEX(CHAR_MICHAEL), "FAM3_DDAA", "MICHAEL", SPEECH_PARAMS_FORCE_NORMAL) SET_LABEL_AS_TRIGGERED("FAM3_GCSGS", TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF ELSE IF ( bRandomConversationAllowed = FALSE ) psMichael.iConversationTimer = GET_GAME_TIMER() //reset timers for random dialogue psFranklin.iConversationTimer = GET_GAME_TIMER() iPlayerShootingTimer = GET_GAME_TIMER() bRandomConversationAllowed = TRUE //allow random conversations ENDIF ENDIF ENDIF ENDIF //play random conversations during the goons chase //play dialogue for enemies being killed by Michael and Franklin FOR i = 0 TO 1 //loop through first vehicle group IF ( psEnemyGoonsCar0[i].bCleanupConversationTriggered = FALSE ) IF ( psEnemyGoonsCar0[i].eCleanupReason <> PED_CLEANUP_NO_CLEANUP ) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() AND NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) SWITCH psEnemyGoonsCar0[i].eCleanupReason CASE PED_CLEANUP_LOST //psEnemyGoonsCar0[i].bCleanupConversationTriggered = TRUE BREAK CASE PED_CLEANUP_KILLED_BY_MICHAEL CASE PED_CLEANUP_KILLED_BY_PLAYER_AS_MICHAEL IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_GCMKG_2") IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCMKG", CONV_PRIORITY_MEDIUM) iMichaelEnemyKillConversations++ psEnemyGoonsCar0[i].bCleanupConversationTriggered = TRUE psMichael.iConversationTimer = GET_GAME_TIMER() psFranklin.iConversationTimer = GET_GAME_TIMER() IF ( iMichaelEnemyKillConversations >= 2 ) SET_LABEL_AS_TRIGGERED("FAM3_GCMKG_2", TRUE) ENDIF ENDIF ELSE psEnemyGoonsCar0[i].bCleanupConversationTriggered = TRUE psMichael.iConversationTimer = GET_GAME_TIMER() psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF BREAK CASE PED_CLEANUP_KILLED_BY_FRANKLIN CASE PED_CLEANUP_KILLED_BY_PLAYER_AS_FRANKLIN IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_GCFKG_3") IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCFKG", CONV_PRIORITY_MEDIUM) iFranklinEnemyKillConversations++ psEnemyGoonsCar0[i].bCleanupConversationTriggered = TRUE psMichael.iConversationTimer = GET_GAME_TIMER() psFranklin.iConversationTimer = GET_GAME_TIMER() IF ( iFranklinEnemyKillConversations >= 3 ) SET_LABEL_AS_TRIGGERED("FAM3_GCFKG_3", TRUE) ENDIF ENDIF ELSE psEnemyGoonsCar0[i].bCleanupConversationTriggered = TRUE psMichael.iConversationTimer = GET_GAME_TIMER() psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF BREAK ENDSWITCH ELSE IF ( psEnemyGoonsCar0[i].iConversationTimer = 0 ) psEnemyGoonsCar0[i].iConversationTimer = GET_GAME_TIMER() ELSE IF HAS_TIME_PASSED(3000, psEnemyGoonsCar0[i].iConversationTimer) psEnemyGoonsCar0[i].bCleanupConversationTriggered = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Unable to play ped ", psEnemyGoonsCar0[i].sDebugName ," cleanup conversation due to another conversation ongoing or queued or text being displayed.") #ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF //loop through second vehicle group IF ( psEnemyGoonsCar1[i].bCleanupConversationTriggered = FALSE ) IF ( psEnemyGoonsCar1[i].eCleanupReason <> PED_CLEANUP_NO_CLEANUP ) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() AND NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) SWITCH psEnemyGoonsCar1[i].eCleanupReason CASE PED_CLEANUP_LOST //psEnemyGoonsCar1[i].bCleanupConversationTriggered = TRUE BREAK CASE PED_CLEANUP_KILLED_BY_MICHAEL CASE PED_CLEANUP_KILLED_BY_PLAYER_AS_MICHAEL IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_GCMKG_2") IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCMKG", CONV_PRIORITY_MEDIUM) iMichaelEnemyKillConversations++ psEnemyGoonsCar1[i].bCleanupConversationTriggered = TRUE psMichael.iConversationTimer = GET_GAME_TIMER() psFranklin.iConversationTimer = GET_GAME_TIMER() IF ( iMichaelEnemyKillConversations >= 2 ) SET_LABEL_AS_TRIGGERED("FAM3_GCMKG_2", TRUE) ENDIF ENDIF ELSE psEnemyGoonsCar1[i].bCleanupConversationTriggered = TRUE psMichael.iConversationTimer = GET_GAME_TIMER() psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF BREAK CASE PED_CLEANUP_KILLED_BY_FRANKLIN CASE PED_CLEANUP_KILLED_BY_PLAYER_AS_FRANKLIN IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_GCFKG_3") IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCFKG", CONV_PRIORITY_MEDIUM) iFranklinEnemyKillConversations++ psEnemyGoonsCar1[i].bCleanupConversationTriggered = TRUE psMichael.iConversationTimer = GET_GAME_TIMER() psFranklin.iConversationTimer = GET_GAME_TIMER() IF ( iFranklinEnemyKillConversations >= 3 ) SET_LABEL_AS_TRIGGERED("FAM3_GCFKG_3", TRUE) ENDIF ENDIF ELSE psEnemyGoonsCar1[i].bCleanupConversationTriggered = TRUE psMichael.iConversationTimer = GET_GAME_TIMER() psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF BREAK ENDSWITCH ELSE IF ( psEnemyGoonsCar1[i].iConversationTimer = 0 ) psEnemyGoonsCar1[i].iConversationTimer = GET_GAME_TIMER() ELSE IF HAS_TIME_PASSED(3000, psEnemyGoonsCar1[i].iConversationTimer) psEnemyGoonsCar1[i].bCleanupConversationTriggered = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Unable to play ped ", psEnemyGoonsCar1[i].sDebugName ," cleanup conversation due to another conversation ongoing or queued or text being displayed.") #ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDFOR IF ( bRandomConversationAllowed = TRUE ) //play random Michael line IF HAS_TIME_PASSED(10000, psMichael.iConversationTimer) IF ARE_PEDS_IN_THE_SAME_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL), GET_PED_INDEX(CHAR_FRANKLIN)) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) //Michael is in the driver seat IF IS_PED_SITTING_IN_THIS_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL), GET_VEHICLE_PED_IS_USING(GET_PED_INDEX(CHAR_MICHAEL))) IF GET_PED_VEHICLE_SEAT(GET_PED_INDEX(CHAR_MICHAEL), GET_VEHICLE_PED_IS_USING(GET_PED_INDEX(CHAR_MICHAEL))) = VS_DRIVER IF GET_DISTANCE_TO_CLOSEST_PED_FROM_GROUPS(psEnemyGoonsCar0, psEnemyGoonsCar1) < 30.0 IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCMEF", CONV_PRIORITY_MEDIUM) psMichael.iConversationTimer = GET_GAME_TIMER() ENDIF ELSE IF ( psMichael.iConversationCounter < 4 ) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCMAF", CONV_PRIORITY_MEDIUM) psMichael.iConversationTimer = GET_GAME_TIMER() psMichael.iConversationCounter++ ENDIF ELSE psMichael.iConversationTimer = GET_GAME_TIMER() ENDIF ENDIF ELSE //Michael is in a passenger seat SWITCH GET_RANDOM_INT_IN_RANGE(0, 2) CASE 0 //Michael in combat from car dialgoue IF GET_DISTANCE_TO_CLOSEST_PED_FROM_GROUPS(psEnemyGoonsCar0, psEnemyGoonsCar1) < 20.0 IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCMAG", CONV_PRIORITY_MEDIUM) psMichael.iConversationTimer = GET_GAME_TIMER() ENDIF ENDIF BREAK CASE 1 //Michael telling Franklin to drive faster IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCMDF", CONV_PRIORITY_MEDIUM) psMichael.iConversationTimer = GET_GAME_TIMER() ENDIF BREAK ENDSWITCH ENDIF ENDIF ENDIF ENDIF ELSE //Michael and Franklin are on foot IF NOT IS_PED_IN_ANY_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL)) AND NOT IS_PED_IN_ANY_VEHICLE(GET_PED_INDEX(CHAR_FRANKLIN)) IF ( psFranklin.fDistanceToTarget < BUDDY_SEPARATION_DIST ) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) SWITCH GET_RANDOM_INT_IN_RANGE(0, 2) CASE 0 //Michael in combat on foot dialogue IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCMAG", CONV_PRIORITY_MEDIUM) psMichael.iConversationTimer = GET_GAME_TIMER() ENDIF BREAK CASE 1 //Michael encouraging Franklin for combat IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCMEF", CONV_PRIORITY_MEDIUM) psMichael.iConversationTimer = GET_GAME_TIMER() ENDIF BREAK ENDSWITCH ENDIF ENDIF ELSE psMichael.iConversationTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF ENDIF //play random Franklin line IF HAS_TIME_PASSED(8000, psFranklin.iConversationTimer) IF ARE_PEDS_IN_THE_SAME_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL), GET_PED_INDEX(CHAR_FRANKLIN)) //Franklin is in the driver seat IF IS_PED_SITTING_IN_THIS_VEHICLE(GET_PED_INDEX(CHAR_FRANKLIN), GET_VEHICLE_PED_IS_USING(GET_PED_INDEX(CHAR_FRANKLIN))) IF GET_PED_VEHICLE_SEAT(GET_PED_INDEX(CHAR_FRANKLIN), GET_VEHICLE_PED_IS_USING(GET_PED_INDEX(CHAR_FRANKLIN))) = VS_DRIVER IF GET_DISTANCE_TO_CLOSEST_PED_FROM_GROUPS(psEnemyGoonsCar0, psEnemyGoonsCar1) < 30.0 IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCFEM", CONV_PRIORITY_MEDIUM) psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF ELSE IF ( psFranklin.iConversationCounter < 4 ) IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCFAM", CONV_PRIORITY_MEDIUM) psFranklin.iConversationTimer = GET_GAME_TIMER() psFranklin.iConversationCounter++ ENDIF ELSE psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF ENDIF ELSE //Franklin is in a passenger seat SWITCH GET_RANDOM_INT_IN_RANGE(0, 2) CASE 0 //Franklin in combat from car dialgoue IF GET_DISTANCE_TO_CLOSEST_PED_FROM_GROUPS(psEnemyGoonsCar0, psEnemyGoonsCar1) < 20.0 IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCFAG", CONV_PRIORITY_MEDIUM) psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF ENDIF BREAK CASE 1 //Franklin telling Michael to drive faster IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCFDF", CONV_PRIORITY_MEDIUM) psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF BREAK ENDSWITCH ENDIF ELSE ENDIF ELSE //Michael and Franklin are on foot IF NOT IS_PED_IN_ANY_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL)) AND NOT IS_PED_IN_ANY_VEHICLE(GET_PED_INDEX(CHAR_FRANKLIN)) IF ( psFranklin.fDistanceToTarget < BUDDY_SEPARATION_DIST ) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) SWITCH GET_RANDOM_INT_IN_RANGE(0, 2) CASE 0 //Franklin in combat on foot dialogue IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCFAG", CONV_PRIORITY_MEDIUM) psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF BREAK CASE 1 //Franklin encouraging Michael for combat IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCFEM", CONV_PRIORITY_MEDIUM) psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF BREAK ENDSWITCH ENDIF ENDIF ELSE psFranklin.iConversationTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF ENDIF //play conversations for player being reminded to shoot the goons when not shooting the goons IF NOT IS_PED_SHOOTING(PLAYER_PED_ID()) AND NOT ( IS_PED_SITTING_IN_THIS_VEHICLE(PLAYER_PED_ID(), GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())) AND GET_PED_VEHICLE_SEAT(PLAYER_PED_ID(), GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())) = VS_DRIVER ) IF HAS_TIME_PASSED(10000, iPlayerShootingTimer) IF ( psFranklin.fDistanceToTarget < BUDDY_SEPARATION_DIST ) IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCMNS", CONV_PRIORITY_MEDIUM) psMichael.iConversationTimer = GET_GAME_TIMER() psFranklin.iConversationTimer = GET_GAME_TIMER() iPlayerShootingTimer = GET_GAME_TIMER() ENDIF BREAK CASE CHAR_FRANKLIN IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCFNS", CONV_PRIORITY_MEDIUM) psMichael.iConversationTimer = GET_GAME_TIMER() psFranklin.iConversationTimer = GET_GAME_TIMER() iPlayerShootingTimer = GET_GAME_TIMER() ENDIF BREAK ENDSWITCH ENDIF ENDIF ELSE iPlayerShootingTimer = GET_GAME_TIMER() ENDIF ENDIF ELSE iPlayerShootingTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF BREAK ENDSWITCH //play conversation for Michael and Franklin taking a different vehicle than the initial player truck or leaving truck behind IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_GCCVTM") AND NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_GCCVTF") IF ( iVehicleSwitchTimer = 0 ) //if player decides to use another vehicle IF DOES_ENTITY_EXIST(GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())) AND GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()) <> vsPlayersCar.VehicleIndex iVehicleSwitchTimer = GET_GAME_TIMER() ENDIF ELSE IF HAS_TIME_PASSED(7500, iVehicleSwitchTimer) SET_LABEL_AS_TRIGGERED("FAM3_GCCVTM", TRUE) SET_LABEL_AS_TRIGGERED("FAM3_GCCVTF", TRUE) ELSE IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) IF ( psFranklin.fDistanceToTarget <= BUDDY_SEPARATION_DIST / 2 ) IF ( bStopScriptedConversations = FALSE ) SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCCVTM", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_GCCVTM", TRUE) ENDIF BREAK CASE CHAR_FRANKLIN IF CREATE_CONVERSATION(sFamily3Conversation, "FAM3AUD", "FAM3_GCCVTF", CONV_PRIORITY_MEDIUM) SET_LABEL_AS_TRIGGERED("FAM3_GCCVTF", TRUE) ENDIF BREAK ENDSWITCH ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDPROC PROC MANAGE_OTHER_PLAYER_PED_DURING_ESCAPE_GOONS(PED_INDEX PedIndex, PED_STRUCT &ped, PED_INDEX TargetPedIndex, VEHICLE_INDEX TargetVehicleIndex, BOOL bEnemiesPresent) IF DOES_ENTITY_EXIST(PedIndex) AND NOT IS_ENTITY_DEAD(PedIndex) IF DOES_ENTITY_EXIST(TargetPedIndex) AND NOT IS_ENTITY_DEAD(TargetPedIndex) #IF IS_DEBUG_BUILD //debug information IF ( bDrawDebugStates = TRUE ) DRAW_DEBUG_TEXT_ABOVE_ENTITY(PedIndex, GET_PED_STATE_NAME_FOR_DEBUG(ped.eState), 1.25) ENDIF SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL ped.sDebugName = "Franklin" BREAK CASE CHAR_FRANKLIN ped.sDebugName = "Michael" BREAK ENDSWITCH #ENDIF ped.fDistanceToTarget = GET_DISTANCE_BETWEEN_ENTITIES(PedIndex, TargetPedIndex) FLOAT fDistanceToDestination = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PedIndex), vMichaelsHousePosition) SET_PED_RESET_FLAG(PedIndex, PRF_BlockWeaponReactionsUnlessDead, TRUE) SET_PED_CAN_PLAY_AMBIENT_ANIMS(PedIndex, FALSE) SET_PED_CAN_PLAY_AMBIENT_BASE_ANIMS(PedIndex, FALSE) IF ( bEnemiesPresent = TRUE ) IF ( bCombatAllowed = TRUE ) IF ( GET_AMMO_IN_PED_WEAPON(PedIndex, WEAPONTYPE_PISTOL) < GET_MAX_AMMO_IN_CLIP(PedIndex, WEAPONTYPE_PISTOL) ) ADD_AMMO_TO_PED(PedIndex, WEAPONTYPE_PISTOL, GET_MAX_AMMO_IN_CLIP(PedIndex, WEAPONTYPE_PISTOL)) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Adding extra pistol clip with ", GET_MAX_AMMO_IN_CLIP(PedIndex, WEAPONTYPE_PISTOL), " bullets to buddy ped ", ped.sDebugName, ".") #ENDIF ENDIF ENDIF ENDIF SWITCH ped.eState CASE PED_STATE_IDLE IF ( ped.bHasTask = FALSE ) SET_PED_INFINITE_AMMO(PedIndex, FALSE) GIVE_WEAPON_TO_PED(PedIndex, WEAPONTYPE_PISTOL, GET_MAX_AMMO_IN_CLIP(PedIndex, WEAPONTYPE_PISTOL) * 6, FALSE, TRUE) SET_CURRENT_PED_WEAPON(PedIndex, WEAPONTYPE_PISTOL) SET_RAGDOLL_BLOCKING_FLAGS(PedIndex, RBF_BULLET_IMPACT) SET_RAGDOLL_BLOCKING_FLAGS(PedIndex, RBF_PLAYER_IMPACT) SET_PED_SUFFERS_CRITICAL_HITS(PedIndex, FALSE) SET_PED_MAX_HEALTH_WITH_SCALE(PedIndex, MAX_BUDDY_PED_HEALTH) IF NOT IS_PED_GROUP_MEMBER(PedIndex, PLAYER_GROUP_ID()) SET_PED_AS_GROUP_MEMBER(PedIndex, PLAYER_GROUP_ID()) SET_PED_GROUP_MEMBER_PASSENGER_INDEX(PedIndex, VS_FRONT_RIGHT) SET_PED_CAN_TELEPORT_TO_GROUP_LEADER(PedIndex, PLAYER_GROUP_ID(), TRUE) SET_PED_CONFIG_FLAG(PedIndex, PCF_TeleportToLeaderVehicle, FALSE) ENDIF SET_PED_CONFIG_FLAG(PedIndex, PCF_DisableHurt, TRUE) SET_PED_CONFIG_FLAG(PedIndex, PCF_DisablePanicInVehicle, TRUE) SET_PED_CONFIG_FLAG(PedIndex, PCF_OnlyAttackLawIfPlayerIsWanted, TRUE) SET_COMBAT_FLOAT(PedIndex, CCF_TIME_TO_INVALIDATE_INJURED_TARGET, 1.0) SET_PED_COMBAT_ATTRIBUTES(PedIndex, CA_ALWAYS_EQUIP_BEST_WEAPON, FALSE) SET_PED_COMBAT_ATTRIBUTES(PedIndex, CA_CAN_FIGHT_ARMED_PEDS_WHEN_NOT_ARMED, TRUE) ADD_ENTITY_TO_AUDIO_MIX_GROUP(PedIndex, "FAMILY_3_BUDDY_GROUP") ped.bHasTask = TRUE ENDIF GO_TO_PED_STATE(ped, PED_STATE_FOLLOWING_PLAYER) BREAK CASE PED_STATE_FOLLOWING_PLAYER IF ( ped.bHasTask = FALSE ) IF NOT IS_PED_GROUP_MEMBER(PedIndex, PLAYER_GROUP_ID()) SET_PED_AS_GROUP_MEMBER(PedIndex, PLAYER_GROUP_ID()) ENDIF SET_GROUP_SEPARATION_RANGE(PLAYER_GROUP_ID(), BUDDY_SEPARATION_DIST) SET_PED_GROUP_MEMBER_PASSENGER_INDEX(PedIndex, VS_FRONT_RIGHT) SET_PED_CAN_TELEPORT_TO_GROUP_LEADER(PedIndex, PLAYER_GROUP_ID(), TRUE) SET_PED_ACCURACY(PedIndex, 20) SET_PED_SHOOT_RATE(PedIndex, 115) SET_PED_HIGHLY_PERCEPTIVE(PedIndex, TRUE) SET_PED_COMBAT_ATTRIBUTES(PedIndex, CA_USE_COVER, TRUE) SET_PED_COMBAT_ATTRIBUTES(PedIndex, CA_DO_DRIVEBYS, TRUE) SET_PED_COMBAT_ATTRIBUTES(PedIndex, CA_USE_VEHICLE, TRUE) SET_PED_COMBAT_ATTRIBUTES(PedIndex, CA_LEAVE_VEHICLES, FALSE) SET_COMBAT_FLOAT(PedIndex, CCF_STRAFE_WHEN_MOVING_CHANCE, 0.9) SET_COMBAT_FLOAT(PedIndex, CCF_WALK_WHEN_STRAFING_CHANCE, 0.0) SET_PED_COMBAT_MOVEMENT(PedIndex, CM_DEFENSIVE) SET_PED_DEFENSIVE_SPHERE_ATTACHED_TO_PED(PedIndex, TargetPedIndex, << 0.0, 0.0, 0.0 >>, 5.0) SET_PED_CAN_RAGDOLL(PedIndex, TRUE) SET_RAGDOLL_BLOCKING_FLAGS(PedIndex, RBF_MELEE) SET_RAGDOLL_BLOCKING_FLAGS(PedIndex, RBF_BULLET_IMPACT) SET_RAGDOLL_BLOCKING_FLAGS(PedIndex, RBF_PLAYER_IMPACT) SET_PED_SUFFERS_CRITICAL_HITS(PedIndex, FALSE) SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(PedIndex, FALSE) SET_PED_CONFIG_FLAG(PedIndex, PCF_DisableHurt, TRUE) SET_PED_CONFIG_FLAG(PedIndex, PCF_TeleportToLeaderVehicle, FALSE) SET_PED_CONFIG_FLAG(PedIndex, PCF_DisableGoToWritheWhenInjured, TRUE) SET_PED_CONFIG_FLAG(PedIndex, PCF_OnlyAttackLawIfPlayerIsWanted, TRUE) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PedIndex, FALSE) IF ( bWantedLevelBlockedOnBuddyDrive = TRUE ) SET_MAX_WANTED_LEVEL(5) SET_CREATE_RANDOM_COPS(TRUE) //unblock wanted level if it was blocked when buddy was driving SET_WANTED_LEVEL_MULTIPLIER(1.0) bWantedLevelBlockedOnBuddyDrive = FALSE ENDIF ped.bHasTask = TRUE ENDIF IF ( ped.bHasTask = TRUE) IF ( bEnemiesPresent = TRUE ) IF ( bCombatAllowed = FALSE ) IF IS_PED_IN_THIS_VEHICLE(PedIndex, TargetVehicleIndex) IF IS_PED_SITTING_IN_THIS_VEHICLE(PedIndex, TargetVehicleIndex) IF ( vsEnemyCars[0].bLOSFlag = TRUE OR vsEnemyCars[1].bLOSFlag = TRUE ) GO_TO_PED_STATE(ped, PED_STATE_LOOKING_BEHIND_IN_VEHICLE) ENDIF ENDIF ENDIF ENDIF ENDIF IF ( ped.fDistanceToTarget > BUDDY_SEPARATION_DIST ) OR NOT IS_PED_GROUP_MEMBER(ped.PedIndex, PLAYER_GROUP_ID()) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Ped with debug name ", ped.sDebugName, " is not player group member any more.") #ENDIF GO_TO_PED_STATE(ped, PED_STATE_WAITING_FOR_PLAYER) ENDIF ENDIF IF ( bBuddyPedCoverTaskCleared = FALSE ) IF ( bGoonsChaseFinished = TRUE AND bGoonsChaseInProgress = FALSE ) IF IS_PED_IN_COVER(PedIndex) OR IS_PED_GOING_INTO_COVER(PedIndex) OR IS_PED_IN_COMBAT(PedIndex) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Clearing buddy ped tasks for ped with debug name ", ped.sDebugName, " due to ped being in cover when goons chase ends.") #ENDIF CLEAR_PED_TASKS(PedIndex) ENDIF bBuddyPedCoverTaskCleared = TRUE ENDIF ENDIF BREAK CASE PED_STATE_WAITING_FOR_PLAYER IF ( ped.bHasTask = FALSE ) SET_PED_COMBAT_MOVEMENT(PedIndex, CM_DEFENSIVE) SET_PED_DEFENSIVE_SPHERE_ATTACHED_TO_PED(PedIndex, TargetPedIndex, << 0.0, 0.0, 0.0 >>, 7.5) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PedIndex, FALSE) ped.bHasTask = TRUE ENDIF IF ( ped.bHasTask = TRUE) IF ( ped.fDistanceToTarget <= BUDDY_SEPARATION_DIST / 3 ) GO_TO_PED_STATE(ped, PED_STATE_FOLLOWING_PLAYER) ENDIF ENDIF BREAK CASE PED_STATE_SITTING_IN_VEHICLE_DRIVER IF ( ped.bHasTask = FALSE ) IF IS_PED_SITTING_IN_THIS_VEHICLE(PedIndex, TargetVehicleIndex) CLEAR_PED_TASKS(PedIndex) TASK_VEHICLE_MISSION_COORS_TARGET(PedIndex, TargetVehicleIndex, GET_ENTITY_COORDS(TargetVehicleIndex), MISSION_STOP, 2.5, DRIVINGMODE_AVOIDCARS, 5.0, 5.0) ENDIF SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PedIndex, TRUE) ped.bHasTask = TRUE ENDIF IF IS_PED_SITTING_IN_THIS_VEHICLE(TargetPedIndex, TargetVehicleIndex) IF ( bEnemiesPresent = TRUE ) GO_TO_PED_STATE(ped, PED_STATE_DRIVE_FLEE_TARGETS) ELSE GO_TO_PED_STATE(ped, PED_STATE_DRIVE_TO_DESTINATION) ENDIF ELSE CLEAR_PED_TASKS(PedIndex) GO_TO_PED_STATE(ped, PED_STATE_FOLLOWING_PLAYER) ENDIF BREAK CASE PED_STATE_LOOKING_BEHIND_IN_VEHICLE IF ( ped.bHasTask = FALSE ) IF NOT IS_ENTITY_PLAYING_LOOK_BEHIND_ANIM(PedIndex) IF IS_PED_SITTING_IN_THIS_VEHICLE(PedIndex, TargetVehicleIndex) REQUEST_ANIM_DICT("missfam3") IF HAS_ANIM_DICT_LOADED("missfam3") TASK_PLAY_LOOK_BEHIND_ANIM(PedIndex, GET_PED_VEHICLE_SEAT(PedIndex, TargetVehicleIndex), 6000) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PedIndex, TRUE) ENDIF ENDIF ELSE ped.iTimer = GET_GAME_TIMER() ped.bHasTask = TRUE ENDIF ENDIF IF IS_ENTITY_PLAYING_LOOK_BEHIND_ANIM(PedIndex) IF HAS_TIME_PASSED(2000, ped.iTimer) //make sure the animation is played for at least a brief moment IF NOT IS_PED_SITTING_IN_ANY_VEHICLE(PedIndex) CLEAR_PED_SECONDARY_TASK(PedIndex) ENDIF VEHICLE_INDEX ClosestEnemyCar ClosestEnemyCar = GET_CLOSEST_MISSION_VEHICLE_TO_ENTITY(PedIndex, 100.0, BALLER) IF DOES_ENTITY_EXIST(TargetVehicleIndex) AND DOES_ENTITY_EXIST(ClosestEnemyCar) VECTOR vTargetVehicleForwardVector VECTOR vEnemyCarForwardVector VECTOR vOffset FLOAT fAngleBetweenVectors vEnemyCarForwardVector = GET_ENTITY_FORWARD_VECTOR(ClosestEnemyCar) vTargetVehicleForwardVector = GET_ENTITY_FORWARD_VECTOR(TargetVehicleIndex) //check angle between player's car and closest enemy car fAngleBetweenVectors = GET_ANGLE_BETWEEN_2D_VECTORS(vTargetVehicleForwardVector.X, vTargetVehicleForwardVector.Y, vEnemyCarForwardVector.X, vEnemyCarForwardVector.Y) //check if player is behind or in front of closest enemy car vOffset = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(ClosestEnemyCar, GET_ENTITY_COORDS(PedIndex, FALSE)) #IF IS_DEBUG_BUILD IF ( bDrawDebugLinesAndSpheres = TRUE ) DRAW_DEBUG_TEXT_ABOVE_ENTITY(TargetVehicleIndex, GET_STRING_FROM_FLOAT(fAngleBetweenVectors), 2.0) DRAW_DEBUG_LINE(GET_ENTITY_COORDS(TargetVehicleIndex, FALSE), GET_ENTITY_COORDS(ClosestEnemyCar, FALSE)) DRAW_DEBUG_TEXT_ABOVE_ENTITY(TargetVehicleIndex, GET_STRING_FROM_FLOAT(vOffset.Y), 2.5) ENDIF #ENDIF IF ( vOffset.Y < 0.0 OR fAngleBetweenVectors > 100.0 ) CLEAR_PED_SECONDARY_TASK(PedIndex) ENDIF ENDIF ENDIF ENDIF IF ( bCombatAllowed = TRUE ) CLEAR_PED_TASKS(PedIndex) CLEAR_PED_SECONDARY_TASK(PedIndex) REMOVE_ANIM_DICT("missfam3") GO_TO_PED_STATE(ped, PED_STATE_FOLLOWING_PLAYER) ENDIF BREAK CASE PED_STATE_DRIVE_FLEE_TARGETS IF (ped.bHasTask = FALSE ) INT i, k PED_INDEX EnemyPedIndex GET_CLOSEST_PED_FROM_GROUP(psEnemyGoonsCar0, i) GET_CLOSEST_PED_FROM_GROUP(psEnemyGoonsCar1, k) IF ( i <> -1 AND k <> -1) IF ( psEnemyGoonsCar0[i].fDistanceToTarget <= psEnemyGoonsCar1[k].fDistanceToTarget ) EnemyPedIndex = psEnemyGoonsCar0[i].PedIndex #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Closest enemy ped to flee from is ", psEnemyGoonsCar0[i].sDebugName, ".") #ENDIF ELSE EnemyPedIndex = psEnemyGoonsCar1[k].PedIndex #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Closest enemy ped to flee from is ", psEnemyGoonsCar1[k].sDebugName, ".") #ENDIF ENDIF ELSE IF ( i <> -1 ) EnemyPedIndex = psEnemyGoonsCar0[i].PedIndex #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Closest enemy ped to flee from is ", psEnemyGoonsCar0[i].sDebugName, ".") #ENDIF ELIF ( k <> -1 ) EnemyPedIndex = psEnemyGoonsCar1[k].PedIndex #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Closest enemy ped to flee from is ", psEnemyGoonsCar1[k].sDebugName, ".") #ENDIF ENDIF ENDIF IF NOT IS_ENTITY_AT_COORD(PedIndex, << -804.86, 166.51, 70.56 >>, << 36.0, 24.0, 12.0 >>) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Buddy ped away from Michael's house area.") #ENDIF IF DOES_ENTITY_EXIST(EnemyPedIndex) //found enemy to flee #IF IS_DEBUG_BUILD VECTOR vPrintCoords vPrintCoords = GET_ENTITY_COORDS(EnemyPedIndex, FALSE) PRINTLN(GET_THIS_SCRIPT_NAME(), ": Found closest enemy to flee. Fleeing coords of enemy ", vPrintCoords, ".") DRAW_DEBUG_LINE(GET_ENTITY_COORDS(PedIndex, FALSE), GET_ENTITY_COORDS(EnemyPedIndex, FALSE), 255, 255, 255) #ENDIF CLEAR_PED_TASKS(PedIndex) //flee from coords where closest enemy ped is TASK_VEHICLE_MISSION_COORS_TARGET(PedIndex, TargetVehicleIndex, GET_ENTITY_COORDS(EnemyPedIndex, FALSE), MISSION_FLEE, 25.0, DF_SteerAroundObjects | DF_SteerAroundPeds | DF_SteerAroundStationaryCars | DF_ChangeLanesAroundObstructions | DF_ForceJoinInRoadDirection | DF_SwerveAroundAllCars, //| DF_UseStringPullingAtJunctions, 500.0, 10.0, FALSE) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PedIndex, TRUE) ped.iTimer = GET_GAME_TIMER() ELSE //not found enemy to flee #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Not found nearby enemies. Fleeing coords of vehicle player ped is using.") #ENDIF CLEAR_PED_TASKS(PedIndex) TASK_VEHICLE_MISSION_COORS_TARGET(PedIndex, TargetVehicleIndex, GET_ENTITY_COORDS(TargetVehicleIndex), MISSION_FLEE, 26.0, DF_SteerAroundObjects | DF_SteerAroundPeds | DF_SteerAroundStationaryCars | DF_ChangeLanesAroundObstructions | DF_ForceJoinInRoadDirection | DF_SwerveAroundAllCars, //| DF_UseStringPullingAtJunctions, 500.0, 10.0, FALSE) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PedIndex, TRUE) ped.iTimer = GET_GAME_TIMER() ENDIF ELSE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Buddy ped doing drive flee task in Michael's house area.") #ENDIF CLEAR_PED_TASKS(PedIndex) GO_TO_PED_STATE(ped, PED_STATE_COMBAT_ON_FOOT) ENDIF ped.bHasTask = TRUE ENDIF IF ( bEnemiesPresent = FALSE ) IF ( bDriveTaskDelayed = FALSE ) GO_TO_PED_STATE(ped, PED_STATE_DRIVE_FLEE_TARGETS) //when goons are lost task the buddy to flee once more bDriveTaskDelayed = TRUE //until dialogue to go home triggers or delay timer expires ENDIF IF ( iDriveTaskDelayTimer = 0 ) iDriveTaskDelayTimer = GET_GAME_TIMER() ENDIF IF ( ( iDriveTaskDelayTimer != 0 ) AND HAS_TIME_PASSED(12500, iDriveTaskDelayTimer) ) OR HAS_LABEL_BEEN_TRIGGERED("FAM3_GCEM") OR HAS_LABEL_BEEN_TRIGGERED("FAM3_GCEF") GO_TO_PED_STATE(ped, PED_STATE_DRIVE_TO_DESTINATION) ELSE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Waiting for drive to destination task to be given.") #ENDIF ENDIF ELSE SWITCH GET_SCRIPT_TASK_STATUS(PedIndex, SCRIPT_TASK_VEHICLE_MISSION) CASE PERFORMING_TASK IF HAS_TIME_PASSED(5000, ped.iTimer) GO_TO_PED_STATE(ped, PED_STATE_DRIVE_FLEE_TARGETS) ENDIF BREAK CASE FINISHED_TASK GO_TO_PED_STATE(ped, PED_STATE_DRIVE_FLEE_TARGETS) BREAK ENDSWITCH ENDIF IF NOT IS_PED_IN_THIS_VEHICLE(TargetPedIndex, TargetVehicleIndex) GO_TO_PED_STATE(ped, PED_STATE_SITTING_IN_VEHICLE_DRIVER) ENDIF IF IS_PED_IN_THIS_VEHICLE(PedIndex, TargetVehicleIndex) AND IS_PED_IN_THIS_VEHICLE(TargetPedIndex, TargetVehicleIndex) IF IS_ENTITY_AT_COORD(PedIndex, << -804.86, 166.51, 70.56 >>, << 36.0, 24.0, 12.0 >>) CLEAR_PED_TASKS(PedIndex) GO_TO_PED_STATE(ped, PED_STATE_COMBAT_ON_FOOT) ENDIF ENDIF BREAK CASE PED_STATE_DRIVE_FLEE_COPS IF (ped.bHasTask = FALSE ) CLEAR_PED_TASKS(PedIndex) PED_INDEX CopPedIndex CopPedIndex = GET_PED_CLOSEST_PED_FROM_RELATIONSHIP_GROUP(PedIndex, RELGROUPHASH_COP) IF DOES_ENTITY_EXIST(CopPedIndex) #IF IS_DEBUG_BUILD DRAW_DEBUG_LINE(GET_ENTITY_COORDS(PedIndex, FALSE), GET_ENTITY_COORDS(CopPedIndex, FALSE), 255, 255, 255) #ENDIF TASK_VEHICLE_MISSION_PED_TARGET(PedIndex, TargetVehicleIndex, CopPedIndex, MISSION_FLEE, 30.0, DF_SteerAroundObjects | DF_SteerAroundPeds | DF_SteerAroundStationaryCars | DF_ChangeLanesAroundObstructions | DF_ForceJoinInRoadDirection | DF_SwerveAroundAllCars, //| DF_UseStringPullingAtJunctions, 400.0, 100.0, FALSE) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PedIndex, TRUE) ped.iTimer = GET_GAME_TIMER() ELSE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Not found nearby cops. Fleeing coords.") #ENDIF TASK_VEHICLE_MISSION_COORS_TARGET(PedIndex, TargetVehicleIndex, GET_ENTITY_COORDS(TargetVehicleIndex), MISSION_FLEE, 25.0, DF_SteerAroundObjects | DF_SteerAroundPeds | DF_SteerAroundStationaryCars | DF_ChangeLanesAroundObstructions | DF_ForceJoinInRoadDirection | DF_SwerveAroundAllCars, //| DF_UseStringPullingAtJunctions, 400.0, 100.0, FALSE) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PedIndex, TRUE) ped.iTimer = GET_GAME_TIMER() ENDIF ped.bHasTask = TRUE ENDIF IF IS_PLAYER_PLAYING(PLAYER_ID()) IF NOT IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0) GO_TO_PED_STATE(ped, PED_STATE_DRIVE_TO_DESTINATION) ELSE SWITCH GET_SCRIPT_TASK_STATUS(PedIndex, SCRIPT_TASK_VEHICLE_MISSION) CASE PERFORMING_TASK IF HAS_TIME_PASSED(5000, ped.iTimer) GO_TO_PED_STATE(ped, PED_STATE_DRIVE_FLEE_COPS) ENDIF BREAK CASE FINISHED_TASK GO_TO_PED_STATE(ped, PED_STATE_DRIVE_FLEE_COPS) BREAK ENDSWITCH ENDIF ENDIF IF NOT IS_PED_IN_THIS_VEHICLE(TargetPedIndex, TargetVehicleIndex) GO_TO_PED_STATE(ped, PED_STATE_SITTING_IN_VEHICLE_DRIVER) ENDIF BREAK CASE PED_STATE_DRIVE_TO_DESTINATION IF ( ped.bHasTask = FALSE ) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Ped in PED_STATE_DRIVE_TO_DESTINATION state.") #ENDIF IF DOES_ENTITY_EXIST(TargetVehicleIndex) CALCULATE_PATH_NODES_AREA_FOR_POS(GET_ENTITY_COORDS(TargetVehicleIndex)) REQUEST_PATH_NODES_IN_AREA_THIS_FRAME(fMinX, fMinY, fMaxX, fMaxY) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Calling REQUEST_PATH_NODES_IN_AREA_THIS_FRAME(", fMinX, ",", fMinY, ",", fMaxX, ",", fMaxY, ").") #ENDIF IF ARE_NODES_LOADED_FOR_AREA(fMinX, fMinY, fMaxX, fMaxY) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Path nodes loaded in area (", fMinX, ",", fMinY, ",", fMaxX, ",", fMaxY, ").") #ENDIF CLEAR_PED_TASKS(PedIndex) TASK_VEHICLE_MISSION_COORS_TARGET(PedIndex, TargetVehicleIndex, vMichaelsHousePosition, MISSION_GOTO, 20.0, DF_SteerAroundStationaryCars | DF_StopForPeds | DF_StopAtLights | DF_ChangeLanesAroundObstructions | DF_StopForCars | DF_ForceJoinInRoadDirection, 1.0, 2.0, FALSE) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PedIndex, TRUE) ped.bHasTask = TRUE ENDIF ENDIF ENDIF IF DOES_ENTITY_EXIST(TargetVehicleIndex) CALCULATE_PATH_NODES_AREA_FOR_POS(GET_ENTITY_COORDS(TargetVehicleIndex)) REQUEST_PATH_NODES_IN_AREA_THIS_FRAME(fMinX, fMinY, fMaxX, fMaxY) ENDIF IF ( bEnemiesPresent = TRUE ) IF ( fDistanceToDestination < 125.0 ) GO_TO_PED_STATE(ped, PED_STATE_DRIVE_FLEE_TARGETS) ENDIF ENDIF IF IS_PED_SITTING_IN_THIS_VEHICLE(PedIndex, TargetVehicleIndex) IF IS_ENTITY_AT_COORD(TargetVehicleIndex, << -847.36, 159.09, 66.32 >>, << 8.0, 3.5, 3.0 >>) SET_DRIVE_TASK_CRUISE_SPEED(PedIndex, 10.0) //make the buddy slow down when reaching mansion gate IF ( bWantedLevelBlockedOnBuddyDrive = FALSE ) IF IS_PLAYER_PLAYING(PLAYER_ID()) IF NOT IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0) //block wanted level when buddy is driving home SET_MAX_WANTED_LEVEL(0) //this is stop buddy AI and player becoming wanted SET_WANTED_LEVEL_MULTIPLIER(0.0) //when they drive into the mansion driveway SET_CREATE_RANDOM_COPS(FALSE) //since AI has trouble fleeing from there bWantedLevelBlockedOnBuddyDrive = TRUE //set the wanted level blocked here only ENDIF ENDIF ENDIF ENDIF ENDIf IF NOT IS_PED_IN_THIS_VEHICLE(TargetPedIndex, TargetVehicleIndex) GO_TO_PED_STATE(ped, PED_STATE_SITTING_IN_VEHICLE_DRIVER) ENDIF IF IS_PLAYER_PLAYING(PLAYER_ID()) IF IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0) GO_TO_PED_STATE(ped, PED_STATE_DRIVE_FLEE_COPS) ENDIF ENDIF BREAK CASE PED_STATE_ENTERING_VEHICLE IF ( ped.bHasTask = FALSE ) IF NOT IS_PED_GROUP_MEMBER(PedIndex, PLAYER_GROUP_ID()) SET_PED_AS_GROUP_MEMBER(PedIndex, PLAYER_GROUP_ID()) SET_PED_GROUP_MEMBER_PASSENGER_INDEX(PedIndex, VS_FRONT_RIGHT) SET_PED_CAN_TELEPORT_TO_GROUP_LEADER(PedIndex, PLAYER_GROUP_ID(), TRUE) SET_PED_CONFIG_FLAG(PedIndex, PCF_TeleportToLeaderVehicle, TRUE) ENDIF TASK_ENTER_VEHICLE(PedIndex, TargetVehicleIndex, DEFAULT_TIME_BEFORE_WARP, VS_ANY_PASSENGER, PEDMOVE_RUN) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PedIndex, TRUE) ped.bHasTask = TRUE ENDIF IF IS_PED_SITTING_IN_THIS_VEHICLE(PedIndex, TargetVehicleIndex) GO_TO_PED_STATE(ped, PED_STATE_FOLLOWING_PLAYER) ENDIF BREAK CASE PED_STATE_COMBAT_ON_FOOT IF ( ped.bHasTask = FALSE ) CLEAR_PED_TASKS(PedIndex) IF IS_PED_GROUP_MEMBER(PedIndex, PLAYER_GROUP_ID()) REMOVE_PED_FROM_GROUP(PedIndex) ENDIF SET_PED_COMBAT_ATTRIBUTES(PedIndex, CA_USE_VEHICLE, FALSE) SET_PED_COMBAT_ATTRIBUTES(PedIndex, CA_LEAVE_VEHICLES, TRUE) SET_COMBAT_FLOAT(PedIndex, CCF_STRAFE_WHEN_MOVING_CHANCE, 0.9) SET_COMBAT_FLOAT(PedIndex, CCF_WALK_WHEN_STRAFING_CHANCE, 0.0) SET_PED_COMBAT_MOVEMENT(PedIndex, CM_DEFENSIVE) SET_PED_DEFENSIVE_SPHERE_ATTACHED_TO_PED(PedIndex, TargetPedIndex, << 0.0, 0.0, 0.0 >>, 5.0) TASK_COMBAT_HATED_TARGETS_AROUND_PED(PedIndex, 250.0) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PedIndex, FALSE) ped.bHasTask = TRUE ENDIF IF ( bEnemiesPresent = FALSE ) CLEAR_PED_TASKS(PedIndex) GO_TO_PED_STATE(ped, PED_STATE_FOLLOWING_PLAYER) ENDIF IF NOT IS_PED_IN_ANY_VEHICLE(TargetPedIndex) GO_TO_PED_STATE(ped, PED_STATE_FOLLOWING_PLAYER) ENDIF BREAK CASE PED_STATE_WAITING_FOR_TASK_AFTER_SWITCH IF ( ped.bHasTask = FALSE ) IF ( bWantedLevelBlockedOnBuddyDrive = TRUE ) SET_MAX_WANTED_LEVEL(5) SET_CREATE_RANDOM_COPS(TRUE) //unblock wanted level if it was blocked when buddy was driving SET_WANTED_LEVEL_MULTIPLIER(1.0) bWantedLevelBlockedOnBuddyDrive = FALSE ENDIF ped.bHasTask = TRUE ENDIF IF IS_PED_IN_THIS_VEHICLE(PedIndex, TargetVehicleIndex) IF IS_PED_SITTING_IN_THIS_VEHICLE(PedIndex, TargetVehicleIndex) SWITCH GET_PED_VEHICLE_SEAT(PedIndex, TargetVehicleIndex) CASE VS_DRIVER IF ( bEnemiesPresent = TRUE ) GO_TO_PED_STATE(ped, PED_STATE_DRIVE_FLEE_TARGETS) ELSE GO_TO_PED_STATE(ped, PED_STATE_DRIVE_TO_DESTINATION) ENDIF BREAK DEFAULT GO_TO_PED_STATE(ped, PED_STATE_FOLLOWING_PLAYER) BREAK ENDSWITCH ENDIF ELSE GO_TO_PED_STATE(ped, PED_STATE_FOLLOWING_PLAYER) ENDIF BREAK ENDSWITCH ENDIF ENDIF ENDPROC FUNC BOOL IS_MISSION_STAGE_ESCAPE_GOONS_COMPLETED(INT &iStageProgress) //don't use locates header J skip SET_BIT(sLocatesData.iLocatesBitSet, BS_DONT_DO_J_SKIP) SUPPRESS_CONTEXT_BUTTON_ACTIONS_THIS_FRAME() DISABLE_CINEMATIC_BONNET_CAMERA_FOR_LOOK_BEHIND_ANIMATION() IF IS_PLAYER_PLAYING(PLAYER_ID()) SET_ALL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID()) ENDIF MANAGE_GOONS(iGoonsProgress) IF ( bAllowHotSwap = TRUE ) IF ( bGoonsChaseFinished = TRUE ) IF NOT IS_SELECTOR_CAM_ACTIVE() IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) bAllowHotSwap = FALSE ELSE IF IS_PED_SITTING_IN_THIS_VEHICLE(PLAYER_PED_ID(), GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())) IF IS_PED_SITTING_IN_VEHICLE_SEAT(PLAYER_PED_ID(), GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()), VS_DRIVER) bAllowHotSwap = FALSE ENDIF ENDIF ENDIF ENDIF ENDIF IF ( bHotSwapHinted = FALSE ) SET_SELECTOR_PED_HINT(sSelectorPeds, SELECTOR_PED_FRANKLIN, TRUE) bHotSwapHinted = TRUE ENDIF IF ( bHotSwapTriggered = FALSE) IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_HSWITCH2") IF ( iHotSwapHintTimer = 0 ) iHotSwapHintTimer = GET_GAME_TIMER() ELSE IF HAS_TIME_PASSED(30000, iHotSwapHintTimer) PRINT_HELP("FAM3_HSWITCH", DEFAULT_HELP_TEXT_TIME + 2500) SET_LABEL_AS_TRIGGERED("FAM3_HSWITCH2", TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF MANAGE_CONVERSATIONS_DURING_ESCAPE_GOONS(iConversationProgress) UPDATE_TRIGGERED_LABEL(sLabelDHOUSE) UPDATE_TRIGGERED_LABEL(sLabelGETBCK) UPDATE_TRIGGERED_LABEL(sLabelFLEAVE) UPDATE_TRIGGERED_LABEL(sLabelMLEAVE) UPDATE_TRIGGERED_LABEL(sLabelLWANTED) IF NOT DOES_PARTICLE_FX_LOOPED_EXIST(ptfxDustCloud) //make sure dust particles are created REQUEST_PTFX_ASSET() IF HAS_PTFX_ASSET_LOADED() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Starting particle fx ent_ray_fam3_dust_settle.") #ENDIF ptfxDustCloud = START_PARTICLE_FX_LOOPED_AT_COORD("ent_ray_fam3_dust_settle", << -1016.0, 642.0, 141.0 >>, << 0.0, 0.0, 0.0 >>) ENDIF ENDIF SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL //player playing as Michael, update Franklin //update Franklin's tasks MANAGE_OTHER_PLAYER_PED_DURING_ESCAPE_GOONS(GET_PED_INDEX(CHAR_FRANKLIN), psFranklin, PLAYER_PED_ID(), GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()), bGoonsChaseInProgress) //display warning when player is leaving Franklin behind IF NOT DOES_BLIP_EXIST(sLocatesData.LocationBlip) AND NOT DOES_BLIP_EXIST(sLocatesData.BuddyBlipID[0]) IF psFranklin.fDistanceToTarget > BUDDY_SEPARATION_DIST IF NOT DOES_BLIP_EXIST(psFranklin.BlipIndex) psFranklin.BlipIndex = CREATE_BLIP_ON_ENTITY(GET_PED_INDEX(CHAR_FRANKLIN), TRUE) ENDIF IF NOT HAS_LABEL_BEEN_TRIGGERED(sLabelFLEAVE) PRINT_GOD_TEXT_ADVANCED(sLabelFLEAVE, DEFAULT_GOD_TEXT_TIME, TRUE) ENDIF ENDIF IF DOES_BLIP_EXIST(psFranklin.BlipIndex) IF ( psFranklin.fDistanceToTarget <= BUDDY_SEPARATION_DIST / 3 ) IF IS_THIS_PRINT_BEING_DISPLAYED(sLabelFLEAVE) CLEAR_PRINTS() ENDIF REMOVE_BLIP(psFranklin.BlipIndex) ENDIF ENDIF ENDIF IF ( bGoonsChaseInProgress = TRUE ) IF NOT IS_AUDIO_SCENE_ACTIVE("FAMILY_3_ESCAPE_AS_MICHAEL") START_AUDIO_SCENE("FAMILY_3_ESCAPE_AS_MICHAEL") ENDIF IF IS_AUDIO_SCENE_ACTIVE("FAMILY_3_ESCAPE_AS_FRANKLIN") STOP_AUDIO_SCENE("FAMILY_3_ESCAPE_AS_FRANKLIN") ENDIF ENDIF BREAK CASE CHAR_FRANKLIN //player playing as Franklin, update Michael //update Michael's tasks MANAGE_OTHER_PLAYER_PED_DURING_ESCAPE_GOONS(GET_PED_INDEX(CHAR_MICHAEL), psFranklin, PLAYER_PED_ID(), GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()), bGoonsChaseInProgress) //display warning when player is leaving Michael behind IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) AND NOT DOES_BLIP_EXIST(sLocatesData.BuddyBlipID[0]) IF psFranklin.fDistanceToTarget > BUDDY_SEPARATION_DIST IF NOT DOES_BLIP_EXIST(psMichael.BlipIndex) psMichael.BlipIndex = CREATE_BLIP_ON_ENTITY(GET_PED_INDEX(CHAR_MICHAEL), TRUE) ENDIF IF NOT HAS_LABEL_BEEN_TRIGGERED(sLabelMLEAVE) PRINT_GOD_TEXT_ADVANCED(sLabelMLEAVE, DEFAULT_GOD_TEXT_TIME, TRUE) ENDIF ENDIF IF DOES_BLIP_EXIST(psMichael.BlipIndex) IF ( psMichael.fDistanceToTarget <= BUDDY_SEPARATION_DIST / 3 ) IF IS_THIS_PRINT_BEING_DISPLAYED(sLabelMLEAVE) CLEAR_PRINTS() ENDIF REMOVE_BLIP(psMichael.BlipIndex) ENDIF ENDIF ENDIF IF ( bGoonsChaseInProgress = TRUE ) IF NOT IS_AUDIO_SCENE_ACTIVE("FAMILY_3_ESCAPE_AS_FRANKLIN") START_AUDIO_SCENE("FAMILY_3_ESCAPE_AS_FRANKLIN") ENDIF IF IS_AUDIO_SCENE_ACTIVE("FAMILY_3_ESCAPE_AS_MICHAEL") STOP_AUDIO_SCENE("FAMILY_3_ESCAPE_AS_MICHAEL") ENDIF ENDIF BREAK ENDSWITCH IF ( bGoonsChaseFinished = TRUE ) IF IS_PLAYER_BROWSING_ITEMS_IN_ANY_SHOP() OR IS_PLAYER_CHANGING_CLOTHES() IF HAS_THIS_CUTSCENE_LOADED("family_3_ext") OR HAS_CUTSCENE_LOADED() OR IS_CUTSCENE_ACTIVE() REMOVE_CUTSCENE() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Player browsing items in a shop or changing clothes. Removing cutscene.") #ENDIF ENDIF ELSE IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), vMichaelsHousePosition) < DEFAULT_CUTSCENE_LOAD_DIST REQUEST_MODEL(BALLER) REQUEST_CUTSCENE("family_3_ext") IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY() IF NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_MICHAEL)) SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Michael", GET_PED_INDEX(CHAR_MICHAEL)) ENDIF IF NOT IS_PED_INJURED(GET_PED_INDEX(CHAR_FRANKLIN)) SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED("Franklin", GET_PED_INDEX(CHAR_FRANKLIN)) ENDIF bCutsceneAssetsRequested = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting cutscene ped components for cutscene ped Michael and Franklin from peds during stage ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eMissionStage), ".") PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting bCutsceneAssetsRequested to ", bCutsceneAssetsRequested, ".") #ENDIF ENDIF ELSE IF HAS_THIS_CUTSCENE_LOADED("family_3_ext") OR HAS_CUTSCENE_LOADED() OR IS_CUTSCENE_ACTIVE() REMOVE_CUTSCENE() SET_MODEL_AS_NO_LONGER_NEEDED(BALLER) bCutsceneAssetsRequested = FALSE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Player too far away from destination to keep cutscene in memory. Removing cutscene.") PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting bCutsceneAssetsRequested to ", bCutsceneAssetsRequested, ".") #ENDIF ENDIF ENDIF ENDIF ENDIF SWITCH iStageProgress CASE 0 IF ( bGoonsChaseInProgress = FALSE ) //goons chase not in progress IF ( bRunLocatesHeaderCheck = TRUE ) IF ( bGoonsChaseFinished = FALSE ) //goons chase not finished //display this initially but also progress the mission if the player gets to the house without spawning goons IF IS_PLAYER_AT_ANGLED_AREA_WITH_BUDDY_ANY_MEANS(sLocatesData, vMichaelsHousePosition, << -824.81, 185.38, 69.95 >>, << -820.61, 179.79, 73.64 >>, 8.5, TRUE, GET_PED_INDEX(CHAR_FRANKLIN), sLabelDHOUSE, sLabelFLEAVE, FALSE, TRUE) IF IS_PED_SITTING_IN_ANY_VEHICLE(PLAYER_PED_ID()) IF IS_VEHICLE_ON_ALL_WHEELS(GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())) KILL_ANY_CONVERSATION() KILL_FACE_TO_FACE_CONVERSATION() //kill conversations and let last line play out bStopScriptedConversations = TRUE SETTIMERA(0) //start backup timer in case the conversations are busted by streaming bGoonsChaseFinished = TRUE //consider the chase ended if the player gets to the house before goons spawn iStageProgress++ ENDIF ELSE KILL_ANY_CONVERSATION() KILL_FACE_TO_FACE_CONVERSATION() //kill conversations and let last line play out bStopScriptedConversations = TRUE SETTIMERA(0) //start backup timer in case the conversations are busted by streaming bGoonsChaseFinished = TRUE //consider the chase ended if the player gets to the house before goons spawn iStageProgress++ ENDIF ENDIF ELSE //goons chase finished, goons lost or killed IF IS_AUDIO_SCENE_ACTIVE("FAMILY_3_ESCAPE_AS_MICHAEL") STOP_AUDIO_SCENE("FAMILY_3_ESCAPE_AS_MICHAEL") ENDIF IF IS_AUDIO_SCENE_ACTIVE("FAMILY_3_ESCAPE_AS_FRANKLIN") STOP_AUDIO_SCENE("FAMILY_3_ESCAPE_AS_FRANKLIN") ENDIF IF NOT IS_AUDIO_SCENE_ACTIVE("FAMILY_3_DRIVE_HOME") IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) START_AUDIO_SCENE("FAMILY_3_DRIVE_HOME") ENDIF ENDIF IF DOES_BLIP_EXIST(psFranklin.BlipIndex) //remove buddy ped blips, locates header REMOVE_BLIP(psFranklin.BlipIndex) //will handle the blips once goons are lost ENDIF IF DOES_BLIP_EXIST(psMichael.BlipIndex) REMOVE_BLIP(psMichael.BlipIndex) ENDIF IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("FAM3_HSWITCH") CLEAR_HELP() //remove switch help text if still on screen ENDIF IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_HSTAT1") IF HAS_LABEL_BEEN_TRIGGERED("FAM3_STATA") OR HAS_LABEL_BEEN_TRIGGERED("FAM3_STATB") IF ( bStatConversationFinished = TRUE ) IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) PRINT_HELP("FAM3_HSTAT1", DEFAULT_HELP_TEXT_TIME + 2500) SET_LABEL_AS_TRIGGERED("FAM3_HSTAT1", TRUE) ENDIF ENDIF ENDIF ELSE IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_HSTAT2") IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF NOT IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("FAM3_HSTAT1") PRINT_HELP("FAM3_HSTAT2", DEFAULT_HELP_TEXT_TIME + 2500) SET_LABEL_AS_TRIGGERED("FAM3_HSTAT2", TRUE) ENDIF ENDIF ENDIF ENDIF //just display the blip and locates checks for correct player ped SWITCH GET_CURRENT_PLAYER_PED_ENUM() CASE CHAR_MICHAEL //just display locates header check IS_PLAYER_AT_LOCATION_WITH_BUDDY_ANY_MEANS(sLocatesData, vMichaelsHousePosition, DEFAULT_LOCATES_SIZE_VECTOR(), TRUE, GET_PED_INDEX(CHAR_FRANKLIN), sLabelDHOUSE, sLabelFLEAVE, FALSE, TRUE, NOT bLoseWantedDisplayed) BREAK CASE CHAR_FRANKLIN //just display locates header check IS_PLAYER_AT_LOCATION_WITH_BUDDY_ANY_MEANS(sLocatesData, vMichaelsHousePosition, DEFAULT_LOCATES_SIZE_VECTOR(), TRUE, GET_PED_INDEX(CHAR_MICHAEL), sLabelDHOUSE, sLabelMLEAVE, FALSE, TRUE, NOT bLoseWantedDisplayed) BREAK ENDSWITCH IF ( bLoseWantedDisplayed = FALSE ) //player is not wanted IF NOT DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0) IF HAS_LABEL_BEEN_TRIGGERED(sLabelLWANTED) bLoseWantedDisplayed = TRUE ENDIF ENDIF ENDIF ELSE //player is wanted IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) IF NOT IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0) sLabelLWANTED = "LOSE_WANTED" bLoseWantedDisplayed = FALSE ENDIF ENDIF ENDIF //do the check to progress the stage here IF DOES_BLIP_EXIST(sLocatesData.LocationBlip) //both peds in vehicle angled area IF ARE_PEDS_IN_THE_SAME_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL), GET_PED_INDEX(CHAR_FRANKLIN)) IF IS_ENTITY_IN_ANGLED_AREA(GET_PED_INDEX(CHAR_MICHAEL), << -824.81, 185.38, 69.95 >>, << -820.61, 179.79, 73.64 >>, 8.5) //7.5 AND IS_ENTITY_IN_ANGLED_AREA(GET_PED_INDEX(CHAR_FRANKLIN), << -824.81, 185.38, 69.95 >>, << -820.61, 179.79, 73.64 >>, 8.5) //7.5 IF IS_VEHICLE_ON_ALL_WHEELS(GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())) CLEAR_MISSION_LOCATION_TEXT_AND_BLIPS(sLocatesData) KILL_ANY_CONVERSATION() KILL_FACE_TO_FACE_CONVERSATION() //kill conversations and let last line play out bStopScriptedConversations = TRUE SETTIMERA(0) //start backup timer in case the conversations are busted by streaming iStageProgress++ ENDIF ENDIF ELSE //one of the peds on foot, while the other on foot IF IS_ENTITY_AT_COORD(GET_PED_INDEX(CHAR_MICHAEL), << -823.28, 180.69, 71.63 >>, << 8.0, 8.0, 3.0 >>) AND IS_ENTITY_AT_COORD(GET_PED_INDEX(CHAR_FRANKLIN), << -823.28, 180.69, 71.63 >>, << 8.0, 8.0, 3.0 >>) IF IS_PED_SITTING_IN_ANY_VEHICLE(PLAYER_PED_ID()) IF IS_VEHICLE_ON_ALL_WHEELS(GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())) CLEAR_MISSION_LOCATION_TEXT_AND_BLIPS(sLocatesData) KILL_ANY_CONVERSATION() KILL_FACE_TO_FACE_CONVERSATION() //kill conversations and let last line play out bStopScriptedConversations = TRUE SETTIMERA(0) //start backup timer in case the conversations are busted by streaming iStageProgress++ ENDIF ELSE CLEAR_MISSION_LOCATION_TEXT_AND_BLIPS(sLocatesData) KILL_ANY_CONVERSATION() KILL_FACE_TO_FACE_CONVERSATION() //kill conversations and let last line play out bStopScriptedConversations = TRUE SETTIMERA(0) //start backup timer in case the conversations are busted by streaming iStageProgress++ ENDIF ENDIF ENDIF ENDIF ENDIF ELSE //not running locates header check when being chased by the goons ENDIF ELSE //goons chase in progress IF ( bRunLocatesHeaderCheck = TRUE ) //disable locates header checks when goons chase starts //clear locates header blip and text CLEAR_MISSION_LOCATION_TEXT_AND_BLIPS(sLocatesData) //set the flag again to false because clearing locates header stuff sets the flag to TRUE SET_PED_CONFIG_FLAG(GET_PED_INDEX(CHAR_MICHAEL), PCF_WillFlyThroughWindscreen, FALSE) SET_PED_CONFIG_FLAG(GET_PED_INDEX(CHAR_FRANKLIN), PCF_WillFlyThroughWindscreen, FALSE) bRunLocatesHeaderCheck = FALSE ENDIF //check if player fired at least once as passenger IF ( bPlayerFiredAsPassenger = FALSE ) IF ARE_PEDS_IN_THE_SAME_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL), GET_PED_INDEX(CHAR_FRANKLIN)) IF IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())) IF ( GET_PED_VEHICLE_SEAT(PLAYER_PED_ID(), GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())) <> VS_DRIVER ) IF IS_PED_SHOOTING(PLAYER_PED_ID()) bPlayerFiredAsPassenger = TRUE ENDIF ENDIF ENDIF ENDIF ENDIF IF ( bCombatAllowed = FALSE ) //allow Franklin to go to comabt, which will allow hot swap afterwards IF ( bGoonsAttacked = FALSE ) IF IS_PED_SHOOTING_AT_ENTITY(PLAYER_PED_ID(), psEnemyGoonsCar0[0].PedIndex, TRUE) OR IS_PED_SHOOTING_AT_ENTITY(PLAYER_PED_ID(), psEnemyGoonsCar0[1].PedIndex, TRUE) OR IS_PED_SHOOTING_AT_ENTITY(PLAYER_PED_ID(), psEnemyGoonsCar0[0].PedIndex, TRUE) OR IS_PED_SHOOTING_AT_ENTITY(PLAYER_PED_ID(), psEnemyGoonsCar1[1].PedIndex, TRUE) bGoonsAttacked = TRUE ENDIF ENDIF IF HAS_LABEL_BEEN_TRIGGERED("FAM3_GCSGS") OR HAS_LABEL_BEEN_TRIGGERED("FAM3_GCSGT") OR ( bGoonsAttacked = TRUE ) bCombatAllowed = TRUE ENDIF ENDIF IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_LGOONS") IF HAS_LABEL_BEEN_TRIGGERED("FAM3_GCSFA") OR HAS_LABEL_BEEN_TRIGGERED("FAM3_GCSFB") IF NOT IS_ANY_TEXT_BEING_DISPLAYED(sLocatesData, IAT_IGNORE_GOD_TEXT_IF_SUBTITLES_OFF) PRINT_GOD_TEXT_ADVANCED("FAM3_LGOONS", DEFAULT_GOD_TEXT_TIME, TRUE) ENDIF ENDIF ELSE IF ( bCombatAllowed = TRUE ) bAllowHotSwap = TRUE //enable hotswap by default IF IS_PED_IN_ANY_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL)) //check what vehicle Michael is in VEHICLE_INDEX MichaelVehicleIndex MichaelVehicleIndex = GET_VEHICLE_PED_IS_IN(GET_PED_INDEX(CHAR_MICHAEL), TRUE) IF DOES_ENTITY_EXIST(MichaelVehicleIndex) IF NOT IS_THIS_MODEL_A_CAR(GET_ENTITY_MODEL(MichaelVehicleIndex)) //allow only cars AND NOT IS_THIS_MODEL_A_BIKE(GET_ENTITY_MODEL(MichaelVehicleIndex)) //allow only bikes AND NOT IS_THIS_MODEL_A_QUADBIKE(GET_ENTITY_MODEL(MichaelVehicleIndex)) //allow only quadbikes bAllowHotSwap = FALSE ENDIF ENDIF ENDIF IF IS_PED_IN_ANY_VEHICLE(GET_PED_INDEX(CHAR_FRANKLIN)) //check what vehicle Franklin is in VEHICLE_INDEX FranklinVehicleIndex FranklinVehicleIndex = GET_VEHICLE_PED_IS_IN(GET_PED_INDEX(CHAR_FRANKLIN), TRUE) IF DOES_ENTITY_EXIST(FranklinVehicleIndex) IF NOT IS_THIS_MODEL_A_CAR(GET_ENTITY_MODEL(FranklinVehicleIndex)) //allow only cars AND NOT IS_THIS_MODEL_A_BIKE(GET_ENTITY_MODEL(FranklinVehicleIndex)) //allow only bikes AND NOT IS_THIS_MODEL_A_QUADBIKE(GET_ENTITY_MODEL(FranklinVehicleIndex)) //allow only quadbikes bAllowHotSwap = FALSE ENDIF ENDIF ENDIF IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_HSWITCH") IF ( bAllowHotSwap = TRUE ) //display floating help text above the switch icon PRINT_HELP("FAM3_HSWITCH", DEFAULT_HELP_TEXT_TIME + 2500) SET_LABEL_AS_TRIGGERED("FAM3_HSWITCH", TRUE) ENDIF ELSE IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("FAM3_HSWITCH") IF IS_SELECTOR_CAM_ACTIVE() //remove switch help text when switch is in progress OR IS_PLAYER_SWITCH_IN_PROGRESS() OR bHotSwapTriggered = TRUE //used in first person switch as we're not running the switch cam CLEAR_HELP() ENDIF ENDIF //help text about shooting as passenger in vehicle IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_HPASS1") IF ARE_PEDS_IN_THE_SAME_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL), GET_PED_INDEX(CHAR_FRANKLIN)) IF IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())) IF ( GET_PED_VEHICLE_SEAT(PLAYER_PED_ID(), GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())) <> VS_DRIVER ) IF NOT IS_HELP_MESSAGE_BEING_DISPLAYED() PRINT_HELP("FAM3_HPASS1", DEFAULT_HELP_TEXT_TIME + 2500) SET_LABEL_AS_TRIGGERED("FAM3_HPASS1", TRUE) ENDIF ENDIF ENDIF ENDIF ELSE //help text about switching weapons in vehicle IF NOT HAS_LABEL_BEEN_TRIGGERED("FAM3_HPASS2") IF ARE_PEDS_IN_THE_SAME_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL), GET_PED_INDEX(CHAR_FRANKLIN)) IF IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())) IF ( GET_PED_VEHICLE_SEAT(PLAYER_PED_ID(), GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())) <> VS_DRIVER ) IF ( bPlayerFiredAsPassenger = TRUE ) IF HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_MICROSMG) OR HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_SAWNOFFSHOTGUN) OR HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_COMBATPISTOL) OR HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_APPISTOL) OR HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_STUNGUN) OR HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_GRENADE) OR HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_SMOKEGRENADE) OR HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_STICKYBOMB) OR HAS_PED_GOT_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_MOLOTOV) IF NOT IS_HELP_MESSAGE_BEING_DISPLAYED() PRINT_HELP(PICK_STRING(IS_USING_KEYBOARD_AND_MOUSE(PLAYER_CONTROL), "FAM3_HPASS3", "FAM3_HPASS2"), DEFAULT_HELP_TEXT_TIME + 2500) SET_LABEL_AS_TRIGGERED("FAM3_HPASS2", TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF BREAK CASE 1 IF IS_PED_SITTING_IN_ANY_VEHICLE(PLAYER_PED_ID()) IF ( bVehicleReversed = FALSE ) IF IS_VEHICLE_REVERSING(GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())) bVehicleReversed = TRUE ENDIF ENDIF IF BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()), 2.0) IF NOT IS_SCRIPTED_CONVERSATION_ONGOING() //check if scripted conversations are not ongoing using native command OR NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() //check if any conversations are not ongoing using script command OR ( TIMERA() > 5000 ) //check backup timer in case the conversations are busted by streaming CALCULATE_VEHICLE_EXIT_DELAYS() SEQUENCE_INDEX SequenceIndex CLEAR_SEQUENCE_TASK(SequenceIndex) OPEN_SEQUENCE_TASK(SequenceIndex) TASK_LEAVE_ANY_VEHICLE(NULL, iMichaelsVehicleExitDelay) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, << -819.05, 177.24, 70.83 >>, PEDMOVE_WALK, DEFAULT_TIME_BEFORE_WARP * 3) CLOSE_SEQUENCE_TASK(SequenceIndex) TASK_PERFORM_SEQUENCE(GET_PED_INDEX(CHAR_MICHAEL), SequenceIndex) CLEAR_SEQUENCE_TASK(SequenceIndex) CLEAR_SEQUENCE_TASK(SequenceIndex) OPEN_SEQUENCE_TASK(SequenceIndex) TASK_LEAVE_ANY_VEHICLE(NULL, iFranklinsVehicleExitDelay) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, << -819.05, 177.24, 70.83 >>, PEDMOVE_WALK, DEFAULT_TIME_BEFORE_WARP * 3) CLOSE_SEQUENCE_TASK(SequenceIndex) TASK_PERFORM_SEQUENCE(GET_PED_INDEX(CHAR_FRANKLIN), SequenceIndex) CLEAR_SEQUENCE_TASK(SequenceIndex) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Peds CHAR_MICHAEL and CHAR_FRANKLIN tasked to leave any vehicle.") #ENDIF bPedsTaskedToLeaveAnyVehicle = TRUE iStageProgress++ ENDIF ENDIF ELSE IF NOT IS_SCRIPTED_CONVERSATION_ONGOING() //check if scripted conversations are not ongoing using native command OR NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() //check if any conversations are not ongoing using script command OR ( TIMERA() > 5000 ) //check backup timer in case the conversations are busted by streaming iStageProgress++ ENDIF ENDIF BREAK CASE 2 IF NOT IS_PED_IN_ANY_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL)) AND NOT IS_PED_IN_ANY_VEHICLE(GET_PED_INDEX(CHAR_FRANKLIN)) IF NOT IS_SCRIPTED_CONVERSATION_ONGOING() //check if scripted conversations are not ongoing using native command OR NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() //check if any conversations are not ongoing using script command OR ( TIMERA() > 5000 ) //check backup timer in case the conversations are busted by streaming IF ( bCutsceneAssetsRequested = TRUE ) //progress if cutscene ped variations were requested //otherwise cutscene might play with default ped variations REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(GET_PED_INDEX(CHAR_MICHAEL)) REMOVE_ENTITY_FROM_AUDIO_MIX_GROUP(GET_PED_INDEX(CHAR_FRANKLIN)) STOP_AUDIO_SCENE("FAMILY_3_DRIVE_HOME") IF DOES_PARTICLE_FX_LOOPED_EXIST(ptfxDustCloud) REMOVE_PARTICLE_FX(ptfxDustCloud) ENDIF REMOVE_PTFX_ASSET() RETURN TRUE ENDIF ENDIF ELSE IF ( bPedsTaskedToLeaveAnyVehicle = FALSE ) CALCULATE_VEHICLE_EXIT_DELAYS() SEQUENCE_INDEX SequenceIndex IF IS_PED_IN_ANY_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL)) IF GET_SCRIPT_TASK_STATUS(GET_PED_INDEX(CHAR_MICHAEL), SCRIPT_TASK_PERFORM_SEQUENCE) != PERFORMING_TASK CLEAR_SEQUENCE_TASK(SequenceIndex) OPEN_SEQUENCE_TASK(SequenceIndex) TASK_LEAVE_ANY_VEHICLE(NULL, iMichaelsVehicleExitDelay) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, << -819.05, 177.24, 70.83 >>, PEDMOVE_WALK, DEFAULT_TIME_BEFORE_WARP * 3) CLOSE_SEQUENCE_TASK(SequenceIndex) TASK_PERFORM_SEQUENCE(GET_PED_INDEX(CHAR_MICHAEL), SequenceIndex) CLEAR_SEQUENCE_TASK(SequenceIndex) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Retasking CHAR_MICHAEL to leave any vehicle.") #ENDIF ENDIF ENDIF IF IS_PED_IN_ANY_VEHICLE(GET_PED_INDEX(CHAR_MICHAEL)) IF GET_SCRIPT_TASK_STATUS(GET_PED_INDEX(CHAR_MICHAEL), SCRIPT_TASK_PERFORM_SEQUENCE) != PERFORMING_TASK CLEAR_SEQUENCE_TASK(SequenceIndex) OPEN_SEQUENCE_TASK(SequenceIndex) TASK_LEAVE_ANY_VEHICLE(NULL, iFranklinsVehicleExitDelay) TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, << -819.05, 177.24, 70.83 >>, PEDMOVE_WALK, DEFAULT_TIME_BEFORE_WARP * 3) CLOSE_SEQUENCE_TASK(SequenceIndex) TASK_PERFORM_SEQUENCE(GET_PED_INDEX(CHAR_FRANKLIN), SequenceIndex) CLEAR_SEQUENCE_TASK(SequenceIndex) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Retasking CHAR_FRANKLIN to leave any vehicle.") #ENDIF ENDIF ENDIF bPedsTaskedToLeaveAnyVehicle = TRUE ENDIF ENDIF BREAK ENDSWITCH RETURN FALSE ENDFUNC #IF IS_DEBUG_BUILD FUNC BOOL IS_MISSION_STAGE_DEBUG_RECORD_CHASE_COMPLETED(INT &iStageProgress) SWITCH iStageProgress CASE 0 IF IS_VEHICLE_DRIVEABLE(vsCoachsCar.VehicleIndex) SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), vsCoachsCar.VehicleIndex) SET_ENTITY_INVINCIBLE(vsCoachsCar.VehicleIndex, TRUE) SET_VEHICLE_CAN_BE_VISIBLY_DAMAGED(vsCoachsCar.VehicleIndex, FALSE) ENDIF #IF IS_DEBUG_BUILD INIT_UBER_RECORDING(sUberRecordingFile) #ENDIF INSTANTLY_FILL_VEHICLE_POPULATION() iStageProgress++ BREAK CASE 1 #IF IS_DEBUG_BUILD UPDATE_UBER_RECORDING() #ENDIF BREAK ENDSWITCH RETURN FALSE ENDFUNC FUNC BOOL IS_MISSION_STAGE_DEBUG_PLAYBACK_CHASE_COMPLETED(INT &iStageProgress) SWITCH iStageProgress CASE 0 IF IS_VEHICLE_DRIVEABLE(vsCoachsCar.VehicleIndex) SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), vsCoachsCar.VehicleIndex) SET_ENTITY_INVINCIBLE(vsCoachsCar.VehicleIndex, TRUE) SET_VEHICLE_CAN_BE_VISIBLY_DAMAGED(vsCoachsCar.VehicleIndex, FALSE) ENDIF INITIALISE_UBER_PLAYBACK(sVehicleRecordingsFile, vsCoachsCar.iRecordingNumber) INITIALISE_UBER_ARRAY() iStageProgress++ BREAK CASE 1 IF IS_VEHICLE_DRIVEABLE(vsCoachsCar.VehicleIndex) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vsCoachsCar.VehicleIndex) DRAW_DEBUG_TEXT_ABOVE_ENTITY(vsCoachsCar.VehicleIndex, GET_STRING_FROM_FLOAT(GET_TIME_POSITION_IN_RECORDING(vsCoachsCar.VehicleIndex)), 1.25) ENDIF ENDIF UPDATE_UBER_PLAYBACK(vsCoachsCar.VehicleIndex, 1.0) BREAK ENDSWITCH RETURN FALSE ENDFUNC #ENDIF //|============================= END MISSION STAGES FUNCTIONS ============================| //|=================================== MAIN SCRIPT LOOP ==================================| SCRIPT SET_MISSION_FLAG(TRUE) //check for death or arrest IF HAS_FORCE_CLEANUP_OCCURRED() Mission_Flow_Mission_Force_Cleanup() CLEANUP_RAYFIRE_MAP_OBJECT(TRUE, TRUE) MISSION_CLEANUP() TERMINATE_THIS_THREAD() ENDIF #IF IS_DEBUG_BUILD CREATE_DEBUG_MISSION_STAGE_MENU() CREATE_DEBUG_WIDGETS() #ENDIF IF IS_REPLAY_IN_PROGRESS() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Mission replay is in progress.") #ENDIF SET_MISSION_STAGE_FOR_REPLAY(eMissionStage, Get_Replay_Mid_Mission_Stage()) bReplayFlag = TRUE //handle shitskip message IF ( g_bShitSkipAccepted = TRUE ) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Shitskip accepted by the player.") #ENDIF eMissionStage = GET_NEXT_MISSION_STAGE(eMissionStage) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Shitskip changed mission stage to ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eMissionStage), ".") #ENDIF ELSE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Shitskip not triggered.") #ENDIF ENDIF ELSE SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(ENUM_TO_INT(MID_MISSION_STAGE_CAR_CHASE), "CAR CHASE", FALSE) ENDIF IF IS_REPEAT_PLAY_ACTIVE() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Repeat play is active.") #ENDIF IF NOT IS_REPLAY_IN_PROGRESS() #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Repeat play is active and mission replay is not in progress.") #ENDIF eMissionStage = MISSION_STAGE_CUTSCENE_INTRO bReplayFlag = TRUE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Setting local replay flag to TRUE for stage loading.") #ENDIF #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Mission stage is ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eMissionStage), " for repeat play and no mission replay.") #ENDIF ELSE #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Repeat play is active and mission replay is in progress.") PRINTLN(GET_THIS_SCRIPT_NAME(), ": Mission stage is ", GET_MISSION_STAGE_NAME_FOR_DEBUG(eMissionStage), " for repeat play and mission replay.") #ENDIF ENDIF ENDIF WHILE TRUE SET_MUST_LEAVE_AREA_VEHICLE_GEN_FLAG(VEHGEN_MICHAEL_SAVEHOUSE) //check each frame if mission is failed due to fail conditions //check only if mission stage loading has finished IF ( bLoadingFlag = TRUE ) RUN_FAIL_CHECKS(eMissionStage, eMissionFail) ENDIF //check each frame for hotswap if it is allowed IF ( bAllowHotSwap = TRUE ) RUN_HOTSWAP() ENDIF REPLAY_CHECK_FOR_EVENT_THIS_FRAME("M_MarriageCounselling") IF iReplayCameraWarpTimer > GET_GAME_TIMER() REPLAY_DISABLE_CAMERA_MOVEMENT_THIS_FRAME() //Fix for bug 2229077 ENDIF SWITCH eMissionStage CASE MISSION_STAGE_CUTSCENE_INTRO SET_PED_DENSITY_MULTIPLIER_THIS_FRAME(0) SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0) IF IS_MISSION_STAGE_LOADED(eMissionStage, iStageSetupProgress, bLoadingFlag, bSkipFlag, bReplayFlag) IF IS_MISSION_STAGE_CUTSCENE_INTRO_COMPLETED(iMissionStageProgress) RESET_MISSION_FLAGS() eMissionStage = MISSION_STAGE_CAR_CHASE ENDIF ENDIF BREAK CASE MISSION_STAGE_CAR_CHASE UPDATE_THIRD_PERSON_RUN_TO_VEHICLE_CAMERA() IF IS_MISSION_STAGE_LOADED(eMissionStage, iStageSetupProgress, bLoadingFlag, bSkipFlag, bReplayFlag) IF IS_MISSION_STAGE_CAR_CHASE_COMPLETED(iMissionStageProgress) RESET_MISSION_FLAGS() eMissionStage = MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE ENDIF ENDIF BREAK CASE MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE SET_PED_DENSITY_MULTIPLIER_THIS_FRAME(0) SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0) IF IS_MISSION_STAGE_LOADED(eMissionStage, iStageSetupProgress, bLoadingFlag, bSkipFlag, bReplayFlag) IF IS_MISSION_STAGE_CUTSCENE_BACK_OF_HOUSE_COMPLETED(iMissionStageProgress) RESET_MISSION_FLAGS() eMissionStage = MISSION_STAGE_PULL_HOUSE_DOWN ENDIF ENDIF BREAK CASE MISSION_STAGE_PULL_HOUSE_DOWN SET_PED_DENSITY_MULTIPLIER_THIS_FRAME(0) SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0) IF IS_MISSION_STAGE_LOADED(eMissionStage, iStageSetupProgress, bLoadingFlag, bSkipFlag, bReplayFlag) IF IS_MISSION_STAGE_PULL_HOUSE_DOWN_COMPLETED(iMissionStageProgress) RESET_MISSION_FLAGS() eMissionStage = MISSION_STAGE_ESCAPE_GOONS ENDIF ENDIF BREAK CASE MISSION_STAGE_ESCAPE_GOONS IF ( bGoonsChaseFinished = FALSE ) SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.4) ENDIF IF IS_MISSION_STAGE_LOADED(eMissionStage, iStageSetupProgress, bLoadingFlag, bSkipFlag, bReplayFlag) IF IS_MISSION_STAGE_ESCAPE_GOONS_COMPLETED(iMissionStageProgress) RESET_MISSION_FLAGS() eMissionStage = MISSION_STAGE_CUTSCENE_END ENDIF ENDIF BREAK CASE MISSION_STAGE_CUTSCENE_END IF IS_MISSION_STAGE_LOADED(eMissionStage, iStageSetupProgress, bLoadingFlag, bSkipFlag, bReplayFlag) IF IS_MISSION_STAGE_CUTSCENE_END_COMPLETED(iMissionStageProgress) RESET_MISSION_FLAGS() IF NOT IS_REPEAT_PLAY_ACTIVE() eMissionStage = MISSION_STAGE_LEADOUT ELSE eMissionStage = MISSION_STAGE_PASSED ENDIF ENDIF ENDIF BREAK CASE MISSION_STAGE_LEADOUT HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_AREA_NAME) HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_STREET_NAME) HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_DISTRICT_NAME) IF IS_MISSION_STAGE_LOADED(eMissionStage, iStageSetupProgress, bLoadingFlag, bSkipFlag, bReplayFlag) IF IS_MISSION_STAGE_LEADOUT_COMPLETED(iMissionStageProgress) RESET_MISSION_FLAGS() eMissionStage = MISSION_STAGE_PASSED ENDIF ENDIF BREAK CASE MISSION_STAGE_PASSED MISSION_FLOW_MISSION_PASSED() MISSION_CLEANUP() TERMINATE_THIS_THREAD() BREAK CASE MISSION_STAGE_FAILED SET_MISSION_FAILED_WITH_REASON(eMissionFail) CLEAR_HELP() CLEAR_PRINTS() KILL_ANY_CONVERSATION() TRIGGER_MUSIC_EVENT("FAM3_MISSION_FAIL") WHILE NOT GET_MISSION_FLOW_SAFE_TO_CLEANUP() WAIT(0) #IF IS_DEBUG_BUILD PRINTLN(GET_THIS_SCRIPT_NAME(), ": Waiting for GET_MISSION_FLOW_SAFE_TO_CLEANUP() to return TRUE.") #ENDIF ENDWHILE CLEANUP_RAYFIRE_MAP_OBJECT(TRUE, FALSE) MISSION_CLEANUP() // must only take 1 frame and terminate the thread TERMINATE_THIS_THREAD() BREAK #IF IS_DEBUG_BUILD //debug mission stages CASE MISSION_STAGE_DEBUG_RECORD_CHASE IF IS_MISSION_STAGE_LOADED(eMissionStage, iStageSetupProgress, bLoadingFlag, bSkipFlag, bReplayFlag) IF IS_MISSION_STAGE_DEBUG_RECORD_CHASE_COMPLETED(iMissionStageProgress) RESET_MISSION_FLAGS() eMissionStage = MISSION_STAGE_PASSED ENDIF ENDIF BREAK CASE MISSION_STAGE_DEBUG_PLAYBACK_CHASE IF IS_MISSION_STAGE_LOADED(eMissionStage, iStageSetupProgress, bLoadingFlag, bSkipFlag, bReplayFlag) IF IS_MISSION_STAGE_DEBUG_PLAYBACK_CHASE_COMPLETED(iMissionStageProgress) RESET_MISSION_FLAGS() eMissionStage = MISSION_STAGE_PASSED ENDIF ENDIF BREAK #ENDIF ENDSWITCH #IF IS_DEBUG_BUILD //handle debug functionality RUN_DEBUG_PASS_AND_FAIL_CHECK(eMissionStage, eMissionFail) //handle key_f and key_s presses RUN_DEBUG_MISSION_STAGE_MENU(iReturnStage, eMissionStage, bSkipFlag, bStageResetFlag) //handle z-skip menu RUN_DEBUG_SKIPS(eMissionStage, bSkipFlag, bStageResetFlag) //handle j-skip and p-skip RUN_DEBUG_WIDGETS(eMissionStage) //handle rag widgets RUN_DEBUG_INFORMATION_DISPLAY() //handle drawing of debug information #ENDIF WAIT(0) ENDWHILE ENDSCRIPT