//Compile out Title Update changes to header functions. //Must be before includes. //CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R. USING "rage_builtins.sch" USING "globals.sch" USING "cutscene_public.sch" USING "commands_cutscene.sch" USING "commands_entity.sch" USING "commands_script.sch" USING "script_player.sch" USING "randomChar_public.sch" USING "script_ped.sch" USING "dialogue_public.sch" USING "comms_control_public.sch" USING "RC_Helper_Functions.sch" USING "CompletionPercentage_public.sch" USING "replay_public.sch" USING "locates_public.sch" USING "initial_scenes_barry.sch" USING "script_drawing.sch" USING "shared_hud_displays.sch" USING "commands_recording.sch" #IF IS_DEBUG_BUILD USING "select_mission_stage.sch" #ENDIF // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** // // MISSION NAME : Barry3A.sc // AUTHOR : Tom Waters // DESCRIPTION : Franklin collects a vehicle for Barry. // // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** // Launcher data g_structRCScriptArgs sRCLauncherDataLocal //************************************************************************************************************************************************* // Z-SKIP //************************************************************************************************************************************************* #IF IS_DEBUG_BUILD // Mission specific z-skip enum ENUM MISSION_SKIP_STAGE MSS_MISSION_TRIGGERED, MSS_RESTART, MSS_WARP_NEAR_END, MSS_TRIGGER_DELIVERY, MSS_TRIGGER_COMPLETION//, // MSS_BODGE_TIMER ENDENUM // Z-skip menu/checkpoints stuff MISSION_SKIP_STAGE eTargetStage CONST_INT MAX_SKIP_MENU_LENGTH 5//6 MissionStageMenuTextStruct mSkipMenu[MAX_SKIP_MENU_LENGTH] WIDGET_GROUP_ID widgetGroup BOOL bDebugClockTo15s #ENDIF //************************************************************************************************************************************************* // :ENUMS: //************************************************************************************************************************************************* // Mission stages ENUM MISSION_STAGE MS_STAGE_INIT, MS_STAGE_CALL_BARRY, MS_STAGE_ENTER_TRUCK, MS_STAGE_RETURN_VEHICLE, MS_STAGE_GET_VEHICLE_BACK, MS_STAGE_LOSE_WANTED, MS_STAGE_DELIVERY, MS_STAGE_LEAVE_AREA, MS_STAGE_TAKE_VEHICLE_BACK, MS_STAGE_FAIL_FADE ENDENUM // Progression for individual cop car handlers ENUM COP_TRAP_SINGLE_CAR CTSC_WAITING_FOR_ENTITIES, CTSC_WAITING_TO_TRIGGER, CTSC_TRIGGER_DELAY, CTSC_TRIGGERED, CTSC_DELETED ENDENUM // Progression within a stage ENUM STAGE_PROGRESS SP_SETUP, SP_RUNNING, SP_CLEANUP ENDENUM // Controls the time-out fail check ENUM TIME_OUT_STAGE TOS_IDLE, TOS_START, TOS_FAILCHECK ENDENUM //************************************************************************************************************************************************* // :STRUCTURES: //************************************************************************************************************************************************* // Vehicles to collect STRUCT COLLECT_VEHICLE VECTOR location FLOAT heading VEHICLE_INDEX vehicle MODEL_NAMES modelName BOOL bStuckCheckActive ENDSTRUCT // Objectives STRUCT MISSION_OBJECTIVE INT iDisplayMax INT iDisplayCount STRING sTextLabel ENDSTRUCT // Franklin flavour convos STRUCT FLAVOUR_CONVO STRING convRoot INT convDelay ENDSTRUCT // Struct for Non-Axis-Aligned triggers STRUCT NAA_TRIGGER VECTOR vEnds[2] FLOAT fWidth ENDSTRUCT // Structs for single-triggered cop cars STRUCT COP_TRIGGER // Vehicle and initial setup stuff VEHICLE_INDEX vehicle PED_INDEX driver PED_INDEX passenger VECTOR location FLOAT heading // Trigger box coordinates NAA_TRIGGER triggers[2] COP_TRAP_SINGLE_CAR ctsProgress // Delay reaction to player INT kickOffTimer // Cleanup stuff BOOL bDriverDeletedOrReleased BOOL bPassengerDeletedOrReleased BOOL bCarDeletedOrReleased ENDSTRUCT //************************************************************************************************************************************************* // :CONSTANTS: //************************************************************************************************************************************************* // Checkpoints CONST_INT CP_DELIVERY 1 CONST_INT CP_SHITSKIP_COMPLETE 2 // Shitskip only - do not set as checkpoint // Cop stuff: // Single triggered cop cars CONST_INT NUM_SINGLE_COPCARS 2 CONST_FLOAT COP_DESPAWN_RANGE 275.0 CONST_INT BARRY3A_ACCURACY 10 CONST_INT COP_TRIGGER_DELAY_TIME 1750 // Set to 750 for B*1415951, increased to 1750 for B*1512323 // Objective label constants. Names should correspond to the text labels for the objectives. CONST_INT MO_B3ADELV 0 // Take the truck to ~y~Barry's apartment.~s~ CONST_INT MO_B3AGETIN 1 // Get in the truck. CONST_INT MO_B3AWAN1 2 // Lose the cops. CONST_INT MO_B3ARTV 3 // Get back in the ~b~truck.~s~ CONST_INT MO_B3AEXIT 4 // Exit the truck. CONST_INT MO_B3ALEAVE 5 // Leave the area. CONST_INT NUM_MISSION_OBJECTIVES 6 // Detect player abandoning truck CONST_INT WARNING_DISTANCE 50 CONST_INT ABANDON_DISTANCE 150 // Distance fail stage after initial delivery CONST_FLOAT DELIVERY_FAIL_DISTANCE 125.0 // Initially set to same as TOF_GRACE_OFF value // Flavour conversations CONST_INT NUM_FLAVOUR_CONVOS 4 // Vehicle restriction CONST_INT RESTRICTION_STASHVEH 0 //************************************************************************************************************************************************* // :VARIABLES: //************************************************************************************************************************************************* // Mission progression MISSION_STAGE mStage = MS_STAGE_INIT // track what mission stage we are at STAGE_PROGRESS sProgress = SP_SETUP // used to track what bit of the current mission stage we're at // General utility blip BLIP_INDEX biMissionBlip // The vehicle COLLECT_VEHICLE stVehicle BOOL bStuckCheckActive = FALSE BOOL bVehicleOnRoofLastFrame = FALSE INT iStuckTimer OBJECT_INDEX oiStashBox VECTOR vecStashOffset = << 0.0, -1.00, 0.64 >> MODEL_NAMES mnStashBox = Prop_Weed_Tub_01b BOOL bSetupVehGen = FALSE // Vehicle delivery destination VECTOR vecDestination = << -1138.9767, -1252.5486, 6.05 >> // 5.9589 >>//<< -1152.4301, -1238.8237, 5.9752 >> SCENARIO_BLOCKING_INDEX sbCarPark[2] // Scenario blocker to stop parking scenario // Objective display structure MISSION_OBJECTIVE moObjectives[NUM_MISSION_OBJECTIVES] // Cop trap trigger data COP_TRIGGER ctTrapInfo[NUM_SINGLE_COPCARS] BOOL bCopModelsLoaded // Control loading/unloading of cop models MODEL_NAMES modelCopCar = POLICE4 MODEL_NAMES modelCopPed = A_M_Y_BUSINESS_01 BOOL bDidScannerLine = FALSE INT iScannerTimer // general utility counter INT iCount // Conversation struct for player structPedsForConversation mConversationStruct // Franklin's flavour conversations while wanted FLAVOUR_CONVO fcFranklinComments[NUM_FLAVOUR_CONVOS] BOOL bFranklinCompletedComment // Has Franklin completed current comment? INT iFranklinCommentCount // Counts completed comments INT iFranklinCommentTimer // Timer (ms) BOOL bCopsChallenged // Controls whether Franklin says wanted dialogue // Has Franklin been wanted? BOOL bBeenWanted = FALSE BOOL bRestartedAfterCP0 = FALSE BOOL bWantedObjectiveNeeded // Used to mark objective as needed if there's a conversation going on // Stuff for Franklin's wanted clear comment BOOL bFranklinSaidClearComment // Delivery event BOOL bHadDeliveryCall // Have we triggered the delivery phone call yet BOOL bCallDelaySet INT iCallDelayTimer // Player removing vehicle tracking stage bools BOOL bObjectiveNeeded BOOL bPlayerInTruck BOOL bPlayerWanted // Monitor time-out fail TIME_OUT_STAGE timeOutStage CONST_INT CLOCK_HOURS_ALLOWED 2 // Limit is 2 hours - B*1112928/1112927 CONST_INT CLOCK_MINS_ALLOWED 0 CONST_INT CLOCK_WARNING_MINUTES 30 INT iTimeLimit // Stores the end limit for mission time in ms INT iWarningTime // Stores the point at which the warning comment should trigger in ms BOOL bDoTheClock // Controls whether the clock gets displayed BOOL bFranklinTimeWarnComment // Franklin comment if time is short // Timeout beeper stuff INT iTenSecondsLeft INT iFiveSecondsLeft INT iZeroSecondsLeft // This is the time when the timer shows zero, which is actually < 1s, not 0 INT iBeepTimer BOOL bStartedBeepTimer // Fail reason store STRING sFailReason // Conversation subtitle interruption RC_CONV_RESTORE_STATE stateRestoreConversation TEXT_LABEL_23 tSavedConversationRoot TEXT_LABEL_23 tSavedConversationLabel //************************************************************************************************************************************************* // :OBJECTIVE FUNCS/PROCS: //************************************************************************************************************************************************* /// PURPOSE: /// Returns a completed struct that holds an objective's info /// PARAMS: /// stTextLabel - The name of the text label that will be displayed as God text /// iDisMax - Maximum number of times it can display. Set to -1 for no limit. FUNC MISSION_OBJECTIVE CREATE_MISSION_OBJECTIVE(STRING stTextLabel, INT iDisMax = 1) MISSION_OBJECTIVE tmpMissionObj tmpMissionObj.sTextLabel = stTextLabel tmpMissionObj.iDisplayMax = iDisMax tmpMissionObj.iDisplayCount = 0 RETURN tmpMissionObj ENDFUNC /// PURPOSE: /// Test whether an objective will display /// Saves having a seperate bool for blip updates, or lets you see whether you need to clear an objective /// PARAMS: /// iObj - which objective to check (use the constants) /// RETURNS: /// TRUE if the objective will display FUNC BOOL MISSION_OBJECTIVE_WILL_DISPLAY(INT iObj) IF moObjectives[iObj].iDisplayCount < moObjectives[iObj].iDisplayMax OR moObjectives[iObj].iDisplayMax = -1 RETURN TRUE ELSE RETURN FALSE ENDIF ENDFUNC /// PURPOSE: /// Display an objective, unless it has already been displayed as many times as allowed /// PARAMS: /// iObj - which objective to display (use the constants) PROC DISPLAY_MISSION_OBJECTIVE(INT iObj) IF MISSION_OBJECTIVE_WILL_DISPLAY(iObj) PRINT_NOW(moObjectives[iObj].sTextLabel, DEFAULT_GOD_TEXT_TIME, 1) moObjectives[iObj].iDisplayCount++ ENDIF ENDPROC /// PURPOSE: /// Remove a specific objective that is being displayed /// PARAMS: /// iObj - which objective we are removing (use the constants) PROC CLEAR_MISSION_OBJECTIVE(INT iObj) CLEAR_THIS_PRINT(moObjectives[iObj].sTextLabel) ENDPROC /// PURPOSE: /// Clear any mission objective that might be shown + stop dialogue + put away phone PROC CLEAR_ALL_MISSION_OBJECTIVES() CLEAR_PRINTS() IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() HANG_UP_AND_PUT_AWAY_PHONE() ENDIF ENDPROC /// PURPOSE: /// Are any mission objectives currently on screen? /// RETURNS: /// True if there is currently a mission objective on screen FUNC BOOL MISSION_OBJECTIVES_CURRENTLY_DISPLAYED() BOOL bResult = FALSE FOR iCount = 0 TO NUM_MISSION_OBJECTIVES-1 IF IS_THIS_PRINT_BEING_DISPLAYED(moObjectives[iCount].sTextLabel) bResult = TRUE ENDIF ENDFOR RETURN bResult ENDFUNC /// PURPOSE: /// Allows skip procs to reset objective counter /// PARAMS: /// iObj - which objective we're resetting /// iNewCount - new iDisplayCount value PROC MISSION_OBJECTIVE_RESET(INT iObj, INT iNewCount = 0) moObjectives[iObj].iDisplayCount = iNewCount ENDPROC /// PURPOSE: /// Allows skip procs to set an objective to act as if it has already displayed /// PARAMS: /// iObj - which objective we're altering PROC MISSION_OBJECTIVE_EXPIRE(INT iObj) IF moObjectives[iObj].iDisplayMax = -1 CPRINTLN(DEBUG_MISSION, "Trying to expire an objective that has unlimited repeats! ", iObj) ELSE moObjectives[iObj].iDisplayCount = moObjectives[iObj].iDisplayMax ENDIF ENDPROC /// PURPOSE: /// Set up all the mission objectives PROC STORE_MISSION_OBJECTIVE_DATA() moObjectives[MO_B3ADELV] = CREATE_MISSION_OBJECTIVE("B3ADELV", 1) // Take the truck to ~y~Barry's apartment.~s~ moObjectives[MO_B3AGETIN] = CREATE_MISSION_OBJECTIVE("B3AGETIN", 1) // Get in the truck. moObjectives[MO_B3AWAN1] = CREATE_MISSION_OBJECTIVE("B3AWAN1", -1) // Lose the cops. moObjectives[MO_B3ARTV] = CREATE_MISSION_OBJECTIVE("B3ARTV", 1) // Get back in the ~b~truck.~s~ moObjectives[MO_B3AEXIT] = CREATE_MISSION_OBJECTIVE("B3AEXIT", 1) // Exit the truck. moObjectives[MO_B3ALEAVE] = CREATE_MISSION_OBJECTIVE("B3ALEAVE", 1) // Leave the area. ENDPROC /// PURPOSE: /// Stuck check on mission vehicle /// RETURN: /// TRUE if the vehicle is stuck! FUNC BOOL VEHICLE_IS_STUCK() // Keep track of vehicle on roof IF IS_VEHICLE_STUCK_ON_ROOF(stVehicle.vehicle) IF bVehicleOnRoofLastFrame IF GET_GAME_TIMER() - iStuckTimer > ROOF_TIME RETURN TRUE ENDIF ELSE CPRINTLN(DEBUG_MISSION, "Vehicle is now stuck on roof!") bVehicleOnRoofLastFrame = TRUE iStuckTimer = GET_GAME_TIMER() ENDIF ELSE IF bVehicleOnRoofLastFrame CPRINTLN(DEBUG_MISSION, "Vehicle is no longer stuck on roof.") ENDIF bVehicleOnRoofLastFrame = FALSE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Beeps on timer for last 10 seconds /// B*1843890 PROC TRIGGER_WARNING_BEEPS() INT iTimeNow = GET_GAME_TIMER() // Less than 1s left IF iTimeNow >= iZeroSecondsLeft IF iTimeNow-iBeepTimer > 500 CDEBUG1LN(DEBUG_MISSION, "BOOP :(") PLAY_SOUND_FRONTEND(-1, "TIMER_STOP", "HUD_MINI_GAME_SOUNDSET") iBeepTimer = GET_GAME_TIMER() + 1000 ENDIF // Down to less than 5s, beep every 0.5s ELIF iTimeNow >= iFiveSecondsLeft IF iTimeNow-iBeepTimer > 500 CDEBUG1LN(DEBUG_MISSION, "BEEP!") PLAY_SOUND_FRONTEND(-1, "10_SEC_WARNING", "HUD_MINI_GAME_SOUNDSET") iBeepTimer = GET_GAME_TIMER() ENDIF // Down to less than 10s but still more than 5s, beep every 1.0s ELIF iTimeNow >= iTenSecondsLeft IF NOT bStartedBeepTimer CDEBUG1LN(DEBUG_MISSION, "BEEP!") PLAY_SOUND_FRONTEND(-1, "10_SEC_WARNING", "HUD_MINI_GAME_SOUNDSET") iBeepTimer = GET_GAME_TIMER() bStartedBeepTimer = TRUE ELIF iTimeNow-iBeepTimer > 1000 CDEBUG1LN(DEBUG_MISSION, "BEEP!") PLAY_SOUND_FRONTEND(-1, "10_SEC_WARNING", "HUD_MINI_GAME_SOUNDSET") iBeepTimer = GET_GAME_TIMER() ENDIF ENDIF ENDPROC /// PURPOSE: /// Check whether the player's taken too long in game-world clock terms /// RETURNS: /// TRUE if we should get a time up fail FUNC BOOL TIME_OUT_FAIL_MONITOR() SWITCH timeOutStage CASE TOS_IDLE RETURN FALSE BREAK CASE TOS_START // Set time limit iTimeLimit = GET_MILLISECONDS_PER_GAME_MINUTE()*((60*CLOCK_HOURS_ALLOWED) + CLOCK_MINS_ALLOWED) CPRINTLN(DEBUG_MISSION, "TIME LIMIT::: ", iTimeLimit, "ms. MS per game minute is ", GET_MILLISECONDS_PER_GAME_MINUTE(), "ms") iTimeLimit += GET_GAME_TIMER() iWarningTime = iTimeLimit - (GET_MILLISECONDS_PER_GAME_MINUTE()*CLOCK_WARNING_MINUTES) // Timeout warning beeps stuff iTenSecondsLeft = iTimeLimit - 11000 iFiveSecondsLeft = iTimeLimit - 6000 iZeroSecondsLeft = iTimeLimit - 1000 bStartedBeepTimer = FALSE timeOutStage = TOS_FAILCHECK RETURN FALSE BREAK CASE TOS_FAILCHECK // We are now checking for a timeout fail // But don't fail if player is nearly there - B*833516 IF GET_GAME_TIMER() >= iTimeLimit RETURN TRUE ELSE // See if Franklin should make hurry up comment. IF NOT bFranklinTimeWarnComment AND GET_GAME_TIMER() >= iWarningTime AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF CREATE_CONVERSATION(mConversationStruct, "BAR3AAU", "BAR3A_HURRY", CONV_PRIORITY_MEDIUM, DISPLAY_SUBTITLES) bFranklinTimeWarnCOmment = TRUE ENDIF ENDIF TRIGGER_WARNING_BEEPS() // Still OK RETURN FALSE ENDIF BREAK ENDSWITCH RETURN FALSE ENDFUNC /// PURPOSE: /// Checks for the player being killed or the truck being destroyed /// RETURNS: /// True if the player has failed the mission FUNC BOOL MISSION_FAILED_CHECKS() // Is player still alive IF NOT IS_ENTITY_ALIVE(PLAYER_PED_ID()) RETURN TRUE // player dead- mission failed ENDIF // Check for timeout fail IF TIME_OUT_FAIL_MONITOR() sFailReason = "B3ATIMEOUT" // You didn't deliver the stash car in time. sProgress = SP_SETUP mStage = MS_STAGE_FAIL_FADE RETURN TRUE ENDIF // Has vehicle been trashed IF NOT IS_ENTITY_ALIVE(stVehicle.vehicle) sFailReason = "B3AVHDEST" // The vehicle was destroyed sProgress = SP_SETUP mStage = MS_STAGE_FAIL_FADE RETURN TRUE // truck destroyed- mission failed ELIF VEHICLE_IS_STUCK() sFailReason = "B3AVHSTUCK" // The vehicle was destroyed sProgress = SP_SETUP mStage = MS_STAGE_FAIL_FADE RETURN TRUE // truck destroyed- mission failed ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Turns off engine and lights /// PARAMS: /// viVehicle - Vehicle to turn off PROC VEHICLE_SHUTDOWN(VEHICLE_INDEX viVehicle) IF IS_ENTITY_ALIVE(viVehicle) SET_VEHICLE_ENGINE_ON(viVehicle, FALSE, FALSE) SET_VEHICLE_LIGHTS(viVehicle, FORCE_VEHICLE_LIGHTS_OFF) ENDIF ENDPROC /// PURPOSE: /// Checks whether the player is in a tow truck that is attached to the stash car /// RETURNS: /// TRUE if the player is mucking about in this way FUNC BOOL PLAYER_IS_TOWING() IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) VEHICLE_INDEX vehTmp vehTmp = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), TRUE) IF IS_ENTITY_ALIVE(vehTmp) IF GET_ENTITY_MODEL(vehTmp) = TOWTRUCK OR GET_ENTITY_MODEL(vehTmp) = TOWTRUCK2 IF IS_VEHICLE_ATTACHED_TO_TOW_TRUCK(vehTmp, stVehicle.vehicle) RETURN TRUE ENDIF ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Save all the stuff we'll need for triggering the single-trigger cops PROC STORE_COP_TRIGGER_DATA() // UC cops in lumber yard ctTrapInfo[0].location = << 1195.30, -1312.74, 34.75 >> ctTrapInfo[0].heading = 282.4 ctTrapInfo[0].triggers[0].vEnds[0] = <<1216.144287,-1287.003906,33.976418>> ctTrapInfo[0].triggers[0].vEnds[1] = <<1202.455566,-1306.053833,39.474110>> ctTrapInfo[0].triggers[0].fWidth = 16.50 ctTrapInfo[0].triggers[1].vEnds[0] = <<1204.858032,-1296.130615,33.976418>> ctTrapInfo[0].triggers[1].vEnds[1] = <<1198.831909,-1365.925903,39.477051>> ctTrapInfo[0].triggers[1].fWidth = 37.50 ctTrapInfo[0].ctsProgress = CTSC_WAITING_FOR_ENTITIES // UC cops past lumber yard ctTrapInfo[1].location = << 1162.71, -1357.86, 33.73 >> ctTrapInfo[1].heading = 266.7 ctTrapInfo[1].triggers[0].vEnds[0] = <<1164.457153,-1363.839478,33.510624>> ctTrapInfo[1].triggers[0].vEnds[1] = <<1180.637207,-1359.837036,39.113964>> ctTrapInfo[1].triggers[0].fWidth = 15.5 ctTrapInfo[1].triggers[1].vEnds[0] = <<0,0,0>> ctTrapInfo[1].triggers[1].vEnds[1] = <<0,0,0>> ctTrapInfo[1].triggers[1].fWidth = 0 ctTrapInfo[1].ctsProgress = CTSC_WAITING_FOR_ENTITIES ENDPROC /// PURPOSE: /// Checks for tripping of cop traps /// RETURNS: /// TRUE if the stash vehicle is in a trigger FUNC BOOL COP_SINGLE_TRIGGER_CHECK(INT iCop) // This used to check player was in trigger after validating player was in truck - changed to checking truck because of issues like B*1118576 or player towing vehicle IF IS_ENTITY_IN_ANGLED_AREA(stVehicle.vehicle, ctTrapInfo[iCop].triggers[0].vEnds[0], ctTrapInfo[iCop].triggers[0].vEnds[1], ctTrapInfo[iCop].triggers[0].fWidth) RETURN TRUE ELIF ctTrapInfo[iCop].triggers[1].fWidth <> 0 AND IS_ENTITY_IN_ANGLED_AREA(stVehicle.vehicle, ctTrapInfo[iCop].triggers[1].vEnds[0], ctTrapInfo[iCop].triggers[1].vEnds[1], ctTrapInfo[iCop].triggers[1].fWidth) RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Checks whether the player is mucking about with stakeout cops /// PARAMS: /// pedCop - cop ped to check /// RETURNS: /// TRUE if player is mucking about FUNC BOOL PLAYER_IS_MESSING_ABOUT_WITH_COP(PED_INDEX pedCop) IF IS_ENTITY_ALIVE(pedCop) VECTOR vTmp = GET_ENTITY_COORDS(pedCop) IF IS_PED_BEING_JACKED(pedCop) AND IS_ENTITY_IN_RANGE_ENTITY(pedCop, PLAYER_PED_ID(), 2.0) CPRINTLN(DEBUG_MISSION, "Player jacking a stakeout cop") RETURN TRUE ELIF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(pedCop, PLAYER_PED_ID()) CPRINTLN(DEBUG_MISSION, "Player damaged a stakeout cop") RETURN TRUE ELIF IS_PROJECTILE_IN_AREA(vTmp-<<3,3,3>>, vTmp+<<3,3,3>>, TRUE) CPRINTLN(DEBUG_MISSION, "Player shot near a stakeout cop") RETURN TRUE ELIF IS_PLAYER_VISIBLY_TARGETTING_PED(pedCop) CPRINTLN(DEBUG_MISSION, "Player visibly targeting a stakeout cop") RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Checks whether the player is mucking about with the stakeout cops /// PARAMS: /// copCar - cop car to check /// RETURNS: /// TRUE if shenanigans are afoot FUNC BOOL PLAYER_IS_MESSING_ABOUT_WITH_COPCAR(VEHICLE_INDEX copCar) IF DOES_ENTITY_EXIST(copCar) VECTOR vTmp = GET_ENTITY_COORDS(copCar, FALSE) IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(copCar, PLAYER_PED_ID()) CPRINTLN(DEBUG_MISSION, "Player damaged a stakeout car") IF NOT IS_ENTITY_DEAD(copCar) CLEAR_ENTITY_LAST_DAMAGE_ENTITY(copCar) ENDIF RETURN TRUE ELIF IS_PROJECTILE_IN_AREA(vTmp-<<5,5,5>>, vTmp+<<5,5,5>>, TRUE) CPRINTLN(DEBUG_MISSION, "Player shot near a stakeout car") RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Sets off the cops in this car /// PARAMS: /// iCopC - array index of cop stakeout struct /// bEngineOn - should we instant-on the car engine? PROC COPS_KICK_OFF(INT iCopC, BOOL bEngineOn = FALSE) CPRINTLN(DEBUG_MISSION, "COP_TRAP_SINGLETRIGGER wakeywakey on cop car ", iCopC) // Franklin can start wanted complaint dialogue IF NOT bCopsChallenged bCopsChallenged = TRUE iFranklinCommentTimer = GET_GAME_TIMER() ENDIF IF IS_ENTITY_ALIVE(ctTrapInfo[iCopC].driver) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ctTrapInfo[iCopC].driver, FALSE) SET_PED_HIGHLY_PERCEPTIVE(ctTrapInfo[iCopC].driver, TRUE) SAFE_RELEASE_PED(ctTrapInfo[iCopC].driver) // Release cops now - if still owned by script they don't use correct arrest/attack behaviours ENDIF IF IS_ENTITY_ALIVE(ctTrapInfo[iCopC].passenger) SET_PED_AS_COP(ctTrapInfo[iCopC].passenger, TRUE) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ctTrapInfo[iCopC].passenger, FALSE) SET_PED_HIGHLY_PERCEPTIVE(ctTrapInfo[iCopC].passenger, TRUE) SAFE_RELEASE_PED(ctTrapInfo[iCopC].passenger) // Release cops now - if still owned by script they don't use correct arrest/attack behaviours ENDIF IF bEngineOn AND IS_ENTITY_ALIVE(ctTrapInfo[iCopC].vehicle) SET_VEHICLE_ENGINE_ON(ctTrapInfo[iCopC].vehicle, TRUE, TRUE) SAFE_RELEASE_VEHICLE(ctTrapInfo[iCopC].vehicle) ENDIF IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) < 2 SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 2) SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID()) ENDIF REPORT_POLICE_SPOTTED_PLAYER(PLAYER_ID()) ctTrapInfo[iCopC].ctsProgress = CTSC_TRIGGERED ENDPROC /// PURPOSE: /// Handle triggering of seperate cop cars /// PARAMS: /// iCop - Array index for the cop struct to use PROC COP_TRAP_SINGLETRIGGER(INT iCop) SWITCH ctTrapInfo[iCop].ctsProgress CASE CTSC_WAITING_FOR_ENTITIES // Create the entities IF NOT DOES_ENTITY_EXIST(ctTrapInfo[iCop].driver) IF IS_ENTITY_ALIVE(ctTrapInfo[iCop].vehicle) IF HAS_MODEL_LOADED(modelCopPed) ctTrapInfo[iCop].driver = CREATE_PED_INSIDE_VEHICLE(ctTrapInfo[iCop].vehicle, PEDTYPE_COP, modelCopPed) ctTrapInfo[iCop].passenger = CREATE_PED_INSIDE_VEHICLE(ctTrapInfo[iCop].vehicle, PEDTYPE_COP, modelCopPed, VS_FRONT_RIGHT) ENDIF ELIF HAS_MODEL_LOADED(modelCopCar) ctTrapInfo[iCop].vehicle = CREATE_VEHICLE(modelCopCar, ctTrapInfo[iCop].location, ctTrapInfo[iCop].heading) #IF IS_DEBUG_BUILD SET_VEHICLE_NAME_DEBUG(ctTrapInfo[iCop].vehicle, GET_STRING_FROM_INT(iCop)) #ENDIF ENDIF ELSE IF NOT IS_ENTITY_DEAD(ctTrapInfo[iCop].driver) // If driver exists, car is ready SET_PED_AS_COP(ctTrapInfo[iCop].driver, TRUE) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ctTrapInfo[iCop].driver, TRUE) GIVE_DELAYED_WEAPON_TO_PED(ctTrapInfo[iCop].driver, WEAPONTYPE_PISTOL, 100, TRUE) SET_PED_ACCURACY(ctTrapInfo[iCop].driver, BARRY3A_ACCURACY) IF IS_ENTITY_ALIVE(ctTrapInfo[iCop].passenger) SET_PED_AS_COP(ctTrapInfo[iCop].passenger, TRUE) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ctTrapInfo[iCop].passenger, TRUE) GIVE_DELAYED_WEAPON_TO_PED(ctTrapInfo[iCop].passenger, WEAPONTYPE_PISTOL, 100, TRUE) SET_PED_ACCURACY(ctTrapInfo[iCop].passenger, BARRY3A_ACCURACY) ENDIF CPRINTLN(DEBUG_MISSION, "COP_TRAP_SINGLETRIGGER finished creating car ", iCop) ctTrapInfo[iCop].ctsProgress = CTSC_WAITING_TO_TRIGGER ENDIF ENDIF BREAK CASE CTSC_WAITING_TO_TRIGGER // Wait for player to set things off IF IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), ctTrapInfo[iCop].location, COP_DESPAWN_RANGE) IF COP_SINGLE_TRIGGER_CHECK(iCop) CPRINTLN(DEBUG_MISSION, "Cop stakeout triggered on cop car ", iCop) ctTrapInfo[iCop].kickOffTimer = GET_GAME_TIMER() + COP_TRIGGER_DELAY_TIME // Reduced this from 3s to make events clearer to player ctTrapInfo[iCop].ctsProgress = CTSC_TRIGGER_DELAY ELIF PLAYER_IS_MESSING_ABOUT_WITH_COPCAR(ctTrapInfo[iCop].vehicle) OR PLAYER_IS_MESSING_ABOUT_WITH_COP(ctTrapInfo[iCop].driver) OR PLAYER_IS_MESSING_ABOUT_WITH_COP(ctTrapInfo[iCop].passenger) CPRINTLN(DEBUG_MISSION, "Cop car ", iCop, " woken by player messing about") COPS_KICK_OFF(iCop) ELIF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0 CPRINTLN(DEBUG_MISSION, "Cop car ", iCop, " woken on wanted level") COPS_KICK_OFF(iCop) ENDIF ELSE CPRINTLN(DEBUG_MISSION, "COP_TRAP_SINGLETRIGGER player is quite far from this cop setup: Cleaning up cop car ", iCop) IF NOT ctTrapInfo[iCop].bDriverDeletedOrReleased AND DOES_ENTITY_EXIST(ctTrapInfo[iCop].driver) SAFE_DELETE_PED(ctTrapInfo[iCop].driver) ctTrapInfo[iCop].bDriverDeletedOrReleased = TRUE ENDIF IF NOT ctTrapInfo[iCop].bPassengerDeletedOrReleased AND DOES_ENTITY_EXIST(ctTrapInfo[iCop].passenger) SAFE_DELETE_PED(ctTrapInfo[iCop].passenger) ctTrapInfo[iCop].bPassengerDeletedOrReleased = TRUE ENDIF IF NOT ctTrapInfo[iCop].bCarDeletedOrReleased AND DOES_ENTITY_EXIST(ctTrapInfo[iCop].vehicle) SAFE_DELETE_VEHICLE(ctTrapInfo[iCop].vehicle) ctTrapInfo[iCop].bCarDeletedOrReleased = TRUE ENDIF IF ctTrapInfo[iCop].bDriverDeletedOrReleased AND ctTrapInfo[iCop].bPassengerDeletedOrReleased AND ctTrapInfo[iCop].bCarDeletedOrReleased ctTrapInfo[iCop].ctsProgress = CTSC_DELETED ENDIF ENDIF // Check for messing about jacking cops on foot IF IS_PED_ON_FOOT(PLAYER_PED_ID()) IF PLAYER_IS_MESSING_ABOUT_WITH_COP(ctTrapInfo[iCop].driver) OR PLAYER_IS_MESSING_ABOUT_WITH_COP(ctTrapInfo[iCop].passenger) OR PLAYER_IS_MESSING_ABOUT_WITH_COPCAR(ctTrapInfo[iCop].vehicle) // Wake up these cops COPS_KICK_OFF(iCop) ENDIF ENDIF BREAK CASE CTSC_TRIGGER_DELAY IF GET_GAME_TIMER() > ctTrapInfo[iCop].kickOffTimer // Wake up these cops - standard trigger COPS_KICK_OFF(iCop, TRUE) ELSE // Check for messing about jacking cops on foot IF PLAYER_IS_MESSING_ABOUT_WITH_COP(ctTrapInfo[iCop].driver) OR PLAYER_IS_MESSING_ABOUT_WITH_COP(ctTrapInfo[iCop].passenger) OR PLAYER_IS_MESSING_ABOUT_WITH_COPCAR(ctTrapInfo[iCop].vehicle) // Wake up these cops COPS_KICK_OFF(iCop) ENDIF ENDIF BREAK CASE CTSC_TRIGGERED // Monitor the cops to clean them up as soon as it is safe to do so, so we don't get script entities falling through world asserts IF NOT IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), ctTrapInfo[iCop].location, COP_DESPAWN_RANGE) IF NOT ctTrapInfo[iCop].bDriverDeletedOrReleased AND DOES_ENTITY_EXIST(ctTrapInfo[iCop].driver) SAFE_RELEASE_PED(ctTrapInfo[iCop].driver) ctTrapInfo[iCop].bDriverDeletedOrReleased = TRUE ENDIF IF NOT ctTrapInfo[iCop].bPassengerDeletedOrReleased AND DOES_ENTITY_EXIST(ctTrapInfo[iCop].passenger) SAFE_DELETE_PED(ctTrapInfo[iCop].passenger) ctTrapInfo[iCop].bPassengerDeletedOrReleased = TRUE ENDIF IF NOT ctTrapInfo[iCop].bCarDeletedOrReleased AND DOES_ENTITY_EXIST(ctTrapInfo[iCop].vehicle) SAFE_DELETE_VEHICLE(ctTrapInfo[iCop].vehicle) ctTrapInfo[iCop].bCarDeletedOrReleased = TRUE ENDIF IF ctTrapInfo[iCop].bDriverDeletedOrReleased AND ctTrapInfo[iCop].bPassengerDeletedOrReleased AND ctTrapInfo[iCop].bCarDeletedOrReleased ctTrapInfo[iCop].ctsProgress = CTSC_DELETED ENDIF ENDIF BREAK CASE CTSC_DELETED // Done - do nothing BREAK ENDSWITCH ENDPROC /// PURPOSE: /// Handles the scripted cops PROC HANDLE_COPS() // Do the single trigger cop cars in lumber yard area FOR iCount = 0 TO NUM_SINGLE_COPCARS-1 COP_TRAP_SINGLETRIGGER(iCount) ENDFOR IF bCopModelsLoaded AND ctTrapInfo[0].ctsProgress = CTSC_WAITING_TO_TRIGGER AND ctTrapInfo[1].ctsProgress = CTSC_WAITING_TO_TRIGGER SET_MODEL_AS_NO_LONGER_NEEDED(modelCopPed) SET_MODEL_AS_NO_LONGER_NEEDED(modelCopCar) bCopModelsLoaded = FALSE ENDIF ENDPROC /// PURPOSE: /// Display the clock when required PROC DO_CLOCK() IF bDoTheClock IF NOT IS_CUTSCENE_PLAYING() AND NOT IS_PHONE_ONSCREEN() AND NOT IS_PLAYER_BROWSING_ITEMS_IN_ANY_SHOP() INT iDisplayTime // Current time remaining converted to milliseconds so generic timer shows it properly iDisplayTime = iTimeLimit - GET_GAME_TIMER() IF iDisplayTime < 0 iDisplayTime = 0 ENDIF HIDE_STREET_AND_CAR_NAMES_THIS_FRAME() IF GET_GAME_TIMER() >= iWarningTime DRAW_GENERIC_TIMER(iDisplayTime, "B3ATIME", 0, TIMER_STYLE_DONTUSEMILLISECONDS, -1, PODIUMPOS_NONE, HUDORDER_DONTCARE, FALSE, HUD_COLOUR_RED) ELSE DRAW_GENERIC_TIMER(iDisplayTime, "B3ATIME", 0, TIMER_STYLE_DONTUSEMILLISECONDS, -1, PODIUMPOS_NONE, HUDORDER_DONTCARE, FALSE) ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Vehicle-specific cleanup of collect area scenarios /// PARAMS: /// bDeleteEntities makes entities get deleted instead of marking as not needed PROC COLLECT_AREA_CLEANUP(BOOL bDeleteEntities = FALSE) IF bDeleteEntities CPRINTLN(DEBUG_MISSION, "Full delete of script entities...") SAFE_DELETE_OBJECT(oiStashBox) SAFE_DELETE_VEHICLE(stVehicle.vehicle) FOR iCount = 0 TO NUM_SINGLE_COPCARS-1 SAFE_DELETE_PED(ctTrapInfo[iCount].driver) SAFE_DELETE_PED(ctTrapInfo[iCount].passenger) ENDFOR FOR iCount = 0 TO NUM_SINGLE_COPCARS-1 SAFE_DELETE_VEHICLE(ctTrapInfo[iCount].vehicle) ENDFOR ELSE CPRINTLN(DEBUG_MISSION, "Releasing script entities...") SAFE_RELEASE_OBJECT(oiStashBox) SAFE_RELEASE_VEHICLE(stVehicle.vehicle) // Clean up cops FOR iCount = 0 TO NUM_SINGLE_COPCARS-1 SAFE_RELEASE_PED(ctTrapInfo[iCount].driver) SAFE_RELEASE_PED(ctTrapInfo[iCount].passenger) SAFE_RELEASE_VEHICLE(ctTrapInfo[iCount].vehicle) ENDFOR ENDIF IF bCopModelsLoaded SET_MODEL_AS_NO_LONGER_NEEDED(modelCopCar) SET_MODEL_AS_NO_LONGER_NEEDED(modelCopPed) ENDIF SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<< -1142.8287, -1254.5848, 0 >>, << -1136.6863, -1246.4720, 8 >>, TRUE) ENDPROC // Set up info for flavour monologues PROC STORE_FLAVOUR_CHAT() fcFranklinComments[0].convRoot = "BAR3A_C1" // Shit, Motherfuckers had eyes on the place fcFranklinComments[0].convDelay = 1000 fcFranklinComments[1].convRoot = "BAR3A_W2" // C'mon, c'mon! How fucking slow is this thing? fcFranklinComments[1].convDelay = 19000 fcFranklinComments[2].convRoot = "BAR3A_W1" // Man, there's gotta be a better way to get weed legalized than this bullshit. fcFranklinComments[2].convDelay = 20000 fcFranklinComments[3].convRoot = "BAR3A_W4" // Man, fuck, I'm never gonna lose these assholes. fcFranklinComments[3].convDelay = 22000 // fcFranklinComments[0].convRoot = "BAR3A_C1" // Shit, Motherfuckers had eyes on the place // fcFranklinComments[0].convDelay = 1000 // fcFranklinComments[1].convRoot = "BAR3A_W1" // Man, there's gotta be a better way to get weed legalized than this bullshit. // fcFranklinComments[1].convDelay = 9500 // fcFranklinComments[2].convRoot = "BAR3A_W2" // C'mon, c'mon! How fucking slow is this thing? // fcFranklinComments[2].convDelay = 8000 // fcFranklinComments[3].convRoot = "BAR3A_W2A" // Better head for Vespucci so I'm set to ditch this shit when I'm clear. // fcFranklinComments[3].convDelay = 8500 // fcFranklinComments[4].convRoot = "BAR3A_W3" // "Fight the good fight!" "San Andreas needs you!" Asshole. // fcFranklinComments[4].convDelay = 8500 // fcFranklinComments[5].convRoot = "BAR3A_W4" // Man, fuck, I'm never gonna lose these assholes. // fcFranklinComments[5].convDelay = 10000 ENDPROC /// PURPOSE: /// Check for cop proximity. Refines comment triggering. /// RETURNS: /// Returns TRUE if player is near a scripted cop FUNC BOOL IS_PLAYER_NEAR_COP() IF IS_COP_PED_IN_AREA_3D(GET_ENTITY_COORDS(PLAYER_PED_ID()) - << 70.0, 70.0, 70.0 >>, GET_ENTITY_COORDS(PLAYER_PED_ID()) + << 70.0, 70.0, 70.0 >>) RETURN TRUE ENDIF // If we get here, no scripted cops were found to exist in range RETURN FALSE ENDFUNC /// PURPOSE: /// Update/trigger Franklin wanted complaint dialogue PROC FRANKLIN_WANTED_DIALOGUE() // Handle Franklin's comments - don't start checking this stuff until after initial cop loudhailer IF bCopsChallenged AND iFranklinCommentCount < NUM_FLAVOUR_CONVOS IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() AND IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) // Only start new comments if in truck // Check whether the conversation has only just finished IF NOT bFranklinCompletedComment bFranklinCompletedComment = TRUE iFranklinCommentTimer = GET_GAME_TIMER() CPRINTLN(DEBUG_MISSION, "FRANKLIN_WANTED_DIALOGUE: Franklin finished a wanted comment, resetting timer") ENDIF // We might need to be playing a conversation, check how long since the timer was reset IF GET_GAME_TIMER() - iFranklinCommentTimer > fcFranklinComments[iFranklinCommentCount].convDelay AND (IS_PLAYER_NEAR_COP() OR iFranklinCommentCount = 0) // Franklin always says first comment right away - B*1358891 IF (iFranklinCommentCount <> 2 OR GET_ENTITY_SPEED(stVehicle.vehicle) > 10.0) // Don't play comment 2 when vehicle is stationary - B*1397348 CPRINTLN(DEBUG_MISSION, "FRANKLIN_WANTED_DIALOGUE: Started a new wanted comment") // Attempt to create new conversation IF MISSION_OBJECTIVES_CURRENTLY_DISPLAYED() OR GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0 IF CREATE_CONVERSATION(mConversationStruct, "BAR3AAU", fcFranklinComments[iFranklinCommentCount].convRoot, CONV_PRIORITY_MEDIUM, DO_NOT_DISPLAY_SUBTITLES) // Successfully created conversation, wait for it to finish and set up to fire the next bFranklinCompletedComment = FALSE iFranklinCommentCount++ ENDIF ELSE IF CREATE_CONVERSATION(mConversationStruct, "BAR3AAU", fcFranklinComments[iFranklinCommentCount].convRoot, CONV_PRIORITY_MEDIUM, DISPLAY_SUBTITLES) // Successfully created conversation, wait for it to finish and set up to fire the next bFranklinCompletedComment = FALSE iFranklinCommentCount++ ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDPROC //************************************************************************************************************************************************* // // Skip procs // //************************************************************************************************************************************************* // Respawn truck and set up stuck check PROC SKIP_RESPAWN_TRUCK(VECTOR vecRSLoc, FLOAT fRSHead, BOOL bInsertPlayer = TRUE) REQUEST_MODEL(stVehicle.modelName) REQUEST_MODEL(mnStashBox) WHILE NOT HAS_MODEL_LOADED(stVehicle.modelName) OR NOT HAS_MODEL_LOADED(mnStashBox) WAIT(0) ENDWHILE IF IS_ENTITY_ALIVE(stVehicle.vehicle) IF bStuckCheckActive REMOVE_VEHICLE_UPSIDEDOWN_CHECK(stVehicle.vehicle) bStuckCheckActive = FALSE ENDIF ENDIF IF bInsertPlayer IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) SET_ENTITY_COORDS(PLAYER_PED_ID(), vecRSLoc) ENDIF ENDIF SAFE_DELETE_OBJECT(oiStashBox) SAFE_DELETE_VEHICLE(stVehicle.vehicle) stvehicle.vehicle = CREATE_VEHICLE(stVehicle.modelName, vecRSLoc, fRSHead) SET_VEHICLE_COLOUR_COMBINATION(stVehicle.vehicle, 1) IF bInsertPlayer SAFE_SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) ENDIF SET_VEHICLE_CAN_LEAK_OIL(stVehicle.vehicle, FALSE) SET_VEHICLE_CAN_LEAK_PETROL(stVehicle.vehicle, FALSE) SET_VEHICLE_STRONG(stVehicle.vehicle, TRUE) SET_VEHICLE_HAS_STRONG_AXLES(stVehicle.vehicle, TRUE) ADD_VEHICLE_UPSIDEDOWN_CHECK(stVehicle.vehicle) SET_VEHICLE_EXTRA(stVehicle.vehicle, 1, TRUE) SET_VEHICLE_EXTRA(stVehicle.vehicle, 2, TRUE) SET_VEHICLE_EXTRA(stVehicle.vehicle, 3, TRUE) oiStashBox = CREATE_OBJECT(mnStashBox, vecRSLoc) ATTACH_ENTITY_TO_ENTITY(oiStashBox, stVehicle.vehicle, 0, vecStashOffset, <<0,0,0>>, FALSE, FALSE, TRUE) SET_ENTITY_COLLISION(oiStashBox, TRUE) bStuckCheckActive = TRUE SET_VEHICLE_AS_RESTRICTED(stVehicle.vehicle, RESTRICTION_STASHVEH) SET_MODEL_AS_NO_LONGER_NEEDED(stVehicle.modelName) SET_MODEL_AS_NO_LONGER_NEEDED(mnStashBox) ENDPROC /// PURPOSE: /// Get rid of wanted level PROC SKIP_CLEAR_WANTED() IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) // Can occur out of main loop, must check this IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0 SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 0) SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID()) ENDIF ENDIF ENDPROC /// PURPOSE: /// Remove cops /// PARAMS: /// bReset - If true, cops will be reset ready to spawn again, if false they will deleted as if spent PROC SKIP_DELETE_COPS(BOOL bReset = TRUE) // Delete the single trigger cops FOR iCount = 0 TO NUM_SINGLE_COPCARS-1 // Clear peds SAFE_DELETE_PED(ctTrapInfo[iCount].driver) SAFE_DELETE_PED(ctTrapInfo[iCount].passenger) SAFE_DELETE_VEHICLE(ctTrapInfo[iCount].vehicle) IF bReset ctTrapInfo[iCount].bDriverDeletedOrReleased = FALSE ctTrapInfo[iCount].bPassengerDeletedOrReleased = FALSE ctTrapInfo[iCount].bCarDeletedOrReleased = FALSE ctTrapInfo[iCount].ctsProgress = CTSC_WAITING_FOR_ENTITIES IF NOT bCopModelsLoaded REQUEST_MODEL(modelCopPed) REQUEST_MODEL(modelCopCar) ENDIF bCopModelsLoaded = TRUE ELSE ctTrapInfo[iCount].bDriverDeletedOrReleased = TRUE ctTrapInfo[iCount].bPassengerDeletedOrReleased = TRUE ctTrapInfo[iCount].bCarDeletedOrReleased = TRUE ctTrapInfo[iCount].ctsProgress = CTSC_DELETED IF bCopModelsLoaded SET_MODEL_AS_NO_LONGER_NEEDED(modelCopPed) SET_MODEL_AS_NO_LONGER_NEEDED(modelCopCar) ENDIF bCopModelsLoaded = FALSE ENDIF ENDFOR ENDPROC #IF IS_DEBUG_BUILD /// PURPOSE: /// SKIP TO INIT /// Restart the mission PROC SKIP_TO_MS_INIT() CPRINTLN(DEBUG_MISSION, "DEBUG SKIP ::: SKIP_TO_MS_INIT - restart mission") // Clear wanted level SKIP_CLEAR_WANTED() // Progression stuff mStage = MS_STAGE_INIT sProgress = SP_SETUP // Teleport player out of vehicle, recreate it SKIP_RESPAWN_TRUCK(stVehicle.location, stVehicle.heading, FALSE) IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) SET_ENTITY_COORDS(PLAYER_PED_ID(), <<1205.5319, -1264.5835, 34.2264>>) SET_ENTITY_HEADING(PLAYER_PED_ID(), 37.74) ENDIF // Reset cops SKIP_DELETE_COPS() bCopsChallenged = FALSE // Reset comments KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() bFranklinCompletedComment = TRUE bFranklinSaidClearComment = FALSE bFranklinTimeWarnComment = FALSE // Delivery call triggered? bHadDeliveryCall = FALSE bCallDelaySet = FALSE MISSION_OBJECTIVE_RESET(MO_B3AGETIN)// Get in the truck. MISSION_OBJECTIVE_RESET(MO_B3ADELV) // Take the truck to ~y~Barry's apartment.~s~ MISSION_OBJECTIVE_RESET(MO_B3AWAN1) // Lose the cops. MISSION_OBJECTIVE_RESET(MO_B3ARTV) // Get back in the ~b~truck.~s~ ENDPROC #ENDIF /// PURPOSE: /// SKIP TO player in truck - CP 0 /// Restart the mission PROC SKIP_TO_START_DRIVE(BOOL bIsACheckpoint = FALSE) CPRINTLN(DEBUG_MISSION, "DEBUG SKIP ::: SKIP_TO_START_DRIVE - restart mission") // Clear wanted level SKIP_CLEAR_WANTED() // Progression stuff mStage = MS_STAGE_RETURN_VEHICLE sProgress = SP_SETUP // Reset cops SKIP_DELETE_COPS() bCopsChallenged = FALSE // Reset comments KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() bFranklinCompletedComment = TRUE bFranklinSaidClearComment = FALSE bFranklinTimeWarnComment = FALSE // Delivery call triggered? bHadDeliveryCall = FALSE bCallDelaySet = FALSE MISSION_OBJECTIVE_EXPIRE(MO_B3AGETIN)// Get in the truck. MISSION_OBJECTIVE_RESET(MO_B3ADELV) // Take the truck to ~y~Barry's apartment.~s~ MISSION_OBJECTIVE_RESET(MO_B3AWAN1) // Lose the cops. MISSION_OBJECTIVE_RESET(MO_B3ARTV) // Get back in the ~b~truck.~s~ SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<< -1142.8287, -1254.5848, 0 >>, << -1136.6863, -1246.4720, 8 >>, FALSE) IF bIsACheckPoint IF NOT DOES_ENTITY_EXIST(stVehicle.vehicle) SKIP_RESPAWN_TRUCK(stVehicle.location, stVehicle.heading, FALSE) ENDIF WHILE NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT) WAIT(0) ENDWHILE END_REPLAY_SETUP(stVehicle.vehicle, VS_DRIVER, FALSE) ELSE SKIP_RESPAWN_TRUCK(stVehicle.location, stVehicle.heading, TRUE) // WAIT_FOR_WORLD_TO_LOAD(stVehicle.location) ENDIF timeOutStage = TOS_START // The mission timer is handled through the fail checks bDoTheClock = TRUE ENDPROC #IF IS_DEBUG_BUILD /// PURPOSE: /// WARP NEAR END - DEBUG ONLY /// Warps player close to endpoint so you can test cutscene trigger PROC SKIP_WARP_TO_END() CPRINTLN(DEBUG_MISSION, "DEBUG SKIP ::: SKIP_WARP_TO_END (teleport near destination)") // Clear wanted level SKIP_CLEAR_WANTED() // Progression stuff mStage = MS_STAGE_RETURN_VEHICLE sProgress = SP_SETUP // Teleport player out of vehicle, recreate it SKIP_RESPAWN_TRUCK(<< -1066.8279, -1259.9740, 4.9642 >>, 209.23) // Delete cops SKIP_DELETE_COPS(FALSE) // Has Franklin said comment? KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() bFranklinCompletedComment = TRUE bFranklinSaidClearComment = TRUE bFranklinTimeWarnComment = TRUE // Delivery call triggered? bHadDeliveryCall = FALSE bCallDelaySet = FALSE MISSION_OBJECTIVE_EXPIRE(MO_B3ADELV) // Take the truck to ~y~Barry's apartment.~s~ MISSION_OBJECTIVE_RESET(MO_B3AWAN1) // Lose the cops. MISSION_OBJECTIVE_RESET(MO_B3ARTV) // Get back in the ~b~truck.~s~ ENDPROC #ENDIF /// PURPOSE: /// WARP TO DELIVERY /// Trigger the end bit if player has already been warped to end and we skip again PROC SKIP_WARP_TO_DELIVERY(BOOL bIsACheckpoint = FALSE) CPRINTLN(DEBUG_MISSION, "DEBUG SKIP ::: SKIP_WARP_TO_DELIVERY") // Clear wanted level SKIP_CLEAR_WANTED() // Remove blip SAFE_REMOVE_BLIP(biMissionBlip) // Progression stuff mStage = MS_STAGE_DELIVERY sProgress = SP_SETUP // Delete cops SKIP_DELETE_COPS(FALSE) // Franklin cleared wanted comment bFranklinSaidClearComment = TRUE // Delivery call triggered? bHadDeliveryCall = FALSE bCallDelaySet = FALSE MISSION_OBJECTIVE_EXPIRE(MO_B3ADELV) // Take the truck to ~y~Barry's apartment.~s~ MISSION_OBJECTIVE_EXPIRE(MO_B3AWAN1) // Lose the cops. MISSION_OBJECTIVE_EXPIRE(MO_B3ARTV) // Get back in the ~b~truck.~s~ IF bIsACheckpoint bRestartedAfterCP0 = TRUE SKIP_RESPAWN_TRUCK(vecDestination, 298.7, FALSE) WHILE NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT) WAIT(0) ENDWHILE END_REPLAY_SETUP(stVehicle.vehicle, VS_DRIVER, FALSE) ELSE // Has Franklin said comment? IF bFranklinCompletedComment = FALSE KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() bFranklinCompletedComment = TRUE ENDIF SKIP_RESPAWN_TRUCK(vecDestination, 298.7, TRUE) // WAIT_FOR_WORLD_TO_LOAD(vecDestination) ENDIF SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_DELIVERY, "Deliver vehicle.", TRUE) ENDPROC /// PURPOSE: /// TRIGGER COMPLETION /// Sets it to the leave area stage and then sets player far enough away that it counts as leaving area PROC SKIP_TRIGGER_COMPLETION(BOOL bIsACheckpoint = FALSE) CPRINTLN(DEBUG_MISSION, "DEBUG SKIP ::: SKIP_TRIGGER_COMPLETION") // Clear wanted level SKIP_CLEAR_WANTED() // Progression stuff mStage = MS_STAGE_LEAVE_AREA sProgress = SP_SETUP // Teleport player out of vehicle, recreate it SKIP_RESPAWN_TRUCK(vecDestination, 298.7, FALSE) // Delete cops SKIP_DELETE_COPS(FALSE) // Has Franklin said comment? IF bFranklinCompletedComment = FALSE IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF bFranklinCompletedComment = TRUE ENDIF // Franklin cleared wanted comment bFranklinSaidClearComment = TRUE // Delivery call triggered? bHadDeliveryCall = TRUE bCallDelaySet = TRUE MISSION_OBJECTIVE_EXPIRE(MO_B3ADELV) // Take the truck to ~y~Barry's apartment.~s~ MISSION_OBJECTIVE_EXPIRE(MO_B3AWAN1) // Lose the cops. MISSION_OBJECTIVE_EXPIRE(MO_B3ARTV) // Get back in the ~b~truck.~s~ IF bIsACheckpoint bRestartedAfterCP0 = TRUE WHILE NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT) WAIT(0) ENDWHILE END_REPLAY_SETUP(NULL, DEFAULT, FALSE) ELSE SET_ENTITY_COORDS(PLAYER_PED_ID(), << -1243.3162, -1041.6366, 7.5121 >>) SET_ENTITY_HEADING(PLAYER_PED_ID(), 28.2) ENDIF SAFE_FADE_SCREEN_IN_FROM_BLACK() // Screen needs to be fully faded back in before the mission complete GUI stuff will display ENDPROC #IF IS_DEBUG_BUILD /// PURPOSE: /// Skip to the desired stage or warp /// PARAMS: /// iSkipStage - Pass an ENUM_TO_INT from the MISSION_SKIP_STAGE enum PROC DO_Z_SKIP(INT iSkipStage) CPRINTLN(DEBUG_MISSION, "::: Starting Z-skip :::") // Z-skip init RC_START_Z_SKIP() // Convert INT to more readbale ENUM eTargetStage = INT_TO_ENUM(MISSION_SKIP_STAGE, iSkipStage) // Skip to appropriate stage IF eTargetStage = MSS_MISSION_TRIGGERED CPRINTLN(DEBUG_MISSION, "::: Going to SKIP_TO_MS_INIT as if the mission has been freshly triggered :::") SKIP_TO_MS_INIT() ELIF eTargetStage = MSS_RESTART CPRINTLN(DEBUG_MISSION, "::: Going to SKIP_TO_START_DRIVE :::") SKIP_TO_START_DRIVE() ELIF eTargetStage = MSS_WARP_NEAR_END CPRINTLN(DEBUG_MISSION, "::: Going to SKIP_WARP_TO_END :::") SKIP_WARP_TO_END() ELIF eTargetStage = MSS_TRIGGER_DELIVERY CPRINTLN(DEBUG_MISSION, "::: Going to SKIP_WARP_TO_DELIVERY :::") SKIP_WARP_TO_DELIVERY() ELIF eTargetStage = MSS_TRIGGER_COMPLETION CPRINTLN(DEBUG_MISSION, "::: Going to SKIP_TRIGGER_COMPLETION :::") SKIP_TRIGGER_COMPLETION() // ELIF eTargetStage = MSS_BODGE_TIMER // CPRINTLN(DEBUG_MISSION, "::: Z-MENU time-skip!!!") // IF GET_GAME_TIMER() >= iWarningTime // CPRINTLN(DEBUG_MISSION, "::: Timer is already past warning timer, doing nothing.") // ELSE // iTimeLimit = GET_GAME_TIMER() + (GET_MILLISECONDS_PER_GAME_MINUTE()*(CLOCK_WARNING_MINUTES+5)) // iWarningTime = iTimeLimit - (GET_MILLISECONDS_PER_GAME_MINUTE()*CLOCK_WARNING_MINUTES) // CPRINTLN(DEBUG_MISSION, "::: Time left was reduced.") // ENDIF ENDIF // Z-skip cleanup RC_END_Z_SKIP() CPRINTLN(DEBUG_MISSION, "::: Finishing Z-skip :::") ENDPROC #ENDIF // =========================================================================================================== // Termination // =========================================================================================================== // ----------------------------------------------------------------------------------------------------------- // Script Cleanup // ----------------------------------------------------------------------------------------------------------- PROC Script_Cleanup() CPRINTLN(DEBUG_MISSION, "SCRIPT_CLEANUP running") // If the mission was triggered then additional mission cleanup will be required. IF (Random_Character_Cleanup_If_Triggered()) CPRINTLN(DEBUG_MISSION, "...Random Character Script was triggered so additional cleanup required") ENDIF RC_CleanupSceneEntities(sRCLauncherDataLocal) COLLECT_AREA_CLEANUP() #IF IS_DEBUG_BUILD // Widgets IF DOES_WIDGET_GROUP_EXIST(widgetGroup) DELETE_WIDGET_GROUP(widgetGroup) ENDIF #ENDIF // Return ambient cop creation to normal SET_CREATE_RANDOM_COPS(TRUE) // Clear GPS disabled zone SET_GPS_DISABLED_ZONE(<< 0, 0, 0 >>, << 0, 0, 0 >>) REMOVE_SCENARIO_BLOCKING_AREA(sbCarPark[0]) REMOVE_SCENARIO_BLOCKING_AREA(sbCarPark[1]) SET_INSTANCE_PRIORITY_HINT(INSTANCE_HINT_NONE) TERMINATE_THIS_THREAD() ENDPROC // ----------------------------------------------------------------------------------------------------------- // Script Pass // ----------------------------------------------------------------------------------------------------------- PROC Script_Passed() CPRINTLN(DEBUG_MISSION, "SCRIPT_PASSED running") Random_Character_Passed(CP_RAND_C_BAR3, FALSE) Script_Cleanup() ENDPROC //************************************************************************************************************************************************* // // Data init // //************************************************************************************************************************************************* // General data init regardless of whether we're starting at the beginning or from a checkpoint PROC DATA_INIT() #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_MISSION, "DATA_INIT running") mSkipMenu[0].sTxtLabel = "Restart as if from fresh trigger" mSkipMenu[1].sTxtLabel = "Restart (CP 0)" mSkipMenu[2].sTxtLabel = "Warp near end" mSkipMenu[3].sTxtLabel = "Trigger delivery (CP 1)" mSkipMenu[4].sTxtLabel = "Trigger mission complete" // mSkipMenu[4].sTxtLabel = "DEVELOPER TOOL: Timeskip" IF NOT DOES_WIDGET_GROUP_EXIST(widgetGroup) widgetGroup = START_WIDGET_GROUP("Barry 3A") ADD_WIDGET_VECTOR_SLIDER("Stash prop offset", vecStashOffset, -4.0, 4.0, 0.05) ADD_WIDGET_BOOL("Set mission timer to 15 seconds left", bDebugClockTo15s) STOP_WIDGET_GROUP() ENDIF #ENDIF REQUEST_ADDITIONAL_TEXT("BARR3A", MISSION_TEXT_SLOT) // Mission vehicle data stVehicle.modelName = dloader stVehicle.location = << 1199.80, -1259.22, 34.23 >> stVehicle.heading = 174.7 IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) ADD_PED_FOR_DIALOGUE(mConversationStruct, 1, PLAYER_PED_ID(), "FRANKLIN") ENDIF // Franklin cleared wanted comment bFranklinSaidClearComment = FALSE bFranklinTimeWarnComment = FALSE // Init stuff for flavour conversations iFranklinCommentCount = 0 STORE_FLAVOUR_CHAT() // Delivery call triggered? bHadDeliveryCall = FALSE bCallDelaySet = FALSE bDidScannerLine = FALSE STORE_MISSION_OBJECTIVE_DATA() STORE_COP_TRIGGER_DATA() // Have cops started after Franklin at start bCopsChallenged = FALSE // Request stuff for cop trap REQUEST_MODEL(modelCopCar) REQUEST_MODEL(modelCopPed) bCopModelsLoaded = TRUE // Init timeout fail timeOutStage = TOS_IDLE bDoTheClock = FALSE sFailReason = "DEFAULT" // Silently add Barry as contact in case we've launched from debug menu ADD_CONTACT_TO_PHONEBOOK(CHAR_BARRY, FRANKLIN_BOOK, FALSE) // Stop car driving behind apartment sbCarPark[0] = ADD_SCENARIO_BLOCKING_AREA(<< -1156.9, -1274.0, 0.0 >>, << -1141.5, -1239.6, 8.0 >>) sbCarPark[1] = ADD_SCENARIO_BLOCKING_AREA(<< -1177.0, -1292.0, 0.0 >>, << -1160.0, -1273.3, 8.0 >>) SET_GPS_DISABLED_ZONE(<< -1132.88, -1262.01, 0.0 >>, << -1102.43, -1196.58, 15.0 >>) SET_CREATE_RANDOM_COPS(FALSE) ENDPROC /// PURPOSE: /// Set up the truck's configuration /// Seperated out from main init so we don't mess up the setup when restarting from a checkpoint PROC TRUCK_INIT() IF IS_ENTITY_ALIVE(stVehicle.vehicle) SET_VEHICLE_STRONG(stVehicle.vehicle, TRUE) SET_VEHICLE_HAS_STRONG_AXLES(stVehicle.vehicle, TRUE) SET_VEHICLE_CAN_LEAK_OIL(stVehicle.vehicle, FALSE) SET_VEHICLE_CAN_LEAK_PETROL(stVehicle.vehicle, FALSE) IF NOT bStuckCheckActive ADD_VEHICLE_UPSIDEDOWN_CHECK(stVehicle.vehicle) ENDIF SET_VEHICLE_AS_RESTRICTED(stVehicle.vehicle, RESTRICTION_STASHVEH) ENDIF ENDPROC //************************************************************************************************************************************************* // // Mission stage procs // //************************************************************************************************************************************************* // MISSION STAGE PROC // Waits for game text PROC STAGE_INIT() // Wait for text before proceeding IF HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT) SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<< -1142.8287, -1254.5848, 0 >>, << -1136.6863, -1246.4720, 8 >>, FALSE) biMissionBlip = CREATE_VEHICLE_BLIP(stVehicle.vehicle) mStage = MS_STAGE_CALL_BARRY sProgress = SP_SETUP ENDIF ENDPROC /// PURPOSE: /// MISSION STAGE PROC /// Player calls Barry once near to truck PROC STAGE_CALL_BARRY() SWITCH sProgress CASE SP_SETUP // Franklin calls Barry ADD_PED_FOR_DIALOGUE(mConversationStruct, 3, NULL, "BARRY") IF PLAYER_CALL_CHAR_CELLPHONE(mConversationStruct, CHAR_BARRY, "BAR3AAU", "BAR3A_PICK2", CONV_PRIORITY_MEDIUM) CPRINTLN(DEBUG_MISSION, "STAGE_CALL_BARRY: SP_SETUP started call") sProgress = SP_RUNNING ENDIF BREAK CASE SP_RUNNING // Mission can progress either by player getting in truck or by call ending // Check for player in truck IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) timeOutStage = TOS_START // The mission timer is handled through the fail checks mStage = MS_STAGE_RETURN_VEHICLE sProgress = SP_SETUP // Check for phone call finishing ELIF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() timeOutStage = TOS_START // The mission timer is handled through the fail checks mStage = MS_STAGE_ENTER_TRUCK sProgress = SP_SETUP ENDIF BREAK ENDSWITCH ENDPROC /// PURPOSE: /// MISSION STAGE PROC /// Wait for player to get in the truck PROC STAGE_ENTER_TRUCK() SWITCH sProgress CASE SP_SETUP // Check whether the player is already in truck IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) // Player not in truck CPRINTLN(DEBUG_MISSION, "STAGE_ENTER_TRUCK: SP_SETUP going to SP_RUNNING") DISPLAY_MISSION_OBJECTIVE(MO_B3AGETIN) // Get in the truck. sProgress = SP_RUNNING ELSE // Player alreayd in truck, skip to main driving stage CPRINTLN(DEBUG_MISSION, "STAGE_ENTER_TRUCK: SP_SETUP going directly to STAGE_RETURN_VEHICLE") mStage = MS_STAGE_RETURN_VEHICLE sProgress = SP_SETUP ENDIF bDoTheClock = TRUE BREAK CASE SP_RUNNING // Wait until player is in truck IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) CPRINTLN(DEBUG_MISSION, "STAGE_ENTER_TRUCK: SP_RUNNING going to STAGE_RETURN_VEHICLE") CLEAR_PRINTS() mStage = MS_STAGE_RETURN_VEHICLE sProgress = SP_SETUP ENDIF BREAK ENDSWITCH ENDPROC // MISSION STAGE PROC // Get vehicle to Barry if player has collected it PROC STAGE_RETURN_VEHICLE() SWITCH sProgress CASE SP_SETUP CPRINTLN(DEBUG_MISSION, "STAGE_RETURN_VEHICLE: SP_SETUP") // Going to start driving SET_INSTANCE_PRIORITY_HINT(INSTANCE_HINT_DRIVING) // Player will be out of their arriving car now IF NOT bSetupVehGen SET_MISSION_START_VEHICLE_AS_VEHICLE_GEN(<<0,0,0>>, 0, FALSE) bSetupVehGen = TRUE ENDIF IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) // Remove vehicle blip if it exists SAFE_REMOVE_BLIP(biMissionBlip) biMissionBlip = CREATE_COORD_BLIP(vecDestination) // Show the delivery objective IF MISSION_OBJECTIVE_WILL_DISPLAY(MO_B3ADELV) AND (GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0 OR NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()) DISPLAY_MISSION_OBJECTIVE(MO_B3ADELV) // Take the truck to ~y~Barry's apartment.~s~ CHECK_CONVERSATION_AND_OBJECTIVE_TEXT_CONFLICT_NOW(stateRestoreConversation) ENDIF iFranklinCommentTimer = GET_GAME_TIMER() // Start stat mission timer INFORM_MISSION_STATS_SYSTEM_OF_TIME_WINDOW_OPEN(BA3A_DELIVERY_TIME) sProgress = SP_RUNNING ELSE mStage = MS_STAGE_GET_VEHICLE_BACK ENDIF // Enable the clock now we're doing the fail check IF timeOutStage = TOS_FAILCHECK bDoTheClock = TRUE ENDIF BREAK CASE SP_RUNNING // Detect player getting out of vehicle IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) // Player is still in truck IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0 // Player wanted: State change required sProgress = SP_CLEANUP ELSE // See if we need to show the delivery objective IF MISSION_OBJECTIVE_WILL_DISPLAY(MO_B3ADELV) AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DISPLAY_MISSION_OBJECTIVE(MO_B3ADELV) // Take the truck to ~y~Barry's apartment.~s~ CHECK_CONVERSATION_AND_OBJECTIVE_TEXT_CONFLICT_NOW(stateRestoreConversation) ENDIF // Player not wanted - Check for vehicle arriving at destination IF IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) // Player cannot be bailing out of car! AND IS_ENTITY_AT_COORD(stVehicle.vehicle, vecDestination, << 6.0, 6.0, LOCATE_SIZE_HEIGHT >>, TRUE) // AND IS_ENTITY_IN_RANGE_COORDS(stVehicle.vehicle, vecDestination, 6.0) timeOutStage = TOS_IDLE sProgress = SP_CLEANUP ENDIF // Not arrived yet, handle Franklin's wanted clear comment IF NOT bFranklinSaidClearComment IF GET_GAME_TIMER() - iFranklinCommentTimer > 8000 AND iFranklinCommentCount >= NUM_FLAVOUR_CONVOS // Franklin should only say this comment if he was wanted for some time AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF CREATE_CONVERSATION(mConversationStruct, "BAR3AAU", "BAR3A_LW", CONV_PRIORITY_MEDIUM) bFranklinSaidClearComment = TRUE ENDIF ENDIF ENDIF ENDIF ELSE // Player not in truck - change states sProgress = SP_CLEANUP ENDIF BREAK CASE SP_CLEANUP // Clear blip + text CLEAR_PRINTS() SAFE_REMOVE_BLIP(biMissionBlip) sProgress = SP_SETUP // choose next stage IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0 CPRINTLN(DEBUG_MISSION, "STAGE_RETURN_VEHICLE: SP_CLEANUP going to STAGE_LOSE_WANTED") mStage = MS_STAGE_LOSE_WANTED ELSE CPRINTLN(DEBUG_MISSION, "STAGE_RETURN_VEHICLE: SP_CLEANUP going to STAGE_DELIVERY") SET_REPLAY_MID_MISSION_STAGE_WITH_NAME(CP_DELIVERY, "Deliver vehicle.", TRUE) mStage = MS_STAGE_DELIVERY ENDIF ELSE CPRINTLN(DEBUG_MISSION, "STAGE_RETURN_VEHICLE: SP_CLEANUP going to STAGE_GET_VEHICLE_BACK") mStage = MS_STAGE_GET_VEHICLE_BACK ENDIF BREAK ENDSWITCH ENDPROC // MISSION STAGE PROC // Tracks player getting back in a collected vehicle if they abandon it en route to Barry PROC STAGE_GET_VEHICLE_BACK() SWITCH sProgress CASE SP_SETUP CPRINTLN(DEBUG_MISSION, "STAGE_GET_VEHICLE_BACK: SP_SETUP") // Remove the destination blip until player gets vehicle back SAFE_REMOVE_BLIP(biMissionBlip) // Blip vehicle instead biMissionBlip = CREATE_VEHICLE_BLIP(stVehicle.vehicle) SET_BLIP_ROUTE(biMissionBlip, TRUE) IF MISSION_OBJECTIVE_WILL_DISPLAY(MO_B3ARTV) AND (GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0 OR NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()) DISPLAY_MISSION_OBJECTIVE(MO_B3ARTV) CHECK_CONVERSATION_AND_OBJECTIVE_TEXT_CONFLICT_NOW(stateRestoreConversation) ENDIF sProgress = SP_RUNNING // Enable the clock now we're doing the fail check IF timeOutStage = TOS_FAILCHECK bDoTheClock = TRUE ENDIF BREAK CASE SP_RUNNING HANDLE_CONVERSATION_AND_OBJECTIVE_TEXT_CONFLICT(stateRestoreConversation, mConversationStruct, "BAR3AAU", tSavedConversationRoot, tSavedConversationLabel) // Track player entering vehicle IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) sProgress = SP_CLEANUP ELSE // See if the objective is needed IF MISSION_OBJECTIVE_WILL_DISPLAY(MO_B3ARTV) AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DISPLAY_MISSION_OBJECTIVE(MO_B3ARTV) CHECK_CONVERSATION_AND_OBJECTIVE_TEXT_CONFLICT_NOW(stateRestoreConversation) ENDIF // Check if player is in ragdoll - dialogue needs to stop in this case IF IS_PED_RAGDOLL(PLAYER_PED_ID()) // Player is in ragdoll - if a wanted complaint conversation is ongoing, kill it IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() ENDIF ELSE // Player not in ragdoll - are they wanted? IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0 // See if we need to update dialogue FRANKLIN_WANTED_DIALOGUE() ENDIF ENDIF ENDIF BREAK CASE SP_CLEANUP // Clear blip + text CLEAR_PRINTS() SAFE_REMOVE_BLIP(biMissionBlip) sProgress = SP_SETUP // go to correct stage IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) < 1 CPRINTLN(DEBUG_MISSION, "STAGE_GET_VEHICLE_BACK: SP_CLEANUP going to STAGE_RETURN_VEHICLE") mStage = MS_STAGE_RETURN_VEHICLE ELSE CPRINTLN(DEBUG_MISSION, "STAGE_GET_VEHICLE_BACK: SP_CLEANUP going to STAGE_LOSE_WANTED") mStage = MS_STAGE_LOSE_WANTED ENDIF ELSE CPRINTLN(DEBUG_MISSION, "STAGE_GET_VEHICLE_BACK: SP_CLEANUP found player not in vehicle! Go back to SP_RUNNING.") sProgress = SP_RUNNING ENDIF BREAK ENDSWITCH ENDPROC // MISSION STAGE PROC // Track player being wanted - as a separate proc because of dialogue triggering PROC STAGE_LOSE_WANTED() SWITCH sProgress CASE SP_SETUP CPRINTLN(DEBUG_MISSION, "STAGE_LOSE_WANTED: SP_SETUP") // Clear destination blip if it exists SAFE_REMOVE_BLIP(biMissionBlip) // Display objective IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() OR GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0 DISPLAY_MISSION_OBJECTIVE(MO_B3AWAN1) // Lose your wanted level CHECK_CONVERSATION_AND_OBJECTIVE_TEXT_CONFLICT_NOW(stateRestoreConversation) bWantedObjectiveNeeded = FALSE ELSE bWantedObjectiveNeeded = TRUE ENDIF // Distance "grace" range does not apply while wanted IF timeOutStage = TOS_IDLE timeOutStage = TOS_FAILCHECK bDoTheClock = TRUE ENDIF // Set marker bool for which ending phone call we want to play bBeenWanted = TRUE // Set timer for playing custom scanner line iScannerTimer = GET_GAME_TIMER() + 2500 sProgress = SP_RUNNING BREAK CASE SP_RUNNING HANDLE_CONVERSATION_AND_OBJECTIVE_TEXT_CONFLICT(stateRestoreConversation, mConversationStruct, "BAR3AAU", tSavedConversationRoot, tSavedConversationLabel) IF NOT bDidScannerLine AND GET_GAME_TIMER() > iScannerTimer PLAY_POLICE_REPORT("SCRIPTED_SCANNER_REPORT_BARRY_3A_01", 0.0) bDidScannerLine = TRUE ENDIF // Detect player getting out of vehicle IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) // Player is still in truck // Has player lost wanted level? IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) < 1 sProgress = SP_CLEANUP ELSE // See if we need to display objective IF bWantedObjectiveNeeded AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DISPLAY_MISSION_OBJECTIVE(MO_B3AWAN1) // Lose your wanted level CHECK_CONVERSATION_AND_OBJECTIVE_TEXT_CONFLICT_NOW(stateRestoreConversation) bWantedObjectiveNeeded = FALSE ENDIF // Do Franklin's wanted dialogue FRANKLIN_WANTED_DIALOGUE() ENDIF ELSE // Player not in vehicle - need to change stage sProgress = SP_CLEANUP ENDIF BREAK CASE SP_CLEANUP // If player is not wanted, some cleanup is needed IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) < 1 // Kill any wanted conversation IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() KILL_FACE_TO_FACE_CONVERSATION() ENDIF ENDIF // Return to appropriate state sProgress = SP_SETUP IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) CPRINTLN(DEBUG_MISSION, "STAGE_LOSE_WANTED: SP_CLEANUP going to STAGE_RETURN_VEHICLE") mStage = MS_STAGE_RETURN_VEHICLE ELSE CPRINTLN(DEBUG_MISSION, "STAGE_LOSE_WANTED: SP_CLEANUP going to STAGE_GET_VEHICLE_BACK") mStage = MS_STAGE_GET_VEHICLE_BACK ENDIF BREAK ENDSWITCH ENDPROC // MISSION STAGE PROC // Handles the player delivering vehicle - force exit etc. PROC STAGE_DELIVERY() SWITCH sProgress CASE SP_SETUP // Set health before vehicle has stopped for maximum leniency! IF GET_VEHICLE_PETROL_TANK_HEALTH(stVehicle.vehicle) < 1 SET_VEHICLE_PETROL_TANK_HEALTH(stVehicle.vehicle, 10.0) ENDIF IF GET_VEHICLE_ENGINE_HEALTH(stVehicle.vehicle) < 1 SET_VEHICLE_ENGINE_HEALTH(stVehicle.vehicle, 10.0) ENDIF // Stop the vehicle ready for delivery event IF BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(stVehicle.vehicle) CPRINTLN(DEBUG_MISSION, "STAGE_DELIVERY: SP_SETUP has stopped car, going to SP_RUNNING") // Stop the mission stat timer INFORM_MISSION_STATS_SYSTEM_OF_TIME_WINDOW_CLOSED() bDoTheClock = FALSE timeOutStage = TOS_IDLE sProgress = SP_RUNNING ENDIF BREAK CASE SP_RUNNING DISPLAY_MISSION_OBJECTIVE(MO_B3AEXIT) sProgress = SP_CLEANUP BREAK CASE SP_CLEANUP ADD_PED_FOR_DIALOGUE(mConversationStruct, 3, NULL, "BARRY") CPRINTLN(DEBUG_MISSION, "STAGE_DELIVERY: SP_CLEANUP - going to STAGE_LEAVE_AREA") sProgress = SP_SETUP mStage = MS_STAGE_LEAVE_AREA BREAK ENDSWITCH ENDPROC // Franklin calls Barry to confirm delivery PROC DO_DELIVERY_PHONE_CALL() IF NOT bCallDelaySet iCallDelayTimer = GET_GAME_TIMER() + 3500 bCallDelaySet = TRUE ELIF NOT bHadDeliveryCall IF GET_GAME_TIMER() > iCallDelayTimer // Start phone call to Barry IF bBeenWanted = TRUE // Has been wanted - mention cops IF PLAYER_CALL_CHAR_CELLPHONE(mConversationStruct, CHAR_BARRY, "BAR3AAU", "BAR3A_P1", CONV_PRIORITY_VERY_HIGH) CPRINTLN(DEBUG_MISSION, "DO_DELIVERY_PHONE_CALL: Started been wanted phone call") sProgress = SP_RUNNING bHadDeliveryCall = TRUE ENDIF ELSE // Hasn't been wanted - mock Barry for worrying IF PLAYER_CALL_CHAR_CELLPHONE(mConversationStruct, CHAR_BARRY, "BAR3AAU", "BAR3A_P1b", CONV_PRIORITY_VERY_HIGH) CPRINTLN(DEBUG_MISSION, "DO_DELIVERY_PHONE_CALL: Started not been wanted phone call") sProgress = SP_RUNNING bHadDeliveryCall = TRUE ENDIF ENDIF ENDIF ENDIF ENDPROC // MISSION STAGE PROC // Handles player leaving area PROC STAGE_LEAVE_AREA() SWITCH sProgress CASE SP_SETUP // If we're sure the player isn't messing about with vehicle, can start leave area checks IF IS_ENTITY_AT_COORD(stVehicle.vehicle, vecDestination, << 10.0, 10.0, LOCATE_SIZE_HEIGHT >>, FALSE) SAFE_REMOVE_BLIP(biMissionBlip) SET_INSTANCE_PRIORITY_HINT(INSTANCE_HINT_NONE) IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) CPRINTLN(DEBUG_MISSION, "STAGE_LEAVE_AREA: SP_SETUP: Truck at drop off point, player still in truck") bPlayerInTruck = TRUE ELSE CPRINTLN(DEBUG_MISSION, "STAGE_LEAVE_AREA: SP_SETUP: Truck at drop off point, player has got out") IF MISSION_OBJECTIVES_CURRENTLY_DISPLAYED() CLEAR_PRINTS() // May be needed to remove expired objective ENDIF bPlayerInTruck = FALSE ENDIF sProgress = SP_RUNNING // Player is mucking about with vehicle ELSE // Truck not at delivery point - drive it back CPRINTLN(DEBUG_MISSION, "STAGE_LEAVE_AREA: SP_SETUP: Truck not at delivery point, go to STAGE_TAKE_VEHICLE_BACK") mStage = MS_STAGE_TAKE_VEHICLE_BACK sProgress = SP_SETUP ENDIF BREAK CASE SP_RUNNING // If we're sure the player isn't dicking about with vehicle, can check for leaving area IF IS_ENTITY_AT_COORD(stVehicle.vehicle, vecDestination, << 10.0, 10.0, LOCATE_SIZE_HEIGHT >>, FALSE) // Checks for when player's in vehicle IF bPlayerInTruck // Check whether player's got out IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) // Player got out again - can drop to leave area check CPRINTLN(DEBUG_MISSION, "STAGE_LEAVE_AREA: Player out of vehicle, vehicle at drop-off point") CLEAR_PRINTS() bPlayerInTruck = FALSE ELSE // Player still in truck bPlayerInTruck = TRUE ENDIF ELIF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) // Player got back in truck CPRINTLN(DEBUG_MISSION, "STAGE_LEAVE_AREA: Player got back in truck") CLEAR_PRINTS() bPlayerInTruck = TRUE ELSE // Check for firing phone call DO_DELIVERY_PHONE_CALL() // Leave area check IF NOT IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), stVehicle.vehicle, 55) AND NOT IS_ENTITY_ON_SCREEN(stVehicle.vehicle) sProgress = SP_CLEANUP // See if we still need the objective ELIF bHadDeliveryCall AND MISSION_OBJECTIVE_WILL_DISPLAY(MO_B3ALEAVE) AND (GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0 OR NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()) DISPLAY_MISSION_OBJECTIVE(MO_B3ALEAVE) ENDIF ENDIF // Player is mucking about with vehicle ELSE // Ditch the leave area objective CLEAR_PRINTS() mStage = MS_STAGE_TAKE_VEHICLE_BACK sProgress = SP_SETUP ENDIF BREAK CASE SP_CLEANUP CPRINTLN(DEBUG_MISSION, "STAGE_LEAVE_AREA: SP_CLEANUP - Player has run off now, script will now exit.") CLEAR_PRINTS() SAFE_DELETE_OBJECT(oiStashBox) SAFE_DELETE_VEHICLE(stVehicle.vehicle) IF bBeenWanted OR bRestartedAfterCP0 INFORM_STAT_SYSTEM_OF_BOOL_STAT_HAPPENED(BA3A_AVOID_STAKEOUT) ENDIF Script_Passed() BREAK ENDSWITCH ENDPROC /// PURPOSE: /// MISSION STAGE PROC /// Player is mucking around with truck and must take it back PROC STAGE_TAKE_VEHICLE_BACK() SWITCH sProgress CASE SP_SETUP CPRINTLN(DEBUG_MISSION, "STAGE_TAKE_VEHICLE_BACK: SP_SETUP") SAFE_REMOVE_BLIP(biMissionBlip) IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) < 1 // Player in truck, not wanted CPRINTLN(DEBUG_MISSION, "STAGE_TAKE_VEHICLE_BACK: SP_SETUP: Player started stage in truck, not wanted") bPlayerInTruck = TRUE bPlayerWanted = FALSE biMissionBlip = CREATE_COORD_BLIP(vecDestination) ELSE // Player in truck, wanted CPRINTLN(DEBUG_MISSION, "STAGE_TAKE_VEHICLE_BACK: SP_SETUP: Player started stage in truck, wanted") bPlayerInTruck = TRUE bPlayerWanted = TRUE IF GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0 OR NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DISPLAY_MISSION_OBJECTIVE(MO_B3AWAN1) bObjectiveNeeded = FALSE ELSE bObjectiveNeeded = TRUE ENDIF ENDIF ELSE // Player not in truck CPRINTLN(DEBUG_MISSION, "STAGE_TAKE_VEHICLE_BACK: SP_SETUP: Player started stage not in truck") bPlayerInTruck = FALSE IF MISSION_OBJECTIVE_WILL_DISPLAY(MO_B3ARTV) IF GET_PROFILE_SETTING(PROFILE_DISPLAY_SUBTITLES) = 0 OR NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DISPLAY_MISSION_OBJECTIVE(MO_B3ARTV) bObjectiveNeeded = FALSE ELSE bObjectiveNeeded = TRUE ENDIF ELSE bObjectiveNeeded = FALSE ENDIF biMissionBlip = CREATE_VEHICLE_BLIP(stVehicle.vehicle) ENDIF sProgress = SP_RUNNING BREAK CASE SP_RUNNING // Checks whether truck is too far from delivery location IF NOT IS_ENTITY_IN_RANGE_COORDS(stVehicle.vehicle, vecDestination, DELIVERY_FAIL_DISTANCE) // FAIL! CPRINTLN(DEBUG_MISSION, "STAGE_TAKE_VEHICLE_BACK: Player wandered off after delivery!") sFailReason = "B3ANOTDELV" // The truck was not delivered. sProgress = SP_SETUP mStage = MS_STAGE_FAIL_FADE // Checks for while player's on foot ELIF NOT bPlayerInTruck // See if Player's back in truck IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) // Back in vehicle bPlayerInTruck = TRUE CLEAR_PRINTS() SAFE_REMOVE_BLIP(biMissionBlip) // Check if wanted IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0 // Wanted CPRINTLN(DEBUG_MISSION, "STAGE_TAKE_VEHICLE_BACK: Player back in truck but is wanted") bPlayerWanted = TRUE bObjectiveNeeded = TRUE ELSE // All is well - Check if at destination CPRINTLN(DEBUG_MISSION, "STAGE_TAKE_VEHICLE_BACK: Player back in vehicle, not wanted") bPlayerWanted = FALSE IF IS_ENTITY_AT_COORD(stVehicle.vehicle, vecDestination, << 6.0, 6.0, LOCATE_SIZE_HEIGHT >>, TRUE) SAFE_REMOVE_BLIP(biMissionBlip) sProgress = SP_SETUP mStage = MS_STAGE_DELIVERY ELSE // Not there yet - blip biMissionBlip = CREATE_COORD_BLIP(vecDestination) ENDIF ENDIF ELSE // Still on foot IF bObjectiveNeeded AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DISPLAY_MISSION_OBJECTIVE(MO_B3ARTV) bObjectiveNeeded = FALSE ENDIF ENDIF // See if player's just got out ELIF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) // Player is on foot - priority objective is get truck back CPRINTLN(DEBUG_MISSION, "STAGE_TAKE_VEHICLE_BACK: Player got out of truck") CLEAR_PRINTS() bPlayerInTruck = FALSE bObjectiveNeeded = TRUE SAFE_REMOVE_BLIP(biMissionBlip) biMissionBlip = CREATE_VEHICLE_BLIP(stVehicle.vehicle) // Checks for while player is wanted ELIF bPlayerWanted IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), stVehicle.vehicle) // Player got out of truck - that state has priority CLEAR_PRINTS() CPRINTLN(DEBUG_MISSION, "STAGE_TAKE_VEHICLE_BACK: Player out of truck while wanted") bPlayerInTruck = FALSE biMissionBlip = CREATE_VEHICLE_BLIP(stVehicle.vehicle) ELIF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) < 1 // Player is in truck and no longer wanted CPRINTLN(DEBUG_MISSION, "STAGE_TAKE_VEHICLE_BACK: Player in truck, no longer wanted") CLEAR_PRINTS() bPlayerWanted = FALSE bObjectiveNeeded = FALSE SAFE_REMOVE_BLIP(biMissionBlip) biMissionBlip = CREATE_COORD_BLIP(vecDestination) ELSE IF bObjectiveNeeded AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() DISPLAY_MISSION_OBJECTIVE(MO_B3AWAN1) bObjectiveNeeded = FALSE ENDIF ENDIF // See if player's just become wanted ELIF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0 // Player is now wanted and in truck as we already checked that CPRINTLN(DEBUG_MISSION, "STAGE_TAKE_VEHICLE_BACK: Player in truck, now wanted") CLEAR_PRINTS() bPlayerWanted = TRUE bObjectiveNeeded = TRUE SAFE_REMOVE_BLIP(biMissionBlip) // Checks for while everything is going swimmingly ELSE // Check for redelivery IF IS_ENTITY_AT_COORD(stVehicle.vehicle, vecDestination, << 6.0, 6.0, LOCATE_SIZE_HEIGHT >>, TRUE) CPRINTLN(DEBUG_MISSION, "STAGE_TAKE_VEHICLE_BACK: Player at delivery location, going to STAGE_DELIVERY") SAFE_REMOVE_BLIP(biMissionBlip) sProgress = SP_SETUP mStage = MS_STAGE_DELIVERY ENDIF ENDIF BREAK CASE SP_CLEANUP CPRINTLN(DEBUG_MISSION, "STAGE_LEAVE_AREA: SP_CLEANUP - Player has run off now, script will now exit.") CLEAR_PRINTS() SAFE_DELETE_OBJECT(oiStashBox) SAFE_DELETE_VEHICLE(stVehicle.vehicle) IF bBeenWanted OR bRestartedAfterCP0 INFORM_STAT_SYSTEM_OF_BOOL_STAT_HAPPENED(BA3A_AVOID_STAKEOUT) ENDIF Script_Passed() BREAK ENDSWITCH ENDPROC /// PURPOSE: /// MISSION STAGE PROC /// Handles the fade out PROC STAGE_FAIL_FADE() SWITCH sProgress CASE SP_SETUP IF NOT IS_PLAYER_BROWSING_ITEMS_IN_ANY_SHOP() // Block mission fail if the player is in shop menus - they might do this after they use a pay and spray and it looks really weird SAFE_REMOVE_BLIP(biMissionBlip) bDoTheClock = FALSE CLEAR_PRINTS() CLEAR_HELP(TRUE) IF IS_STRING_NULL_OR_EMPTY(sFailReason) // Guard against null string case SCRIPT_ASSERT("Reached STAGE_FAIL_FADE with NULL/empty fail reason string - Please add detailed repro steps when bugging this.") sFailReason = "DEFAULT" ENDIF IF ARE_STRINGS_EQUAL(sFailReason, "DEFAULT") // No fail reason Random_Character_Failed() ELSE Random_Character_Failed_With_Reason(sFailReason) ENDIF CPRINTLN(DEBUG_MISSION, "STAGE_FAIL_FADE: SP_SETUP - going to SP_RUNNING") sProgress = SP_RUNNING ENDIF BREAK CASE SP_RUNNING IF GET_MISSION_FLOW_SAFE_TO_CLEANUP() CPRINTLN(DEBUG_MISSION, "STAGE_FAIL_FADE: SP_CLEANUP - script will now exit") bDoTheClock = FALSE // Do a check here to see if we need to warp the player at all // (only set the fail warp locations if we can't leave the player where he was) // MISSION_FLOW_SET_FAIL_WARP_LOCATION(vPos, fHeading) // SET_REPLAY_DECLINED_VEHICLE_WARP_LOCATION(vPos, fHeading) COLLECT_AREA_CLEANUP(TRUE) Script_Cleanup() // script_cleanup should terminate the thread ELSE // not finished fading out // you may want to handle dialogue etc here. ENDIF BREAK ENDSWITCH ENDPROC // =========================================================================================================== // DEBUG FUNCTIONS // =========================================================================================================== /// PURPOSE: Check for Forced Pass or Fail PROC DEBUG_Check_Debug_Keys() #IF IS_DEBUG_BUILD INT iNewStage // Check for Pass IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S)) CLEAR_ALL_MISSION_OBJECTIVES() Script_Passed() // Check for Fail ELIF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F)) CLEAR_ALL_MISSION_OBJECTIVES() mStage = MS_STAGE_FAIL_FADE sProgress = SP_SETUP // Check for skip forward ELIF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J)) IF mStage = MS_STAGE_CALL_BARRY OR mStage = MS_STAGE_ENTER_TRUCK DO_Z_SKIP(ENUM_TO_INT(MSS_RESTART)) ELIF mStage = MS_STAGE_RETURN_VEHICLE OR mStage = MS_STAGE_GET_VEHICLE_BACK OR mStage = MS_STAGE_LOSE_WANTED IF IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), vecDestination, 125) // If the player is close to the drop-off, trigger delivery DO_Z_SKIP(ENUM_TO_INT(MSS_TRIGGER_DELIVERY)) ELSE // Player still distant, warp near the drop-off location DO_Z_SKIP(ENUM_TO_INT(MSS_WARP_NEAR_END)) ENDIF ELIF mStage = MS_STAGE_DELIVERY OR mStage = MS_STAGE_LEAVE_AREA // Complete mission warp DO_Z_SKIP(ENUM_TO_INT(MSS_TRIGGER_COMPLETION)) ENDIF // Check for skip backward ELIF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P)) IF mStage = MS_STAGE_DELIVERY // If the player's reached the drop-off, warp to the near end location DO_Z_SKIP(ENUM_TO_INT(MSS_WARP_NEAR_END)) ELIF mStage = MS_STAGE_LEAVE_AREA // Leaving area - skip back to delivery DO_Z_SKIP(ENUM_TO_INT(MSS_TRIGGER_DELIVERY)) ELIF mStage = MS_STAGE_RETURN_VEHICLE IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) AND IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), stVehicle.location, 3.0) DO_Z_SKIP(ENUM_TO_INT(MSS_MISSION_TRIGGERED)) ELSE DO_Z_SKIP(ENUM_TO_INT(MSS_RESTART)) ENDIF ELIF mStage = MS_STAGE_LOSE_WANTED DO_Z_SKIP(ENUM_TO_INT(MSS_RESTART)) ELIF mStage = MS_STAGE_CALL_BARRY OR mStage = MS_STAGE_ENTER_TRUCK // Otherwise, restart DO_Z_SKIP(ENUM_TO_INT(MSS_MISSION_TRIGGERED)) ENDIF // Check for Z menu ELIF LAUNCH_MISSION_STAGE_MENU(mSkipMenu, iNewStage) DO_Z_SKIP(iNewStage) ENDIF IF bDebugClockTo15s bDebugClockTo15s = FALSE IF timeOutStage = TOS_FAILCHECK // Set time limit to 15 seconds iTimeLimit = GET_GAME_TIMER() + 15000 CPRINTLN(DEBUG_MISSION, "TIME LIMIT debug reset::: ", iTimeLimit, "ms. MS per game minute is ", GET_MILLISECONDS_PER_GAME_MINUTE(), "ms") // Stop Franklin saying his remark so we can hear the beeps bFranklinTimeWarnComment = TRUE iTenSecondsLeft = iTimeLimit - 11000 iFiveSecondsLeft = iTimeLimit - 6000 iZeroSecondsLeft = iTimeLimit - 1000 bStartedBeepTimer = FALSE ENDIF ENDIF #ENDIF ENDPROC // =========================================================================================================== // Script Loop // =========================================================================================================== SCRIPT(g_structRCScriptArgs sRCLauncherDataIn) sRCLauncherDataLocal = sRCLauncherDataIn RC_TakeEntityOwnership(sRCLauncherDataLocal) RC_CLEANUP_LAUNCHER() SET_MISSION_FLAG(TRUE) // Setup callback when player is killed, arrested or goes to multiplayer IF (HAS_FORCE_CLEANUP_OCCURRED(DEFAULT_FORCE_CLEANUP_FLAGS|FORCE_CLEANUP_FLAG_DEBUG_MENU)) PRINT_LAUNCHER_DEBUG("Force cleanup [TERMINATING]") Random_Character_Failed() Script_Cleanup() ENDIF // Initialisation DATA_INIT() // Grab stash truck now in case checkpoints need to respawn it IF DOES_ENTITY_EXIST(sRCLauncherDataLocal.vehID[0]) stVehicle.vehicle = sRCLauncherDataLocal.vehID[0] ENDIF IF DOES_ENTITY_EXIST(sRCLauncherDataLocal.objID[0]) oiStashBox = sRCLauncherDataLocal.objID[0] ENDIF // Check whether this is a replay IF Is_Replay_In_Progress() INT iReplayStage = GET_REPLAY_MID_MISSION_STAGE() // Check for shit skip IF g_bShitskipAccepted iReplayStage++ ENDIF SWITCH iReplayStage CASE 0 CPRINTLN(DEBUG_MISSION, "On a replay - CP 0") START_REPLAY_SETUP(stVehicle.location, stVehicle.heading) SKIP_TO_START_DRIVE(TRUE) BREAK CASE CP_DELIVERY CPRINTLN(DEBUG_MISSION, "On a replay - CP_DELIVERY") START_REPLAY_SETUP(vecDestination, 298.7) SKIP_WARP_TO_DELIVERY(TRUE) BREAK CASE CP_SHITSKIP_COMPLETE CPRINTLN(DEBUG_MISSION, "On a replay - CP_SHITSKIP_COMPLETE") START_REPLAY_SETUP(<< -1243.3162, -1041.6366, 7.5121 >>, 28.2) SKIP_TRIGGER_COMPLETION(TRUE) BREAK DEFAULT SCRIPT_ASSERT("Replay in progress: Unknown checkpoint selected") BREAK ENDSWITCH RC_END_Z_SKIP() ELIF IS_REPEAT_PLAY_ACTIVE() CPRINTLN(DEBUG_MISSION, "Barry3A - repeat play") RC_END_Z_SKIP() ENDIF // Grab cop car IF DOES_ENTITY_EXIST(sRCLauncherDataLocal.vehID[1]) ASSIGN_VEHICLE_INDEX(ctTrapInfo[0].vehicle, sRCLauncherDataLocal.vehID[1]) ENDIF IF DOES_ENTITY_EXIST(sRCLauncherDataLocal.pedID[0]) ASSIGN_PED_INDEX(ctTrapInfo[0].driver, sRCLauncherDataLocal.pedID[0]) ENDIF IF DOES_ENTITY_EXIST(sRCLauncherDataLocal.pedID[1]) ASSIGN_PED_INDEX(ctTrapInfo[0].passenger, sRCLauncherDataLocal.pedID[1]) ENDIF TRUCK_INIT() // Loop within here until the mission passes or fails WHILE(TRUE) REPLAY_CHECK_FOR_EVENT_THIS_FRAME("SF_GRTP") UPDATE_MISSION_NAME_DISPLAYING(sRCLauncherDataLocal.sIntroCutscene, FALSE, FALSE, TRUE) DO_CLOCK() // Clock should stay on in fade if it's active, so this lives outside fail stage check IF mStage = MS_STAGE_FAIL_FADE STAGE_FAIL_FADE() ELSE IF NOT MISSION_FAILED_CHECKS() // Check debug completion/failure DEBUG_Check_Debug_Keys() HANDLE_COPS() SWITCH mStage CASE MS_STAGE_INIT STAGE_INIT() BREAK CASE MS_STAGE_CALL_BARRY STAGE_CALL_BARRY() BREAK CASE MS_STAGE_ENTER_TRUCK STAGE_ENTER_TRUCK() BREAK CASE MS_STAGE_RETURN_VEHICLE STAGE_RETURN_VEHICLE() BREAK CASE MS_STAGE_GET_VEHICLE_BACK STAGE_GET_VEHICLE_BACK() BREAK CASE MS_STAGE_LOSE_WANTED STAGE_LOSE_WANTED() BREAK CASE MS_STAGE_DELIVERY STAGE_DELIVERY() BREAK CASE MS_STAGE_LEAVE_AREA STAGE_LEAVE_AREA() BREAK CASE MS_STAGE_TAKE_VEHICLE_BACK STAGE_TAKE_VEHICLE_BACK() BREAK ENDSWITCH ENDIF ENDIF WAIT(0) ENDWHILE // Script should never reach here. Always terminate with cleanup function. ENDSCRIPT